Skip to content

Commit

Permalink
Merge pull request #11 from permafrost-dev/add-class-def-support
Browse files Browse the repository at this point in the history
Add class definition support
  • Loading branch information
patinthehat authored Jul 30, 2021
2 parents cb08566 + a0a2d7e commit 1baf5c1
Show file tree
Hide file tree
Showing 39 changed files with 545 additions and 134 deletions.
25 changes: 25 additions & 0 deletions src/Results/Nodes/ClassConstantNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasValue;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
use PhpParser\Node;

class ClassConstantNode implements ResultNode
{
use BootsTraits;
use HasLocation;
use HasName;
use HasValue;
use HasVisibility;

public function __construct(Node\Stmt\ClassConst $node)
{
$this->bootTraits($node);
$this->bootHasValue($node->consts[0]);
}
}
41 changes: 41 additions & 0 deletions src/Results/Nodes/ClassDefinitionNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Support\NameResolver;
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
use PhpParser\Node;

class ClassDefinitionNode implements ResultNode
{
use BootsTraits;
use HasName;
use HasLocation;

/** @var array|ResultNode[]|ValueNode[] */
public $properties;

/** @var array|ResultNode[]|ValueNode[] */
public $methods;

public $implements = [];

public $extends;

/** @var array|ResultNode[]|ValueNode[] */
public $constants = [];

public function __construct(Node\Stmt\Class_ $node)
{
$this->bootTraits($node);

$this->extends = NameResolver::resolve($node->extends);
$this->implements = NameResolver::resolveAll($node->implements);
$this->properties = StatementTransformer::parserNodesToResultNode($node->getProperties());
$this->methods = StatementTransformer::parserNodesToResultNode($node->getMethods());
$this->constants = StatementTransformer::parserNodesToResultNode($node->getConstants());
}
}
40 changes: 40 additions & 0 deletions src/Results/Nodes/ClassMethodNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
use Permafrost\PhpCodeSearch\Support\NameResolver;
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
use PhpParser\Node;

class ClassMethodNode implements ResultNode
{
use BootsTraits;
use HasName;
use HasLocation;
use HasVisibility;

/** @var string|null */
public $returnType;

public $isStatic = false;

public $isAbstract = false;

/** @var array|ResultNode[]|ValueNode[] */
public $params = [];

public function __construct(Node\Stmt\ClassMethod $node)
{
$this->bootTraits($node);

$this->isStatic = $node->isStatic();
$this->isAbstract = $node->isAbstract();
$this->returnType = NameResolver::resolve($node->getReturnType());
$this->params = StatementTransformer::parserNodesToResultNode($node->params);
}
}
32 changes: 32 additions & 0 deletions src/Results/Nodes/ClassPropertyNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasVisibility;
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;
use PhpParser\Node;

class ClassPropertyNode implements ResultNode
{
use BootsTraits;
use HasName;
use HasLocation;
use HasVisibility;

/** @var ResultNode|ValueNode|null */
public $default;

public $isStatic = false;

public function __construct(Node\Stmt\Property $node)
{
$this->bootTraits($node);

$this->isStatic = $node->isStatic();
$this->default = ExpressionTransformer::parserNodeToResultNode($node->props[0]->default);
}
}
20 changes: 8 additions & 12 deletions src/Results/Nodes/FunctionCallNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,31 @@
namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\TransformsArguments;
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;
use PhpParser\Node;

class FunctionCallNode implements ResultNode
{
use BootsTraits;
use HasName;
use HasLocation;
use TransformsArguments;

/** @var string */
public $name;

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

public function __construct(Node\Expr\FuncCall $node)
{
$this->name = $node->name->toString();
$this->args = $this->transformArgumentsToNodes($node->args);
$this->location = GenericCodeLocation::createFromNode($node);
$this->bootTraits($node);

$this->args = ExpressionTransformer::parserNodesToResultNodes($node->args);
}

public static function create(Node\Expr\FuncCall $node): self
{
return new static(...func_get_args());
}

public function name(): string
{
return $this->name;
}
}
18 changes: 7 additions & 11 deletions src/Results/Nodes/FunctionDefinitionNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,32 @@
namespace Permafrost\PhpCodeSearch\Results\Nodes;

use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\BootsTraits;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\HasName;
use Permafrost\PhpCodeSearch\Results\Nodes\Traits\TransformsArguments;
use Permafrost\PhpCodeSearch\Support\StatementTransformer;
use PhpParser\Node;

