Skip to content

Commit 1baf5c1

Browse files
authored
Merge pull request #11 from permafrost-dev/add-class-def-support
Add class definition support
2 parents cb08566 + a0a2d7e commit 1baf5c1

39 files changed

+545
-134
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes;
4+
5+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
7+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
8+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasValue;
9+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
10+
use PhpParser\Node;
11+
12+
class ClassConstantNode implements ResultNode
13+
{
14+
use BootsTraits;
15+
use HasLocation;
16+
use HasName;
17+
use HasValue;
18+
use HasVisibility;
19+
20+
public function __construct(Node\Stmt\ClassConst $node)
21+
{
22+
$this->bootTraits($node);
23+
$this->bootHasValue($node->consts[0]);
24+
}
25+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes;
4+
5+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
7+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
8+
use Permafrost\PhpCodeSearch\Support\NameResolver;
9+
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
10+
use PhpParser\Node;
11+
12+
class ClassDefinitionNode implements ResultNode
13+
{
14+
use BootsTraits;
15+
use HasName;
16+
use HasLocation;
17+
18+
/** @var array|ResultNode[]|ValueNode[] */
19+
public $properties;
20+
21+
/** @var array|ResultNode[]|ValueNode[] */
22+
public $methods;
23+
24+
public $implements = [];
25+
26+
public $extends;
27+
28+
/** @var array|ResultNode[]|ValueNode[] */
29+
public $constants = [];
30+
31+
public function __construct(Node\Stmt\Class_ $node)
32+
{
33+
$this->bootTraits($node);
34+
35+
$this->extends = NameResolver::resolve($node->extends);
36+
$this->implements = NameResolver::resolveAll($node->implements);
37+
$this->properties = StatementTransformer::parserNodesToResultNode($node->getProperties());
38+
$this->methods = StatementTransformer::parserNodesToResultNode($node->getMethods());
39+
$this->constants = StatementTransformer::parserNodesToResultNode($node->getConstants());
40+
}
41+
}

src/Results/Nodes/ClassMethodNode.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes;
4+
5+
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
7+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
8+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
9+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
10+
use Permafrost\PhpCodeSearch\Support\NameResolver;
11+
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
12+
use PhpParser\Node;
13+
14+
class ClassMethodNode implements ResultNode
15+
{
16+
use BootsTraits;
17+
use HasName;
18+
use HasLocation;
19+
use HasVisibility;
20+
21+
/** @var string|null */
22+
public $returnType;
23+
24+
public $isStatic = false;
25+
26+
public $isAbstract = false;
27+
28+
/** @var array|ResultNode[]|ValueNode[] */
29+
public $params = [];
30+
31+
public function __construct(Node\Stmt\ClassMethod $node)
32+
{
33+
$this->bootTraits($node);
34+
35+
$this->isStatic = $node->isStatic();
36+
$this->isAbstract = $node->isAbstract();
37+
$this->returnType = NameResolver::resolve($node->getReturnType());
38+
$this->params = StatementTransformer::parserNodesToResultNode($node->params);
39+
}
40+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes;
4+
5+
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
7+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
8+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
9+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
10+
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;
11+
use PhpParser\Node;
12+
13+
class ClassPropertyNode implements ResultNode
14+
{
15+
use BootsTraits;
16+
use HasName;
17+
use HasLocation;
18+
use HasVisibility;
19+
20+
/** @var ResultNode|ValueNode|null */
21+
public $default;
22+
23+
public $isStatic = false;
24+
25+
public function __construct(Node\Stmt\Property $node)
26+
{
27+
$this->bootTraits($node);
28+
29+
$this->isStatic = $node->isStatic();
30+
$this->default = ExpressionTransformer::parserNodeToResultNode($node->props[0]->default);
31+
}
32+
}

src/Results/Nodes/FunctionCallNode.php

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,31 @@
33
namespace Permafrost\PhpCodeSearch\Results\Nodes;
44

55
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
67
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
8+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
79
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\TransformsArguments;
10+
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;
811
use PhpParser\Node;
912

1013
class FunctionCallNode implements ResultNode
1114
{
15+
use BootsTraits;
16+
use HasName;
1217
use HasLocation;
13-
use TransformsArguments;
14-
15-
/** @var string */
16-
public $name;
1718

1819
/** @var array|ResultNode[]|ValueNode[] */
1920
public $args;
2021

2122
public function __construct(Node\Expr\FuncCall $node)
2223
{
23-
$this->name = $node->name->toString();
24-
$this->args = $this->transformArgumentsToNodes($node->args);
25-
$this->location = GenericCodeLocation::createFromNode($node);
24+
$this->bootTraits($node);
25+
26+
$this->args = ExpressionTransformer::parserNodesToResultNodes($node->args);
2627
}
2728

2829
public static function create(Node\Expr\FuncCall $node): self
2930
{
3031
return new static(...func_get_args());
3132
}
32-
33-
public function name(): string
34-
{
35-
return $this->name;
36-
}
3733
}

src/Results/Nodes/FunctionDefinitionNode.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,32 @@
33
namespace Permafrost\PhpCodeSearch\Results\Nodes;
44

55
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
6+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
67
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
8+
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
79
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\TransformsArguments;
810
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
911
use PhpParser\Node;
1012

1113
class FunctionDefinitionNode implements ResultNode
1214
{
15+
use BootsTraits;
16+
use HasName;
1317
use HasLocation;
1418
use TransformsArguments;
1519

16-
/** @var string */
17-
public $name;
18-
1920
/** @var array|ResultNode[]|ValueNode[] */
2021
public $args;
2122

2223
public function __construct(Node\Stmt\Function_ $node)
2324
{
24-
$this->name = $node->name->toString();
25-
$this->args = (new StatementTransformer())->parserNodesToResultNode($node->getParams());
26-
$this->location = GenericCodeLocation::createFromNode($node);
25+
$this->bootTraits($node);
26+
27+
$this->args = StatementTransformer::parserNodesToResultNode($node->getParams());
2728
}
2829

2930
public static function create(Node\Stmt\Function_ $node): self
3031
{
3132
return new static(...func_get_args());
3233
}
33-
34-
public function name(): string
35-
{
36-
return $this->name;
37-
}
3834
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;
4+
5+
use Permafrost\PhpCodeSearch\Support\Arr;
6+
7+
trait BootsTraits
8+
{
9+
protected function bootTraits($node): void
10+
{
11+
$reflectionObject = new \ReflectionObject($this);
12+
13+
collect($reflectionObject->getTraitNames())
14+
->map(function(string $name){
15+
if (strpos($name, __NAMESPACE__) === false) {
16+
return null;
17+
}
18+
return Arr::last(explode('\\', $name));
19+
})
20+
->filter()
21+
->each(function(string $name) use ($node) {
22+
$bootMethodName = 'boot'.$name;
23+
24+
if (method_exists($this, $bootMethodName)) {
25+
$this->$bootMethodName($node);
26+
}
27+
});
28+
}
29+
}

src/Results/Nodes/Traits/HasLocation.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;
44

55
use Permafrost\PhpCodeSearch\Code\CodeLocation;
6+
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
67

78
trait HasLocation
89
{
@@ -20,4 +21,9 @@ public function withLocation(CodeLocation $location): self
2021

2122
return $this;
2223
}
24+
25+
protected function bootHasLocation($node): void
26+
{
27+
$this->location = GenericCodeLocation::createFromNode($node);
28+
}
2329
}

src/Results/Nodes/Traits/HasName.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;
44

5+
use Permafrost\PhpCodeSearch\Support\NameResolver;
6+
57
trait HasName
68
{
79
/** @var string */
@@ -11,4 +13,9 @@ public function name(): string
1113
{
1214
return $this->name;
1315
}
16+
17+
protected function bootHasName($node): void
18+
{
19+
$this->name = NameResolver::resolve($node);
20+
}
1421
}

src/Results/Nodes/Traits/HasValue.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;
4+
5+
use Permafrost\PhpCodeSearch\Results\Nodes\Scalar\StringNode;
6+
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;
7+
8+
trait HasValue
9+
{
10+
/** @var string|StringNode */
11+
public $value;
12+
13+
public function value()
14+
{
15+
return $this->value;
16+
}
17+
18+
protected function bootHasValue($node): void
19+
{
20+
if (property_exists($node, 'value')) {
21+
$this->value = ExpressionTransformer::parserNodeToResultNode($node->value);
22+
}
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;
4+
5+
trait HasVisibility {
6+
7+
/** @var string */
8+
public $visibility = 'unknown';
9+
10+
protected function bootHasVisibility($node): void
11+
{
12+
$this->initVisibilityAttribute($node);
13+
}
14+
15+
protected function initVisibilityAttribute($node): void
16+
{
17+
$visibilityMap = [
18+
'isPublic' => 'public',
19+
'isPrivate' => 'private',
20+
'isProtected' => 'protected',
21+
];
22+
23+
foreach($visibilityMap as $method => $visibility) {
24+
if ($node->$method()) {
25+
$this->visibility = $visibility;
26+
return;
27+
}
28+
}
29+
30+
$this->visibility = 'unknown';
31+
}
32+
}

src/Searcher.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Permafrost\PhpCodeSearch\Support\NameResolver;
1010
use Permafrost\PhpCodeSearch\Support\VirtualFile;
1111
use Permafrost\PhpCodeSearch\Visitors\AssignmentVisitor;
12+
use Permafrost\PhpCodeSearch\Visitors\ClassDefinitionVisitor;
1213
use Permafrost\PhpCodeSearch\Visitors\FunctionCallVisitor;
1314
use Permafrost\PhpCodeSearch\Visitors\FunctionDefinitionVisitor;
1415
use Permafrost\PhpCodeSearch\Visitors\MethodCallVisitor;
@@ -162,6 +163,7 @@ protected function findAllReferences(array $ast): array
162163
Node\Expr\StaticCall::class => $this->static,
163164
Node\Expr\StaticPropertyFetch::class => $this->static,
164165
Node\Expr\Variable::class => $this->variables,
166+
Node\Stmt\Class_::class => $this->classes,
165167
Node\Stmt\Function_::class => $this->functions,
166168
];
167169

@@ -190,6 +192,7 @@ protected function traverseNodes(FileSearchResults $results, array $nodes): void
190192
$traverser = new NodeTraverser();
191193

192194
$traverser->addVisitor(new AssignmentVisitor($results, $this->assignments));
195+
$traverser->addVisitor(new ClassDefinitionVisitor($results, $this->classes));
193196
$traverser->addVisitor(new FunctionCallVisitor($results, $this->functions));
194197
$traverser->addVisitor(new FunctionDefinitionVisitor($results, $this->functions));
195198
$traverser->addVisitor(new MethodCallVisitor($results, $this->methods));

0 commit comments

Comments
 (0)