44
55use Parser \UseParser ;
66use Parser \CommentParser ;
7+ use Complete \Resolver \NodeTypeResolver ;
8+ use Parser \ParamParser ;
9+
710use Entity \FQCN ;
811use Entity \Index ;
912use Entity \Node \Uses ;
1013use Entity \Node \Variable ;
1114use Entity \Completion \Scope ;
12- use Complete \ Resolver \ NodeTypeResolver ;
15+
1316use PhpParser \NodeTraverserInterface ;
17+ use PhpParser \NodeVisitorAbstract ;
18+
1419use PhpParser \Node ;
1520use PhpParser \Node \Expr \Variable as NodeVar ;
21+ use PhpParser \Node \Expr \Assign ;
1622use PhpParser \Node \Stmt \Use_ ;
1723use PhpParser \Node \Stmt \Class_ ;
1824use PhpParser \Node \Stmt \ClassMethod ;
19- use PhpParser \Node \Expr \Assign ;
20- use PhpParser \NodeVisitorAbstract ;
25+ use PhpParser \Node \Expr \Closure ;
2126
2227class ScopeProcessor extends NodeVisitorAbstract implements ProcessorInterface {
2328 public function __construct (
2429 UseParser $ useParser ,
2530 NodeTypeResolver $ typeResolver ,
26- CommentParser $ commentParser
31+ CommentParser $ commentParser ,
32+ ParamParser $ paramParser
2733 ){
2834 $ this ->resultNodes = [];
2935 $ this ->useParser = $ useParser ;
3036 $ this ->typeResolver = $ typeResolver ;
3137 $ this ->commentParser = $ commentParser ;
38+ $ this ->paramParser = $ paramParser ;
3239 }
3340 public function setLine ($ line ){
3441 $ this ->line = $ line ;
@@ -39,20 +46,14 @@ public function enterNode(Node $node){
3946 return NodeTraverserInterface::DONT_TRAVERSE_CHILDREN ;
4047 }
4148 if ($ node instanceof Class_){
42- $ this ->scope ->setFQCN (
43- new FQCN (
44- $ node ->name ,
45- $ this ->scope ->getUses ()->getFQCN ()
46- )
47- );
48- $ this ->createScope ();
49- $ var = new Variable ('this ' );
50- $ var ->setType ($ this ->scope ->getFQCN ());
51- $ this ->scope ->addVar ($ var );
49+ $ this ->createScopeFromClass ($ node );
5250 }
5351 elseif ($ node instanceof ClassMethod){
5452 $ this ->createScopeFromMethod ($ node );
5553 }
54+ elseif ($ node instanceof Closure){
55+ $ this ->createScopeFromClosure ($ node );
56+ }
5657 elseif ($ node instanceof Assign){
5758 $ this ->addVarToScope ($ node );
5859 }
@@ -74,7 +75,10 @@ public function getResultNodes(){
7475 }
7576 public function isIn ($ node , $ line ){
7677 list ($ startLine , $ endLine ) = $ this ->getNodeLines ($ node );
77- if ($ node instanceof ClassMethod){
78+ if ($ node instanceof ClassMethod
79+ || $ node instanceof Closure
80+ || $ node instanceof Class_
81+ ){
7882 return $ line >= $ startLine && $ line <= $ endLine ;
7983 }
8084 return $ line >= $ startLine ;
@@ -89,7 +93,38 @@ public function getNodeLines($node){
8993 }
9094 return [$ startLine , $ endLine ];
9195 }
96+ protected function createScopeFromClass (Class_ $ node ){
97+ $ this ->createScope ();
98+ $ this ->scope ->setFQCN (
99+ new FQCN (
100+ $ node ->name ,
101+ $ this ->scope ->getUses ()->getFQCN ()
102+ )
103+ );
104+ $ var = new Variable ('this ' );
105+ $ var ->setType ($ this ->scope ->getFQCN ());
106+ $ this ->scope ->addVar ($ var );
107+ }
108+ public function createScopeFromClosure (Closure $ node ){
109+ $ this ->createScope ();
110+ foreach ($ node ->params AS $ param ){
111+ $ this ->scope ->addVar (
112+ $ this ->paramParser ->parse ($ param )
113+ );
114+ }
115+ foreach ($ node ->uses as $ closureUse ){
116+ $ var = $ this ->scope ->getParent ()->getVar ($ closureUse ->var );
117+ if ($ var instanceof Variable){
118+ $ this ->scope ->addVar (
119+ $ var
120+ );
121+ }
122+
123+ }
124+ }
92125 public function createScopeFromMethod (ClassMethod $ node ){
126+ $ this ->createScope ();
127+ $ this ->scope ->addVar ($ this ->scope ->getParent ()->getVar ('this ' ));
93128 $ index = $ this ->getIndex ();
94129 if (empty ($ index )){
95130 return ;
@@ -160,4 +195,6 @@ protected function createScope(){
160195 private $ scope ;
161196 private $ typeResolver ;
162197 private $ commentParser ;
198+ /** @property ParamParser */
199+ private $ paramParser ;
163200}
0 commit comments