@@ -1680,23 +1680,28 @@ function! phpcomplete#GetCallChainReturnType(classname_candidate, class_candidat
1680
1680
for classstructure in classcontents
1681
1681
let docblock_target_pattern = ' function\s\+&\?' .method.' \>\|\(public\|private\|protected\|var\).\+\$' .method.' \>\|@property.\+\$' .method.' \>'
1682
1682
let doc_str = phpcomplete#GetDocBlock (split (classstructure.content, ' \n' ), docblock_target_pattern)
1683
- if doc_str != ' '
1683
+ let return_type_hint = phpcomplete#GetFunctionReturnTypeHint (split (classstructure.content, ' \n' ), ' function\s\+&\?' .method.' \>' )
1684
+ if doc_str != ' ' || return_type_hint != ' '
1684
1685
break
1685
1686
endif
1686
1687
endfor
1687
- if doc_str != ' '
1688
+ if doc_str != ' ' || return_type_hint != ' '
1688
1689
let docblock = phpcomplete#ParseDocBlock (doc_str)
1689
- if has_key (docblock.return , ' type' ) || has_key (docblock.var , ' type' ) || len (docblock.properties) > 0
1690
- let type = has_key (docblock.return , ' type' ) ? docblock.return .type : has_key (docblock.var , ' type' ) ? docblock.var .type : ' '
1691
-
1692
- if type == ' '
1693
- for property in docblock.properties
1694
- if property.description = ~? method
1695
- let type = property.type
1696
- break
1697
- endif
1698
- endfor
1699
- endif
1690
+ if has_key (docblock.return , ' type' ) || has_key (docblock.var , ' type' ) || len (docblock.properties) > 0 || return_type_hint != ' '
1691
+ if return_type_hint == ' '
1692
+ let type = has_key (docblock.return , ' type' ) ? docblock.return .type : has_key (docblock.var , ' type' ) ? docblock.var .type : ' '
1693
+
1694
+ if type == ' '
1695
+ for property in docblock.properties
1696
+ if property.description = ~? method
1697
+ let type = property.type
1698
+ break
1699
+ endif
1700
+ endfor
1701
+ endif
1702
+ else
1703
+ let type = return_type_hint
1704
+ end
1700
1705
1701
1706
" there's a namespace in the type, threat the type as FQCN
1702
1707
if type = ~ ' \\'
@@ -1874,9 +1879,11 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
1874
1879
elseif function_file != ' ' && filereadable (function_file)
1875
1880
let file_lines = readfile (function_file)
1876
1881
let docblock_str = phpcomplete#GetDocBlock (file_lines, ' function\s*&\?\<' .function_name.' \>' )
1882
+ let return_type_hint = phpcomplete#GetFunctionReturnTypeHint (file_lines, ' function\s*&\?' .function_name.' \>' )
1877
1883
let docblock = phpcomplete#ParseDocBlock (docblock_str)
1878
- if has_key (docblock.return , ' type' )
1879
- let classname_candidate = docblock.return .type
1884
+ let type = has_key (docblock.return , ' type' ) ? docblock.return .type : return_type_hint
1885
+ if type != ' '
1886
+ let classname_candidate = type
1880
1887
let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace (file_lines)
1881
1888
" try to expand the classname of the returned type with the context got from the function's source file
1882
1889
@@ -2108,9 +2115,11 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
2108
2115
elseif function_file != ' ' && filereadable (function_file)
2109
2116
let file_lines = readfile (function_file)
2110
2117
let docblock_str = phpcomplete#GetDocBlock (file_lines, ' function\s*&\?\<' .function_name.' \>' )
2118
+ let return_type_hint = phpcomplete#GetFunctionReturnTypeHint (file_lines, ' function\s*&\?' .function_name.' \>' )
2111
2119
let docblock = phpcomplete#ParseDocBlock (docblock_str)
2112
- if has_key (docblock.return , ' type' )
2113
- let classname_candidate = docblock.return .type
2120
+ let type = has_key (docblock.return , ' type' ) ? docblock.return .type : return_type_hint
2121
+ if type != ' '
2122
+ let classname_candidate = type
2114
2123
let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace (file_lines)
2115
2124
" try to expand the classname of the returned type with the context got from the function's source file
2116
2125
let [classname_candidate, class_candidate_namespace] = phpcomplete#ExpandClassName (classname_candidate, class_candidate_namespace, function_imports)
@@ -2703,6 +2712,44 @@ function! phpcomplete#ParseDocBlock(docblock) " {{{
2703
2712
endfunction
2704
2713
" }}}
2705
2714
2715
+ function ! phpcomplete#GetFunctionReturnTypeHint (sccontent, search )
2716
+ let i = 0
2717
+ let l = 0
2718
+ let function_line_start = -1
2719
+ let function_line_end = -1
2720
+ let sccontent_len = len (a: sccontent )
2721
+ let return_type = ' '
2722
+
2723
+ while (i < sccontent_len)
2724
+ let line = a: sccontent [i ]
2725
+ " search for a function declaration
2726
+ if line = ~? a: search
2727
+ let l = i
2728
+ let function_line_start = i
2729
+ " now search for the first { where the function body starts
2730
+ while l < sccontent_len
2731
+ let line = a: sccontent [l ]
2732
+ if line = ~? ' \V{'
2733
+ let function_line_end = l
2734
+ break
2735
+ endif
2736
+ let l += 1
2737
+ endwhile
2738
+ break
2739
+ endif
2740
+ let i += 1
2741
+ endwhile
2742
+
2743
+ " now grab the lines that holds the function declaration line
2744
+ if function_line_start != -1 && function_line_end != -1
2745
+ let function_line = join (a: sccontent [function_line_start :function_line_end], " " )
2746
+ let class_name_pattern = ' [a-zA-Z_\x7f-\xff\\][a-zA-Z_0-9\x7f-\xff\\]*'
2747
+ let return_type = matchstr (function_line, ' \c\s*:\s*\zs' .class_name_pattern.' \ze\s*{' )
2748
+ endif
2749
+ return return_type
2750
+
2751
+ endfunction
2752
+
2706
2753
function ! phpcomplete#GetTypeFromDocBlockParam (docblock_type) " {{{
2707
2754
if a: docblock_type !~ ' |'
2708
2755
return a: docblock_type
0 commit comments