Skip to content

Commit

Permalink
Moving the ReflectionClassLikeCollection creation to the reflector
Browse files Browse the repository at this point in the history
  • Loading branch information
mamazu committed Apr 9, 2024
1 parent caa112a commit b7acb99
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 46 deletions.
Expand Up @@ -19,7 +19,6 @@
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionClassLikeCollection;
use Phpactor\WorseReflection\Core\Reflection\ReflectionOffset;
use Phpactor\WorseReflection\Core\Reflection\ReflectionMethodCall;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionClassLikeCollection as TolerantReflectionClassCollection;
use Phpactor\TextDocument\TextDocument;
use Phpactor\TextDocument\ByteOffset;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionOffset as TolerantReflectionOffset;
Expand All @@ -29,6 +28,17 @@
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionFunctionCollection as TolerantReflectionFunctionCollection;
use function Amp\call;
use function Amp\delay;
use Microsoft\PhpParser\Node\Expression\ObjectCreationExpression;
use Microsoft\PhpParser\Node\Statement\ClassDeclaration;
use Microsoft\PhpParser\Node\Statement\EnumDeclaration;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionEnum;
use Microsoft\PhpParser\Node\Statement\InterfaceDeclaration;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionInterface;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionClass;
use Microsoft\PhpParser\Node\Statement\TraitDeclaration;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionTrait;
use Microsoft\PhpParser\ClassLike;
use Phpactor\WorseReflection\Core\Util\NodeUtil;

class TolerantSourceCodeReflector implements SourceCodeReflector
{
Expand All @@ -46,7 +56,7 @@ public function reflectClassesIn(
array $visited = []
): ReflectionClassLikeCollection {
$node = $this->parseSourceCode($sourceCode);
return TolerantReflectionClassCollection::fromNode($this->serviceLocator, $sourceCode, $node, $visited);
return $this->reflectClassesFromNode($sourceCode, $node, $visited);
}

public function reflectOffset(
Expand Down Expand Up @@ -149,6 +159,50 @@ public function reflectNode(
return $nodeReflector->reflectNode($frame, $node);
}

/**
* @param array<string,bool> $visited
*/
private function reflectClassesFromNode(TextDocument $source, Node $node, array $visited): ReflectionClassLikeCollection
{
$items = [];

$nodeCollection = $node->getDescendantNodes(function (Node $node) {
return false === $node instanceof ClassLike && false === $node instanceof ObjectCreationExpression;
});

foreach ($nodeCollection as $child) {
if (false === $child instanceof ClassLike && !$child instanceof ObjectCreationExpression) {
continue;
}

if ($child instanceof TraitDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionTrait($this->serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof EnumDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionEnum($this->serviceLocator, $source, $child);
continue;
}

if ($child instanceof InterfaceDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionInterface($this->serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof ClassDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionClass($this->serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof ObjectCreationExpression && !($child->classTypeDesignator instanceof Node)) {
$items[NodeUtil::nameFromTokenOrNode($node, $child)] = new ReflectionClass($this->serviceLocator, $source, $child, $visited);
}
}

return ReflectionClassLikeCollection::fromReflections($items);
}

private function parseSourceCode(TextDocument $sourceCode): SourceFileNode
{
return $this->parser->parseSourceFile((string) $sourceCode, $sourceCode->uri()?->__toString());
Expand Down
Expand Up @@ -24,50 +24,6 @@
*/
final class ReflectionClassLikeCollection extends AbstractReflectionCollection
{
/**
* @param array<string,bool> $visited
*/
public static function fromNode(ServiceLocator $serviceLocator, TextDocument $source, Node $node, array $visited = []): self
{
$items = [];

$nodeCollection = $node->getDescendantNodes(function (Node $node) {
return false === $node instanceof ClassLike && false === $node instanceof ObjectCreationExpression;
});

foreach ($nodeCollection as $child) {
if (false === $child instanceof ClassLike && !$child instanceof ObjectCreationExpression) {
continue;
}

if ($child instanceof TraitDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionTrait($serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof EnumDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionEnum($serviceLocator, $source, $child);
continue;
}

if ($child instanceof InterfaceDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionInterface($serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof ClassDeclaration) {
$items[(string) $child->getNamespacedName()] = new ReflectionClass($serviceLocator, $source, $child, $visited);
continue;
}

if ($child instanceof ObjectCreationExpression && !($child->classTypeDesignator instanceof Node)) {
$items[NodeUtil::nameFromTokenOrNode($node, $child)] = new ReflectionClass($serviceLocator, $source, $child, $visited);
}
}

return new static($items);
}

public function classes(): ReflectionClassCollection
{
/** @phpstan-ignore-next-line */
Expand Down

0 comments on commit b7acb99

Please sign in to comment.