class FunctionDefinitionNode implements ResultNode
{
use BootsTraits;
use HasName;
use HasLocation;
use TransformsArguments;

/** @var string */
public $name;

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

public function __construct(Node\Stmt\Function_ $node)
{
$this->name = $node->name->toString();
$this->args = (new StatementTransformer())->parserNodesToResultNode($node->getParams());
$this->location = GenericCodeLocation::createFromNode($node);
$this->bootTraits($node);

$this->args = StatementTransformer::parserNodesToResultNode($node->getParams());
}

public static function create(Node\Stmt\Function_ $node): self
{
return new static(...func_get_args());
}

public function name(): string
{
return $this->name;
}
}
29 changes: 29 additions & 0 deletions src/Results/Nodes/Traits/BootsTraits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;

use Permafrost\PhpCodeSearch\Support\Arr;

trait BootsTraits
{
protected function bootTraits($node): void
{
$reflectionObject = new \ReflectionObject($this);

collect($reflectionObject->getTraitNames())
->map(function(string $name){
if (strpos($name, __NAMESPACE__) === false) {
return null;
}
return Arr::last(explode('\\', $name));
})
->filter()
->each(function(string $name) use ($node) {
$bootMethodName = 'boot'.$name;

if (method_exists($this, $bootMethodName)) {
$this->$bootMethodName($node);
}
});
}
}
6 changes: 6 additions & 0 deletions src/Results/Nodes/Traits/HasLocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;

use Permafrost\PhpCodeSearch\Code\CodeLocation;
use Permafrost\PhpCodeSearch\Code\GenericCodeLocation;

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

return $this;
}

protected function bootHasLocation($node): void
{
$this->location = GenericCodeLocation::createFromNode($node);
}
}
7 changes: 7 additions & 0 deletions src/Results/Nodes/Traits/HasName.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;

use Permafrost\PhpCodeSearch\Support\NameResolver;

trait HasName
{
/** @var string */
Expand All @@ -11,4 +13,9 @@ public function name(): string
{
return $this->name;
}

protected function bootHasName($node): void
{
$this->name = NameResolver::resolve($node);
}
}
24 changes: 24 additions & 0 deletions src/Results/Nodes/Traits/HasValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;

use Permafrost\PhpCodeSearch\Results\Nodes\Scalar\StringNode;
use Permafrost\PhpCodeSearch\Support\ExpressionTransformer;

trait HasValue
{
/** @var string|StringNode */
public $value;

public function value()
{
return $this->value;
}

protected function bootHasValue($node): void
{
if (property_exists($node, 'value')) {
$this->value = ExpressionTransformer::parserNodeToResultNode($node->value);
}
}
}
32 changes: 32 additions & 0 deletions src/Results/Nodes/Traits/HasVisibility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes\Traits;

trait HasVisibility {

/** @var string */
public $visibility = 'unknown';

protected function bootHasVisibility($node): void
{
$this->initVisibilityAttribute($node);
}

protected function initVisibilityAttribute($node): void
{
$visibilityMap = [
'isPublic' => 'public',
'isPrivate' => 'private',
'isProtected' => 'protected',
];

foreach($visibilityMap as $method => $visibility) {
if ($node->$method()) {
$this->visibility = $visibility;
return;
}
}

$this->visibility = 'unknown';
}
}
3 changes: 3 additions & 0 deletions src/Searcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Permafrost\PhpCodeSearch\Support\NameResolver;
use Permafrost\PhpCodeSearch\Support\VirtualFile;
use Permafrost\PhpCodeSearch\Visitors\AssignmentVisitor;
use Permafrost\PhpCodeSearch\Visitors\ClassDefinitionVisitor;
use Permafrost\PhpCodeSearch\Visitors\FunctionCallVisitor;
use Permafrost\PhpCodeSearch\Visitors\FunctionDefinitionVisitor;
use Permafrost\PhpCodeSearch\Visitors\MethodCallVisitor;
Expand Down Expand Up @@ -162,6 +163,7 @@ protected function findAllReferences(array $ast): array
Node\Expr\StaticCall::class => $this->static,
Node\Expr\StaticPropertyFetch::class => $this->static,
Node\Expr\Variable::class => $this->variables,
Node\Stmt\Class_::class => $this->classes,
Node\Stmt\Function_::class => $this->functions,
];

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

$traverser->addVisitor(new AssignmentVisitor($results, $this->assignments));
$traverser->addVisitor(new ClassDefinitionVisitor($results, $this->classes));
$traverser->addVisitor(new FunctionCallVisitor($results, $this->functions));
$traverser->addVisitor(new FunctionDefinitionVisitor($results, $this->functions));
$traverser->addVisitor(new MethodCallVisitor($results, $this->methods));
Expand Down
Loading

0 comments on commit 1baf5c1

Please sign in to comment.