33" Maintainer: Dávid Szabó ( complex857 AT gmail DOT com )
44" Previous Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )
55" URL: https://github.com/shawncplus/phpcomplete.vim
6- " Last Change: 2015 Jul 13
6+ " Last Change: 2016 Oct 10
77"
88" OPTIONS:
99"
@@ -195,6 +195,8 @@ function! phpcomplete#CompletePHP(findstart, base) " {{{
195195 " }}}
196196 elseif context = ~? ' implements'
197197 return phpcomplete#CompleteClassName (a: base , [' i' ], current_namespace, imports)
198+ elseif context = ~? ' instanceof'
199+ return phpcomplete#CompleteClassName (a: base , [' c' , ' n' ], current_namespace, imports)
198200 elseif context = ~? ' extends\s\+.\+$' && a: base == ' '
199201 return [' implements' ]
200202 elseif context = ~? ' extends'
@@ -787,6 +789,8 @@ function! phpcomplete#CompleteClassName(base, kinds, current_namespace, imports)
787789
788790 if kinds == [' c' , ' i' ]
789791 let filterstr = ' v:val =~? "\\(class\\|interface\\)\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
792+ elseif kinds == [' c' , ' n' ]
793+ let filterstr = ' v:val =~? "\\(class\\|namespace\\)\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
790794 elseif kinds == [' c' ]
791795 let filterstr = ' v:val =~? "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*"'
792796 elseif kinds == [' i' ]
@@ -996,7 +1000,7 @@ function! phpcomplete#CompleteUserClass(context, base, sccontent, visibility) "
9961000 let required_modifiers += [' static' ]
9971001 endif
9981002 let all_variable = filter (deepcopy (a: sccontent ),
999- \ ' v:val =~ "^\\s*\\(var\\s\\+\\|public\\s\\+\\|protected\\s\\+\\|private\\s\\+\\|final\\s\\+\\|abstract\\s\\+\\|static\\s\\+\\)\\+\\$"' )
1003+ \ ' v:val =~ "\\( ^\\s*\\(var\\s\\+\\|public\\s\\+\\|protected\\s\\+\\|private\\s\\+\\|final\\s\\+\\|abstract\\s\\+\\|static\\s\\+\\)\\+\\$\\|^\\s*\\(\\/\\|\\*\\)*\\s*@property\\s\\+\\S\\+\\s\\S\\{-}\\s*$\\) "' )
10001004
10011005 let variables = []
10021006 for i in all_variable
@@ -1160,6 +1164,14 @@ function! phpcomplete#GetTaglist(pattern) " {{{
11601164 endif
11611165
11621166 let tags = taglist (a: pattern )
1167+ for tag in tags
1168+ for prop in keys (tag )
1169+ if prop == ' cmd' || prop == ' static' || prop == ' kind' || prop == ' builtin'
1170+ continue
1171+ endif
1172+ let tag [prop] = substitute (tag [prop], ' \\\\' , ' \\' , ' g' )
1173+ endfor
1174+ endfor
11631175 let s: cache_tags [a: pattern ] = tags
11641176 let has_key = has_key (s: cache_tags , a: pattern )
11651177 let s: cache_tags_checksum = cache_checksum
@@ -1379,16 +1391,25 @@ function! phpcomplete#GetCallChainReturnType(classname_candidate, class_candidat
13791391 " Get Structured information of all classes and subclasses including namespace and includes
13801392 " try to find the method's return type in docblock comment
13811393 for classstructure in classcontents
1382- let docblock_target_pattern = ' function\s\+&\?' .method.' \|\(public\|private\|protected\|var\).\+\$' .method
1394+ let docblock_target_pattern = ' function\s\+&\?' .method.' \>\ |\(public\|private\|protected\|var\).\+\$' .method. ' \>\|@property.\+\$ ' .method. ' \> '
13831395 let doc_str = phpcomplete#GetDocBlock (split (classstructure.content, ' \n' ), docblock_target_pattern)
13841396 if doc_str != ' '
13851397 break
13861398 endif
13871399 endfor
13881400 if doc_str != ' '
13891401 let docblock = phpcomplete#ParseDocBlock (doc_str)
1390- if has_key (docblock.return , ' type' ) || has_key (docblock.var , ' type' )
1391- let type = has_key (docblock.return , ' type' ) ? docblock.return .type : docblock.var .type
1402+ if has_key (docblock.return , ' type' ) || has_key (docblock.var , ' type' ) || len (docblock.properties) > 0
1403+ let type = has_key (docblock.return , ' type' ) ? docblock.return .type : has_key (docblock.var , ' type' ) ? docblock.var .type : ' '
1404+
1405+ if type == ' '
1406+ for property in docblock.properties
1407+ if property.description = ~? method
1408+ let type = property.type
1409+ break
1410+ endif
1411+ endfor
1412+ endif
13921413
13931414 " there's a namespace in the type, threat the type as FQCN
13941415 if type = ~ ' \\'
@@ -1554,6 +1575,9 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
15541575 elseif get (methodstack, 0 ) = ~# function_invocation_pattern
15551576 let function_name = matchstr (methodstack[0 ], ' ^\s*\zs' .function_name_pattern)
15561577 let function_file = phpcomplete#GetFunctionLocation (function_name, a: current_namespace )
1578+ if function_file == ' '
1579+ let function_file = phpcomplete#GetFunctionLocation (function_name, ' \' )
1580+ endif
15571581
15581582 if function_file == ' VIMPHP_BUILTINFUNCTION'
15591583 " built in function, grab the return type from the info string
@@ -1569,7 +1593,7 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
15691593 let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace (file_lines)
15701594 " try to expand the classname of the returned type with the context got from the function's source file
15711595
1572- let [classname_candidate, unused ] = phpcomplete#ExpandClassName (classname_candidate, class_candidate_namespace, function_imports)
1596+ let [classname_candidate, class_candidate_namespace ] = phpcomplete#ExpandClassName (classname_candidate, class_candidate_namespace, function_imports)
15731597 endif
15741598 endif
15751599 if classname_candidate != ' '
@@ -1650,9 +1674,10 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
16501674 let sub_methodstack = phpcomplete#GetMethodStack (matchstr (line , ' ^\s*' .object.' \s*=&\?\s*\s\+\zs.*' ))
16511675 let [classname_candidate, class_candidate_namespace] = phpcomplete#GetCallChainReturnType (
16521676 \ classname,
1653- \ a: current_namespace ,
1677+ \ namespace_for_class ,
16541678 \ a: imports ,
16551679 \ sub_methodstack)
1680+
16561681 return (class_candidate_namespace == ' \' || class_candidate_namespace == ' ' ) ? classname_candidate : class_candidate_namespace.' \' .classname_candidate
16571682 endif
16581683 endif
@@ -1783,6 +1808,9 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
17831808 let [function_name, function_namespace] = phpcomplete#ExpandClassName (function_name, a: current_namespace , a: imports )
17841809
17851810 let function_file = phpcomplete#GetFunctionLocation (function_name, function_namespace)
1811+ if function_file == ' '
1812+ let function_file = phpcomplete#GetFunctionLocation (function_name, ' \' )
1813+ endif
17861814
17871815 if function_file == ' VIMPHP_BUILTINFUNCTION'
17881816 " built in function, grab the return type from the info string
@@ -1798,7 +1826,7 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
17981826 let classname_candidate = docblock.return .type
17991827 let [class_candidate_namespace, function_imports] = phpcomplete#GetCurrentNameSpace (file_lines)
18001828 " try to expand the classname of the returned type with the context got from the function's source file
1801- let [classname_candidate, unused ] = phpcomplete#ExpandClassName (classname_candidate, class_candidate_namespace, function_imports)
1829+ let [classname_candidate, class_candidate_namespace ] = phpcomplete#ExpandClassName (classname_candidate, class_candidate_namespace, function_imports)
18021830 break
18031831 endif
18041832 endif
@@ -1861,6 +1889,8 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor
18611889 for tag in tags
18621890 if tag .kind == ? ' v' && tag .cmd = ~? ' =\s*new\s\+\zs' .class_name_pattern.' \ze'
18631891 let classname = matchstr (tag .cmd, ' =\s*new\s\+\zs' .class_name_pattern.' \ze' )
1892+ " unescape the classname, it would have "\" doubled since it is an ex command
1893+ let classname = substitute (classname, ' \\\(\_.\)' , ' \1' , ' g' )
18641894 return classname
18651895 endif
18661896 endfor
@@ -2077,6 +2107,19 @@ function! phpcomplete#GetClassContentsStructure(file_path, file_lines, class_nam
20772107 endif
20782108 call searchpair (' {' , ' ' , ' }' , ' W' )
20792109 let class_closing_bracket_line = line (' .' )
2110+
2111+ " Include class docblock
2112+ let doc_line = cfline - 1
2113+ if getline (doc_line) = ~? ' ^\s*\*/'
2114+ while doc_line != 0
2115+ if getline (doc_line) = ~? ' ^\s*/\*\*'
2116+ let cfline = doc_line
2117+ break
2118+ endif
2119+ let doc_line -= 1
2120+ endwhile
2121+ endif
2122+
20802123 let classcontent = join (getline (cfline, class_closing_bracket_line), " \n " )
20812124
20822125 let used_traits = []
@@ -2241,8 +2284,19 @@ function! phpcomplete#GetDocBlock(sccontent, search) " {{{
22412284 let line = a: sccontent [i ]
22422285 " search for a function declaration
22432286 if line = ~? a: search
2244- let l = i - 1
2245- " start backward serch for the comment block
2287+ if line = ~? ' @property'
2288+ let doc_line = i
2289+ while doc_line != sccontent_len - 1
2290+ if a: sccontent [doc_line] = ~? ' ^\s*\*/'
2291+ let l = doc_line
2292+ break
2293+ endif
2294+ let doc_line += 1
2295+ endwhile
2296+ else
2297+ let l = i - 1
2298+ endif
2299+ " start backward search for the comment block
22462300 while l != 0
22472301 let line = a: sccontent [l ]
22482302 " if it's a one line docblock like comment and we can just return it right away
@@ -2263,7 +2317,7 @@ function! phpcomplete#GetDocBlock(sccontent, search) " {{{
22632317 return ' '
22642318 end
22652319
2266- while l ! = 0
2320+ while l > = 0
22672321 let line = a: sccontent [l ]
22682322 if line = ~? ' ^\s*/\*\*'
22692323 let comment_start = l
@@ -2297,9 +2351,10 @@ function! phpcomplete#ParseDocBlock(docblock) " {{{
22972351 \ ' return' : {},
22982352 \ ' throws' : [],
22992353 \ ' var' : {},
2354+ \ ' properties' : [],
23002355 \ }
23012356
2302- let res .description = substitute (matchstr (a: docblock , ' \zs\_.\{-}\ze\(@var\|@param\|@return\|$\)' ), ' \(^\_s*\|\_s*$\)' , ' ' , ' g' )
2357+ let res .description = substitute (matchstr (a: docblock , ' \zs\_.\{-}\ze\(@type\|@ var\|@param\|@return\|$\)' ), ' \(^\_s*\|\_s*$\)' , ' ' , ' g' )
23032358 let docblock_lines = split (a: docblock , " \n " )
23042359
23052360 let param_lines = filter (copy (docblock_lines), ' v:val =~? "^@param"' )
@@ -2334,15 +2389,26 @@ function! phpcomplete#ParseDocBlock(docblock) " {{{
23342389 endif
23352390 endfor
23362391
2337- let var_line = filter (copy (docblock_lines), ' v:val =~? "^@var"' )
2392+ let var_line = filter (copy (docblock_lines), ' v:val =~? "^\\( @var\\|@type\\) "' )
23382393 if len (var_line) > 0
2339- let var_parts = matchlist (var_line[0 ], ' @var\s\+\(\S\+\)\s*\(.*\)' )
2394+ let var_parts = matchlist (var_line[0 ], ' \( @var\|@type\) \s\+\(\S\+\)\s*\(.*\)' )
23402395 let res [' var' ] = {
23412396 \ ' line' : var_parts[0 ],
2342- \ ' type' : phpcomplete#GetTypeFromDocBlockParam (get (var_parts, 1 , ' ' )),
2343- \ ' description' : get (var_parts, 2 , ' ' )}
2397+ \ ' type' : phpcomplete#GetTypeFromDocBlockParam (get (var_parts, 2 , ' ' )),
2398+ \ ' description' : get (var_parts, 3 , ' ' )}
23442399 endif
23452400
2401+ let property_lines = filter (copy (docblock_lines), ' v:val =~? "^@property"' )
2402+ for property_line in property_lines
2403+ let parts = matchlist (property_line, ' \(@property\)\s\+\(\S\+\)\s*\(.*\)' )
2404+ if len (parts) > 0
2405+ call add (res .properties, {
2406+ \ ' line' : parts[0 ],
2407+ \ ' type' : phpcomplete#GetTypeFromDocBlockParam (get (parts, 2 , ' ' )),
2408+ \ ' description' : get (parts, 3 , ' ' )})
2409+ endif
2410+ endfor
2411+
23462412 return res
23472413endfunction
23482414" }}}
@@ -2498,6 +2564,7 @@ function! phpcomplete#GetCurrentNameSpace(file_lines) " {{{
24982564 let name = matchstr (name, ' \\\zs[^\\]\+\ze$' )
24992565 endif
25002566 endif
2567+
25012568 " leading slash is not required use imports are always absolute
25022569 let imports[name] = {' name' : object, ' kind' : ' ' }
25032570 endfor
@@ -2533,6 +2600,7 @@ function! phpcomplete#GetCurrentNameSpace(file_lines) " {{{
25332600 elseif ! exists (' no_namespace_candidate' )
25342601 " save the first namespacless match to be used if no better
25352602 " candidate found later on
2603+ let tag .namespace = namespace_for_classes
25362604 let no_namespace_candidate = tag
25372605 endif
25382606 endif
0 commit comments