Skip to content

Commit 6dce680

Browse files
committed
added Closure parsing
Splitted MethodParser into MethodParser and ParamParser. Added Closure processing to ScopeProcessor
1 parent 0c19cba commit 6dce680

10 files changed

Lines changed: 105 additions & 41 deletions

File tree

src/Entity/Collection/MethodsCollection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function remove(MethodData $method){
2323
}
2424
public function get($name, Specification $spec = null){
2525
if($spec === null){
26-
$spec = new Specification;
26+
$spec = new Specification('private', false, true);
2727
}
2828
if(array_key_exists($name, $this->methods)){
2929
$method = $this->methods[$name];

src/Entity/FQN.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public function getLast(){
3838
$parts = $this->getParts();
3939
return array_pop($parts);
4040
}
41+
public function getTail(){
42+
$parts = $this->getParts();
43+
array_pop($parts);
44+
return $parts;
45+
}
4146
public function getParts(){
4247
if(is_array($this->parts)){
4348
return $this->parts;

src/Entity/Index.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ public function addClass(ClassData $class){
100100
$this->addExtend($class, $class->getParent());
101101
}
102102
foreach($class->getInterfaces() as $interface){
103-
$this->addImplement($class, $interface);
103+
if($interface instanceof FQCN){
104+
$this->addImplement($class, $interface);
105+
}
104106
}
105107
foreach($this->findClassChildren($class->fqcn) AS $child){
106108
$child->setParent($class);
@@ -110,7 +112,7 @@ public function addClass(ClassData $class){
110112
public function addInterface(InterfaceData $interface){
111113
$this->interfaces[$interface->fqcn->toString()] = $interface;
112114
foreach($this->findInterfaceChildrenClasses($interface->fqcn) as $child){
113-
$child->addInterface($interface);
115+
$this->addImplement($child, $interface->fqcn);
114116
}
115117
}
116118

@@ -144,13 +146,10 @@ protected function addExtend(ClassData $class, FQCN $parent){
144146
}
145147
}
146148

147-
protected function addImplement(ClassData $class, FQCN $interface){
148-
if(!array_key_exists($interface->toString(), $this->implements)
149-
|| !is_array($this->implements[$interface->toString()])){
150-
$this->implements[$interface->toString()] = [];
151-
}
152-
$this->implements[$interface->toString()][$class->fqcn->toString()] = $class;
153-
$interface = $this->findInterfaceByFQCN($interface);
149+
protected function addImplement(ClassData $class, FQCN $fqcn){
150+
$this->findInterfaceChildrenClasses($fqcn);
151+
$this->implements[$fqcn->toString()][$class->fqcn->toString()] = $class;
152+
$interface = $this->findInterfaceByFQCN($fqcn);
154153
if($interface instanceof InterfaceData){
155154
$class->addInterface($interface);
156155
}

src/Entity/Node/ClassData.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Entity\Node;
44

55
use Entity\FQCN;
6+
use Entity\FQN;
67
use Entity\Collection\MethodsCollection;
78
use Entity\Collection\PropertiesCollection;
89

src/Generator/IndexGenerator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ public function processFileNodes(Index $index, $nodes){
156156
$this->getLogger()->addDebug('Processing nodes ' . count($nodes));
157157
foreach($nodes as $node){
158158
if($node instanceof ClassData){
159-
$this->getLogger()->addDebug('Processing node ' . $node->name);
159+
$this->getLogger()->addDebug('Processing node ' . $node->fqcn->toString());
160160
$index->addFQCN($node->fqcn);
161161
$index->addClass($node);
162162
}
163163
elseif($node instanceof InterfaceData){
164-
$this->getLogger()->addDebug('Processing node ' . $node->name);
164+
$this->getLogger()->addDebug('Processing node ' . $node->fqcn->toString());
165165
$index->addFQCN($node->fqcn);
166166
$index->addInterface($node);
167167
}

src/Parser/ClassParser.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public function __construct(
4141

4242
public function parse(Class_ $node, Entity\FQN $fqn, $file){
4343
$fqcn = new Entity\FQCN($node->name, $fqn);
44-
print_r('Parsing class: ' . $fqcn->toString() . "\n");
4544
$classData = new Node\ClassData($fqcn, $file);
4645
if($node->extends instanceof Name){
4746
$classData->setParent(

src/Parser/MethodParser.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ class MethodParser{
1717
*/
1818
public function __construct(
1919
UseParser $useParser,
20-
CommentParser $commentParser
20+
CommentParser $commentParser,
21+
ParamParser $paramParser
2122
)
2223
{
2324
$this->useParser = $useParser;
2425
$this->commentParser = $commentParser;
26+
$this->paramParser = $paramParser;
2527
}
2628

2729
/**
@@ -57,17 +59,13 @@ public function parse(ClassMethod $node)
5759
return $method;
5860
}
5961
protected function parseMethodArgument(Param $node){
60-
$param = new MethodParam($node->name);
61-
if($node->type instanceof Name)
62-
$param->setFQCN($this->useParser->getFQCN($node->type));
63-
else{
64-
$param->setType($node->type);
65-
}
66-
return $param;
62+
return $this->paramParser->parse($node);
6763
}
6864

6965
/** @var UseParser $useParser */
7066
private $useParser;
7167
/** @property CommentParser $commentParser */
7268
private $commentParser;
69+
/** @var ParamParser */
70+
private $paramParser;
7371
}

src/Parser/ParamParser.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Parser;
4+
5+
use PhpParser\Node\Param;
6+
use PhpParser\Node\Name;
7+
use Entity\Node\MethodParam;
8+
9+
class ParamParser {
10+
public function __construct(UseParser $useParser){
11+
$this->useParser = $useParser;
12+
}
13+
public function parse(Param $node){
14+
$param = new MethodParam($node->name);
15+
if($node->type instanceof Name)
16+
$param->setFQCN($this->useParser->getFQCN($node->type));
17+
else{
18+
$param->setType($node->type);
19+
}
20+
return $param;
21+
}
22+
23+
private $useParser;
24+
}

src/Parser/Processor/ScopeProcessor.php

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,38 @@
44

55
use Parser\UseParser;
66
use Parser\CommentParser;
7+
use Complete\Resolver\NodeTypeResolver;
8+
use Parser\ParamParser;
9+
710
use Entity\FQCN;
811
use Entity\Index;
912
use Entity\Node\Uses;
1013
use Entity\Node\Variable;
1114
use Entity\Completion\Scope;
12-
use Complete\Resolver\NodeTypeResolver;
15+
1316
use PhpParser\NodeTraverserInterface;
17+
use PhpParser\NodeVisitorAbstract;
18+
1419
use PhpParser\Node;
1520
use PhpParser\Node\Expr\Variable as NodeVar;
21+
use PhpParser\Node\Expr\Assign;
1622
use PhpParser\Node\Stmt\Use_;
1723
use PhpParser\Node\Stmt\Class_;
1824
use PhpParser\Node\Stmt\ClassMethod;
19-
use PhpParser\Node\Expr\Assign;
20-
use PhpParser\NodeVisitorAbstract;
25+
use PhpParser\Node\Expr\Closure;
2126

2227
class 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
}

src/Parser/UseParser.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ public function parseType($type){
2828
if(!empty($fqcn)){
2929
return $fqcn;
3030
}
31-
return $this->uses->getFQCN()->join(
32-
$pureFQCN
33-
);
31+
return $this->createFQCN($pureFQCN);
3432
}
3533
public function getFQCN(Name $node = null){
3634
if($node === null)
@@ -42,8 +40,7 @@ public function getFQCN(Name $node = null){
4240
if($fqcn){
4341
return $fqcn;
4442
}
45-
$fqcn = $this->uses->getFQCN()->join($this->parseFQCN($node->toString()));
46-
return $fqcn;
43+
return $this->createFQCN($node->toString());
4744
}
4845
public function parseFQCN($fqcn){
4946
$fqcn = trim($fqcn, '\\');
@@ -71,4 +68,8 @@ public function getUses(){
7168
public function setUses(Uses $uses = null){
7269
$this->uses = $uses;
7370
}
71+
protected function createFQCN($fqcn){
72+
$fqn = $this->uses->getFQCN()->join($this->parseFQCN($fqcn));
73+
return new FQCN($fqn->getLast(), $fqn->getTail());
74+
}
7475
}

0 commit comments

Comments
 (0)