Skip to content

Commit

Permalink
Moved doc parsing to FileReferenceVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
ariddlestone committed Jul 12, 2023
1 parent 7309e45 commit 2388165
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 169 deletions.
2 changes: 1 addition & 1 deletion src/Contract/Ast/TokenReferenceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function getFilepath(): ?string;
public function getToken(): TokenInterface;

/**
* @return TokenReferenceMetaInterface[]
* @return TokenReferenceMetaDatumInterface[]
*/
public function getMetaData(): array;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

namespace Qossmic\Deptrac\Contract\Ast;

interface TokenReferenceMetaInterface
interface TokenReferenceMetaDatumInterface
{
}
4 changes: 2 additions & 2 deletions src/Core/Ast/AstMap/ClassLike/ClassLikeReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Qossmic\Deptrac\Core\Ast\AstMap\ClassLike;

use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\AstMap\AstInherit;
use Qossmic\Deptrac\Core\Ast\AstMap\DependencyToken;
use Qossmic\Deptrac\Core\Ast\AstMap\File\FileReference;
Expand All @@ -19,7 +19,7 @@ class ClassLikeReference implements TokenReferenceInterface

/**
* @param AstInherit[] $inherits
* @param TokenReferenceMetaInterface[] $metaData
* @param TokenReferenceMetaDatumInterface[] $metaData
* @param DependencyToken[] $dependencies
*/
public function __construct(
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Ast/AstMap/File/FileReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Qossmic\Deptrac\Contract\Ast\TokenInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeReference;
use Qossmic\Deptrac\Core\Ast\AstMap\DependencyToken;
use Qossmic\Deptrac\Core\Ast\AstMap\Function\FunctionReference;
Expand All @@ -25,7 +25,7 @@ class FileReference implements TokenReferenceInterface
/**
* @param ClassLikeReference[] $classLikeReferences
* @param FunctionReference[] $functionReferences
* @param TokenReferenceMetaInterface[] $metaData
* @param TokenReferenceMetaDatumInterface[] $metaData
* @param DependencyToken[] $dependencies
*/
public function __construct(
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Ast/AstMap/Function/FunctionReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Qossmic\Deptrac\Contract\Ast\TokenInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\AstMap\DependencyToken;
use Qossmic\Deptrac\Core\Ast\AstMap\File\FileReference;

Expand All @@ -16,7 +16,7 @@
class FunctionReference implements TokenReferenceInterface
{
/**
* @param TokenReferenceMetaInterface[] $metaData
* @param TokenReferenceMetaDatumInterface[] $metaData
* @param DependencyToken[] $dependencies
*/
public function __construct(
Expand Down
8 changes: 4 additions & 4 deletions src/Core/Ast/AstMap/ReferenceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

use Qossmic\Deptrac\Contract\Ast\DependencyType;
use Qossmic\Deptrac\Contract\Ast\FileOccurrence;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeToken;
use Qossmic\Deptrac\Core\Ast\AstMap\Function\FunctionToken;
use Qossmic\Deptrac\Core\Ast\AstMap\Variable\SuperGlobalToken;

abstract class ReferenceBuilder
{
/**
* @var TokenReferenceMetaInterface[]
* @var TokenReferenceMetaDatumInterface[]
*/
protected array $metaData = [];

Expand All @@ -34,9 +34,9 @@ final public function getTokenTemplates(): array
return $this->tokenTemplates;
}

public function addMetaData(TokenReferenceMetaInterface $metaDataItem): void
public function addMetaDatum(TokenReferenceMetaDatumInterface $metaDatum): void
{
$this->metaData[] = $metaDataItem;
$this->metaData[] = $metaDatum;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Ast/AstMap/Variable/VariableReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

use Qossmic\Deptrac\Contract\Ast\TokenInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;

/**
* @psalm-immutable
*/
class VariableReference implements TokenReferenceInterface
{
/**
* @param TokenReferenceMetaInterface[] $metaData
* @param TokenReferenceMetaDatumInterface[] $metaData
*/
public function __construct(
private readonly SuperGlobalToken $tokenName,
Expand Down
18 changes: 18 additions & 0 deletions src/Core/Ast/MetaData/PackageName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Qossmic\Deptrac\Core\Ast\MetaData;

use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;

class PackageName implements TokenReferenceMetaDatumInterface
{
public function __construct(private readonly string $packageName)
{
}

public function getPackageName(): string
{
return $this->packageName;
}
}
8 changes: 8 additions & 0 deletions src/Core/Ast/Parser/NikicPhpParser/FileReferenceVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
use PhpParser\Node\Stmt\Use_;
use PhpParser\NodeVisitorAbstract;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\AstMap\File\FileReferenceBuilder;
use Qossmic\Deptrac\Core\Ast\AstMap\ReferenceBuilder;
use Qossmic\Deptrac\Core\Ast\MetaData\PackageName;
use Qossmic\Deptrac\Core\Ast\Parser\Extractors\ReferenceExtractorInterface;
use Qossmic\Deptrac\Core\Ast\Parser\TypeResolver;
use Qossmic\Deptrac\Core\Ast\Parser\TypeScope;
Expand Down Expand Up @@ -290,5 +293,10 @@ private function processClassLikeDocs(array $docNodeCrate): void
$this->currentReference->variable($type, $line);
}
}

$packageNames = $docNode->getTagsByName('@package');
foreach ($packageNames as $packageName) {
$this->currentReference->addMetaDatum(new PackageName((string) $packageName->value));
}
}
}
68 changes: 10 additions & 58 deletions src/Core/Layer/Collector/PackageNameCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,15 @@

namespace Qossmic\Deptrac\Core\Layer\Collector;

use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use Qossmic\Deptrac\Contract\Ast\CouldNotParseFileException;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceInterface;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Contract\Layer\InvalidCollectorDefinitionException;
use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeReference;
use Qossmic\Deptrac\Core\Ast\Parser\NikicPhpParser\NikicPhpParser;
use Qossmic\Deptrac\Core\Ast\MetaData\PackageName;

class PackageNameCollector extends RegexCollector
{
private readonly Lexer $lexer;
private readonly PhpDocParser $docParser;

public function __construct(
private readonly NikicPhpParser $nikicPhpParser
) {
$this->lexer = new Lexer();
$this->docParser = new PhpDocParser(new TypeParser(), new ConstExprParser());
}

public function satisfy(array $config, TokenReferenceInterface $reference): bool
{
if (!$reference instanceof ClassLikeReference) {
return false;
}

$regex = $this->getValidatedPattern($config);

foreach ($this->getPackages($reference) as $package) {
Expand All @@ -53,44 +32,17 @@ protected function getPattern(array $config): string
}

/**
* @return array<string>
*
* @throws CouldNotParseFileException
* @return string[]
*/
private function getPackages(ClassLikeReference $reference): array
private function getPackages(TokenReferenceInterface $reference): array
{
$docBlock = $this->getCommentDoc($reference);

if (!$docBlock) {
return [];
}

$tokens = new TokenIterator($this->lexer->tokenize($docBlock));
$docNode = $this->docParser->parse($tokens);

$packageNameMetaData = array_filter(
$reference->getMetaData(),
fn (TokenReferenceMetaDatumInterface $metaData) => $metaData instanceof PackageName
);
return array_map(
static fn (PhpDocTagNode $node) => (string) $node->value,
$docNode->getTagsByName('@package')
fn (PackageName $packageName) => $packageName->getPackageName(),
$packageNameMetaData
);
}

/**
* @throws CouldNotParseFileException
*/
private function getCommentDoc(ClassLikeReference $reference): string
{
$node = $this->nikicPhpParser->getNodeForClassLikeReference($reference);

if (null === $node) {
return '';
}

$doc = $node->getDocComment();

if (null === $doc) {
return '';
}

return $doc->getText();
}
}
14 changes: 14 additions & 0 deletions tests/Core/Ast/Parser/NikicPhpParser/Fixtures/PackageNames.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Tests\Qossmic\Deptrac\Core\Ast\Parser\NikicPhpParser\Fixtures;

/**
* @package PackageA
*/
class PackageAClass
{
}

class NoPackageClass
{
}
29 changes: 29 additions & 0 deletions tests/Core/Ast/Parser/NikicPhpParser/NikicPhpParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
use Qossmic\Deptrac\Contract\Ast\TokenReferenceMetaDatumInterface;
use Qossmic\Deptrac\Core\Ast\MetaData\PackageName;
use Qossmic\Deptrac\Core\Ast\Parser\Cache\AstFileReferenceInMemoryCache;
use Qossmic\Deptrac\Core\Ast\Parser\Extractors\AnnotationReferenceExtractor;
use Qossmic\Deptrac\Core\Ast\Parser\NikicPhpParser\NikicPhpParser;
Expand Down Expand Up @@ -85,4 +87,31 @@ public function testParseTemplateTypes(): void
$astClassReferences = $astFileReference->classLikeReferences;
self::assertCount(0, $astClassReferences[0]->dependencies);
}

public function testParsePackageNames(): void
{
$filterPackageNames = function (TokenReferenceMetaDatumInterface $metaDatum) {
return $metaDatum instanceof PackageName;
};

$parser = new NikicPhpParser(
(new ParserFactory())->create(ParserFactory::ONLY_PHP7, new Lexer()),
new AstFileReferenceInMemoryCache(),
new TypeResolver(),
[]
);

$filePath = __DIR__ . '/Fixtures/PackageNames.php';
$astFileReference = $parser->parseFile($filePath);

$astClassReferences = $astFileReference->classLikeReferences;
self::assertCount(2, $astClassReferences);

$packageNames = array_filter($astClassReferences[0]->getMetaData(), $filterPackageNames);
self::assertCount(1, $packageNames);
$this->assertSame('PackageA', $packageNames[0]->getPackageName());

$packageNames = array_filter($astClassReferences[1]->getMetaData(), $filterPackageNames);
self::assertCount(0, $packageNames);
}
}
Loading

0 comments on commit 2388165

Please sign in to comment.