From 88ade9d48107219e1b35e71b25b666f92df17ae3 Mon Sep 17 00:00:00 2001 From: smoench Date: Fri, 31 Jan 2020 13:40:27 +0100 Subject: [PATCH 1/6] refactor type resolving --- config/services.xml | 6 +- src/AstRunner/AstMap.php | 17 +++-- src/AstRunner/AstMap/AstClassReference.php | 4 +- src/AstRunner/AstMap/AstDependency.php | 30 ++++---- src/AstRunner/AstMap/AstFileReference.php | 2 +- src/AstRunner/AstMap/AstInherit.php | 10 +-- src/AstRunner/AstMap/ClassLikeName.php | 33 ++++++++ .../AstParser/AstFileReferenceFileCache.php | 2 + .../AstClassReferenceResolver.php | 75 +++++++++++++------ .../NikicPhpParser/NikicPhpParser.php | 8 +- .../Resolver/AnnotationDependencyResolver.php | 28 ++++--- .../Resolver/AnonymousClassResolver.php | 7 +- .../Resolver/ClassConstantResolver.php | 7 +- .../Resolver/ClassDependencyResolver.php | 2 +- src/AstRunner/Resolver/NameScope.php | 75 +++---------------- src/AstRunner/Resolver/TypeResolver.php | 71 +++++++++++------- src/ClassNameLayerResolver.php | 3 +- src/ClassNameLayerResolverCacheDecorator.php | 10 ++- src/ClassNameLayerResolverInterface.php | 4 +- src/Collector/ClassNameCollector.php | 2 +- src/Collector/ClassNameRegexCollector.php | 2 +- .../ConfigurationSkippedViolation.php | 10 ++- src/Dependency/Dependency.php | 7 +- src/Dependency/DependencyInterface.php | 5 +- src/Dependency/InheritDependency.php | 7 +- src/Dependency/Result.php | 20 +++-- .../BasicDependencyEmitter.php | 2 +- src/OutputFormatter/JUnitOutputFormatter.php | 2 +- .../AstRunner/AstMapFlattenGeneratorTest.php | 3 +- tests/AstRunner/AstMapGeneratorTest.php | 15 ++-- tests/AstRunner/NameScopeTest.php | 26 ------- .../AnnotationDependencyResolverTest.php | 15 ++-- .../Resolver/AnonymousClassResolverTest.php | 4 +- .../Resolver/ClassConstantResolverTest.php | 2 +- ...assNameLayerResolverCacheDecoratorTest.php | 8 +- tests/ClassNameLayerResolverTest.php | 11 +-- tests/Collector/ClassNameCollectorTest.php | 4 +- .../Collector/ClassNameRegexCollectorTest.php | 5 +- tests/Collector/DirectoryCollectorTest.php | 5 +- .../InheritanceLevelCollectorTest.php | 7 +- tests/Collector/MethodCollectorTest.php | 7 +- .../ConfigurationSkippedViolationTest.php | 15 ++-- tests/Configuration/ConfigurationTest.php | 5 +- tests/Dependency/DependencyTest.php | 3 +- tests/Dependency/InheritDependencyTest.php | 12 ++- tests/Dependency/InheritanceFlatterTest.php | 13 ++-- tests/Dependency/ResultTest.php | 24 ++++-- .../BasicDependencyEmitterTest.php | 6 +- .../ConsoleOutputFormatterTest.php | 22 +++--- .../GraphVizOutputFormatterTest.php | 12 ++- .../JUnitOutputFormatterTest.php | 52 +++++++------ tests/RulesetEngineTest.php | 11 ++- 52 files changed, 408 insertions(+), 330 deletions(-) create mode 100644 src/AstRunner/AstMap/ClassLikeName.php delete mode 100644 tests/AstRunner/NameScopeTest.php diff --git a/config/services.xml b/config/services.xml index e4a601858..da399ebf8 100644 --- a/config/services.xml +++ b/config/services.xml @@ -34,7 +34,11 @@ - + + + + + diff --git a/src/AstRunner/AstMap.php b/src/AstRunner/AstMap.php index b4273e0bc..3e71c3364 100644 --- a/src/AstRunner/AstMap.php +++ b/src/AstRunner/AstMap.php @@ -7,6 +7,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; class AstMap { @@ -46,15 +47,15 @@ public function getAstFileReferences(): array return $this->astFileReferences; } - public function getClassReferenceByClassName(string $className): ?AstClassReference + public function getClassReferenceByClassName(ClassLikeName $className): ?AstClassReference { - return $this->astClassReferences[$className] ?? null; + return $this->astClassReferences[(string) $className] ?? null; } /** * @return AstInherit[]|iterable */ - public function getClassInherits(string $className): iterable + public function getClassInherits(ClassLikeName $className): iterable { $classReference = $this->getClassReferenceByClassName($className); @@ -85,7 +86,9 @@ private function resolveDepsRecursive( $path->push($inheritDependency); } - if (isset($alreadyResolved[$inheritDependency->getClassName()])) { + $className = (string) $inheritDependency->getClassName(); + + if (isset($alreadyResolved[$className])) { $path->pop(); return []; @@ -98,7 +101,7 @@ private function resolveDepsRecursive( } foreach ($classReference->getInherits() as $inherit) { - $alreadyResolved[$inheritDependency->getClassName()] = true; + $alreadyResolved[$className] = true; yield $inherit->withPath(iterator_to_array($path)); @@ -106,14 +109,14 @@ private function resolveDepsRecursive( yield from $this->resolveDepsRecursive($inherit, $alreadyResolved, $path); - unset($alreadyResolved[$inheritDependency->getClassName()]); + unset($alreadyResolved[$className]); $path->pop(); } } private function addAstClassReference(AstClassReference $astClassReference): void { - $this->astClassReferences[$astClassReference->getClassName()] = $astClassReference; + $this->astClassReferences[(string) $astClassReference->getClassName()] = $astClassReference; } private function addAstFileReference(AstFileReference $astFileReference): void diff --git a/src/AstRunner/AstMap/AstClassReference.php b/src/AstRunner/AstMap/AstClassReference.php index b5fad1ae2..c2dd34d27 100644 --- a/src/AstRunner/AstMap/AstClassReference.php +++ b/src/AstRunner/AstMap/AstClassReference.php @@ -15,7 +15,7 @@ class AstClassReference /** @var AstInherit[] */ private $inherits; - public function __construct(string $className, AstFileReference $fileReference = null) + public function __construct(ClassLikeName $className, AstFileReference $fileReference = null) { $this->className = $className; $this->fileReference = $fileReference; @@ -28,7 +28,7 @@ public function getFileReference(): ?AstFileReference return $this->fileReference; } - public function getClassName(): string + public function getClassName(): ClassLikeName { return $this->className; } diff --git a/src/AstRunner/AstMap/AstDependency.php b/src/AstRunner/AstMap/AstDependency.php index 720e362fe..321c87008 100644 --- a/src/AstRunner/AstMap/AstDependency.php +++ b/src/AstRunner/AstMap/AstDependency.php @@ -10,14 +10,14 @@ class AstDependency private $fileOccurrence; private $type; - public function __construct(string $class, FileOccurrence $fileOccurrence, string $type) + public function __construct(ClassLikeName $class, FileOccurrence $fileOccurrence, string $type) { $this->class = $class; $this->fileOccurrence = $fileOccurrence; $this->type = $type; } - public function getClass(): string + public function getClassLikeName(): ClassLikeName { return $this->class; } @@ -32,67 +32,67 @@ public function getType(): string return $this->type; } - public static function useStmt(string $class, FileOccurrence $fileOccurrence): self + public static function useStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'use'); } - public static function returnType(string $class, FileOccurrence $fileOccurrence): self + public static function returnType(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'returntype'); } - public static function parameter(string $class, FileOccurrence $fileOccurrence): self + public static function parameter(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'parameter'); } - public static function newStmt(string $class, FileOccurrence $fileOccurrence): self + public static function newStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'new'); } - public static function staticProperty(string $class, FileOccurrence $fileOccurrence): self + public static function staticProperty(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'static_property'); } - public static function staticMethod(string $class, FileOccurrence $fileOccurrence): self + public static function staticMethod(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'static_method'); } - public static function instanceofExpr(string $class, FileOccurrence $fileOccurrence): self + public static function instanceofExpr(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'instanceof'); } - public static function catchStmt(string $class, FileOccurrence $fileOccurrence): self + public static function catchStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'catch'); } - public static function variable(string $class, FileOccurrence $fileOccurrence): self + public static function variable(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'variable'); } - public static function throwStmt(string $class, FileOccurrence $fileOccurrence): self + public static function throwStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'throw'); } - public static function constFetch(string $class, FileOccurrence $fileOccurrence): self + public static function constFetch(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'const'); } - public static function anonymousClassExtends(string $class, FileOccurrence $fileOccurrence): self + public static function anonymousClassExtends(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'anonymous_class_extends'); } - public static function anonymousClassImplements(string $class, FileOccurrence $fileOccurrence): self + public static function anonymousClassImplements(ClassLikeName $class, FileOccurrence $fileOccurrence): self { return new self($class, $fileOccurrence, 'anonymous_class_implements'); } diff --git a/src/AstRunner/AstMap/AstFileReference.php b/src/AstRunner/AstMap/AstFileReference.php index 9d2eaf8f1..39f26b738 100644 --- a/src/AstRunner/AstMap/AstFileReference.php +++ b/src/AstRunner/AstMap/AstFileReference.php @@ -21,7 +21,7 @@ public function __construct(string $filepath) $this->dependencies = []; } - public function addClassReference(string $className): AstClassReference + public function addClassReference(ClassLikeName $className): AstClassReference { $astClassReference = new AstClassReference($className, $this); diff --git a/src/AstRunner/AstMap/AstInherit.php b/src/AstRunner/AstMap/AstInherit.php index 58c0b2f0c..32450ddc7 100644 --- a/src/AstRunner/AstMap/AstInherit.php +++ b/src/AstRunner/AstMap/AstInherit.php @@ -17,7 +17,7 @@ class AstInherit /** @var AstInherit[] */ private $path; - private function __construct(string $className, FileOccurrence $fileOccurrence, int $type) + private function __construct(ClassLikeName $className, FileOccurrence $fileOccurrence, int $type) { $this->className = $className; $this->fileOccurrence = $fileOccurrence; @@ -25,17 +25,17 @@ private function __construct(string $className, FileOccurrence $fileOccurrence, $this->path = []; } - public static function newExtends(string $className, FileOccurrence $fileOccurrence): self + public static function newExtends(ClassLikeName $className, FileOccurrence $fileOccurrence): self { return new self($className, $fileOccurrence, static::TYPE_EXTENDS); } - public static function newImplements(string $className, FileOccurrence $fileOccurrence): self + public static function newImplements(ClassLikeName $className, FileOccurrence $fileOccurrence): self { return new self($className, $fileOccurrence, static::TYPE_IMPLEMENTS); } - public static function newTraitUse(string $className, FileOccurrence $fileOccurrence): self + public static function newTraitUse(ClassLikeName $className, FileOccurrence $fileOccurrence): self { return new self($className, $fileOccurrence, static::TYPE_USES); } @@ -70,7 +70,7 @@ public function __toString(): string return $description.' (path: '.rtrim($buffer, ' -> ').')'; } - public function getClassName(): string + public function getClassName(): ClassLikeName { return $this->className; } diff --git a/src/AstRunner/AstMap/ClassLikeName.php b/src/AstRunner/AstMap/ClassLikeName.php new file mode 100644 index 000000000..6d0096aea --- /dev/null +++ b/src/AstRunner/AstMap/ClassLikeName.php @@ -0,0 +1,33 @@ +className = ltrim($className, '\\'); + } + + public static function fromString(string $className): self + { + return new self($className); + } + + public function match(string $pattern): bool + { + return 1 === preg_match($pattern, $this->className); + } + + public function __toString() + { + return $this->className; + } +} diff --git a/src/AstRunner/AstParser/AstFileReferenceFileCache.php b/src/AstRunner/AstParser/AstFileReferenceFileCache.php index 2632b116b..787d43339 100644 --- a/src/AstRunner/AstParser/AstFileReferenceFileCache.php +++ b/src/AstRunner/AstParser/AstFileReferenceFileCache.php @@ -8,6 +8,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Console\Application; @@ -113,6 +114,7 @@ static function (array $data): array { AstClassReference::class, AstInherit::class, AstDependency::class, + ClassLikeName::class, FileOccurrence::class, ], ] diff --git a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php index 3895829d4..90dc7c74c 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php +++ b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php @@ -4,14 +4,17 @@ namespace SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser; +use phpDocumentor\Reflection\Types\Context; use PhpParser\Node; use PhpParser\NodeVisitorAbstract; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\AstRunner\Resolver\ClassDependencyResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\NameScope; class AstClassReferenceResolver extends NodeVisitorAbstract { @@ -23,22 +26,30 @@ class AstClassReferenceResolver extends NodeVisitorAbstract /** @var ClassDependencyResolver[] */ private $classDependencyResolvers; + /** @var Context */ + private $currentTypeContext; + public function __construct(AstFileReference $fileReference, ClassDependencyResolver ...$classDependencyResolvers) { + $this->currentTypeContext = new NameScope('global'); $this->fileReference = $fileReference; $this->classDependencyResolvers = $classDependencyResolvers; } public function enterNode(Node $node) { + if ($node instanceof Node\Stmt\Namespace_) { + $this->currentTypeContext = new NameScope($node->name ? $node->name->toString() : 'global'); + } + if (!$node instanceof Node\Stmt\ClassLike) { return null; } if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) { - $className = $node->namespacedName->toString(); + $className = ClassLikeName::fromString($node->namespacedName->toString()); } elseif ($node->name instanceof Node\Identifier) { - $className = $node->name->toString(); + $className = ClassLikeName::fromString($node->name->toString()); } else { return null; // map anonymous classes on current class } @@ -49,7 +60,7 @@ public function enterNode(Node $node) if ($node->extends instanceof Node\Name) { $this->currentClassReference->addInherit( AstInherit::newExtends( - $node->extends->toString(), + ClassLikeName::fromString($node->extends->toString()), new FileOccurrence($this->fileReference, $node->extends->getLine()) ) ); @@ -57,7 +68,7 @@ public function enterNode(Node $node) foreach ($node->implements as $implement) { $this->currentClassReference->addInherit( AstInherit::newImplements( - $implement->toString(), + ClassLikeName::fromString($implement->toString()), new FileOccurrence($this->fileReference, $implement->getLine()) ) ); @@ -68,7 +79,7 @@ public function enterNode(Node $node) foreach ($node->extends as $extend) { $this->currentClassReference->addInherit( AstInherit::newExtends( - $extend->toString(), + ClassLikeName::fromString($extend->toString()), new FileOccurrence($this->fileReference, $extend->getLine()) ) ); @@ -81,9 +92,10 @@ public function enterNode(Node $node) public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\UseUse) { + $this->currentTypeContext->addUse($node->name->toString(), $node->getAlias()->toString()); $this->fileReference->addDependency( AstDependency::useStmt( - $node->name->toString(), + ClassLikeName::fromString($node->name->toString()), new FileOccurrence($this->fileReference, $node->name->getLine()) ) ); @@ -97,70 +109,70 @@ public function leaveNode(Node $node) foreach ($node->traits as $trait) { $this->currentClassReference->addInherit( AstInherit::newTraitUse( - $trait->toString(), + ClassLikeName::fromString($trait->toString()), new FileOccurrence($this->fileReference, $trait->getLine()) ) ); } } - if ($node instanceof Node\Expr\Instanceof_ && $node->class instanceof Node\Name) { + if ($node instanceof Node\Expr\Instanceof_ && $this->isQualifiedClassName($node->class)) { $this->currentClassReference->addDependency( AstDependency::instanceofExpr( - $node->class->toString(), + ClassLikeName::fromString($node->class->toString()), new FileOccurrence($this->fileReference, $node->class->getLine()) ) ); } - if ($node instanceof Node\Param && $node->type instanceof Node\Name) { + if ($node instanceof Node\Param && $this->isQualifiedClassName($node->type)) { $this->currentClassReference->addDependency( AstDependency::parameter( - $node->type->toString(), + ClassLikeName::fromString($node->type->toString()), new FileOccurrence($this->fileReference, $node->type->getLine()) ) ); } - if ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) { + if ($node instanceof Node\Expr\New_ && $this->isQualifiedClassName($node->class)) { $this->currentClassReference->addDependency( AstDependency::newStmt( - $node->class->toString(), + ClassLikeName::fromString($node->class->toString()), new FileOccurrence($this->fileReference, $node->class->getLine()) ) ); } - if ($node instanceof Node\Expr\StaticPropertyFetch && $node->class instanceof Node\Name) { + if ($node instanceof Node\Expr\StaticPropertyFetch && $this->isQualifiedClassName($node->class)) { $this->currentClassReference->addDependency( AstDependency::staticProperty( - $node->class->toString(), + ClassLikeName::fromString($node->class->toString()), new FileOccurrence($this->fileReference, $node->class->getLine()) ) ); } - if ($node instanceof Node\Expr\StaticCall && $node->class instanceof Node\Name) { + if ($node instanceof Node\Expr\StaticCall && $this->isQualifiedClassName($node->class)) { $this->currentClassReference->addDependency( AstDependency::staticMethod( - $node->class->toString(), + ClassLikeName::fromString($node->class->toString()), new FileOccurrence($this->fileReference, $node->class->getLine()) ) ); } if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) { - if ($node->returnType instanceof Node\Name) { + if ($this->isQualifiedClassName($node->returnType)) { $this->currentClassReference->addDependency( AstDependency::returnType( - $node->returnType->toString(), + ClassLikeName::fromString($node->returnType->toString()), new FileOccurrence($this->fileReference, $node->returnType->getLine()) ) ); - } elseif ($node->returnType instanceof Node\NullableType) { + } elseif ($node->returnType instanceof Node\NullableType && $this->isQualifiedClassName($node->returnType->type)) { $this->currentClassReference->addDependency( AstDependency::returnType( - (string) $node->returnType->type, + ClassLikeName::fromString((string) $node->returnType->type), new FileOccurrence($this->fileReference, $node->returnType->getLine()) ) ); @@ -169,9 +181,13 @@ public function leaveNode(Node $node) if ($node instanceof Node\Stmt\Catch_) { foreach ($node->types as $type) { + if (!$this->isQualifiedClassName($type)) { + continue; + } + $this->currentClassReference->addDependency( AstDependency::catchStmt( - $type->toString(), + ClassLikeName::fromString($type->toString()), new FileOccurrence($this->fileReference, $type->getLine()) ) ); @@ -179,9 +195,22 @@ public function leaveNode(Node $node) } foreach ($this->classDependencyResolvers as $resolver) { - $resolver->processNode($node, $this->fileReference, $this->currentClassReference); + $resolver->processNode($node, $this->fileReference, $this->currentClassReference, $this->currentTypeContext); } return null; } + + private function isQualifiedClassName($type): bool + { + if (null === $type) { + return false; + } + + if ($type instanceof Node\Name) { + return !$type->isSpecialClassName(); + } + + return false; + } } diff --git a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php index 7e9184b16..064c00566 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php +++ b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php @@ -82,8 +82,10 @@ public function parse($data): AstFileReference public function getAstForClassReference(AstClassReference $classReference): ?Node\Stmt\ClassLike { - if (isset(self::$classAstMap[$classReference->getClassName()])) { - return self::$classAstMap[$classReference->getClassName()]; + $classLikeName = (string) $classReference->getClassName(); + + if (isset(self::$classAstMap[$classLikeName])) { + return self::$classAstMap[$classLikeName]; } if (null === $classReference->getFileReference()) { @@ -116,6 +118,6 @@ static function (Node $node): bool { self::$classAstMap[$className] = $classLikeNode; } - return self::$classAstMap[$classReference->getClassName()] ?? null; + return self::$classAstMap[$classLikeName] ?? null; } } diff --git a/src/AstRunner/Resolver/AnnotationDependencyResolver.php b/src/AstRunner/Resolver/AnnotationDependencyResolver.php index 6e71541c0..404311662 100644 --- a/src/AstRunner/Resolver/AnnotationDependencyResolver.php +++ b/src/AstRunner/Resolver/AnnotationDependencyResolver.php @@ -14,6 +14,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; class AnnotationDependencyResolver implements ClassDependencyResolver @@ -21,13 +22,19 @@ class AnnotationDependencyResolver implements ClassDependencyResolver private $lexer; private $docParser; - public function __construct() + /** + * @var TypeResolver + */ + private $typeResolver; + + public function __construct(TypeResolver $typeResolver) { $this->lexer = new Lexer(); $this->docParser = new PhpDocParser(new TypeParser(), new ConstExprParser()); + $this->typeResolver = $typeResolver; } - public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference): void + public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference, NameScope $nameScope): void { if (!$node instanceof Node\Stmt\Property && !$node instanceof Node\Expr\Variable @@ -41,17 +48,16 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas return; } - $typeResolver = new TypeResolver(new NameScope($astClassReference)); $tokens = new TokenIterator($this->lexer->tokenize($docComment->getText())); $docNode = $this->docParser->parse($tokens); foreach ($docNode->getParamTagValues() as $tag) { - $types = $typeResolver->resolveType($tag->type); + $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { $astClassReference->addDependency( AstDependency::parameter( - $type, + ClassLikeName::fromString($type), new FileOccurrence($fileReference, $docComment->getLine()) ) ); @@ -59,12 +65,12 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas } foreach ($docNode->getVarTagValues() as $tag) { - $types = $typeResolver->resolveType($tag->type); + $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { $astClassReference->addDependency( AstDependency::variable( - $type, + ClassLikeName::fromString($type), new FileOccurrence($fileReference, $docComment->getLine()) ) ); @@ -72,12 +78,12 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas } foreach ($docNode->getReturnTagValues() as $tag) { - $types = $typeResolver->resolveType($tag->type); + $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { $astClassReference->addDependency( AstDependency::returnType( - $type, + ClassLikeName::fromString($type), new FileOccurrence($fileReference, $docComment->getLine()) ) ); @@ -85,12 +91,12 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas } foreach ($docNode->getThrowsTagValues() as $tag) { - $types = $typeResolver->resolveType($tag->type); + $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { $astClassReference->addDependency( AstDependency::throwStmt( - $type, + ClassLikeName::fromString($type), new FileOccurrence($fileReference, $docComment->getLine()) ) ); diff --git a/src/AstRunner/Resolver/AnonymousClassResolver.php b/src/AstRunner/Resolver/AnonymousClassResolver.php index 14a57dbc1..f563fad79 100644 --- a/src/AstRunner/Resolver/AnonymousClassResolver.php +++ b/src/AstRunner/Resolver/AnonymousClassResolver.php @@ -8,11 +8,12 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; class AnonymousClassResolver implements ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference): void + public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference, NameScope $nameScope): void { if (!$node instanceof Node\Stmt\Class_ || null !== $node->name) { return; @@ -21,7 +22,7 @@ public function processNode(Node $node, AstFileReference $astFileReference, AstC if ($node->extends instanceof Node\Name) { $astClassReference->addDependency( AstDependency::anonymousClassExtends( - $node->extends->toString(), + ClassLikeName::fromString($node->extends->toString()), new FileOccurrence($astFileReference, $node->extends->getLine()) ) ); @@ -29,7 +30,7 @@ public function processNode(Node $node, AstFileReference $astFileReference, AstC foreach ($node->implements as $implement) { $astClassReference->addDependency( AstDependency::anonymousClassImplements( - $implement->toString(), + ClassLikeName::fromString($implement->toString()), new FileOccurrence($astFileReference, $implement->getLine()) ) ); diff --git a/src/AstRunner/Resolver/ClassConstantResolver.php b/src/AstRunner/Resolver/ClassConstantResolver.php index 2038de2fd..a4cc0974c 100644 --- a/src/AstRunner/Resolver/ClassConstantResolver.php +++ b/src/AstRunner/Resolver/ClassConstantResolver.php @@ -9,19 +9,20 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; class ClassConstantResolver implements ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference): void + public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference, NameScope $nameScope): void { - if (!$node instanceof ClassConstFetch || !$node->class instanceof Node\Name) { + if (!$node instanceof ClassConstFetch || !$node->class instanceof Node\Name || $node->class->isSpecialClassName()) { return; } $astClassReference->addDependency( AstDependency::constFetch( - $node->class->toString(), + ClassLikeName::fromString($node->class->toString()), new FileOccurrence($astFileReference, $node->class->getLine()) ) ); diff --git a/src/AstRunner/Resolver/ClassDependencyResolver.php b/src/AstRunner/Resolver/ClassDependencyResolver.php index d1dc0e0a2..0afb33458 100644 --- a/src/AstRunner/Resolver/ClassDependencyResolver.php +++ b/src/AstRunner/Resolver/ClassDependencyResolver.php @@ -10,5 +10,5 @@ interface ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference): void; + public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference, NameScope $nameScope): void; } diff --git a/src/AstRunner/Resolver/NameScope.php b/src/AstRunner/Resolver/NameScope.php index 2f9a92ec9..ee01f06a6 100644 --- a/src/AstRunner/Resolver/NameScope.php +++ b/src/AstRunner/Resolver/NameScope.php @@ -4,8 +4,6 @@ namespace SensioLabs\Deptrac\AstRunner\Resolver; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; - class NameScope { /** @@ -14,82 +12,31 @@ class NameScope private $namespace; /** - * @var string[] alias(string) => fullName(string) + * @var array alias => className */ private $uses; - public function __construct(AstClassReference $classReference) + public function __construct(string $namespace) { - $this->namespace = $this->resolveNamespace($classReference->getClassName()); - $this->uses = $this->normalizeUses($classReference); + $this->namespace = $namespace; + $this->uses = []; } - public function resolveStringName(string $name): string + public function addUse(string $className, ?string $alias): void { - if (0 === strpos($name, '\\')) { - return ltrim($name, '\\'); - } - - $nameParts = explode('\\', $name); - $firstNamePart = $nameParts[0]; - - if (isset($this->uses[$firstNamePart])) { - if (1 === count($nameParts)) { - return $this->uses[$firstNamePart]; - } - array_shift($nameParts); - - return sprintf('%s\\%s', $this->uses[$firstNamePart], implode('\\', $nameParts)); - } - - if (null !== $this->namespace) { - return sprintf('%s\\%s', $this->namespace, $name); - } - - return $name; + $this->uses[$alias ?: $className] = $className; } - private function resolveNamespace(string $className): ?string + public function getNamespace(): string { - $className = ltrim($className, '\\'); - $nameParts = explode('\\', $className); - - if (1 === count($nameParts)) { - return null; - } - - array_pop($nameParts); - - return implode('\\', $nameParts); + return $this->namespace; } /** - * @return string[] alias(string) => fullName(string) + * @return array */ - private function normalizeUses(AstClassReference $astClassReference): array + public function getUses(): array { - if (null === $astClassReference->getFileReference()) { - return []; - } - - $uses = []; - - foreach ($astClassReference->getFileReference()->getDependencies() as $dependency) { - if ('use' !== $dependency->getType()) { - continue; - } - - $className = $dependency->getClass(); - $nameParts = explode('\\', $className); - $alias = end($nameParts); - - if (false === $alias) { - $alias = $className; - } - - $uses[$alias] = $className; - } - - return $uses; + return $this->uses; } } diff --git a/src/AstRunner/Resolver/TypeResolver.php b/src/AstRunner/Resolver/TypeResolver.php index ce1609962..ccb3d0d0d 100644 --- a/src/AstRunner/Resolver/TypeResolver.php +++ b/src/AstRunner/Resolver/TypeResolver.php @@ -4,54 +4,73 @@ namespace SensioLabs\Deptrac\AstRunner\Resolver; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\Types\Compound; +use phpDocumentor\Reflection\Types\Context; +use phpDocumentor\Reflection\Types\Object_; use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; +use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode; use PHPStan\PhpDocParser\Ast\Type\NullableTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; +use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode; class TypeResolver { - private const BUILTIN_TYPES = [ - 'array', - 'callable', - 'string', - 'int', - 'float', - 'double', - 'bool', - 'iterable', - 'void', - 'object', - 'mixed', - ]; - - private $nameScope; - - public function __construct(NameScope $nameScope) + /** + * @var \phpDocumentor\Reflection\TypeResolver + */ + private $typeResolver; + + public function __construct() { - $this->nameScope = $nameScope; + $this->typeResolver = new \phpDocumentor\Reflection\TypeResolver(new FqsenResolver()); } /** * @return string[] */ - public function resolveType(TypeNode $type): array + public function resolveType(TypeNode $type, NameScope $nameScope): array { - if ($type instanceof IdentifierTypeNode && !$this->isBuiltinType($type->name)) { - return [$this->nameScope->resolveStringName($type->name)]; + if ($type instanceof IdentifierTypeNode) { + return $this->resolveString($type->name, $nameScope); } if ($type instanceof NullableTypeNode) { - return $this->resolveType($type->type); + return $this->resolveType($type->type, $nameScope); } if ($type instanceof ArrayTypeNode) { - return $this->resolveType($type->type); + return $this->resolveType($type->type, $nameScope); + } + if ($type instanceof UnionTypeNode || $type instanceof IntersectionTypeNode) { + return array_merge([], ...array_map(function (TypeNode $typeNode) use ($nameScope) { + return $this->resolveType($typeNode, $nameScope); + }, $type->types)); } - return []; + return $this->resolveString((string) $type, $nameScope); + } + + public function resolveString(string $type, NameScope $nameScope): array + { + $context = new Context($nameScope->getNamespace(), $nameScope->getUses()); + $resolvedType = $this->typeResolver->resolve($type, $context); + + return $this->resolveReflectionType($resolvedType); } - private function isBuiltinType(string $type): bool + private function resolveReflectionType(Type $resolvedType): array { - return in_array($type, self::BUILTIN_TYPES, true); + if ($resolvedType instanceof Object_) { + return ($fqsen = $resolvedType->getFqsen()) ? [(string) $fqsen] : []; + } + + if ($resolvedType instanceof Compound) { + return array_merge([], ...array_map(function (Type $type) { + return $this->resolveReflectionType($type); + }, iterator_to_array($resolvedType))); + } + + return []; } } diff --git a/src/ClassNameLayerResolver.php b/src/ClassNameLayerResolver.php index 5b4ee8607..b5d5c359c 100644 --- a/src/ClassNameLayerResolver.php +++ b/src/ClassNameLayerResolver.php @@ -6,6 +6,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Collector\Registry; use SensioLabs\Deptrac\Configuration\Configuration; use SensioLabs\Deptrac\Configuration\ConfigurationLayer; @@ -29,7 +30,7 @@ public function __construct( /** * @return string[] */ - public function getLayersByClassName(string $className): array + public function getLayersByClassName(ClassLikeName $className): array { /** @var array $layers */ $layers = []; diff --git a/src/ClassNameLayerResolverCacheDecorator.php b/src/ClassNameLayerResolverCacheDecorator.php index 1cf9a588a..f604e995d 100644 --- a/src/ClassNameLayerResolverCacheDecorator.php +++ b/src/ClassNameLayerResolverCacheDecorator.php @@ -4,6 +4,8 @@ namespace SensioLabs\Deptrac; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; + class ClassNameLayerResolverCacheDecorator implements ClassNameLayerResolverInterface { private $classNameLayerResolver; @@ -19,13 +21,13 @@ public function __construct(ClassNameLayerResolverInterface $classNameLayerResol $this->classNameLayerResolver = $classNameLayerResolver; } - public function getLayersByClassName(string $className): array + public function getLayersByClassName(ClassLikeName $className): array { - if (!isset($this->layerNamesByClassCache[$className])) { - $this->layerNamesByClassCache[$className] = $this->classNameLayerResolver->getLayersByClassName($className); + if (!isset($this->layerNamesByClassCache[(string) $className])) { + $this->layerNamesByClassCache[(string) $className] = $this->classNameLayerResolver->getLayersByClassName($className); } - return $this->layerNamesByClassCache[$className]; + return $this->layerNamesByClassCache[(string) $className]; } public function getLayers(): array diff --git a/src/ClassNameLayerResolverInterface.php b/src/ClassNameLayerResolverInterface.php index d8c330ae9..1c7456367 100644 --- a/src/ClassNameLayerResolverInterface.php +++ b/src/ClassNameLayerResolverInterface.php @@ -4,12 +4,14 @@ namespace SensioLabs\Deptrac; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; + interface ClassNameLayerResolverInterface { /** * @return string[] */ - public function getLayersByClassName(string $className): array; + public function getLayersByClassName(ClassLikeName $className): array; /** * @return string[] diff --git a/src/Collector/ClassNameCollector.php b/src/Collector/ClassNameCollector.php index a8dd1b1b7..e0a844330 100644 --- a/src/Collector/ClassNameCollector.php +++ b/src/Collector/ClassNameCollector.php @@ -20,7 +20,7 @@ public function satisfy( AstMap $astMap, Registry $collectorRegistry ): bool { - return 1 === preg_match($this->getPattern($configuration), $astClassReference->getClassName()); + return $astClassReference->getClassName()->match($this->getPattern($configuration)); } /** diff --git a/src/Collector/ClassNameRegexCollector.php b/src/Collector/ClassNameRegexCollector.php index 81e6e64d0..90e870b3e 100644 --- a/src/Collector/ClassNameRegexCollector.php +++ b/src/Collector/ClassNameRegexCollector.php @@ -20,7 +20,7 @@ public function satisfy( AstMap $astMap, Registry $collectorRegistry ): bool { - return 1 === preg_match($this->getPattern($configuration), $astClassReference->getClassName()); + return $astClassReference->getClassName()->match($this->getPattern($configuration)); } /** diff --git a/src/Configuration/ConfigurationSkippedViolation.php b/src/Configuration/ConfigurationSkippedViolation.php index ed55fc665..c455e3dc9 100644 --- a/src/Configuration/ConfigurationSkippedViolation.php +++ b/src/Configuration/ConfigurationSkippedViolation.php @@ -4,6 +4,8 @@ namespace SensioLabs\Deptrac\Configuration; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; + /** * @author Dmitry Balabka */ @@ -28,8 +30,12 @@ private function __construct(array $classesDeps) $this->classesDeps = $classesDeps; } - public function isViolationSkipped(string $classA, string $classB): bool + public function isViolationSkipped(ClassLikeName $classA, ClassLikeName $classB): bool { - return isset($this->classesDeps[$classA]) && \in_array($classB, $this->classesDeps[$classA], true); + $classLikeNameA = (string) $classA; + $classLikeNameB = (string) $classB; + + return isset($this->classesDeps[$classLikeNameA]) + && \in_array($classLikeNameB, $this->classesDeps[$classLikeNameA], true); } } diff --git a/src/Dependency/Dependency.php b/src/Dependency/Dependency.php index 34f921338..9d027db23 100644 --- a/src/Dependency/Dependency.php +++ b/src/Dependency/Dependency.php @@ -4,6 +4,7 @@ namespace SensioLabs\Deptrac\Dependency; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; class Dependency implements DependencyInterface @@ -12,19 +13,19 @@ class Dependency implements DependencyInterface private $classA; private $fileOccurrence; - public function __construct(string $classA, string $classB, FileOccurrence $fileOccurrence) + public function __construct(ClassLikeName $classA, ClassLikeName $classB, FileOccurrence $fileOccurrence) { $this->classA = $classA; $this->classB = $classB; $this->fileOccurrence = $fileOccurrence; } - public function getClassA(): string + public function getClassA(): ClassLikeName { return $this->classA; } - public function getClassB(): string + public function getClassB(): ClassLikeName { return $this->classB; } diff --git a/src/Dependency/DependencyInterface.php b/src/Dependency/DependencyInterface.php index c39781a19..9b6ca047e 100644 --- a/src/Dependency/DependencyInterface.php +++ b/src/Dependency/DependencyInterface.php @@ -4,13 +4,14 @@ namespace SensioLabs\Deptrac\Dependency; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; interface DependencyInterface { - public function getClassA(): string; + public function getClassA(): ClassLikeName; - public function getClassB(): string; + public function getClassB(): ClassLikeName; public function getFileOccurrence(): FileOccurrence; } diff --git a/src/Dependency/InheritDependency.php b/src/Dependency/InheritDependency.php index 63d43d50e..04c7b87be 100644 --- a/src/Dependency/InheritDependency.php +++ b/src/Dependency/InheritDependency.php @@ -5,6 +5,7 @@ namespace SensioLabs\Deptrac\Dependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; class InheritDependency implements DependencyInterface @@ -14,7 +15,7 @@ class InheritDependency implements DependencyInterface private $path; private $originalDependency; - public function __construct(string $classA, string $classB, DependencyInterface $originalDependency, AstInherit $path) + public function __construct(ClassLikeName $classA, ClassLikeName $classB, DependencyInterface $originalDependency, AstInherit $path) { $this->classA = $classA; $this->classB = $classB; @@ -22,7 +23,7 @@ public function __construct(string $classA, string $classB, DependencyInterface $this->path = $path; } - public function getClassA(): string + public function getClassA(): ClassLikeName { return $this->classA; } @@ -32,7 +33,7 @@ public function getFileOccurrence(): FileOccurrence return $this->getOriginalDependency()->getFileOccurrence(); } - public function getClassB(): string + public function getClassB(): ClassLikeName { return $this->classB; } diff --git a/src/Dependency/Result.php b/src/Dependency/Result.php index 1016fe3b7..1d0005b1a 100644 --- a/src/Dependency/Result.php +++ b/src/Dependency/Result.php @@ -4,6 +4,8 @@ namespace SensioLabs\Deptrac\Dependency; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; + class Result { /** @var array */ @@ -14,22 +16,24 @@ class Result public function addDependency(Dependency $dependency): self { - if (!isset($this->dependencies[$dependency->getClassA()])) { - $this->dependencies[$dependency->getClassA()] = []; + $classLikeName = (string) $dependency->getClassA(); + if (!isset($this->dependencies[$classLikeName])) { + $this->dependencies[$classLikeName] = []; } - $this->dependencies[$dependency->getClassA()][] = $dependency; + $this->dependencies[$classLikeName][] = $dependency; return $this; } public function addInheritDependency(InheritDependency $dependency): self { - if (!isset($this->inheritDependencies[$dependency->getClassA()])) { - $this->inheritDependencies[$dependency->getClassA()] = []; + $classLikeName = (string) $dependency->getClassA(); + if (!isset($this->inheritDependencies[$classLikeName])) { + $this->inheritDependencies[$classLikeName] = []; } - $this->inheritDependencies[$dependency->getClassA()][] = $dependency; + $this->inheritDependencies[$classLikeName][] = $dependency; return $this; } @@ -37,9 +41,9 @@ public function addInheritDependency(InheritDependency $dependency): self /** * @return Dependency[] */ - public function getDependenciesByClass(string $className): array + public function getDependenciesByClass(ClassLikeName $className): array { - return $this->dependencies[$className] ?? []; + return $this->dependencies[(string) $className] ?? []; } /** diff --git a/src/DependencyEmitter/BasicDependencyEmitter.php b/src/DependencyEmitter/BasicDependencyEmitter.php index 81825162a..42e32ef2f 100644 --- a/src/DependencyEmitter/BasicDependencyEmitter.php +++ b/src/DependencyEmitter/BasicDependencyEmitter.php @@ -29,7 +29,7 @@ public function applyDependencies(AstMap $astMap, Result $dependencyResult): voi $dependencyResult->addDependency( new Dependency( $astClassReference->getClassName(), - $emittedDependency->getClass(), + $emittedDependency->getClassLikeName(), $emittedDependency->getFileOccurrence() ) ); diff --git a/src/OutputFormatter/JUnitOutputFormatter.php b/src/OutputFormatter/JUnitOutputFormatter.php index 19cc46960..b0b0a8d0d 100644 --- a/src/OutputFormatter/JUnitOutputFormatter.php +++ b/src/OutputFormatter/JUnitOutputFormatter.php @@ -107,7 +107,7 @@ private function addTestSuite(Context $context, \DOMDocument $xmlDoc, \DOMElemen $rulesByClassName = []; foreach ($rules as $rule) { - $rulesByClassName[$rule->getDependency()->getClassA()][] = $rule; + $rulesByClassName[(string) $rule->getDependency()->getClassA()][] = $rule; } $testSuite = $xmlDoc->createElement('testsuite'); diff --git a/tests/AstRunner/AstMapFlattenGeneratorTest.php b/tests/AstRunner/AstMapFlattenGeneratorTest.php index cd0c0af73..0094cf807 100644 --- a/tests/AstRunner/AstMapFlattenGeneratorTest.php +++ b/tests/AstRunner/AstMapFlattenGeneratorTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstParser\AstFileReferenceInMemoryCache; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\FileParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; @@ -53,7 +54,7 @@ private function getAstMap(string $fixture): AstMap private function getInheritedInherits(string $class, AstMap $astMap): array { $inherits = []; - foreach ($astMap->getClassInherits($class) as $v) { + foreach ($astMap->getClassInherits(ClassLikeName::fromString($class)) as $v) { if (count($v->getPath()) > 0) { $inherits[] = (string) $v; } diff --git a/tests/AstRunner/AstMapGeneratorTest.php b/tests/AstRunner/AstMapGeneratorTest.php index e01faf199..6793ab70d 100644 --- a/tests/AstRunner/AstMapGeneratorTest.php +++ b/tests/AstRunner/AstMapGeneratorTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstParser\AstFileReferenceInMemoryCache; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\FileParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; @@ -49,7 +50,7 @@ public function testBasicDependencyClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassA::9 (Extends)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceA::9 (Implements)', ], - $astMap->getClassReferenceByClassName(BasicDependencyClassB::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyClassB::class))->getInherits() ); static::assertArrayValuesEquals( @@ -57,7 +58,7 @@ public function testBasicDependencyClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceA::13 (Implements)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceB::13 (Implements)', ], - $astMap->getClassReferenceByClassName(BasicDependencyClassC::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyClassC::class))->getInherits() ); } @@ -67,17 +68,17 @@ public function testBasicTraitsClass(): void static::assertArrayValuesEquals( [], - $astMap->getClassReferenceByClassName(BasicDependencyTraitA::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitA::class))->getInherits() ); static::assertArrayValuesEquals( [], - $astMap->getClassReferenceByClassName(BasicDependencyTraitB::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitB::class))->getInherits() ); static::assertArrayValuesEquals( ['Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitB::7 (Uses)'], - $astMap->getClassReferenceByClassName(BasicDependencyTraitC::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitC::class))->getInherits() ); static::assertArrayValuesEquals( @@ -85,12 +86,12 @@ public function testBasicTraitsClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitA::10 (Uses)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitB::11 (Uses)', ], - $astMap->getClassReferenceByClassName(BasicDependencyTraitD::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitD::class))->getInherits() ); static::assertArrayValuesEquals( ['Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitA::15 (Uses)'], - $astMap->getClassReferenceByClassName(BasicDependencyTraitClass::class)->getInherits() + $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitClass::class))->getInherits() ); } } diff --git a/tests/AstRunner/NameScopeTest.php b/tests/AstRunner/NameScopeTest.php deleted file mode 100644 index 4c6bdb6a5..000000000 --- a/tests/AstRunner/NameScopeTest.php +++ /dev/null @@ -1,26 +0,0 @@ -addDependency(AstDependency::useStmt('FooBar\OtherNamespace\OtherNamespaceClass', new FileOccurrence($fileReference, 1))); - $classReference = $fileReference->addClassReference('FooBar\Baz'); - - $nameScope = new NameScope($classReference); - - static::assertSame('FooBar\SameNamespaceClass', $nameScope->resolveStringName('SameNamespaceClass')); - static::assertSame('FooBar\OtherNamespace\OtherNamespaceClass', $nameScope->resolveStringName('OtherNamespaceClass')); - } -} diff --git a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php index 5e35ff6e5..d086a65b1 100644 --- a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php +++ b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php @@ -10,6 +10,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\Resolver\AnnotationDependencyResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use SplFileInfo; class AnnotationDependencyResolverTest extends TestCase @@ -19,7 +20,7 @@ public function testPropertyDependencyResolving(): void $parser = new NikicPhpParser( new FileParser(ParserFactory::createParser()), new AstFileReferenceInMemoryCache(), - new AnnotationDependencyResolver() + new AnnotationDependencyResolver(new TypeResolver()) ); $filePath = __DIR__.'/fixtures/AnnotationDependency.php'; @@ -34,7 +35,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - $annotationDependency[0]->getClass() + (string) $annotationDependency[0]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[0]->getFileOccurrence()->getFilenpath()); static::assertSame(9, $annotationDependency[0]->getFileOccurrence()->getLine()); @@ -42,7 +43,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - $annotationDependency[1]->getClass() + (string) $annotationDependency[1]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[1]->getFileOccurrence()->getFilenpath()); static::assertSame(23, $annotationDependency[1]->getFileOccurrence()->getLine()); @@ -50,7 +51,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - $annotationDependency[2]->getClass() + (string) $annotationDependency[2]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[2]->getFileOccurrence()->getFilenpath()); static::assertSame(26, $annotationDependency[2]->getFileOccurrence()->getLine()); @@ -58,7 +59,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Symfony\Component\Console\Exception\RuntimeException', - $annotationDependency[3]->getClass() + (string) $annotationDependency[3]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[3]->getFileOccurrence()->getFilenpath()); static::assertSame(29, $annotationDependency[3]->getFileOccurrence()->getLine()); @@ -66,7 +67,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Symfony\Component\Finder\SplFileInfo', - $annotationDependency[4]->getClass() + (string) $annotationDependency[4]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[4]->getFileOccurrence()->getFilenpath()); static::assertSame(14, $annotationDependency[4]->getFileOccurrence()->getLine()); @@ -74,7 +75,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - $annotationDependency[5]->getClass() + (string) $annotationDependency[5]->getClassLikeName() ); static::assertSame($filePath, $annotationDependency[5]->getFileOccurrence()->getFilenpath()); static::assertSame(14, $annotationDependency[5]->getFileOccurrence()->getLine()); diff --git a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php index a79e286f4..cd054b54d 100644 --- a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php +++ b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php @@ -36,7 +36,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\ClassA', - $dependencies[0]->getClass() + (string) $dependencies[0]->getClassLikeName() ); static::assertSame($filePath, $dependencies[0]->getFileOccurrence()->getFilenpath()); static::assertSame(19, $dependencies[0]->getFileOccurrence()->getLine()); @@ -44,7 +44,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\InterfaceC', - $dependencies[1]->getClass() + (string) $dependencies[1]->getClassLikeName() ); static::assertSame($filePath, $dependencies[1]->getFileOccurrence()->getFilenpath()); static::assertSame(19, $dependencies[1]->getFileOccurrence()->getLine()); diff --git a/tests/AstRunner/Resolver/ClassConstantResolverTest.php b/tests/AstRunner/Resolver/ClassConstantResolverTest.php index 5e0e8a431..62d5ab175 100644 --- a/tests/AstRunner/Resolver/ClassConstantResolverTest.php +++ b/tests/AstRunner/Resolver/ClassConstantResolverTest.php @@ -34,7 +34,7 @@ public function testPropertyDependencyResolving(): void $dependencies = $astClassReferences[1]->getDependencies(); static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\ClassA', - $dependencies[0]->getClass() + (string) $dependencies[0]->getClassLikeName() ); static::assertSame($filePath, $dependencies[0]->getFileOccurrence()->getFilenpath()); static::assertSame(15, $dependencies[0]->getFileOccurrence()->getLine()); diff --git a/tests/ClassNameLayerResolverCacheDecoratorTest.php b/tests/ClassNameLayerResolverCacheDecoratorTest.php index 9843b7bd4..b0755b939 100644 --- a/tests/ClassNameLayerResolverCacheDecoratorTest.php +++ b/tests/ClassNameLayerResolverCacheDecoratorTest.php @@ -5,6 +5,7 @@ namespace Tests\SensioLabs\Deptrac; use PHPUnit\Framework\TestCase; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\ClassNameLayerResolverCacheDecorator; use SensioLabs\Deptrac\ClassNameLayerResolverInterface; @@ -12,12 +13,13 @@ class ClassNameLayerResolverCacheDecoratorTest extends TestCase { public function testGetLayersByClassName(): void { + $classLikeName = ClassLikeName::fromString('foo'); $decorated = $this->prophesize(ClassNameLayerResolverInterface::class); - $decorated->getLayersByClassName('foo')->willReturn(['bar']); + $decorated->getLayersByClassName($classLikeName)->willReturn(['bar']); $decorator = new ClassNameLayerResolverCacheDecorator($decorated->reveal()); - static::assertEquals(['bar'], $decorator->getLayersByClassName('foo')); - static::assertEquals(['bar'], $decorator->getLayersByClassName('foo')); + static::assertEquals(['bar'], $decorator->getLayersByClassName($classLikeName)); + static::assertEquals(['bar'], $decorator->getLayersByClassName($classLikeName)); } } diff --git a/tests/ClassNameLayerResolverTest.php b/tests/ClassNameLayerResolverTest.php index 1050abce5..baacedc73 100644 --- a/tests/ClassNameLayerResolverTest.php +++ b/tests/ClassNameLayerResolverTest.php @@ -8,6 +8,7 @@ use Prophecy\Argument; use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\ClassNameLayerResolver; use SensioLabs\Deptrac\Collector\CollectorInterface; use SensioLabs\Deptrac\Collector\Registry; @@ -16,7 +17,7 @@ class ClassNameLayerResolverTest extends TestCase { - private function getCollector($return) + private function getCollector(bool $return) { $collector = $this->prophesize(CollectorInterface::class); $collector->satisfy( @@ -99,13 +100,13 @@ public function testGetLayersByClassName(bool $collectA, bool $collectB1, bool $ $astMap = $this->prophesize(AstMap::class); $collectorRegistry = $this->prophesize(Registry::class); $collectorRegistry->getCollector('CollectorA')->willReturn( - $this->getCollector($collectA, ['type' => 'CollectorA', 'foo' => 'bar']) + $this->getCollector($collectA) ); $collectorRegistry->getCollector('CollectorB1')->willReturn( - $this->getCollector($collectB1, ['type' => 'CollectorB', 'foo' => 'bar']) + $this->getCollector($collectB1) ); $collectorRegistry->getCollector('CollectorB2')->willReturn( - $this->getCollector($collectB2, ['type' => 'CollectorB', 'foo' => 'bar']) + $this->getCollector($collectB2) ); $resolver = new ClassNameLayerResolver( @@ -116,7 +117,7 @@ public function testGetLayersByClassName(bool $collectA, bool $collectB1, bool $ static::assertEquals( $expectedLayers, - $resolver->getLayersByClassName('classA') + $resolver->getLayersByClassName(ClassLikeName::fromString('classA')) ); } } diff --git a/tests/Collector/ClassNameCollectorTest.php b/tests/Collector/ClassNameCollectorTest.php index 0f9e8de28..57fc19620 100644 --- a/tests/Collector/ClassNameCollectorTest.php +++ b/tests/Collector/ClassNameCollectorTest.php @@ -30,7 +30,7 @@ public function testSatisfy(array $configuration, string $className, bool $expec { $stat = (new ClassNameCollector())->satisfy( $configuration, - new AstClassReference($className), + new AstClassReference(AstMap\ClassLikeName::fromString($className)), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); @@ -44,7 +44,7 @@ public function testWrongRegexParam(): void (new ClassNameCollector())->satisfy( ['Foo' => 'a'], - $this->prophesize(AstClassReference::class)->reveal(), + new AstClassReference(AstMap\ClassLikeName::fromString('Foo')), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/ClassNameRegexCollectorTest.php b/tests/Collector/ClassNameRegexCollectorTest.php index bde5c8d8b..b15d76cbb 100644 --- a/tests/Collector/ClassNameRegexCollectorTest.php +++ b/tests/Collector/ClassNameRegexCollectorTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Collector\ClassNameRegexCollector; use SensioLabs\Deptrac\Collector\Registry; @@ -30,7 +31,7 @@ public function testSatisfy(array $configuration, string $className, bool $expec { $stat = (new ClassNameRegexCollector())->satisfy( $configuration, - new AstClassReference($className), + new AstClassReference(ClassLikeName::fromString($className)), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); @@ -44,7 +45,7 @@ public function testWrongRegexParam(): void (new ClassNameRegexCollector())->satisfy( ['Foo' => 'a'], - $this->prophesize(AstClassReference::class)->reveal(), + new AstClassReference(ClassLikeName::fromString('Foo')), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/DirectoryCollectorTest.php b/tests/Collector/DirectoryCollectorTest.php index 498c1fcd3..a2e45a573 100644 --- a/tests/Collector/DirectoryCollectorTest.php +++ b/tests/Collector/DirectoryCollectorTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Collector\DirectoryCollector; use SensioLabs\Deptrac\Collector\Registry; @@ -30,7 +31,7 @@ public function dataProviderSatisfy(): iterable public function testSatisfy(array $configuration, string $filePath, bool $expected): void { $fileReference = new AstFileReference($filePath); - $astClassReference = $fileReference->addClassReference('Test'); + $astClassReference = $fileReference->addClassReference(ClassLikeName::fromString('Test')); $stat = (new DirectoryCollector())->satisfy( $configuration, @@ -45,7 +46,7 @@ public function testSatisfy(array $configuration, string $filePath, bool $expect public function testMissingRegexThrowsException(): void { $fileReference = new AstFileReference('/some/path/to/file.php'); - $astClassReference = $fileReference->addClassReference('Test'); + $astClassReference = $fileReference->addClassReference(ClassLikeName::fromString('Test')); $this->expectException(\LogicException::class); $this->expectExceptionMessage('DirectoryCollector needs the regex configuration.'); diff --git a/tests/Collector/InheritanceLevelCollectorTest.php b/tests/Collector/InheritanceLevelCollectorTest.php index acf5ddeb2..02b920667 100644 --- a/tests/Collector/InheritanceLevelCollectorTest.php +++ b/tests/Collector/InheritanceLevelCollectorTest.php @@ -8,6 +8,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Collector\InheritanceLevelCollector; use SensioLabs\Deptrac\Collector\Registry; @@ -38,13 +39,9 @@ public function testSatisfy(int $pathLevel, int $levelConfig, bool $expected): v $astMap->getClassInherits(AstInherit::class) ->willReturn([$classInherit->reveal()]); - $classReference = $this->prophesize(AstClassReference::class); - $classReference->getClassName() - ->willReturn(AstInherit::class); - $stat = (new InheritanceLevelCollector())->satisfy( ['level' => $levelConfig], - $classReference->reveal(), + new AstClassReference(ClassLikeName::fromString(AstInherit::class)), $astMap->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/MethodCollectorTest.php b/tests/Collector/MethodCollectorTest.php index 1e591f2cb..199806971 100644 --- a/tests/Collector/MethodCollectorTest.php +++ b/tests/Collector/MethodCollectorTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\Collector\MethodCollector; use SensioLabs\Deptrac\Collector\Registry; @@ -54,7 +55,7 @@ public function dataProviderSatisfy(): iterable */ public function testSatisfy(array $configuration, array $methods, bool $expected): void { - $astClassReference = new AstClassReference('foo'); + $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); $classLike = $this->createMock(Node\Stmt\ClassLike::class); $classLike->method('getMethods')->willReturn($methods); @@ -77,7 +78,7 @@ public function testSatisfy(array $configuration, array $methods, bool $expected public function testClassLikeAstNotFoundDoesNotSatisfy(): void { - $astClassReference = new AstClassReference('foo'); + $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); $parser = $this->createMock(NikicPhpParser::class); $parser ->method('getAstForClassReference') @@ -96,7 +97,7 @@ public function testClassLikeAstNotFoundDoesNotSatisfy(): void public function testMissingNameThrowsException(): void { - $astClassReference = new AstClassReference('foo'); + $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); $parser = $this->createMock(NikicPhpParser::class); $this->expectException(\LogicException::class); diff --git a/tests/Configuration/ConfigurationSkippedViolationTest.php b/tests/Configuration/ConfigurationSkippedViolationTest.php index a95f11f85..d042e359b 100644 --- a/tests/Configuration/ConfigurationSkippedViolationTest.php +++ b/tests/Configuration/ConfigurationSkippedViolationTest.php @@ -5,6 +5,7 @@ namespace Tests\SensioLabs\Deptrac\Configuration; use PHPUnit\Framework\TestCase; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Configuration\ConfigurationSkippedViolation; class ConfigurationSkippedViolationTest extends TestCase @@ -22,19 +23,19 @@ public function testFromArray(): void 'DependencyClass2', ], ]); - $this->assertTrue($configuration->isViolationSkipped('ClassWithOneDep', 'DependencyClass')); - $this->assertFalse($configuration->isViolationSkipped('ClassWithEmptyDeps', 'DependencyClass')); - $this->assertTrue($configuration->isViolationSkipped('ClassWithMultipleDeps', 'DependencyClass1')); - $this->assertTrue($configuration->isViolationSkipped('ClassWithMultipleDeps', 'DependencyClass2')); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithOneDep'), ClassLikeName::fromString('DependencyClass'))); + static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithEmptyDeps'), ClassLikeName::fromString('DependencyClass'))); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithMultipleDeps'), ClassLikeName::fromString('DependencyClass1'))); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithMultipleDeps'), ClassLikeName::fromString('DependencyClass2'))); } - public function testFromArrayWithEmptyArrayAcceptable() + public function testFromArrayWithEmptyArrayAcceptable(): void { $configuration = ConfigurationSkippedViolation::fromArray([]); - $this->assertFalse($configuration->isViolationSkipped('AnyClass', 'AnotherAnyClass')); + static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromString('AnyClass'), ClassLikeName::fromString('AnotherAnyClass'))); } - public function testFromArrayRequireOneArgument() + public function testFromArrayRequireOneArgument(): void { $this->expectException(\TypeError::class); ConfigurationSkippedViolation::fromArray(); diff --git a/tests/Configuration/ConfigurationTest.php b/tests/Configuration/ConfigurationTest.php index 5264517bb..33d375fa1 100644 --- a/tests/Configuration/ConfigurationTest.php +++ b/tests/Configuration/ConfigurationTest.php @@ -5,6 +5,7 @@ namespace Tests\SensioLabs\Deptrac\Configuration; use PHPUnit\Framework\TestCase; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Configuration\Configuration; class ConfigurationTest extends TestCase @@ -94,7 +95,7 @@ public function testSkipViolations(): void ], ]); - static::assertTrue($configuration->getSkipViolations()->isViolationSkipped('FooClass', 'BarClass')); - static::assertTrue($configuration->getSkipViolations()->isViolationSkipped('FooClass', 'AnotherClass')); + static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromString('FooClass'), ClassLikeName::fromString('BarClass'))); + static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromString('FooClass'), ClassLikeName::fromString('AnotherClass'))); } } diff --git a/tests/Dependency/DependencyTest.php b/tests/Dependency/DependencyTest.php index c6e5b4685..971423d5e 100644 --- a/tests/Dependency/DependencyTest.php +++ b/tests/Dependency/DependencyTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; @@ -13,7 +14,7 @@ class DependencyTest extends TestCase { public function testGetSet(): void { - $dependency = new Dependency('a', 'b', new FileOccurrence(new AstFileReference('/foo.php'), 23)); + $dependency = new Dependency(ClassLikeName::fromString('a'), ClassLikeName::fromString('b'), new FileOccurrence(new AstFileReference('/foo.php'), 23)); static::assertEquals('a', $dependency->getClassA()); static::assertEquals('/foo.php', $dependency->getFileOccurrence()->getFilenpath()); static::assertEquals(23, $dependency->getFileOccurrence()->getLine()); diff --git a/tests/Dependency/InheritDependencyTest.php b/tests/Dependency/InheritDependencyTest.php index 125b914d5..bb3a9711f 100644 --- a/tests/Dependency/InheritDependencyTest.php +++ b/tests/Dependency/InheritDependencyTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritDependency; @@ -15,12 +16,15 @@ class InheritDependencyTest extends TestCase { public function testGetSet(): void { + $classA = ClassLikeName::fromString('a'); + $classB = ClassLikeName::fromString('b'); + $fileOccurrence = new FileOccurrence(new AstFileReference('a.php'), 1); $dependency = new InheritDependency( - 'a', - 'b', - $dep = new Dependency('a', 'b', $fileOccurrence), - $astInherit = AstInherit::newExtends('b', $fileOccurrence) + $classA, + $classB, + $dep = new Dependency($classA, $classB, $fileOccurrence), + $astInherit = AstInherit::newExtends($classB, $fileOccurrence) ); static::assertEquals('a', $dependency->getClassA()); diff --git a/tests/Dependency/InheritanceFlatterTest.php b/tests/Dependency/InheritanceFlatterTest.php index 74c4e1837..c7023123a 100644 --- a/tests/Dependency/InheritanceFlatterTest.php +++ b/tests/Dependency/InheritanceFlatterTest.php @@ -9,6 +9,7 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritanceFlatter; @@ -20,7 +21,7 @@ class InheritanceFlatterTest extends TestCase private function getAstReference($className) { $astClass = $this->prophesize(AstClassReference::class); - $astClass->getClassName()->willReturn($className); + $astClass->getClassName()->willReturn(ClassLikeName::fromString($className)); return $astClass->reveal(); } @@ -28,8 +29,8 @@ private function getAstReference($className) private function getDependency($className) { $dep = $this->prophesize(Dependency::class); - $dep->getClassA()->willReturn($className); - $dep->getClassB()->willReturn($className.'_b'); + $dep->getClassA()->willReturn(ClassLikeName::fromString($className)); + $dep->getClassB()->willReturn(ClassLikeName::fromString($className.'_b')); return $dep->reveal(); } @@ -56,12 +57,12 @@ public function testFlattenDependencies(): void $astMap->getClassInherits('classB')->willReturn([]); $astMap->getClassInherits('classBaum')->willReturn([]); $astMap->getClassInherits('classWeihnachtsbaum')->willReturn([ - AstInherit::newTraitUse('classBaum', new FileOccurrence(new AstFileReference('classWeihnachtsbaum.php'), 3)), + AstInherit::newTraitUse(ClassLikeName::fromString('classBaum'), new FileOccurrence(new AstFileReference('classWeihnachtsbaum.php'), 3)), ]); $astMap->getClassInherits('classGeschmückterWeihnachtsbaum')->willReturn([ - AstMap\AstInherit::newExtends('classBaum', new FileOccurrence(new AstFileReference('classGeschmückterWeihnachtsbaum.php'), 3)) + AstMap\AstInherit::newExtends(ClassLikeName::fromString('classBaum'), new FileOccurrence(new AstFileReference('classGeschmückterWeihnachtsbaum.php'), 3)) ->withPath([ - AstInherit::newTraitUse('classWeihnachtsbaum', new FileOccurrence(new AstFileReference('classBaum.php'), 3)), + AstInherit::newTraitUse(ClassLikeName::fromString('classWeihnachtsbaum'), new FileOccurrence(new AstFileReference('classBaum.php'), 3)), ]), ]); diff --git a/tests/Dependency/ResultTest.php b/tests/Dependency/ResultTest.php index 90de4acb8..268e19418 100644 --- a/tests/Dependency/ResultTest.php +++ b/tests/Dependency/ResultTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritDependency; @@ -16,21 +17,28 @@ class ResultTest extends TestCase { public function testAddDependency(): void { + $classA = ClassLikeName::fromString('A'); + $classB = ClassLikeName::fromString('B'); + $classC = ClassLikeName::fromString('C'); + $dependencyResult = new Result(); - $dependencyResult->addDependency($dep1 = new Dependency('A', 'B', new FileOccurrence(new AstFileReference('a.php'), 12))); - $dependencyResult->addDependency($dep2 = new Dependency('B', 'C', new FileOccurrence(new AstFileReference('b.php'), 12))); - $dependencyResult->addDependency($dep3 = new Dependency('A', 'C', new FileOccurrence(new AstFileReference('a.php'), 12))); - static::assertSame([$dep1, $dep3], $dependencyResult->getDependenciesByClass('A')); - static::assertSame([$dep2], $dependencyResult->getDependenciesByClass('B')); - static::assertSame([], $dependencyResult->getDependenciesByClass('C')); + $dependencyResult->addDependency($dep1 = new Dependency($classA, $classB, new FileOccurrence(new AstFileReference('a.php'), 12))); + $dependencyResult->addDependency($dep2 = new Dependency($classB, $classC, new FileOccurrence(new AstFileReference('b.php'), 12))); + $dependencyResult->addDependency($dep3 = new Dependency($classA, $classC, new FileOccurrence(new AstFileReference('a.php'), 12))); + static::assertSame([$dep1, $dep3], $dependencyResult->getDependenciesByClass($classA)); + static::assertSame([$dep2], $dependencyResult->getDependenciesByClass($classB)); + static::assertSame([], $dependencyResult->getDependenciesByClass($classC)); static::assertCount(3, $dependencyResult->getDependenciesAndInheritDependencies()); } public function testGetDependenciesAndInheritDependencies(): void { + $classA = ClassLikeName::fromString('A'); + $classB = ClassLikeName::fromString('B'); + $dependencyResult = new Result(); - $dependencyResult->addDependency($dep1 = new Dependency('A', 'B', new FileOccurrence(new AstFileReference('a.php'), 12))); - $dependencyResult->addInheritDependency($dep2 = new InheritDependency('A', 'B', $dep1, AstInherit::newExtends('B', new FileOccurrence(new AstFileReference('a.php'), 12)))); + $dependencyResult->addDependency($dep1 = new Dependency($classA, $classB, new FileOccurrence(new AstFileReference('a.php'), 12))); + $dependencyResult->addInheritDependency($dep2 = new InheritDependency($classA, $classB, $dep1, AstInherit::newExtends($classB, new FileOccurrence(new AstFileReference('a.php'), 12)))); static::assertEquals([$dep1, $dep2], $dependencyResult->getDependenciesAndInheritDependencies()); } } diff --git a/tests/DependencyEmitter/BasicDependencyEmitterTest.php b/tests/DependencyEmitter/BasicDependencyEmitterTest.php index 5635687ab..d4e1e0c52 100644 --- a/tests/DependencyEmitter/BasicDependencyEmitterTest.php +++ b/tests/DependencyEmitter/BasicDependencyEmitterTest.php @@ -23,7 +23,7 @@ public function testApplyDependencies(): void new \SplFileInfo(__DIR__.'/Fixtures/Foo.php') ); - static::assertCount(18, $deps); + static::assertCount(15, $deps); static::assertContains('Foo\Bar:4 on SomeUse', $deps); static::assertContains('Foo\Bar:10 on Foo\SomeParam', $deps); static::assertContains('Foo\Bar:10 on Foo\SomeClass', $deps); @@ -37,10 +37,6 @@ public function testApplyDependencies(): void static::assertContains('Foo\Bar:30 on Foo\SomeClass', $deps); static::assertContains('Foo\Bar:32 on Foo\SomeClass', $deps); static::assertContains('Foo\Bar:36 on Foo\string2', $deps); - static::assertContains('Foo\Bar:38 on string', $deps); - static::assertContains('Foo\Bar:40 on string', $deps); static::assertContains('Foo\Bar:42 on Foo\SomeClass', $deps); - static::assertContains('Foo\Bar:44 on self', $deps); - static::assertContains('Foo\Bar:46 on self', $deps); } } diff --git a/tests/OutputFormatter/ConsoleOutputFormatterTest.php b/tests/OutputFormatter/ConsoleOutputFormatterTest.php index f5c16750c..4af06878c 100644 --- a/tests/OutputFormatter/ConsoleOutputFormatterTest.php +++ b/tests/OutputFormatter/ConsoleOutputFormatterTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritDependency; @@ -26,18 +27,21 @@ public function testGetName(): void public function basicDataProvider(): iterable { + $originalA = ClassLikeName::fromString('OriginalA'); + $originalB = ClassLikeName::fromString('OriginalB'); + yield [ [ new Violation( new InheritDependency( - 'ClassA', - 'ClassB', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('originalA.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('originalA.php'), 3)) + ClassLikeName::fromString('ClassA'), + ClassLikeName::fromString('ClassB'), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('originalA.php'), 12)), + AstInherit::newExtends(ClassLikeName::fromString('ClassInheritA'), new FileOccurrence(new AstFileReference('originalA.php'), 3)) ->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('originalA.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('originalA.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('originalA.php'), 6)), + AstInherit::newExtends(ClassLikeName::fromString('ClassInheritB'), new FileOccurrence(new AstFileReference('originalA.php'), 4)), + AstInherit::newExtends(ClassLikeName::fromString('ClassInheritC'), new FileOccurrence(new AstFileReference('originalA.php'), 5)), + AstInherit::newExtends(ClassLikeName::fromString('ClassInheritD'), new FileOccurrence(new AstFileReference('originalA.php'), 6)), ]) ), 'LayerA', @@ -63,7 +67,7 @@ public function basicDataProvider(): iterable yield [ [ new Violation( - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('originalA.php'), 12)), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('originalA.php'), 12)), 'LayerA', 'LayerB' ), @@ -94,7 +98,7 @@ public function basicDataProvider(): iterable yield [ [ new SkippedViolation( - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('originalA.php'), 12)), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('originalA.php'), 12)), 'LayerA', 'LayerB' ), diff --git a/tests/OutputFormatter/GraphVizOutputFormatterTest.php b/tests/OutputFormatter/GraphVizOutputFormatterTest.php index fada90dda..49c1d924e 100644 --- a/tests/OutputFormatter/GraphVizOutputFormatterTest.php +++ b/tests/OutputFormatter/GraphVizOutputFormatterTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\OutputFormatter\GraphVizOutputFormatter; @@ -27,11 +28,14 @@ public function testFinish(): void { $dotFile = __DIR__.'/data/graphviz.dot'; + $fileOccurrenceA = new FileOccurrence(new AstFileReference('classA.php'), 0); + $classA = ClassLikeName::fromString('ClassA'); + $context = new Context([ - new Violation(new Dependency('ClassA', 'ClassB', new FileOccurrence(new AstFileReference('classA.php'), 0)), 'LayerA', 'LayerB'), - new Violation(new Dependency('ClassAB', 'ClassBA', new FileOccurrence(new AstFileReference('classAB.php'), 1)), 'LayerA', 'LayerB'), - new Allowed(new Dependency('ClassA', 'ClassC', new FileOccurrence(new AstFileReference('classA.php'), 0)), 'LayerA', 'LayerC'), - new Uncovered(new Dependency('ClassA', 'ClassD', new FileOccurrence(new AstFileReference('classA.php'), 0)), 'LayerC'), + new Violation(new Dependency($classA, ClassLikeName::fromString('ClassB'), $fileOccurrenceA), 'LayerA', 'LayerB'), + new Violation(new Dependency(ClassLikeName::fromString('ClassAB'), ClassLikeName::fromString('ClassBA'), new FileOccurrence(new AstFileReference('classAB.php'), 1)), 'LayerA', 'LayerB'), + new Allowed(new Dependency($classA, ClassLikeName::fromString('ClassC'), $fileOccurrenceA), 'LayerA', 'LayerC'), + new Uncovered(new Dependency($classA, ClassLikeName::fromString('ClassD'), $fileOccurrenceA), 'LayerC'), ]); $output = new BufferedOutput(); diff --git a/tests/OutputFormatter/JUnitOutputFormatterTest.php b/tests/OutputFormatter/JUnitOutputFormatterTest.php index 1b21d77c1..995b81f43 100644 --- a/tests/OutputFormatter/JUnitOutputFormatterTest.php +++ b/tests/OutputFormatter/JUnitOutputFormatterTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritDependency; @@ -35,17 +36,24 @@ public function testGetName(): void public function basicDataProvider(): iterable { + $originalA = ClassLikeName::fromString('OriginalA'); + $originalB = ClassLikeName::fromString('OriginalB'); + $classInheritA = ClassLikeName::fromString('ClassInheritA'); + $classInheritB = ClassLikeName::fromString('ClassInheritB'); + $classInheritC = ClassLikeName::fromString('ClassInheritC'); + $classInheritD = ClassLikeName::fromString('ClassInheritD'); + yield [ [ new Violation( new InheritDependency( - 'ClassA', - 'ClassB', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('foo.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('foo.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('foo.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('foo.php'), 6)), + ClassLikeName::fromString('ClassA'), + ClassLikeName::fromString('ClassB'), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), + AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ + AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), + AstInherit::newExtends($classInheritC, new FileOccurrence(new AstFileReference('foo.php'), 5)), + AstInherit::newExtends($classInheritD, new FileOccurrence(new AstFileReference('foo.php'), 6)), ]) ), 'LayerA', @@ -58,7 +66,7 @@ public function basicDataProvider(): iterable yield [ [ new Violation( - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('foo.php'), 12)), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), 'LayerA', 'LayerB' ), @@ -75,13 +83,13 @@ public function basicDataProvider(): iterable [ new SkippedViolation( new InheritDependency( - 'ClassA', - 'ClassB', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('foo.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('foo.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('foo.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('foo.php'), 6)), + ClassLikeName::fromString('ClassA'), + ClassLikeName::fromString('ClassB'), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), + AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ + AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), + AstInherit::newExtends($classInheritC, new FileOccurrence(new AstFileReference('foo.php'), 5)), + AstInherit::newExtends($classInheritD, new FileOccurrence(new AstFileReference('foo.php'), 6)), ]) ), 'LayerA', @@ -89,13 +97,13 @@ public function basicDataProvider(): iterable ), new Violation( new InheritDependency( - 'ClassC', - 'ClassD', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('foo.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('foo.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('foo.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('foo.php'), 6)), + ClassLikeName::fromString('ClassC'), + ClassLikeName::fromString('ClassD'), + new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), + AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ + AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), + AstInherit::newExtends($classInheritC, new FileOccurrence(new AstFileReference('foo.php'), 5)), + AstInherit::newExtends($classInheritD, new FileOccurrence(new AstFileReference('foo.php'), 6)), ]) ), 'LayerA', diff --git a/tests/RulesetEngineTest.php b/tests/RulesetEngineTest.php index b847ff7ee..7fec26b76 100644 --- a/tests/RulesetEngineTest.php +++ b/tests/RulesetEngineTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\ClassNameLayerResolverInterface; use SensioLabs\Deptrac\Configuration\Configuration; @@ -18,7 +19,11 @@ class RulesetEngineTest extends TestCase private function createDependencies(array $fromTo): iterable { foreach ($fromTo as $from => $to) { - yield new Dependency($from, $to, new FileOccurrence(new AstFileReference('foo.php'), 0)); + yield new Dependency( + ClassLikeName::fromString($from), + ClassLikeName::fromString($to), + new FileOccurrence(new AstFileReference('foo.php'), 0) + ); } } @@ -149,7 +154,7 @@ public function testProcess(array $dependenciesAsArray, array $classesInLayers, $classNameLayerResolver = $this->prophesize(ClassNameLayerResolverInterface::class); foreach ($classesInLayers as $classInLayer => $layers) { - $classNameLayerResolver->getLayersByClassName($classInLayer)->willReturn($layers); + $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromString($classInLayer))->willReturn($layers); } $configuration = Configuration::fromArray([ @@ -216,7 +221,7 @@ public function testGetSkippedViolations(array $dependenciesAsArray, array $clas $classNameLayerResolver = $this->prophesize(ClassNameLayerResolverInterface::class); foreach ($classesInLayers as $classInLayer => $layers) { - $classNameLayerResolver->getLayersByClassName($classInLayer)->willReturn($layers); + $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromString($classInLayer))->willReturn($layers); } $configuration = Configuration::fromArray([ From a8ecc12f4f84658e3538dad459afed38cb4f903b Mon Sep 17 00:00:00 2001 From: smoench Date: Fri, 31 Jan 2020 17:33:33 +0100 Subject: [PATCH 2/6] adds class reference builder --- src/AstRunner/AstMap/AstClassReference.php | 10 +- src/AstRunner/AstMap/AstDependency.php | 2 +- src/AstRunner/AstMap/AstFileReference.php | 4 +- .../AstMap/ClassReferenceBuilder.php | 190 ++++++++++++++++++ .../AstClassReferenceResolver.php | 121 ++++------- .../Resolver/AnnotationDependencyResolver.php | 36 +--- .../Resolver/AnonymousClassResolver.php | 22 +- .../Resolver/ClassConstantResolver.php | 15 +- .../Resolver/ClassDependencyResolver.php | 5 +- .../AstMap/ClassReferenceBuilderTest.php | 20 ++ 10 files changed, 270 insertions(+), 155 deletions(-) create mode 100644 src/AstRunner/AstMap/ClassReferenceBuilder.php create mode 100644 tests/AstRunner/AstMap/ClassReferenceBuilderTest.php diff --git a/src/AstRunner/AstMap/AstClassReference.php b/src/AstRunner/AstMap/AstClassReference.php index c2dd34d27..7a5b6704b 100644 --- a/src/AstRunner/AstMap/AstClassReference.php +++ b/src/AstRunner/AstMap/AstClassReference.php @@ -15,12 +15,16 @@ class AstClassReference /** @var AstInherit[] */ private $inherits; - public function __construct(ClassLikeName $className, AstFileReference $fileReference = null) + /** + * @param AstInherit[] $inherits + * @param AstDependency[] $dependencies + */ + public function __construct(ClassLikeName $className, AstFileReference $fileReference = null, array $inherits = [], array $dependencies = []) { $this->className = $className; $this->fileReference = $fileReference; - $this->dependencies = []; - $this->inherits = []; + $this->dependencies = $dependencies; + $this->inherits = $inherits; } public function getFileReference(): ?AstFileReference diff --git a/src/AstRunner/AstMap/AstDependency.php b/src/AstRunner/AstMap/AstDependency.php index 321c87008..89a7c8c9d 100644 --- a/src/AstRunner/AstMap/AstDependency.php +++ b/src/AstRunner/AstMap/AstDependency.php @@ -10,7 +10,7 @@ class AstDependency private $fileOccurrence; private $type; - public function __construct(ClassLikeName $class, FileOccurrence $fileOccurrence, string $type) + private function __construct(ClassLikeName $class, FileOccurrence $fileOccurrence, string $type) { $this->class = $class; $this->fileOccurrence = $fileOccurrence; diff --git a/src/AstRunner/AstMap/AstFileReference.php b/src/AstRunner/AstMap/AstFileReference.php index 39f26b738..0575426d6 100644 --- a/src/AstRunner/AstMap/AstFileReference.php +++ b/src/AstRunner/AstMap/AstFileReference.php @@ -21,9 +21,9 @@ public function __construct(string $filepath) $this->dependencies = []; } - public function addClassReference(ClassLikeName $className): AstClassReference + public function addClassReference(ClassLikeName $className, array $inherits = [], array $dependencies = []): AstClassReference { - $astClassReference = new AstClassReference($className, $this); + $astClassReference = new AstClassReference($className, $this, $inherits, $dependencies); $this->astClassReferences[] = $astClassReference; diff --git a/src/AstRunner/AstMap/ClassReferenceBuilder.php b/src/AstRunner/AstMap/ClassReferenceBuilder.php new file mode 100644 index 000000000..92c020e85 --- /dev/null +++ b/src/AstRunner/AstMap/ClassReferenceBuilder.php @@ -0,0 +1,190 @@ +fileReference = $fileReference; + $this->classLikeName = $classLikeName; + } + + public static function create(AstFileReference $fileReference, string $classLikeName): self + { + return new static($fileReference, $classLikeName); + } + + public function build(): AstClassReference + { + return $this->fileReference->addClassReference( + ClassLikeName::fromString($this->classLikeName), + $this->inherits, + $this->dependencies + ); + } + + public function extends(string $classLikeName, int $occursAtLine): self + { + $this->inherits[] = AstInherit::newExtends( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function implements(string $classLikeName, int $occursAtLine): self + { + $this->inherits[] = AstInherit::newImplements( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function trait(string $classLikeName, int $occursAtLine): self + { + $this->inherits[] = AstInherit::newTraitUse( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function instanceof(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::instanceofExpr( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function parameter(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::parameter( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function newStatement(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::newStmt( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function staticProperty(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::staticProperty( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function staticMethod(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::staticMethod( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function returnType(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::returnType( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function catchStmt(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::catchStmt( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function variable(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::variable( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function throwStatement(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::throwStmt( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function anonymousClassExtends(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::anonymousClassExtends( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function anonymousClassImplements(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::anonymousClassImplements( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } + + public function constFetch(string $classLikeName, int $occursAtLine): self + { + $this->dependencies[] = AstDependency::constFetch( + ClassLikeName::fromString($classLikeName), + new FileOccurrence($this->fileReference, $occursAtLine) + ); + + return $this; + } +} diff --git a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php index 90dc7c74c..2726f0ae7 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php +++ b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php @@ -10,8 +10,8 @@ use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; -use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\AstRunner\Resolver\ClassDependencyResolver; use SensioLabs\Deptrac\AstRunner\Resolver\NameScope; @@ -20,15 +20,15 @@ class AstClassReferenceResolver extends NodeVisitorAbstract { private $fileReference; - /** @var AstClassReference */ - private $currentClassReference; - /** @var ClassDependencyResolver[] */ private $classDependencyResolvers; - /** @var Context */ + /** @var NameScope */ private $currentTypeContext; + /** @var ClassReferenceBuilder */ + private $currentClassReferenceBuilder; + public function __construct(AstFileReference $fileReference, ClassDependencyResolver ...$classDependencyResolvers) { $this->currentTypeContext = new NameScope('global'); @@ -47,42 +47,31 @@ public function enterNode(Node $node) } if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) { - $className = ClassLikeName::fromString($node->namespacedName->toString()); + $className = $node->namespacedName->toString(); } elseif ($node->name instanceof Node\Identifier) { - $className = ClassLikeName::fromString($node->name->toString()); + $className = $node->name->toString(); } else { return null; // map anonymous classes on current class } - $this->currentClassReference = $this->fileReference->addClassReference($className); + if (null !== $this->currentClassReferenceBuilder) { + $this->currentClassReferenceBuilder->build(); + } + + $this->currentClassReferenceBuilder = ClassReferenceBuilder::create($this->fileReference, $className); if ($node instanceof Node\Stmt\Class_) { if ($node->extends instanceof Node\Name) { - $this->currentClassReference->addInherit( - AstInherit::newExtends( - ClassLikeName::fromString($node->extends->toString()), - new FileOccurrence($this->fileReference, $node->extends->getLine()) - ) - ); + $this->currentClassReferenceBuilder->extends($node->extends->toString(), $node->extends->getLine()); } foreach ($node->implements as $implement) { - $this->currentClassReference->addInherit( - AstInherit::newImplements( - ClassLikeName::fromString($implement->toString()), - new FileOccurrence($this->fileReference, $implement->getLine()) - ) - ); + $this->currentClassReferenceBuilder->implements($implement->toString(), $implement->getLine()); } } if ($node instanceof Node\Stmt\Interface_) { foreach ($node->extends as $extend) { - $this->currentClassReference->addInherit( - AstInherit::newExtends( - ClassLikeName::fromString($extend->toString()), - new FileOccurrence($this->fileReference, $extend->getLine()) - ) - ); + $this->currentClassReferenceBuilder->extends($extend->toString(), $extend->getLine()); } } @@ -101,101 +90,61 @@ public function leaveNode(Node $node) ); } - if (null === $this->currentClassReference) { + if (null === $this->currentClassReferenceBuilder) { return null; } if ($node instanceof Node\Stmt\TraitUse) { foreach ($node->traits as $trait) { - $this->currentClassReference->addInherit( - AstInherit::newTraitUse( - ClassLikeName::fromString($trait->toString()), - new FileOccurrence($this->fileReference, $trait->getLine()) - ) - ); + $this->currentClassReferenceBuilder->trait($trait->toString(), $trait->getLine()); } } if ($node instanceof Node\Expr\Instanceof_ && $this->isQualifiedClassName($node->class)) { - $this->currentClassReference->addDependency( - AstDependency::instanceofExpr( - ClassLikeName::fromString($node->class->toString()), - new FileOccurrence($this->fileReference, $node->class->getLine()) - ) - ); + $this->currentClassReferenceBuilder->instanceof($node->class->toString(), $node->class->getLine()); } if ($node instanceof Node\Param && $this->isQualifiedClassName($node->type)) { - $this->currentClassReference->addDependency( - AstDependency::parameter( - ClassLikeName::fromString($node->type->toString()), - new FileOccurrence($this->fileReference, $node->type->getLine()) - ) - ); + $this->currentClassReferenceBuilder->parameter($node->type->toString(), $node->type->getLine()); } if ($node instanceof Node\Expr\New_ && $this->isQualifiedClassName($node->class)) { - $this->currentClassReference->addDependency( - AstDependency::newStmt( - ClassLikeName::fromString($node->class->toString()), - new FileOccurrence($this->fileReference, $node->class->getLine()) - ) - ); + $this->currentClassReferenceBuilder->newStatement($node->class->toString(), $node->class->getLine()); } if ($node instanceof Node\Expr\StaticPropertyFetch && $this->isQualifiedClassName($node->class)) { - $this->currentClassReference->addDependency( - AstDependency::staticProperty( - ClassLikeName::fromString($node->class->toString()), - new FileOccurrence($this->fileReference, $node->class->getLine()) - ) - ); + $this->currentClassReferenceBuilder->staticProperty($node->class->toString(), $node->class->getLine()); } if ($node instanceof Node\Expr\StaticCall && $this->isQualifiedClassName($node->class)) { - $this->currentClassReference->addDependency( - AstDependency::staticMethod( - ClassLikeName::fromString($node->class->toString()), - new FileOccurrence($this->fileReference, $node->class->getLine()) - ) - ); + $this->currentClassReferenceBuilder->staticMethod($node->class->toString(), $node->class->getLine()); } if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) { if ($this->isQualifiedClassName($node->returnType)) { - $this->currentClassReference->addDependency( - AstDependency::returnType( - ClassLikeName::fromString($node->returnType->toString()), - new FileOccurrence($this->fileReference, $node->returnType->getLine()) - ) - ); + $this->currentClassReferenceBuilder->returnType($node->returnType->toString(), $node->returnType->getLine()); } elseif ($node->returnType instanceof Node\NullableType && $this->isQualifiedClassName($node->returnType->type)) { - $this->currentClassReference->addDependency( - AstDependency::returnType( - ClassLikeName::fromString((string) $node->returnType->type), - new FileOccurrence($this->fileReference, $node->returnType->getLine()) - ) - ); + $this->currentClassReferenceBuilder->returnType($node->returnType->type->toString(), $node->returnType->getLine()); } } if ($node instanceof Node\Stmt\Catch_) { foreach ($node->types as $type) { - if (!$this->isQualifiedClassName($type)) { - continue; - } - - $this->currentClassReference->addDependency( - AstDependency::catchStmt( - ClassLikeName::fromString($type->toString()), - new FileOccurrence($this->fileReference, $type->getLine()) - ) - ); + $this->currentClassReferenceBuilder->catchStmt($type->toString(), $type->getLine()); } } foreach ($this->classDependencyResolvers as $resolver) { - $resolver->processNode($node, $this->fileReference, $this->currentClassReference, $this->currentTypeContext); + $resolver->processNode($node, $this->currentClassReferenceBuilder, $this->currentTypeContext); + } + + return null; + } + + public function afterTraverse(array $nodes) + { + if (null !== $this->currentClassReferenceBuilder) { + $this->currentClassReferenceBuilder->build(); } return null; diff --git a/src/AstRunner/Resolver/AnnotationDependencyResolver.php b/src/AstRunner/Resolver/AnnotationDependencyResolver.php index 404311662..49397228c 100644 --- a/src/AstRunner/Resolver/AnnotationDependencyResolver.php +++ b/src/AstRunner/Resolver/AnnotationDependencyResolver.php @@ -11,11 +11,7 @@ use PHPStan\PhpDocParser\Parser\PhpDocParser; use PHPStan\PhpDocParser\Parser\TokenIterator; use PHPStan\PhpDocParser\Parser\TypeParser; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; -use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; -use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; -use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; -use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; class AnnotationDependencyResolver implements ClassDependencyResolver { @@ -34,7 +30,7 @@ public function __construct(TypeResolver $typeResolver) $this->typeResolver = $typeResolver; } - public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void { if (!$node instanceof Node\Stmt\Property && !$node instanceof Node\Expr\Variable @@ -55,12 +51,7 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { - $astClassReference->addDependency( - AstDependency::parameter( - ClassLikeName::fromString($type), - new FileOccurrence($fileReference, $docComment->getLine()) - ) - ); + $classReferenceBuilder->parameter($type, $docComment->getLine()); } } @@ -68,12 +59,7 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { - $astClassReference->addDependency( - AstDependency::variable( - ClassLikeName::fromString($type), - new FileOccurrence($fileReference, $docComment->getLine()) - ) - ); + $classReferenceBuilder->variable($type, $docComment->getLine()); } } @@ -81,12 +67,7 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { - $astClassReference->addDependency( - AstDependency::returnType( - ClassLikeName::fromString($type), - new FileOccurrence($fileReference, $docComment->getLine()) - ) - ); + $classReferenceBuilder->returnType($type, $docComment->getLine()); } } @@ -94,12 +75,7 @@ public function processNode(Node $node, AstFileReference $fileReference, AstClas $types = $this->typeResolver->resolveType($tag->type, $nameScope); foreach ($types as $type) { - $astClassReference->addDependency( - AstDependency::throwStmt( - ClassLikeName::fromString($type), - new FileOccurrence($fileReference, $docComment->getLine()) - ) - ); + $classReferenceBuilder->throwStatement($type, $docComment->getLine()); } } } diff --git a/src/AstRunner/Resolver/AnonymousClassResolver.php b/src/AstRunner/Resolver/AnonymousClassResolver.php index f563fad79..7741b2ed4 100644 --- a/src/AstRunner/Resolver/AnonymousClassResolver.php +++ b/src/AstRunner/Resolver/AnonymousClassResolver.php @@ -5,35 +5,21 @@ namespace SensioLabs\Deptrac\AstRunner\Resolver; use PhpParser\Node; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; -use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; -use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; -use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; -use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; class AnonymousClassResolver implements ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void { if (!$node instanceof Node\Stmt\Class_ || null !== $node->name) { return; } if ($node->extends instanceof Node\Name) { - $astClassReference->addDependency( - AstDependency::anonymousClassExtends( - ClassLikeName::fromString($node->extends->toString()), - new FileOccurrence($astFileReference, $node->extends->getLine()) - ) - ); + $classReferenceBuilder->anonymousClassExtends($node->extends->toString(), $node->extends->getLine()); } foreach ($node->implements as $implement) { - $astClassReference->addDependency( - AstDependency::anonymousClassImplements( - ClassLikeName::fromString($implement->toString()), - new FileOccurrence($astFileReference, $implement->getLine()) - ) - ); + $classReferenceBuilder->anonymousClassImplements($implement->toString(), $implement->getLine()); } } } diff --git a/src/AstRunner/Resolver/ClassConstantResolver.php b/src/AstRunner/Resolver/ClassConstantResolver.php index a4cc0974c..d0c54c7dc 100644 --- a/src/AstRunner/Resolver/ClassConstantResolver.php +++ b/src/AstRunner/Resolver/ClassConstantResolver.php @@ -6,25 +6,16 @@ use PhpParser\Node; use PhpParser\Node\Expr\ClassConstFetch; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; -use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; -use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; -use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; -use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; class ClassConstantResolver implements ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void { if (!$node instanceof ClassConstFetch || !$node->class instanceof Node\Name || $node->class->isSpecialClassName()) { return; } - $astClassReference->addDependency( - AstDependency::constFetch( - ClassLikeName::fromString($node->class->toString()), - new FileOccurrence($astFileReference, $node->class->getLine()) - ) - ); + $classReferenceBuilder->constFetch($node->class->toString(), $node->class->getLine()); } } diff --git a/src/AstRunner/Resolver/ClassDependencyResolver.php b/src/AstRunner/Resolver/ClassDependencyResolver.php index 0afb33458..0673f6658 100644 --- a/src/AstRunner/Resolver/ClassDependencyResolver.php +++ b/src/AstRunner/Resolver/ClassDependencyResolver.php @@ -5,10 +5,9 @@ namespace SensioLabs\Deptrac\AstRunner\Resolver; use PhpParser\Node; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; -use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; interface ClassDependencyResolver { - public function processNode(Node $node, AstFileReference $fileReference, AstClassReference $astClassReference, NameScope $nameScope): void; + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void; } diff --git a/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php b/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php new file mode 100644 index 000000000..ce7c21517 --- /dev/null +++ b/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php @@ -0,0 +1,20 @@ +extends('Bar', 12) + ->implements('Baz', 12) + ->build(); + } +} From 0f5258a4f7b157b0538340a7d7f6a12f27ae2749 Mon Sep 17 00:00:00 2001 From: smoench Date: Wed, 5 Feb 2020 17:15:23 +0100 Subject: [PATCH 3/6] naming + explicit toString method + fixing tests --- src/AstRunner/AstMap.php | 24 ++++---- src/AstRunner/AstMap/AstClassReference.php | 22 ++----- src/AstRunner/AstMap/AstDependency.php | 60 +++++++++---------- src/AstRunner/AstMap/AstInherit.php | 10 ++-- src/AstRunner/AstMap/ClassLikeName.php | 8 +-- .../AstMap/ClassReferenceBuilder.php | 32 +++++----- src/AstRunner/AstMap/FileOccurrence.php | 2 +- .../AstClassReferenceResolver.php | 52 ++++++++-------- .../NikicPhpParser/NikicPhpParser.php | 2 +- .../Resolver/AnonymousClassResolver.php | 4 +- .../Resolver/ClassConstantResolver.php | 2 +- src/ClassNameLayerResolver.php | 2 +- src/ClassNameLayerResolverCacheDecorator.php | 6 +- src/Collector/ClassNameCollector.php | 2 +- src/Collector/ClassNameRegexCollector.php | 2 +- src/Collector/InheritanceLevelCollector.php | 2 +- .../ConfigurationSkippedViolation.php | 9 +-- src/Dependency/Dependency.php | 18 +++--- src/Dependency/DependencyInterface.php | 4 +- src/Dependency/InheritDependency.php | 18 +++--- src/Dependency/InheritanceFlatter.php | 8 +-- src/Dependency/Result.php | 8 +-- .../BasicDependencyEmitter.php | 2 +- .../InheritanceDependencyEmitter.php | 6 +- .../ConsoleOutputFormatter.php | 14 ++--- src/OutputFormatter/JUnitOutputFormatter.php | 6 +- src/RulesetEngine.php | 6 +- .../AstRunner/AstMapFlattenGeneratorTest.php | 2 +- tests/AstRunner/AstMapGeneratorTest.php | 26 +++++--- .../AnnotationDependencyResolverTest.php | 12 ++-- .../Resolver/AnonymousClassResolverTest.php | 4 +- .../Resolver/ClassConstantResolverTest.php | 2 +- ...assNameLayerResolverCacheDecoratorTest.php | 2 +- tests/ClassNameLayerResolverTest.php | 2 +- tests/Collector/ClassNameCollectorTest.php | 4 +- .../Collector/ClassNameRegexCollectorTest.php | 4 +- tests/Collector/DirectoryCollectorTest.php | 4 +- .../InheritanceLevelCollectorTest.php | 4 +- tests/Collector/MethodCollectorTest.php | 6 +- .../ConfigurationSkippedViolationTest.php | 10 ++-- tests/Configuration/ConfigurationTest.php | 4 +- tests/Dependency/DependencyTest.php | 10 ++-- tests/Dependency/InheritDependencyTest.php | 20 +++---- tests/Dependency/InheritanceFlatterTest.php | 42 ++++++------- tests/Dependency/ResultTest.php | 10 ++-- tests/DependencyEmitter/EmitterTrait.php | 6 +- .../ConsoleOutputFormatterTest.php | 16 ++--- .../GraphVizOutputFormatterTest.php | 10 ++-- .../JUnitOutputFormatterTest.php | 24 ++++---- tests/RulesetEngineTest.php | 8 +-- 50 files changed, 283 insertions(+), 280 deletions(-) diff --git a/src/AstRunner/AstMap.php b/src/AstRunner/AstMap.php index 3e71c3364..00d698adb 100644 --- a/src/AstRunner/AstMap.php +++ b/src/AstRunner/AstMap.php @@ -4,10 +4,12 @@ namespace SensioLabs\Deptrac\AstRunner; +use ArrayObject; use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; +use SplStack; class AstMap { @@ -49,15 +51,15 @@ public function getAstFileReferences(): array public function getClassReferenceByClassName(ClassLikeName $className): ?AstClassReference { - return $this->astClassReferences[(string) $className] ?? null; + return $this->astClassReferences[$className->toString()] ?? null; } /** * @return AstInherit[]|iterable */ - public function getClassInherits(ClassLikeName $className): iterable + public function getClassInherits(ClassLikeName $classLikeName): iterable { - $classReference = $this->getClassReferenceByClassName($className); + $classReference = $this->getClassReferenceByClassName($classLikeName); if (null === $classReference) { return []; @@ -70,23 +72,23 @@ public function getClassInherits(ClassLikeName $className): iterable } /** - * @param \ArrayObject|null $alreadyResolved + * @param ArrayObject|null $alreadyResolved * * @return iterable */ private function resolveDepsRecursive( AstInherit $inheritDependency, - \ArrayObject $alreadyResolved = null, - \SplStack $path = null + ArrayObject $alreadyResolved = null, + SplStack $path = null ): iterable { - $alreadyResolved = $alreadyResolved ?? new \ArrayObject(); + $alreadyResolved = $alreadyResolved ?? new ArrayObject(); if (null === $path) { - $path = new \SplStack(); + $path = new SplStack(); $path->push($inheritDependency); } - $className = (string) $inheritDependency->getClassName(); + $className = $inheritDependency->getClassLikeName()->toString(); if (isset($alreadyResolved[$className])) { $path->pop(); @@ -94,7 +96,7 @@ private function resolveDepsRecursive( return []; } - $classReference = $this->getClassReferenceByClassName($inheritDependency->getClassName()); + $classReference = $this->getClassReferenceByClassName($inheritDependency->getClassLikeName()); if (null === $classReference) { return []; @@ -116,7 +118,7 @@ private function resolveDepsRecursive( private function addAstClassReference(AstClassReference $astClassReference): void { - $this->astClassReferences[(string) $astClassReference->getClassName()] = $astClassReference; + $this->astClassReferences[$astClassReference->getClassLikeName()->toString()] = $astClassReference; } private function addAstFileReference(AstFileReference $astFileReference): void diff --git a/src/AstRunner/AstMap/AstClassReference.php b/src/AstRunner/AstMap/AstClassReference.php index 7a5b6704b..a01f76a32 100644 --- a/src/AstRunner/AstMap/AstClassReference.php +++ b/src/AstRunner/AstMap/AstClassReference.php @@ -6,7 +6,7 @@ class AstClassReference { - private $className; + private $classLikeName; private $fileReference; /** @var AstDependency[] */ @@ -19,9 +19,9 @@ class AstClassReference * @param AstInherit[] $inherits * @param AstDependency[] $dependencies */ - public function __construct(ClassLikeName $className, AstFileReference $fileReference = null, array $inherits = [], array $dependencies = []) + public function __construct(ClassLikeName $classLikeName, AstFileReference $fileReference = null, array $inherits = [], array $dependencies = []) { - $this->className = $className; + $this->classLikeName = $classLikeName; $this->fileReference = $fileReference; $this->dependencies = $dependencies; $this->inherits = $inherits; @@ -29,12 +29,12 @@ public function __construct(ClassLikeName $className, AstFileReference $fileRefe public function getFileReference(): ?AstFileReference { - return $this->fileReference; + return $this->fileReference ? clone $this->fileReference : null; } - public function getClassName(): ClassLikeName + public function getClassLikeName(): ClassLikeName { - return $this->className; + return $this->classLikeName; } /** @@ -52,14 +52,4 @@ public function getInherits(): array { return $this->inherits; } - - public function addDependency(AstDependency $dependency): void - { - $this->dependencies[] = $dependency; - } - - public function addInherit(AstInherit $inherit): void - { - $this->inherits[] = $inherit; - } } diff --git a/src/AstRunner/AstMap/AstDependency.php b/src/AstRunner/AstMap/AstDependency.php index 89a7c8c9d..0c4a4b24d 100644 --- a/src/AstRunner/AstMap/AstDependency.php +++ b/src/AstRunner/AstMap/AstDependency.php @@ -6,20 +6,20 @@ class AstDependency { - private $class; + private $classLikeName; private $fileOccurrence; private $type; - private function __construct(ClassLikeName $class, FileOccurrence $fileOccurrence, string $type) + private function __construct(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence, string $type) { - $this->class = $class; + $this->classLikeName = $classLikeName; $this->fileOccurrence = $fileOccurrence; $this->type = $type; } public function getClassLikeName(): ClassLikeName { - return $this->class; + return $this->classLikeName; } public function getFileOccurrence(): FileOccurrence @@ -32,68 +32,68 @@ public function getType(): string return $this->type; } - public static function useStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function useStmt(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'use'); + return new self($classLikeName, $fileOccurrence, 'use'); } - public static function returnType(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function returnType(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'returntype'); + return new self($classLikeName, $fileOccurrence, 'returntype'); } - public static function parameter(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function parameter(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'parameter'); + return new self($classLikeName, $fileOccurrence, 'parameter'); } - public static function newStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function newStmt(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'new'); + return new self($classLikeName, $fileOccurrence, 'new'); } - public static function staticProperty(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function staticProperty(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'static_property'); + return new self($classLikeName, $fileOccurrence, 'static_property'); } - public static function staticMethod(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function staticMethod(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'static_method'); + return new self($classLikeName, $fileOccurrence, 'static_method'); } - public static function instanceofExpr(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function instanceofExpr(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'instanceof'); + return new self($classLikeName, $fileOccurrence, 'instanceof'); } - public static function catchStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function catchStmt(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'catch'); + return new self($classLikeName, $fileOccurrence, 'catch'); } - public static function variable(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function variable(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'variable'); + return new self($classLikeName, $fileOccurrence, 'variable'); } - public static function throwStmt(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function throwStmt(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'throw'); + return new self($classLikeName, $fileOccurrence, 'throw'); } - public static function constFetch(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function constFetch(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'const'); + return new self($classLikeName, $fileOccurrence, 'const'); } - public static function anonymousClassExtends(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function anonymousClassExtends(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'anonymous_class_extends'); + return new self($classLikeName, $fileOccurrence, 'anonymous_class_extends'); } - public static function anonymousClassImplements(ClassLikeName $class, FileOccurrence $fileOccurrence): self + public static function anonymousClassImplements(ClassLikeName $classLikeName, FileOccurrence $fileOccurrence): self { - return new self($class, $fileOccurrence, 'anonymous_class_implements'); + return new self($classLikeName, $fileOccurrence, 'anonymous_class_implements'); } } diff --git a/src/AstRunner/AstMap/AstInherit.php b/src/AstRunner/AstMap/AstInherit.php index 32450ddc7..3ce933d54 100644 --- a/src/AstRunner/AstMap/AstInherit.php +++ b/src/AstRunner/AstMap/AstInherit.php @@ -10,7 +10,7 @@ class AstInherit private const TYPE_IMPLEMENTS = 2; private const TYPE_USES = 3; - private $className; + private $classLikeName; private $fileOccurrence; private $type; @@ -19,7 +19,7 @@ class AstInherit private function __construct(ClassLikeName $className, FileOccurrence $fileOccurrence, int $type) { - $this->className = $className; + $this->classLikeName = $className; $this->fileOccurrence = $fileOccurrence; $this->type = $type; $this->path = []; @@ -56,7 +56,7 @@ public function __toString(): string $type = 'Unknown'; } - $description = "{$this->className}::{$this->fileOccurrence->getLine()} ($type)"; + $description = "{$this->classLikeName->toString()}::{$this->fileOccurrence->getLine()} ($type)"; if (0 === count($this->path)) { return $description; @@ -70,9 +70,9 @@ public function __toString(): string return $description.' (path: '.rtrim($buffer, ' -> ').')'; } - public function getClassName(): ClassLikeName + public function getClassLikeName(): ClassLikeName { - return $this->className; + return $this->classLikeName; } public function getFileOccurrence(): FileOccurrence diff --git a/src/AstRunner/AstMap/ClassLikeName.php b/src/AstRunner/AstMap/ClassLikeName.php index 6d0096aea..6dad0093a 100644 --- a/src/AstRunner/AstMap/ClassLikeName.php +++ b/src/AstRunner/AstMap/ClassLikeName.php @@ -13,12 +13,12 @@ final class ClassLikeName private function __construct(string $className) { - $this->className = ltrim($className, '\\'); + $this->className = $className; } - public static function fromString(string $className): self + public static function fromFQCN(string $className): self { - return new self($className); + return new self(ltrim($className, '\\')); } public function match(string $pattern): bool @@ -26,7 +26,7 @@ public function match(string $pattern): bool return 1 === preg_match($pattern, $this->className); } - public function __toString() + public function toString(): string { return $this->className; } diff --git a/src/AstRunner/AstMap/ClassReferenceBuilder.php b/src/AstRunner/AstMap/ClassReferenceBuilder.php index 92c020e85..ca5d7de06 100644 --- a/src/AstRunner/AstMap/ClassReferenceBuilder.php +++ b/src/AstRunner/AstMap/ClassReferenceBuilder.php @@ -32,7 +32,7 @@ public static function create(AstFileReference $fileReference, string $classLike public function build(): AstClassReference { return $this->fileReference->addClassReference( - ClassLikeName::fromString($this->classLikeName), + ClassLikeName::fromFQCN($this->classLikeName), $this->inherits, $this->dependencies ); @@ -41,7 +41,7 @@ public function build(): AstClassReference public function extends(string $classLikeName, int $occursAtLine): self { $this->inherits[] = AstInherit::newExtends( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -51,7 +51,7 @@ public function extends(string $classLikeName, int $occursAtLine): self public function implements(string $classLikeName, int $occursAtLine): self { $this->inherits[] = AstInherit::newImplements( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -61,7 +61,7 @@ public function implements(string $classLikeName, int $occursAtLine): self public function trait(string $classLikeName, int $occursAtLine): self { $this->inherits[] = AstInherit::newTraitUse( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -71,7 +71,7 @@ public function trait(string $classLikeName, int $occursAtLine): self public function instanceof(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::instanceofExpr( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -81,7 +81,7 @@ public function instanceof(string $classLikeName, int $occursAtLine): self public function parameter(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::parameter( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -91,7 +91,7 @@ public function parameter(string $classLikeName, int $occursAtLine): self public function newStatement(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::newStmt( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -101,7 +101,7 @@ public function newStatement(string $classLikeName, int $occursAtLine): self public function staticProperty(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::staticProperty( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -111,7 +111,7 @@ public function staticProperty(string $classLikeName, int $occursAtLine): self public function staticMethod(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::staticMethod( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -121,7 +121,7 @@ public function staticMethod(string $classLikeName, int $occursAtLine): self public function returnType(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::returnType( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -131,7 +131,7 @@ public function returnType(string $classLikeName, int $occursAtLine): self public function catchStmt(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::catchStmt( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -141,7 +141,7 @@ public function catchStmt(string $classLikeName, int $occursAtLine): self public function variable(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::variable( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -151,7 +151,7 @@ public function variable(string $classLikeName, int $occursAtLine): self public function throwStatement(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::throwStmt( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -161,7 +161,7 @@ public function throwStatement(string $classLikeName, int $occursAtLine): self public function anonymousClassExtends(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::anonymousClassExtends( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -171,7 +171,7 @@ public function anonymousClassExtends(string $classLikeName, int $occursAtLine): public function anonymousClassImplements(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::anonymousClassImplements( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); @@ -181,7 +181,7 @@ public function anonymousClassImplements(string $classLikeName, int $occursAtLin public function constFetch(string $classLikeName, int $occursAtLine): self { $this->dependencies[] = AstDependency::constFetch( - ClassLikeName::fromString($classLikeName), + ClassLikeName::fromFQCN($classLikeName), new FileOccurrence($this->fileReference, $occursAtLine) ); diff --git a/src/AstRunner/AstMap/FileOccurrence.php b/src/AstRunner/AstMap/FileOccurrence.php index 2bbb85bb7..a1ef83d6b 100644 --- a/src/AstRunner/AstMap/FileOccurrence.php +++ b/src/AstRunner/AstMap/FileOccurrence.php @@ -4,7 +4,7 @@ namespace SensioLabs\Deptrac\AstRunner\AstMap; -class FileOccurrence +final class FileOccurrence { /** * @var AstFileReference diff --git a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php index 2726f0ae7..822abd890 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php +++ b/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php @@ -4,10 +4,8 @@ namespace SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser; -use phpDocumentor\Reflection\Types\Context; use PhpParser\Node; use PhpParser\NodeVisitorAbstract; -use SensioLabs\Deptrac\AstRunner\AstMap\AstClassReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstDependency; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; @@ -39,7 +37,7 @@ public function __construct(AstFileReference $fileReference, ClassDependencyReso public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Namespace_) { - $this->currentTypeContext = new NameScope($node->name ? $node->name->toString() : 'global'); + $this->currentTypeContext = new NameScope($node->name ? $node->name->toCodeString() : 'global'); } if (!$node instanceof Node\Stmt\ClassLike) { @@ -47,9 +45,9 @@ public function enterNode(Node $node) } if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) { - $className = $node->namespacedName->toString(); + $className = $node->namespacedName->toCodeString(); } elseif ($node->name instanceof Node\Identifier) { - $className = $node->name->toString(); + $className = $node->name->toCodeString(); } else { return null; // map anonymous classes on current class } @@ -62,16 +60,16 @@ public function enterNode(Node $node) if ($node instanceof Node\Stmt\Class_) { if ($node->extends instanceof Node\Name) { - $this->currentClassReferenceBuilder->extends($node->extends->toString(), $node->extends->getLine()); + $this->currentClassReferenceBuilder->extends($node->extends->toCodeString(), $node->extends->getLine()); } foreach ($node->implements as $implement) { - $this->currentClassReferenceBuilder->implements($implement->toString(), $implement->getLine()); + $this->currentClassReferenceBuilder->implements($implement->toCodeString(), $implement->getLine()); } } if ($node instanceof Node\Stmt\Interface_) { foreach ($node->extends as $extend) { - $this->currentClassReferenceBuilder->extends($extend->toString(), $extend->getLine()); + $this->currentClassReferenceBuilder->extends($extend->toCodeString(), $extend->getLine()); } } @@ -81,10 +79,10 @@ public function enterNode(Node $node) public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\UseUse) { - $this->currentTypeContext->addUse($node->name->toString(), $node->getAlias()->toString()); + $this->currentTypeContext->addUse($node->name->toCodeString(), $node->getAlias()->toString()); $this->fileReference->addDependency( AstDependency::useStmt( - ClassLikeName::fromString($node->name->toString()), + ClassLikeName::fromFQCN($node->name->toCodeString()), new FileOccurrence($this->fileReference, $node->name->getLine()) ) ); @@ -96,41 +94,41 @@ public function leaveNode(Node $node) if ($node instanceof Node\Stmt\TraitUse) { foreach ($node->traits as $trait) { - $this->currentClassReferenceBuilder->trait($trait->toString(), $trait->getLine()); + $this->currentClassReferenceBuilder->trait($trait->toCodeString(), $trait->getLine()); } } - if ($node instanceof Node\Expr\Instanceof_ && $this->isQualifiedClassName($node->class)) { - $this->currentClassReferenceBuilder->instanceof($node->class->toString(), $node->class->getLine()); + if ($node instanceof Node\Expr\Instanceof_ && $this->isQualifiedType($node->class)) { + $this->currentClassReferenceBuilder->instanceof($node->class->toCodeString(), $node->class->getLine()); } - if ($node instanceof Node\Param && $this->isQualifiedClassName($node->type)) { - $this->currentClassReferenceBuilder->parameter($node->type->toString(), $node->type->getLine()); + if ($node instanceof Node\Param && $this->isQualifiedType($node->type)) { + $this->currentClassReferenceBuilder->parameter($node->type->toCodeString(), $node->type->getLine()); } - if ($node instanceof Node\Expr\New_ && $this->isQualifiedClassName($node->class)) { - $this->currentClassReferenceBuilder->newStatement($node->class->toString(), $node->class->getLine()); + if ($node instanceof Node\Expr\New_ && $this->isQualifiedType($node->class)) { + $this->currentClassReferenceBuilder->newStatement($node->class->toCodeString(), $node->class->getLine()); } - if ($node instanceof Node\Expr\StaticPropertyFetch && $this->isQualifiedClassName($node->class)) { - $this->currentClassReferenceBuilder->staticProperty($node->class->toString(), $node->class->getLine()); + if ($node instanceof Node\Expr\StaticPropertyFetch && $this->isQualifiedType($node->class)) { + $this->currentClassReferenceBuilder->staticProperty($node->class->toCodeString(), $node->class->getLine()); } - if ($node instanceof Node\Expr\StaticCall && $this->isQualifiedClassName($node->class)) { - $this->currentClassReferenceBuilder->staticMethod($node->class->toString(), $node->class->getLine()); + if ($node instanceof Node\Expr\StaticCall && $this->isQualifiedType($node->class)) { + $this->currentClassReferenceBuilder->staticMethod($node->class->toCodeString(), $node->class->getLine()); } if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) { - if ($this->isQualifiedClassName($node->returnType)) { - $this->currentClassReferenceBuilder->returnType($node->returnType->toString(), $node->returnType->getLine()); - } elseif ($node->returnType instanceof Node\NullableType && $this->isQualifiedClassName($node->returnType->type)) { - $this->currentClassReferenceBuilder->returnType($node->returnType->type->toString(), $node->returnType->getLine()); + if ($this->isQualifiedType($node->returnType)) { + $this->currentClassReferenceBuilder->returnType($node->returnType->toCodeString(), $node->returnType->getLine()); + } elseif ($node->returnType instanceof Node\NullableType && $this->isQualifiedType($node->returnType->type)) { + $this->currentClassReferenceBuilder->returnType($node->returnType->type->toCodeString(), $node->returnType->getLine()); } } if ($node instanceof Node\Stmt\Catch_) { foreach ($node->types as $type) { - $this->currentClassReferenceBuilder->catchStmt($type->toString(), $type->getLine()); + $this->currentClassReferenceBuilder->catchStmt($type->toCodeString(), $type->getLine()); } } @@ -150,7 +148,7 @@ public function afterTraverse(array $nodes) return null; } - private function isQualifiedClassName($type): bool + private function isQualifiedType($type): bool { if (null === $type) { return false; diff --git a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php index 064c00566..1d7de67d8 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php +++ b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php @@ -82,7 +82,7 @@ public function parse($data): AstFileReference public function getAstForClassReference(AstClassReference $classReference): ?Node\Stmt\ClassLike { - $classLikeName = (string) $classReference->getClassName(); + $classLikeName = $classReference->getClassLikeName()->toString(); if (isset(self::$classAstMap[$classLikeName])) { return self::$classAstMap[$classLikeName]; diff --git a/src/AstRunner/Resolver/AnonymousClassResolver.php b/src/AstRunner/Resolver/AnonymousClassResolver.php index 7741b2ed4..5b3343779 100644 --- a/src/AstRunner/Resolver/AnonymousClassResolver.php +++ b/src/AstRunner/Resolver/AnonymousClassResolver.php @@ -16,10 +16,10 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui } if ($node->extends instanceof Node\Name) { - $classReferenceBuilder->anonymousClassExtends($node->extends->toString(), $node->extends->getLine()); + $classReferenceBuilder->anonymousClassExtends($node->extends->toCodeString(), $node->extends->getLine()); } foreach ($node->implements as $implement) { - $classReferenceBuilder->anonymousClassImplements($implement->toString(), $implement->getLine()); + $classReferenceBuilder->anonymousClassImplements($implement->toCodeString(), $implement->getLine()); } } } diff --git a/src/AstRunner/Resolver/ClassConstantResolver.php b/src/AstRunner/Resolver/ClassConstantResolver.php index d0c54c7dc..cfdf65df5 100644 --- a/src/AstRunner/Resolver/ClassConstantResolver.php +++ b/src/AstRunner/Resolver/ClassConstantResolver.php @@ -16,6 +16,6 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui return; } - $classReferenceBuilder->constFetch($node->class->toString(), $node->class->getLine()); + $classReferenceBuilder->constFetch($node->class->toCodeString(), $node->class->getLine()); } } diff --git a/src/ClassNameLayerResolver.php b/src/ClassNameLayerResolver.php index b5d5c359c..b8750b8da 100644 --- a/src/ClassNameLayerResolver.php +++ b/src/ClassNameLayerResolver.php @@ -45,7 +45,7 @@ public function getLayersByClassName(ClassLikeName $className): array if ($collector->satisfy( $configurationCollector->getArgs(), - clone $astClassReference, + $astClassReference, $this->astMap, $this->collectorRegistry )) { diff --git a/src/ClassNameLayerResolverCacheDecorator.php b/src/ClassNameLayerResolverCacheDecorator.php index f604e995d..9f7058dae 100644 --- a/src/ClassNameLayerResolverCacheDecorator.php +++ b/src/ClassNameLayerResolverCacheDecorator.php @@ -23,11 +23,11 @@ public function __construct(ClassNameLayerResolverInterface $classNameLayerResol public function getLayersByClassName(ClassLikeName $className): array { - if (!isset($this->layerNamesByClassCache[(string) $className])) { - $this->layerNamesByClassCache[(string) $className] = $this->classNameLayerResolver->getLayersByClassName($className); + if (!isset($this->layerNamesByClassCache[$className->toString()])) { + $this->layerNamesByClassCache[$className->toString()] = $this->classNameLayerResolver->getLayersByClassName($className); } - return $this->layerNamesByClassCache[(string) $className]; + return $this->layerNamesByClassCache[$className->toString()]; } public function getLayers(): array diff --git a/src/Collector/ClassNameCollector.php b/src/Collector/ClassNameCollector.php index e0a844330..8d7564317 100644 --- a/src/Collector/ClassNameCollector.php +++ b/src/Collector/ClassNameCollector.php @@ -20,7 +20,7 @@ public function satisfy( AstMap $astMap, Registry $collectorRegistry ): bool { - return $astClassReference->getClassName()->match($this->getPattern($configuration)); + return $astClassReference->getClassLikeName()->match($this->getPattern($configuration)); } /** diff --git a/src/Collector/ClassNameRegexCollector.php b/src/Collector/ClassNameRegexCollector.php index 90e870b3e..eb16993ef 100644 --- a/src/Collector/ClassNameRegexCollector.php +++ b/src/Collector/ClassNameRegexCollector.php @@ -20,7 +20,7 @@ public function satisfy( AstMap $astMap, Registry $collectorRegistry ): bool { - return $astClassReference->getClassName()->match($this->getPattern($configuration)); + return $astClassReference->getClassLikeName()->match($this->getPattern($configuration)); } /** diff --git a/src/Collector/InheritanceLevelCollector.php b/src/Collector/InheritanceLevelCollector.php index 3462ac13f..9930320db 100644 --- a/src/Collector/InheritanceLevelCollector.php +++ b/src/Collector/InheritanceLevelCollector.php @@ -20,7 +20,7 @@ public function satisfy( AstMap $astMap, Registry $collectorRegistry ): bool { - $classInherits = $astMap->getClassInherits($astClassReference->getClassName()); + $classInherits = $astMap->getClassInherits($astClassReference->getClassLikeName()); foreach ($classInherits as $classInherit) { if (count($classInherit->getPath()) >= $configuration['level']) { diff --git a/src/Configuration/ConfigurationSkippedViolation.php b/src/Configuration/ConfigurationSkippedViolation.php index c455e3dc9..9d3126b74 100644 --- a/src/Configuration/ConfigurationSkippedViolation.php +++ b/src/Configuration/ConfigurationSkippedViolation.php @@ -30,12 +30,9 @@ private function __construct(array $classesDeps) $this->classesDeps = $classesDeps; } - public function isViolationSkipped(ClassLikeName $classA, ClassLikeName $classB): bool + public function isViolationSkipped(ClassLikeName $classLikeNameA, ClassLikeName $classLikeNameB): bool { - $classLikeNameA = (string) $classA; - $classLikeNameB = (string) $classB; - - return isset($this->classesDeps[$classLikeNameA]) - && \in_array($classLikeNameB, $this->classesDeps[$classLikeNameA], true); + return isset($this->classesDeps[$classLikeNameA->toString()]) + && \in_array($classLikeNameB->toString(), $this->classesDeps[$classLikeNameA->toString()], true); } } diff --git a/src/Dependency/Dependency.php b/src/Dependency/Dependency.php index 9d027db23..4390b5a48 100644 --- a/src/Dependency/Dependency.php +++ b/src/Dependency/Dependency.php @@ -9,25 +9,25 @@ class Dependency implements DependencyInterface { - private $classB; - private $classA; + private $classLikeNameB; + private $classLikeNameA; private $fileOccurrence; - public function __construct(ClassLikeName $classA, ClassLikeName $classB, FileOccurrence $fileOccurrence) + public function __construct(ClassLikeName $classLikeNameA, ClassLikeName $classLikeNameB, FileOccurrence $fileOccurrence) { - $this->classA = $classA; - $this->classB = $classB; + $this->classLikeNameA = $classLikeNameA; + $this->classLikeNameB = $classLikeNameB; $this->fileOccurrence = $fileOccurrence; } - public function getClassA(): ClassLikeName + public function getClassLikeNameA(): ClassLikeName { - return $this->classA; + return $this->classLikeNameA; } - public function getClassB(): ClassLikeName + public function getClassLikeNameB(): ClassLikeName { - return $this->classB; + return $this->classLikeNameB; } public function getFileOccurrence(): FileOccurrence diff --git a/src/Dependency/DependencyInterface.php b/src/Dependency/DependencyInterface.php index 9b6ca047e..db5840516 100644 --- a/src/Dependency/DependencyInterface.php +++ b/src/Dependency/DependencyInterface.php @@ -9,9 +9,9 @@ interface DependencyInterface { - public function getClassA(): ClassLikeName; + public function getClassLikeNameA(): ClassLikeName; - public function getClassB(): ClassLikeName; + public function getClassLikeNameB(): ClassLikeName; public function getFileOccurrence(): FileOccurrence; } diff --git a/src/Dependency/InheritDependency.php b/src/Dependency/InheritDependency.php index 04c7b87be..9a2e665d1 100644 --- a/src/Dependency/InheritDependency.php +++ b/src/Dependency/InheritDependency.php @@ -10,22 +10,22 @@ class InheritDependency implements DependencyInterface { - private $classA; - private $classB; + private $classLikeNameA; + private $classLikeNameB; private $path; private $originalDependency; - public function __construct(ClassLikeName $classA, ClassLikeName $classB, DependencyInterface $originalDependency, AstInherit $path) + public function __construct(ClassLikeName $classLikeNameA, ClassLikeName $classLikeNameB, DependencyInterface $originalDependency, AstInherit $path) { - $this->classA = $classA; - $this->classB = $classB; + $this->classLikeNameA = $classLikeNameA; + $this->classLikeNameB = $classLikeNameB; $this->originalDependency = $originalDependency; $this->path = $path; } - public function getClassA(): ClassLikeName + public function getClassLikeNameA(): ClassLikeName { - return $this->classA; + return $this->classLikeNameA; } public function getFileOccurrence(): FileOccurrence @@ -33,9 +33,9 @@ public function getFileOccurrence(): FileOccurrence return $this->getOriginalDependency()->getFileOccurrence(); } - public function getClassB(): ClassLikeName + public function getClassLikeNameB(): ClassLikeName { - return $this->classB; + return $this->classLikeNameB; } public function getInheritPath(): AstInherit diff --git a/src/Dependency/InheritanceFlatter.php b/src/Dependency/InheritanceFlatter.php index d1dc68ced..b6cb9e84e 100644 --- a/src/Dependency/InheritanceFlatter.php +++ b/src/Dependency/InheritanceFlatter.php @@ -13,11 +13,11 @@ public function flattenDependencies( Result $dependencyResult ): void { foreach ($astMap->getAstClassReferences() as $classReference) { - foreach ($astMap->getClassInherits($classReference->getClassName()) as $inherit) { - foreach ($dependencyResult->getDependenciesByClass($inherit->getClassName()) as $dep) { + foreach ($astMap->getClassInherits($classReference->getClassLikeName()) as $inherit) { + foreach ($dependencyResult->getDependenciesByClass($inherit->getClassLikeName()) as $dep) { $dependencyResult->addInheritDependency(new InheritDependency( - $classReference->getClassName(), - $dep->getClassB(), + $classReference->getClassLikeName(), + $dep->getClassLikeNameB(), $dep, $inherit )); diff --git a/src/Dependency/Result.php b/src/Dependency/Result.php index 1d0005b1a..80b4cd307 100644 --- a/src/Dependency/Result.php +++ b/src/Dependency/Result.php @@ -16,7 +16,7 @@ class Result public function addDependency(Dependency $dependency): self { - $classLikeName = (string) $dependency->getClassA(); + $classLikeName = $dependency->getClassLikeNameA()->toString(); if (!isset($this->dependencies[$classLikeName])) { $this->dependencies[$classLikeName] = []; } @@ -28,7 +28,7 @@ public function addDependency(Dependency $dependency): self public function addInheritDependency(InheritDependency $dependency): self { - $classLikeName = (string) $dependency->getClassA(); + $classLikeName = $dependency->getClassLikeNameA()->toString(); if (!isset($this->inheritDependencies[$classLikeName])) { $this->inheritDependencies[$classLikeName] = []; } @@ -41,9 +41,9 @@ public function addInheritDependency(InheritDependency $dependency): self /** * @return Dependency[] */ - public function getDependenciesByClass(ClassLikeName $className): array + public function getDependenciesByClass(ClassLikeName $classLikeName): array { - return $this->dependencies[(string) $className] ?? []; + return $this->dependencies[$classLikeName->toString()] ?? []; } /** diff --git a/src/DependencyEmitter/BasicDependencyEmitter.php b/src/DependencyEmitter/BasicDependencyEmitter.php index 42e32ef2f..71bf40067 100644 --- a/src/DependencyEmitter/BasicDependencyEmitter.php +++ b/src/DependencyEmitter/BasicDependencyEmitter.php @@ -28,7 +28,7 @@ public function applyDependencies(AstMap $astMap, Result $dependencyResult): voi foreach ($dependencies as $emittedDependency) { $dependencyResult->addDependency( new Dependency( - $astClassReference->getClassName(), + $astClassReference->getClassLikeName(), $emittedDependency->getClassLikeName(), $emittedDependency->getFileOccurrence() ) diff --git a/src/DependencyEmitter/InheritanceDependencyEmitter.php b/src/DependencyEmitter/InheritanceDependencyEmitter.php index 087b153f9..7afc43d82 100644 --- a/src/DependencyEmitter/InheritanceDependencyEmitter.php +++ b/src/DependencyEmitter/InheritanceDependencyEmitter.php @@ -18,11 +18,11 @@ public function getName(): string public function applyDependencies(AstMap $astMap, Result $dependencyResult): void { foreach ($astMap->getAstClassReferences() as $classReference) { - foreach ($astMap->getClassInherits($classReference->getClassName()) as $inherit) { + foreach ($astMap->getClassInherits($classReference->getClassLikeName()) as $inherit) { $dependencyResult->addDependency( new Dependency( - $classReference->getClassName(), - $inherit->getClassName(), + $classReference->getClassLikeName(), + $inherit->getClassLikeName(), $inherit->getFileOccurrence() ) ); diff --git a/src/OutputFormatter/ConsoleOutputFormatter.php b/src/OutputFormatter/ConsoleOutputFormatter.php index 4aa7a825f..76e1fd469 100644 --- a/src/OutputFormatter/ConsoleOutputFormatter.php +++ b/src/OutputFormatter/ConsoleOutputFormatter.php @@ -90,8 +90,8 @@ private function handleInheritDependency(Rule $rule, OutputInterface $output): v sprintf( "%s%s must not depend on %s (%s on %s) \n%s", $rule instanceof SkippedViolation ? '[SKIPPED] ' : '', - $dependency->getClassA(), - $dependency->getClassB(), + $dependency->getClassLikeNameA()->toString(), + $dependency->getClassLikeNameB()->toString(), $rule->getLayerA(), $rule->getLayerB(), $this->formatPath($dependency->getInheritPath(), $dependency) @@ -110,9 +110,9 @@ private function handleDependency(Rule $rule, OutputInterface $output): void sprintf( '%s%s::%s must not depend on %s (%s on %s)', $rule instanceof SkippedViolation ? '[SKIPPED] ' : '', - $dependency->getClassA(), + $dependency->getClassLikeNameA()->toString(), $dependency->getFileOccurrence()->getLine(), - $dependency->getClassB(), + $dependency->getClassLikeNameB()->toString(), $rule->getLayerA(), $rule->getLayerB() ) @@ -123,13 +123,13 @@ private function formatPath(AstInherit $astInherit, InheritDependency $dependenc { $buffer = []; foreach ($astInherit->getPath() as $p) { - array_unshift($buffer, sprintf("\t%s::%d", $p->getClassName(), $p->getFileOccurrence()->getLine())); + array_unshift($buffer, sprintf("\t%s::%d", $p->getClassLikeName()->toString(), $p->getFileOccurrence()->getLine())); } - $buffer[] = sprintf("\t%s::%d", $astInherit->getClassName(), $astInherit->getFileOccurrence()->getLine()); + $buffer[] = sprintf("\t%s::%d", $astInherit->getClassLikeName()->toString(), $astInherit->getFileOccurrence()->getLine()); $buffer[] = sprintf( "\t%s::%d", - $dependency->getOriginalDependency()->getClassB(), + $dependency->getOriginalDependency()->getClassLikeNameB()->toString(), $dependency->getOriginalDependency()->getFileOccurrence()->getLine() ); diff --git a/src/OutputFormatter/JUnitOutputFormatter.php b/src/OutputFormatter/JUnitOutputFormatter.php index b0b0a8d0d..a176019e7 100644 --- a/src/OutputFormatter/JUnitOutputFormatter.php +++ b/src/OutputFormatter/JUnitOutputFormatter.php @@ -107,7 +107,7 @@ private function addTestSuite(Context $context, \DOMDocument $xmlDoc, \DOMElemen $rulesByClassName = []; foreach ($rules as $rule) { - $rulesByClassName[(string) $rule->getDependency()->getClassA()][] = $rule; + $rulesByClassName[$rule->getDependency()->getClassLikeNameA()->toString()][] = $rule; } $testSuite = $xmlDoc->createElement('testsuite'); @@ -156,9 +156,9 @@ private function addFailure(Violation $violation, \DOMDocument $xmlDoc, \DOMElem $message = sprintf( '%s:%d must not depend on %s (%s on %s)', - $dependency->getClassA(), + $dependency->getClassLikeNameA()->toString(), $dependency->getFileOccurrence()->getLine(), - $dependency->getClassB(), + $dependency->getClassLikeNameB()->toString(), $violation->getLayerA(), $violation->getLayerB() ); diff --git a/src/RulesetEngine.php b/src/RulesetEngine.php index a3287ae56..918936b01 100644 --- a/src/RulesetEngine.php +++ b/src/RulesetEngine.php @@ -25,12 +25,12 @@ public function process( $configurationSkippedViolation = $configuration->getSkipViolations(); foreach ($dependencyResult->getDependenciesAndInheritDependencies() as $dependency) { - $layerNames = $classNameLayerResolver->getLayersByClassName($dependency->getClassA()); + $layerNames = $classNameLayerResolver->getLayersByClassName($dependency->getClassLikeNameA()); foreach ($layerNames as $layerName) { $allowedDependencies = $configurationRuleset->getAllowedDependencies($layerName); - $layersNamesClassB = $classNameLayerResolver->getLayersByClassName($dependency->getClassB()); + $layersNamesClassB = $classNameLayerResolver->getLayersByClassName($dependency->getClassLikeNameB()); if (0 === count($layersNamesClassB)) { $rules[] = new Uncovered($dependency, $layerName); @@ -47,7 +47,7 @@ public function process( continue; } - if ($configurationSkippedViolation->isViolationSkipped($dependency->getClassA(), $dependency->getClassB())) { + if ($configurationSkippedViolation->isViolationSkipped($dependency->getClassLikeNameA(), $dependency->getClassLikeNameB())) { $rules[] = new SkippedViolation($dependency, $layerName, $layerNameOfDependency); continue; } diff --git a/tests/AstRunner/AstMapFlattenGeneratorTest.php b/tests/AstRunner/AstMapFlattenGeneratorTest.php index 0094cf807..22ff1a336 100644 --- a/tests/AstRunner/AstMapFlattenGeneratorTest.php +++ b/tests/AstRunner/AstMapFlattenGeneratorTest.php @@ -54,7 +54,7 @@ private function getAstMap(string $fixture): AstMap private function getInheritedInherits(string $class, AstMap $astMap): array { $inherits = []; - foreach ($astMap->getClassInherits(ClassLikeName::fromString($class)) as $v) { + foreach ($astMap->getClassInherits(ClassLikeName::fromFQCN($class)) as $v) { if (count($v->getPath()) > 0) { $inherits[] = (string) $v; } diff --git a/tests/AstRunner/AstMapGeneratorTest.php b/tests/AstRunner/AstMapGeneratorTest.php index 6793ab70d..947dcfab4 100644 --- a/tests/AstRunner/AstMapGeneratorTest.php +++ b/tests/AstRunner/AstMapGeneratorTest.php @@ -50,7 +50,7 @@ public function testBasicDependencyClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassA::9 (Extends)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceA::9 (Implements)', ], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyClassB::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyClassB::class))) ); static::assertArrayValuesEquals( @@ -58,7 +58,7 @@ public function testBasicDependencyClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceA::13 (Implements)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassInterfaceB::13 (Implements)', ], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyClassC::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyClassC::class))) ); } @@ -68,17 +68,17 @@ public function testBasicTraitsClass(): void static::assertArrayValuesEquals( [], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitA::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitA::class))) ); static::assertArrayValuesEquals( [], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitB::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitB::class))) ); static::assertArrayValuesEquals( ['Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitB::7 (Uses)'], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitC::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitC::class))) ); static::assertArrayValuesEquals( @@ -86,12 +86,24 @@ public function testBasicTraitsClass(): void 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitA::10 (Uses)', 'Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitB::11 (Uses)', ], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitD::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitD::class))) ); static::assertArrayValuesEquals( ['Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyTraitA::15 (Uses)'], - $astMap->getClassReferenceByClassName(ClassLikeName::fromString(BasicDependencyTraitClass::class))->getInherits() + $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitClass::class))) ); } + + /** + * @return string[] + */ + private function getInheritsAsString(?AstMap\AstClassReference $classReference): array + { + if (null === $classReference) { + return []; + } + + return array_map('strval', $classReference->getInherits()); + } } diff --git a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php index d086a65b1..127d08944 100644 --- a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php +++ b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php @@ -35,7 +35,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - (string) $annotationDependency[0]->getClassLikeName() + $annotationDependency[0]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[0]->getFileOccurrence()->getFilenpath()); static::assertSame(9, $annotationDependency[0]->getFileOccurrence()->getLine()); @@ -43,7 +43,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - (string) $annotationDependency[1]->getClassLikeName() + $annotationDependency[1]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[1]->getFileOccurrence()->getFilenpath()); static::assertSame(23, $annotationDependency[1]->getFileOccurrence()->getLine()); @@ -51,7 +51,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - (string) $annotationDependency[2]->getClassLikeName() + $annotationDependency[2]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[2]->getFileOccurrence()->getFilenpath()); static::assertSame(26, $annotationDependency[2]->getFileOccurrence()->getLine()); @@ -59,7 +59,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Symfony\Component\Console\Exception\RuntimeException', - (string) $annotationDependency[3]->getClassLikeName() + $annotationDependency[3]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[3]->getFileOccurrence()->getFilenpath()); static::assertSame(29, $annotationDependency[3]->getFileOccurrence()->getLine()); @@ -67,7 +67,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Symfony\Component\Finder\SplFileInfo', - (string) $annotationDependency[4]->getClassLikeName() + $annotationDependency[4]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[4]->getFileOccurrence()->getFilenpath()); static::assertSame(14, $annotationDependency[4]->getFileOccurrence()->getLine()); @@ -75,7 +75,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild', - (string) $annotationDependency[5]->getClassLikeName() + $annotationDependency[5]->getClassLikeName()->toString() ); static::assertSame($filePath, $annotationDependency[5]->getFileOccurrence()->getFilenpath()); static::assertSame(14, $annotationDependency[5]->getFileOccurrence()->getLine()); diff --git a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php index cd054b54d..0cbee92f4 100644 --- a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php +++ b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php @@ -36,7 +36,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\ClassA', - (string) $dependencies[0]->getClassLikeName() + $dependencies[0]->getClassLikeName()->toString() ); static::assertSame($filePath, $dependencies[0]->getFileOccurrence()->getFilenpath()); static::assertSame(19, $dependencies[0]->getFileOccurrence()->getLine()); @@ -44,7 +44,7 @@ public function testPropertyDependencyResolving(): void static::assertSame( 'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\InterfaceC', - (string) $dependencies[1]->getClassLikeName() + $dependencies[1]->getClassLikeName()->toString() ); static::assertSame($filePath, $dependencies[1]->getFileOccurrence()->getFilenpath()); static::assertSame(19, $dependencies[1]->getFileOccurrence()->getLine()); diff --git a/tests/AstRunner/Resolver/ClassConstantResolverTest.php b/tests/AstRunner/Resolver/ClassConstantResolverTest.php index 62d5ab175..2c121ed30 100644 --- a/tests/AstRunner/Resolver/ClassConstantResolverTest.php +++ b/tests/AstRunner/Resolver/ClassConstantResolverTest.php @@ -34,7 +34,7 @@ public function testPropertyDependencyResolving(): void $dependencies = $astClassReferences[1]->getDependencies(); static::assertSame( 'Tests\SensioLabs\Deptrac\Integration\fixtures\ClassA', - (string) $dependencies[0]->getClassLikeName() + $dependencies[0]->getClassLikeName()->toString() ); static::assertSame($filePath, $dependencies[0]->getFileOccurrence()->getFilenpath()); static::assertSame(15, $dependencies[0]->getFileOccurrence()->getLine()); diff --git a/tests/ClassNameLayerResolverCacheDecoratorTest.php b/tests/ClassNameLayerResolverCacheDecoratorTest.php index b0755b939..d90d82591 100644 --- a/tests/ClassNameLayerResolverCacheDecoratorTest.php +++ b/tests/ClassNameLayerResolverCacheDecoratorTest.php @@ -13,7 +13,7 @@ class ClassNameLayerResolverCacheDecoratorTest extends TestCase { public function testGetLayersByClassName(): void { - $classLikeName = ClassLikeName::fromString('foo'); + $classLikeName = ClassLikeName::fromFQCN('foo'); $decorated = $this->prophesize(ClassNameLayerResolverInterface::class); $decorated->getLayersByClassName($classLikeName)->willReturn(['bar']); diff --git a/tests/ClassNameLayerResolverTest.php b/tests/ClassNameLayerResolverTest.php index baacedc73..30dc20bdf 100644 --- a/tests/ClassNameLayerResolverTest.php +++ b/tests/ClassNameLayerResolverTest.php @@ -117,7 +117,7 @@ public function testGetLayersByClassName(bool $collectA, bool $collectB1, bool $ static::assertEquals( $expectedLayers, - $resolver->getLayersByClassName(ClassLikeName::fromString('classA')) + $resolver->getLayersByClassName(ClassLikeName::fromFQCN('classA')) ); } } diff --git a/tests/Collector/ClassNameCollectorTest.php b/tests/Collector/ClassNameCollectorTest.php index 57fc19620..60f0d2b77 100644 --- a/tests/Collector/ClassNameCollectorTest.php +++ b/tests/Collector/ClassNameCollectorTest.php @@ -30,7 +30,7 @@ public function testSatisfy(array $configuration, string $className, bool $expec { $stat = (new ClassNameCollector())->satisfy( $configuration, - new AstClassReference(AstMap\ClassLikeName::fromString($className)), + new AstClassReference(AstMap\ClassLikeName::fromFQCN($className)), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); @@ -44,7 +44,7 @@ public function testWrongRegexParam(): void (new ClassNameCollector())->satisfy( ['Foo' => 'a'], - new AstClassReference(AstMap\ClassLikeName::fromString('Foo')), + new AstClassReference(AstMap\ClassLikeName::fromFQCN('Foo')), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/ClassNameRegexCollectorTest.php b/tests/Collector/ClassNameRegexCollectorTest.php index b15d76cbb..166684230 100644 --- a/tests/Collector/ClassNameRegexCollectorTest.php +++ b/tests/Collector/ClassNameRegexCollectorTest.php @@ -31,7 +31,7 @@ public function testSatisfy(array $configuration, string $className, bool $expec { $stat = (new ClassNameRegexCollector())->satisfy( $configuration, - new AstClassReference(ClassLikeName::fromString($className)), + new AstClassReference(ClassLikeName::fromFQCN($className)), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); @@ -45,7 +45,7 @@ public function testWrongRegexParam(): void (new ClassNameRegexCollector())->satisfy( ['Foo' => 'a'], - new AstClassReference(ClassLikeName::fromString('Foo')), + new AstClassReference(ClassLikeName::fromFQCN('Foo')), $this->prophesize(AstMap::class)->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/DirectoryCollectorTest.php b/tests/Collector/DirectoryCollectorTest.php index a2e45a573..13a231d65 100644 --- a/tests/Collector/DirectoryCollectorTest.php +++ b/tests/Collector/DirectoryCollectorTest.php @@ -31,7 +31,7 @@ public function dataProviderSatisfy(): iterable public function testSatisfy(array $configuration, string $filePath, bool $expected): void { $fileReference = new AstFileReference($filePath); - $astClassReference = $fileReference->addClassReference(ClassLikeName::fromString('Test')); + $astClassReference = $fileReference->addClassReference(ClassLikeName::fromFQCN('Test')); $stat = (new DirectoryCollector())->satisfy( $configuration, @@ -46,7 +46,7 @@ public function testSatisfy(array $configuration, string $filePath, bool $expect public function testMissingRegexThrowsException(): void { $fileReference = new AstFileReference('/some/path/to/file.php'); - $astClassReference = $fileReference->addClassReference(ClassLikeName::fromString('Test')); + $astClassReference = $fileReference->addClassReference(ClassLikeName::fromFQCN('Test')); $this->expectException(\LogicException::class); $this->expectExceptionMessage('DirectoryCollector needs the regex configuration.'); diff --git a/tests/Collector/InheritanceLevelCollectorTest.php b/tests/Collector/InheritanceLevelCollectorTest.php index 02b920667..689788e48 100644 --- a/tests/Collector/InheritanceLevelCollectorTest.php +++ b/tests/Collector/InheritanceLevelCollectorTest.php @@ -36,12 +36,12 @@ public function testSatisfy(int $pathLevel, int $levelConfig, bool $expected): v ->willReturn(array_fill(0, $pathLevel, 1)); $astMap = $this->prophesize(AstMap::class); - $astMap->getClassInherits(AstInherit::class) + $astMap->getClassInherits(ClassLikeName::fromFQCN(AstInherit::class)) ->willReturn([$classInherit->reveal()]); $stat = (new InheritanceLevelCollector())->satisfy( ['level' => $levelConfig], - new AstClassReference(ClassLikeName::fromString(AstInherit::class)), + new AstClassReference(ClassLikeName::fromFQCN(AstInherit::class)), $astMap->reveal(), $this->prophesize(Registry::class)->reveal() ); diff --git a/tests/Collector/MethodCollectorTest.php b/tests/Collector/MethodCollectorTest.php index 199806971..2ac3de549 100644 --- a/tests/Collector/MethodCollectorTest.php +++ b/tests/Collector/MethodCollectorTest.php @@ -55,7 +55,7 @@ public function dataProviderSatisfy(): iterable */ public function testSatisfy(array $configuration, array $methods, bool $expected): void { - $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); + $astClassReference = new AstClassReference(ClassLikeName::fromFQCN('foo')); $classLike = $this->createMock(Node\Stmt\ClassLike::class); $classLike->method('getMethods')->willReturn($methods); @@ -78,7 +78,7 @@ public function testSatisfy(array $configuration, array $methods, bool $expected public function testClassLikeAstNotFoundDoesNotSatisfy(): void { - $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); + $astClassReference = new AstClassReference(ClassLikeName::fromFQCN('foo')); $parser = $this->createMock(NikicPhpParser::class); $parser ->method('getAstForClassReference') @@ -97,7 +97,7 @@ public function testClassLikeAstNotFoundDoesNotSatisfy(): void public function testMissingNameThrowsException(): void { - $astClassReference = new AstClassReference(ClassLikeName::fromString('foo')); + $astClassReference = new AstClassReference(ClassLikeName::fromFQCN('foo')); $parser = $this->createMock(NikicPhpParser::class); $this->expectException(\LogicException::class); diff --git a/tests/Configuration/ConfigurationSkippedViolationTest.php b/tests/Configuration/ConfigurationSkippedViolationTest.php index d042e359b..af9f72041 100644 --- a/tests/Configuration/ConfigurationSkippedViolationTest.php +++ b/tests/Configuration/ConfigurationSkippedViolationTest.php @@ -23,16 +23,16 @@ public function testFromArray(): void 'DependencyClass2', ], ]); - static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithOneDep'), ClassLikeName::fromString('DependencyClass'))); - static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithEmptyDeps'), ClassLikeName::fromString('DependencyClass'))); - static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithMultipleDeps'), ClassLikeName::fromString('DependencyClass1'))); - static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromString('ClassWithMultipleDeps'), ClassLikeName::fromString('DependencyClass2'))); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromFQCN('ClassWithOneDep'), ClassLikeName::fromFQCN('DependencyClass'))); + static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromFQCN('ClassWithEmptyDeps'), ClassLikeName::fromFQCN('DependencyClass'))); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromFQCN('ClassWithMultipleDeps'), ClassLikeName::fromFQCN('DependencyClass1'))); + static::assertTrue($configuration->isViolationSkipped(ClassLikeName::fromFQCN('ClassWithMultipleDeps'), ClassLikeName::fromFQCN('DependencyClass2'))); } public function testFromArrayWithEmptyArrayAcceptable(): void { $configuration = ConfigurationSkippedViolation::fromArray([]); - static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromString('AnyClass'), ClassLikeName::fromString('AnotherAnyClass'))); + static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromFQCN('AnyClass'), ClassLikeName::fromFQCN('AnotherAnyClass'))); } public function testFromArrayRequireOneArgument(): void diff --git a/tests/Configuration/ConfigurationTest.php b/tests/Configuration/ConfigurationTest.php index 33d375fa1..479847fee 100644 --- a/tests/Configuration/ConfigurationTest.php +++ b/tests/Configuration/ConfigurationTest.php @@ -95,7 +95,7 @@ public function testSkipViolations(): void ], ]); - static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromString('FooClass'), ClassLikeName::fromString('BarClass'))); - static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromString('FooClass'), ClassLikeName::fromString('AnotherClass'))); + static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromFQCN('FooClass'), ClassLikeName::fromFQCN('BarClass'))); + static::assertTrue($configuration->getSkipViolations()->isViolationSkipped(ClassLikeName::fromFQCN('FooClass'), ClassLikeName::fromFQCN('AnotherClass'))); } } diff --git a/tests/Dependency/DependencyTest.php b/tests/Dependency/DependencyTest.php index 971423d5e..a1b142d2a 100644 --- a/tests/Dependency/DependencyTest.php +++ b/tests/Dependency/DependencyTest.php @@ -14,10 +14,10 @@ class DependencyTest extends TestCase { public function testGetSet(): void { - $dependency = new Dependency(ClassLikeName::fromString('a'), ClassLikeName::fromString('b'), new FileOccurrence(new AstFileReference('/foo.php'), 23)); - static::assertEquals('a', $dependency->getClassA()); - static::assertEquals('/foo.php', $dependency->getFileOccurrence()->getFilenpath()); - static::assertEquals(23, $dependency->getFileOccurrence()->getLine()); - static::assertEquals('b', $dependency->getClassB()); + $dependency = new Dependency(ClassLikeName::fromFQCN('a'), ClassLikeName::fromFQCN('b'), new FileOccurrence(new AstFileReference('/foo.php'), 23)); + static::assertSame('a', $dependency->getClassLikeNameA()->toString()); + static::assertSame('/foo.php', $dependency->getFileOccurrence()->getFilenpath()); + static::assertSame(23, $dependency->getFileOccurrence()->getLine()); + static::assertSame('b', $dependency->getClassLikeNameB()->toString()); } } diff --git a/tests/Dependency/InheritDependencyTest.php b/tests/Dependency/InheritDependencyTest.php index bb3a9711f..7d3ef2ae3 100644 --- a/tests/Dependency/InheritDependencyTest.php +++ b/tests/Dependency/InheritDependencyTest.php @@ -16,21 +16,21 @@ class InheritDependencyTest extends TestCase { public function testGetSet(): void { - $classA = ClassLikeName::fromString('a'); - $classB = ClassLikeName::fromString('b'); + $classLikeNameA = ClassLikeName::fromFQCN('a'); + $classLikeNameB = ClassLikeName::fromFQCN('b'); $fileOccurrence = new FileOccurrence(new AstFileReference('a.php'), 1); $dependency = new InheritDependency( - $classA, - $classB, - $dep = new Dependency($classA, $classB, $fileOccurrence), - $astInherit = AstInherit::newExtends($classB, $fileOccurrence) + $classLikeNameA, + $classLikeNameB, + $dep = new Dependency($classLikeNameA, $classLikeNameB, $fileOccurrence), + $astInherit = AstInherit::newExtends($classLikeNameB, $fileOccurrence) ); - static::assertEquals('a', $dependency->getClassA()); - static::assertEquals('b', $dependency->getClassB()); - static::assertEquals(1, $dependency->getFileOccurrence()->getLine()); - static::assertEquals($dep, $dependency->getOriginalDependency()); + static::assertSame($classLikeNameA, $dependency->getClassLikeNameA()); + static::assertSame($classLikeNameB, $dependency->getClassLikeNameB()); + static::assertSame(1, $dependency->getFileOccurrence()->getLine()); + static::assertSame($dep, $dependency->getOriginalDependency()); static::assertSame($astInherit, $dependency->getInheritPath()); } } diff --git a/tests/Dependency/InheritanceFlatterTest.php b/tests/Dependency/InheritanceFlatterTest.php index c7023123a..d0e9ed3e9 100644 --- a/tests/Dependency/InheritanceFlatterTest.php +++ b/tests/Dependency/InheritanceFlatterTest.php @@ -18,10 +18,10 @@ class InheritanceFlatterTest extends TestCase { - private function getAstReference($className) + private function getAstClassReference($className) { $astClass = $this->prophesize(AstClassReference::class); - $astClass->getClassName()->willReturn(ClassLikeName::fromString($className)); + $astClass->getClassLikeName()->willReturn(ClassLikeName::fromFQCN($className)); return $astClass->reveal(); } @@ -29,8 +29,8 @@ private function getAstReference($className) private function getDependency($className) { $dep = $this->prophesize(Dependency::class); - $dep->getClassA()->willReturn(ClassLikeName::fromString($className)); - $dep->getClassB()->willReturn(ClassLikeName::fromString($className.'_b')); + $dep->getClassLikeNameA()->willReturn(ClassLikeName::fromFQCN($className)); + $dep->getClassLikeNameB()->willReturn(ClassLikeName::fromFQCN($className.'_b')); return $dep->reveal(); } @@ -40,29 +40,29 @@ public function testFlattenDependencies(): void $astMap = $this->prophesize(AstMap::class); $astMap->getAstClassReferences()->willReturn([ - $this->getAstReference('classA'), - $this->getAstReference('classB'), - $this->getAstReference('classBaum'), - $this->getAstReference('classWeihnachtsbaum'), - $this->getAstReference('classGeschmückterWeihnachtsbaum'), + $this->getAstClassReference('classA'), + $this->getAstClassReference('classB'), + $this->getAstClassReference('classBaum'), + $this->getAstClassReference('classWeihnachtsbaum'), + $this->getAstClassReference('classGeschmückterWeihnachtsbaum'), ]); $dependencyResult = new Result(); - $dependencyResult->addDependency($classADep = $this->getDependency('classA')); - $dependencyResult->addDependency($classBDep = $this->getDependency('classB')); - $dependencyResult->addDependency($classBaumDep = $this->getDependency('classBaum')); - $dependencyResult->addDependency($classWeihnachtsbaumsDep = $this->getDependency('classWeihnachtsbaumsA')); + $dependencyResult->addDependency($this->getDependency('classA')); + $dependencyResult->addDependency($this->getDependency('classB')); + $dependencyResult->addDependency($this->getDependency('classBaum')); + $dependencyResult->addDependency($this->getDependency('classWeihnachtsbaumsA')); - $astMap->getClassInherits('classA')->willReturn([]); - $astMap->getClassInherits('classB')->willReturn([]); - $astMap->getClassInherits('classBaum')->willReturn([]); - $astMap->getClassInherits('classWeihnachtsbaum')->willReturn([ - AstInherit::newTraitUse(ClassLikeName::fromString('classBaum'), new FileOccurrence(new AstFileReference('classWeihnachtsbaum.php'), 3)), + $astMap->getClassInherits(ClassLikeName::fromFQCN('classA'))->willReturn([]); + $astMap->getClassInherits(ClassLikeName::fromFQCN('classB'))->willReturn([]); + $astMap->getClassInherits(ClassLikeName::fromFQCN('classBaum'))->willReturn([]); + $astMap->getClassInherits(ClassLikeName::fromFQCN('classWeihnachtsbaum'))->willReturn([ + AstInherit::newTraitUse(ClassLikeName::fromFQCN('classBaum'), new FileOccurrence(new AstFileReference('classWeihnachtsbaum.php'), 3)), ]); - $astMap->getClassInherits('classGeschmückterWeihnachtsbaum')->willReturn([ - AstMap\AstInherit::newExtends(ClassLikeName::fromString('classBaum'), new FileOccurrence(new AstFileReference('classGeschmückterWeihnachtsbaum.php'), 3)) + $astMap->getClassInherits(ClassLikeName::fromFQCN('classGeschmückterWeihnachtsbaum'))->willReturn([ + AstMap\AstInherit::newExtends(ClassLikeName::fromFQCN('classBaum'), new FileOccurrence(new AstFileReference('classGeschmückterWeihnachtsbaum.php'), 3)) ->withPath([ - AstInherit::newTraitUse(ClassLikeName::fromString('classWeihnachtsbaum'), new FileOccurrence(new AstFileReference('classBaum.php'), 3)), + AstInherit::newTraitUse(ClassLikeName::fromFQCN('classWeihnachtsbaum'), new FileOccurrence(new AstFileReference('classBaum.php'), 3)), ]), ]); diff --git a/tests/Dependency/ResultTest.php b/tests/Dependency/ResultTest.php index 268e19418..4bb57ad70 100644 --- a/tests/Dependency/ResultTest.php +++ b/tests/Dependency/ResultTest.php @@ -17,9 +17,9 @@ class ResultTest extends TestCase { public function testAddDependency(): void { - $classA = ClassLikeName::fromString('A'); - $classB = ClassLikeName::fromString('B'); - $classC = ClassLikeName::fromString('C'); + $classA = ClassLikeName::fromFQCN('A'); + $classB = ClassLikeName::fromFQCN('B'); + $classC = ClassLikeName::fromFQCN('C'); $dependencyResult = new Result(); $dependencyResult->addDependency($dep1 = new Dependency($classA, $classB, new FileOccurrence(new AstFileReference('a.php'), 12))); @@ -33,8 +33,8 @@ public function testAddDependency(): void public function testGetDependenciesAndInheritDependencies(): void { - $classA = ClassLikeName::fromString('A'); - $classB = ClassLikeName::fromString('B'); + $classA = ClassLikeName::fromFQCN('A'); + $classB = ClassLikeName::fromFQCN('B'); $dependencyResult = new Result(); $dependencyResult->addDependency($dep1 = new Dependency($classA, $classB, new FileOccurrence(new AstFileReference('a.php'), 12))); diff --git a/tests/DependencyEmitter/EmitterTrait.php b/tests/DependencyEmitter/EmitterTrait.php index 89161c3bd..9fea3f1af 100644 --- a/tests/DependencyEmitter/EmitterTrait.php +++ b/tests/DependencyEmitter/EmitterTrait.php @@ -29,7 +29,11 @@ public function getDeps(DependencyEmitterInterface $emitter, \SplFileInfo $fileI return array_map( static function (DependencyInterface $d) { - return $d->getClassA().':'.$d->getFileOccurrence()->getLine().' on '.$d->getClassB(); + return sprintf('%s:%d on %s', + $d->getClassLikeNameA()->toString(), + $d->getFileOccurrence()->getLine(), + $d->getClassLikeNameB()->toString() + ); }, $result->getDependenciesAndInheritDependencies() ); diff --git a/tests/OutputFormatter/ConsoleOutputFormatterTest.php b/tests/OutputFormatter/ConsoleOutputFormatterTest.php index 4af06878c..e2c0a5dff 100644 --- a/tests/OutputFormatter/ConsoleOutputFormatterTest.php +++ b/tests/OutputFormatter/ConsoleOutputFormatterTest.php @@ -27,21 +27,21 @@ public function testGetName(): void public function basicDataProvider(): iterable { - $originalA = ClassLikeName::fromString('OriginalA'); - $originalB = ClassLikeName::fromString('OriginalB'); + $originalA = ClassLikeName::fromFQCN('OriginalA'); + $originalB = ClassLikeName::fromFQCN('OriginalB'); yield [ [ new Violation( new InheritDependency( - ClassLikeName::fromString('ClassA'), - ClassLikeName::fromString('ClassB'), + ClassLikeName::fromFQCN('ClassA'), + ClassLikeName::fromFQCN('ClassB'), new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('originalA.php'), 12)), - AstInherit::newExtends(ClassLikeName::fromString('ClassInheritA'), new FileOccurrence(new AstFileReference('originalA.php'), 3)) + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritA'), new FileOccurrence(new AstFileReference('originalA.php'), 3)) ->withPath([ - AstInherit::newExtends(ClassLikeName::fromString('ClassInheritB'), new FileOccurrence(new AstFileReference('originalA.php'), 4)), - AstInherit::newExtends(ClassLikeName::fromString('ClassInheritC'), new FileOccurrence(new AstFileReference('originalA.php'), 5)), - AstInherit::newExtends(ClassLikeName::fromString('ClassInheritD'), new FileOccurrence(new AstFileReference('originalA.php'), 6)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritB'), new FileOccurrence(new AstFileReference('originalA.php'), 4)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritC'), new FileOccurrence(new AstFileReference('originalA.php'), 5)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritD'), new FileOccurrence(new AstFileReference('originalA.php'), 6)), ]) ), 'LayerA', diff --git a/tests/OutputFormatter/GraphVizOutputFormatterTest.php b/tests/OutputFormatter/GraphVizOutputFormatterTest.php index 49c1d924e..b9f4ef796 100644 --- a/tests/OutputFormatter/GraphVizOutputFormatterTest.php +++ b/tests/OutputFormatter/GraphVizOutputFormatterTest.php @@ -29,13 +29,13 @@ public function testFinish(): void $dotFile = __DIR__.'/data/graphviz.dot'; $fileOccurrenceA = new FileOccurrence(new AstFileReference('classA.php'), 0); - $classA = ClassLikeName::fromString('ClassA'); + $classA = ClassLikeName::fromFQCN('ClassA'); $context = new Context([ - new Violation(new Dependency($classA, ClassLikeName::fromString('ClassB'), $fileOccurrenceA), 'LayerA', 'LayerB'), - new Violation(new Dependency(ClassLikeName::fromString('ClassAB'), ClassLikeName::fromString('ClassBA'), new FileOccurrence(new AstFileReference('classAB.php'), 1)), 'LayerA', 'LayerB'), - new Allowed(new Dependency($classA, ClassLikeName::fromString('ClassC'), $fileOccurrenceA), 'LayerA', 'LayerC'), - new Uncovered(new Dependency($classA, ClassLikeName::fromString('ClassD'), $fileOccurrenceA), 'LayerC'), + new Violation(new Dependency($classA, ClassLikeName::fromFQCN('ClassB'), $fileOccurrenceA), 'LayerA', 'LayerB'), + new Violation(new Dependency(ClassLikeName::fromFQCN('ClassAB'), ClassLikeName::fromFQCN('ClassBA'), new FileOccurrence(new AstFileReference('classAB.php'), 1)), 'LayerA', 'LayerB'), + new Allowed(new Dependency($classA, ClassLikeName::fromFQCN('ClassC'), $fileOccurrenceA), 'LayerA', 'LayerC'), + new Uncovered(new Dependency($classA, ClassLikeName::fromFQCN('ClassD'), $fileOccurrenceA), 'LayerC'), ]); $output = new BufferedOutput(); diff --git a/tests/OutputFormatter/JUnitOutputFormatterTest.php b/tests/OutputFormatter/JUnitOutputFormatterTest.php index 995b81f43..49dd84a4c 100644 --- a/tests/OutputFormatter/JUnitOutputFormatterTest.php +++ b/tests/OutputFormatter/JUnitOutputFormatterTest.php @@ -36,19 +36,19 @@ public function testGetName(): void public function basicDataProvider(): iterable { - $originalA = ClassLikeName::fromString('OriginalA'); - $originalB = ClassLikeName::fromString('OriginalB'); - $classInheritA = ClassLikeName::fromString('ClassInheritA'); - $classInheritB = ClassLikeName::fromString('ClassInheritB'); - $classInheritC = ClassLikeName::fromString('ClassInheritC'); - $classInheritD = ClassLikeName::fromString('ClassInheritD'); + $originalA = ClassLikeName::fromFQCN('OriginalA'); + $originalB = ClassLikeName::fromFQCN('OriginalB'); + $classInheritA = ClassLikeName::fromFQCN('ClassInheritA'); + $classInheritB = ClassLikeName::fromFQCN('ClassInheritB'); + $classInheritC = ClassLikeName::fromFQCN('ClassInheritC'); + $classInheritD = ClassLikeName::fromFQCN('ClassInheritD'); yield [ [ new Violation( new InheritDependency( - ClassLikeName::fromString('ClassA'), - ClassLikeName::fromString('ClassB'), + ClassLikeName::fromFQCN('ClassA'), + ClassLikeName::fromFQCN('ClassB'), new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), @@ -83,8 +83,8 @@ public function basicDataProvider(): iterable [ new SkippedViolation( new InheritDependency( - ClassLikeName::fromString('ClassA'), - ClassLikeName::fromString('ClassB'), + ClassLikeName::fromFQCN('ClassA'), + ClassLikeName::fromFQCN('ClassB'), new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), @@ -97,8 +97,8 @@ public function basicDataProvider(): iterable ), new Violation( new InheritDependency( - ClassLikeName::fromString('ClassC'), - ClassLikeName::fromString('ClassD'), + ClassLikeName::fromFQCN('ClassC'), + ClassLikeName::fromFQCN('ClassD'), new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('foo.php'), 12)), AstInherit::newExtends($classInheritA, new FileOccurrence(new AstFileReference('foo.php'), 3))->withPath([ AstInherit::newExtends($classInheritB, new FileOccurrence(new AstFileReference('foo.php'), 4)), diff --git a/tests/RulesetEngineTest.php b/tests/RulesetEngineTest.php index 7fec26b76..2e31a96a2 100644 --- a/tests/RulesetEngineTest.php +++ b/tests/RulesetEngineTest.php @@ -20,8 +20,8 @@ private function createDependencies(array $fromTo): iterable { foreach ($fromTo as $from => $to) { yield new Dependency( - ClassLikeName::fromString($from), - ClassLikeName::fromString($to), + ClassLikeName::fromFQCN($from), + ClassLikeName::fromFQCN($to), new FileOccurrence(new AstFileReference('foo.php'), 0) ); } @@ -154,7 +154,7 @@ public function testProcess(array $dependenciesAsArray, array $classesInLayers, $classNameLayerResolver = $this->prophesize(ClassNameLayerResolverInterface::class); foreach ($classesInLayers as $classInLayer => $layers) { - $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromString($classInLayer))->willReturn($layers); + $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromFQCN($classInLayer))->willReturn($layers); } $configuration = Configuration::fromArray([ @@ -221,7 +221,7 @@ public function testGetSkippedViolations(array $dependenciesAsArray, array $clas $classNameLayerResolver = $this->prophesize(ClassNameLayerResolverInterface::class); foreach ($classesInLayers as $classInLayer => $layers) { - $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromString($classInLayer))->willReturn($layers); + $classNameLayerResolver->getLayersByClassName(ClassLikeName::fromFQCN($classInLayer))->willReturn($layers); } $configuration = Configuration::fromArray([ From 066933bffe775a346242c12cfe3664b5e5893076 Mon Sep 17 00:00:00 2001 From: smoench Date: Sun, 9 Feb 2020 19:03:47 +0100 Subject: [PATCH 4/6] more refactoring --- config/services.xml | 1 + src/AstRunner/AstParser/AstParser.php | 11 +-- ...Resolver.php => ClassReferenceVisitor.php} | 84 +++++++++---------- .../NikicPhpParser/NikicPhpParser.php | 50 +++++------ src/AstRunner/AstRunner.php | 4 - .../Resolver/AnnotationDependencyResolver.php | 10 +-- .../Resolver/AnonymousClassResolver.php | 2 +- .../Resolver/ClassConstantResolver.php | 2 +- .../Resolver/ClassDependencyResolver.php | 2 +- src/AstRunner/Resolver/TypeResolver.php | 46 ++++++++-- .../Resolver/{NameScope.php => TypeScope.php} | 4 +- src/ClassNameLayerResolver.php | 11 --- src/ClassNameLayerResolverCacheDecorator.php | 9 -- src/ClassNameLayerResolverInterface.php | 5 -- .../AstMap/ClassReferenceBuilderTest.php | 20 ----- .../AstRunner/AstMapFlattenGeneratorTest.php | 4 +- tests/AstRunner/AstMapGeneratorTest.php | 4 +- .../NikicPhpParser/NikicPhpParserTest.php | 17 +--- .../AnnotationDependencyResolverTest.php | 4 +- .../Resolver/AnonymousClassResolverTest.php | 2 + .../Resolver/ClassConstantResolverTest.php | 2 + tests/DependencyEmitter/EmitterTrait.php | 4 +- 22 files changed, 141 insertions(+), 157 deletions(-) rename src/AstRunner/AstParser/NikicPhpParser/{AstClassReferenceResolver.php => ClassReferenceVisitor.php} (53%) rename src/AstRunner/Resolver/{NameScope.php => TypeScope.php} (94%) delete mode 100644 tests/AstRunner/AstMap/ClassReferenceBuilderTest.php diff --git a/config/services.xml b/config/services.xml index da399ebf8..524e886c2 100644 --- a/config/services.xml +++ b/config/services.xml @@ -29,6 +29,7 @@ + diff --git a/src/AstRunner/AstParser/AstParser.php b/src/AstRunner/AstParser/AstParser.php index 5bbd18ee0..92b725f6e 100644 --- a/src/AstRunner/AstParser/AstParser.php +++ b/src/AstRunner/AstParser/AstParser.php @@ -5,16 +5,9 @@ namespace SensioLabs\Deptrac\AstRunner\AstParser; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; +use SplFileInfo; interface AstParser { - /** - * @param mixed $data - */ - public function parse($data): AstFileReference; - - /** - * @param mixed $data - */ - public function supports($data): bool; + public function parse(SplFileInfo $data): AstFileReference; } diff --git a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php b/src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php similarity index 53% rename from src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php rename to src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php index 822abd890..fe8cb0e6e 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php +++ b/src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php @@ -12,32 +12,37 @@ use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\AstRunner\Resolver\ClassDependencyResolver; -use SensioLabs\Deptrac\AstRunner\Resolver\NameScope; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeScope; -class AstClassReferenceResolver extends NodeVisitorAbstract +class ClassReferenceVisitor extends NodeVisitorAbstract { private $fileReference; /** @var ClassDependencyResolver[] */ private $classDependencyResolvers; - /** @var NameScope */ - private $currentTypeContext; + /** @var TypeScope */ + private $currentTypeScope; /** @var ClassReferenceBuilder */ private $currentClassReferenceBuilder; - public function __construct(AstFileReference $fileReference, ClassDependencyResolver ...$classDependencyResolvers) + /** @var TypeResolver */ + private $typeResolver; + + public function __construct(AstFileReference $fileReference, TypeResolver $typeResolver, ClassDependencyResolver ...$classDependencyResolvers) { - $this->currentTypeContext = new NameScope('global'); + $this->currentTypeScope = new TypeScope(''); $this->fileReference = $fileReference; $this->classDependencyResolvers = $classDependencyResolvers; + $this->typeResolver = $typeResolver; } public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Namespace_) { - $this->currentTypeContext = new NameScope($node->name ? $node->name->toCodeString() : 'global'); + $this->currentTypeScope = new TypeScope($node->name ? $node->name->toCodeString() : ''); } if (!$node instanceof Node\Stmt\ClassLike) { @@ -47,7 +52,7 @@ public function enterNode(Node $node) if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) { $className = $node->namespacedName->toCodeString(); } elseif ($node->name instanceof Node\Identifier) { - $className = $node->name->toCodeString(); + $className = $node->name->toString(); } else { return null; // map anonymous classes on current class } @@ -79,7 +84,7 @@ public function enterNode(Node $node) public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\UseUse) { - $this->currentTypeContext->addUse($node->name->toCodeString(), $node->getAlias()->toString()); + $this->currentTypeScope->addUse($node->name->toCodeString(), $node->getAlias()->toString()); $this->fileReference->addDependency( AstDependency::useStmt( ClassLikeName::fromFQCN($node->name->toCodeString()), @@ -93,47 +98,55 @@ public function leaveNode(Node $node) } if ($node instanceof Node\Stmt\TraitUse) { - foreach ($node->traits as $trait) { - $this->currentClassReferenceBuilder->trait($trait->toCodeString(), $trait->getLine()); + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, ...$node->traits) as $classLikeName) { + $this->currentClassReferenceBuilder->trait($classLikeName, $node->getLine()); } } - if ($node instanceof Node\Expr\Instanceof_ && $this->isQualifiedType($node->class)) { - $this->currentClassReferenceBuilder->instanceof($node->class->toCodeString(), $node->class->getLine()); + if ($node instanceof Node\Expr\Instanceof_ && $node->class instanceof Node\Name) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->class) as $classLikeName) { + $this->currentClassReferenceBuilder->instanceof($classLikeName, $node->class->getLine()); + } } - if ($node instanceof Node\Param && $this->isQualifiedType($node->type)) { - $this->currentClassReferenceBuilder->parameter($node->type->toCodeString(), $node->type->getLine()); + if ($node instanceof Node\Param && null !== $node->type) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->type) as $classLikeName) { + $this->currentClassReferenceBuilder->parameter($classLikeName, $node->type->getLine()); + } } - if ($node instanceof Node\Expr\New_ && $this->isQualifiedType($node->class)) { - $this->currentClassReferenceBuilder->newStatement($node->class->toCodeString(), $node->class->getLine()); + if ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->class) as $classLikeName) { + $this->currentClassReferenceBuilder->newStatement($classLikeName, $node->class->getLine()); + } } - if ($node instanceof Node\Expr\StaticPropertyFetch && $this->isQualifiedType($node->class)) { - $this->currentClassReferenceBuilder->staticProperty($node->class->toCodeString(), $node->class->getLine()); + if ($node instanceof Node\Expr\StaticPropertyFetch && $node->class instanceof Node\Name) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->class) as $classLikeName) { + $this->currentClassReferenceBuilder->staticProperty($classLikeName, $node->class->getLine()); + } } - if ($node instanceof Node\Expr\StaticCall && $this->isQualifiedType($node->class)) { - $this->currentClassReferenceBuilder->staticMethod($node->class->toCodeString(), $node->class->getLine()); + if ($node instanceof Node\Expr\StaticCall && $node->class instanceof Node\Name) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->class) as $classLikeName) { + $this->currentClassReferenceBuilder->staticMethod($classLikeName, $node->class->getLine()); + } } - if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) { - if ($this->isQualifiedType($node->returnType)) { - $this->currentClassReferenceBuilder->returnType($node->returnType->toCodeString(), $node->returnType->getLine()); - } elseif ($node->returnType instanceof Node\NullableType && $this->isQualifiedType($node->returnType->type)) { - $this->currentClassReferenceBuilder->returnType($node->returnType->type->toCodeString(), $node->returnType->getLine()); + if (($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Expr\Closure) && null !== $node->returnType) { + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, $node->returnType) as $classLikeName) { + $this->currentClassReferenceBuilder->returnType($classLikeName, $node->returnType->getLine()); } } if ($node instanceof Node\Stmt\Catch_) { - foreach ($node->types as $type) { - $this->currentClassReferenceBuilder->catchStmt($type->toCodeString(), $type->getLine()); + foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, ...$node->types) as $classLikeName) { + $this->currentClassReferenceBuilder->catchStmt($classLikeName, $node->getLine()); } } foreach ($this->classDependencyResolvers as $resolver) { - $resolver->processNode($node, $this->currentClassReferenceBuilder, $this->currentTypeContext); + $resolver->processNode($node, $this->currentClassReferenceBuilder, $this->currentTypeScope); } return null; @@ -147,17 +160,4 @@ public function afterTraverse(array $nodes) return null; } - - private function isQualifiedType($type): bool - { - if (null === $type) { - return false; - } - - if ($type instanceof Node\Name) { - return !$type->isSpecialClassName(); - } - - return false; - } } diff --git a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php index 1d7de67d8..b422f021f 100644 --- a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php +++ b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php @@ -13,6 +13,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\AstFileReferenceCache; use SensioLabs\Deptrac\AstRunner\AstParser\AstParser; use SensioLabs\Deptrac\AstRunner\Resolver\ClassDependencyResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; class NikicPhpParser implements AstParser { @@ -31,49 +32,49 @@ class NikicPhpParser implements AstParser */ private $cache; + /** + * @var TypeResolver + */ + private $typeResolver; + /** * @var ClassDependencyResolver[] */ private $classDependencyResolvers; + /** + * @var NodeTraverser + */ + private $traverser; + public function __construct( FileParser $fileParser, AstFileReferenceCache $cache, + TypeResolver $typeResolver, ClassDependencyResolver ...$classDependencyResolvers ) { $this->fileParser = $fileParser; $this->cache = $cache; + $this->typeResolver = $typeResolver; $this->classDependencyResolvers = $classDependencyResolvers; - } - public function supports($data): bool - { - if (!$data instanceof \SplFileInfo) { - return false; - } - - return 'php' === strtolower($data->getExtension()); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor(new NameResolver()); } - public function parse($data): AstFileReference + public function parse(\SplFileInfo $data): AstFileReference { - /** @var \SplFileInfo $data */ - if (!$this->supports($data)) { - throw new \LogicException('data not supported'); - } - $realPath = (string) $data->getRealPath(); if (null !== $fileReference = $this->cache->get($realPath)) { return $fileReference; } $fileReference = new AstFileReference($realPath); + $visitor = new ClassReferenceVisitor($fileReference, $this->typeResolver, ...$this->classDependencyResolvers); - $traverser = new NodeTraverser(); - $traverser->addVisitor(new NameResolver()); - $traverser->addVisitor(new AstClassReferenceResolver($fileReference, ...$this->classDependencyResolvers)); - - $traverser->traverse($this->fileParser->parse($data)); + $this->traverser->addVisitor($visitor); + $this->traverser->traverse($this->fileParser->parse($data)); + $this->traverser->removeVisitor($visitor); $this->cache->set($fileReference); @@ -92,21 +93,20 @@ public function getAstForClassReference(AstClassReference $classReference): ?Nod return null; } - $finding = new FindingVisitor( + $findingVisitor = new FindingVisitor( static function (Node $node): bool { return $node instanceof Node\Stmt\ClassLike; } ); - $traverser = new NodeTraverser(); - $traverser->addVisitor(new NameResolver()); - $traverser->addVisitor($finding); - $traverser->traverse( + $this->traverser->addVisitor($findingVisitor); + $this->traverser->traverse( $this->fileParser->parse(new \SplFileInfo($classReference->getFileReference()->getFilepath())) ); + $this->traverser->removeVisitor($findingVisitor); /** @var Node\Stmt\ClassLike[] $classLikeNodes */ - $classLikeNodes = $finding->getFoundNodes(); + $classLikeNodes = $findingVisitor->getFoundNodes(); foreach ($classLikeNodes as $classLikeNode) { if (isset($classLikeNode->namespacedName) && $classLikeNode->namespacedName instanceof Node\Name) { diff --git a/src/AstRunner/AstRunner.php b/src/AstRunner/AstRunner.php index 85defa09a..37c83a43e 100644 --- a/src/AstRunner/AstRunner.php +++ b/src/AstRunner/AstRunner.php @@ -32,10 +32,6 @@ public function createAstMapByFiles(array $files): AstMap $this->dispatcher->dispatch(new PreCreateAstMapEvent(count($files))); foreach ($files as $file) { - if (!$this->astParser->supports($file)) { - continue; - } - try { $references[] = $this->astParser->parse($file); diff --git a/src/AstRunner/Resolver/AnnotationDependencyResolver.php b/src/AstRunner/Resolver/AnnotationDependencyResolver.php index 49397228c..52bf18b5e 100644 --- a/src/AstRunner/Resolver/AnnotationDependencyResolver.php +++ b/src/AstRunner/Resolver/AnnotationDependencyResolver.php @@ -30,7 +30,7 @@ public function __construct(TypeResolver $typeResolver) $this->typeResolver = $typeResolver; } - public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void { if (!$node instanceof Node\Stmt\Property && !$node instanceof Node\Expr\Variable @@ -48,7 +48,7 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui $docNode = $this->docParser->parse($tokens); foreach ($docNode->getParamTagValues() as $tag) { - $types = $this->typeResolver->resolveType($tag->type, $nameScope); + $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope); foreach ($types as $type) { $classReferenceBuilder->parameter($type, $docComment->getLine()); @@ -56,7 +56,7 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui } foreach ($docNode->getVarTagValues() as $tag) { - $types = $this->typeResolver->resolveType($tag->type, $nameScope); + $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope); foreach ($types as $type) { $classReferenceBuilder->variable($type, $docComment->getLine()); @@ -64,7 +64,7 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui } foreach ($docNode->getReturnTagValues() as $tag) { - $types = $this->typeResolver->resolveType($tag->type, $nameScope); + $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope); foreach ($types as $type) { $classReferenceBuilder->returnType($type, $docComment->getLine()); @@ -72,7 +72,7 @@ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBui } foreach ($docNode->getThrowsTagValues() as $tag) { - $types = $this->typeResolver->resolveType($tag->type, $nameScope); + $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope); foreach ($types as $type) { $classReferenceBuilder->throwStatement($type, $docComment->getLine()); diff --git a/src/AstRunner/Resolver/AnonymousClassResolver.php b/src/AstRunner/Resolver/AnonymousClassResolver.php index 5b3343779..3a29970b2 100644 --- a/src/AstRunner/Resolver/AnonymousClassResolver.php +++ b/src/AstRunner/Resolver/AnonymousClassResolver.php @@ -9,7 +9,7 @@ class AnonymousClassResolver implements ClassDependencyResolver { - public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void { if (!$node instanceof Node\Stmt\Class_ || null !== $node->name) { return; diff --git a/src/AstRunner/Resolver/ClassConstantResolver.php b/src/AstRunner/Resolver/ClassConstantResolver.php index cfdf65df5..21d30e7f6 100644 --- a/src/AstRunner/Resolver/ClassConstantResolver.php +++ b/src/AstRunner/Resolver/ClassConstantResolver.php @@ -10,7 +10,7 @@ class ClassConstantResolver implements ClassDependencyResolver { - public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void { if (!$node instanceof ClassConstFetch || !$node->class instanceof Node\Name || $node->class->isSpecialClassName()) { return; diff --git a/src/AstRunner/Resolver/ClassDependencyResolver.php b/src/AstRunner/Resolver/ClassDependencyResolver.php index 0673f6658..99e47051a 100644 --- a/src/AstRunner/Resolver/ClassDependencyResolver.php +++ b/src/AstRunner/Resolver/ClassDependencyResolver.php @@ -9,5 +9,5 @@ interface ClassDependencyResolver { - public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, NameScope $nameScope): void; + public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void; } diff --git a/src/AstRunner/Resolver/TypeResolver.php b/src/AstRunner/Resolver/TypeResolver.php index ccb3d0d0d..52b7d5145 100644 --- a/src/AstRunner/Resolver/TypeResolver.php +++ b/src/AstRunner/Resolver/TypeResolver.php @@ -9,6 +9,8 @@ use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\Object_; +use PhpParser\Node; +use PhpParser\NodeAbstract; use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode; @@ -31,27 +33,61 @@ public function __construct() /** * @return string[] */ - public function resolveType(TypeNode $type, NameScope $nameScope): array + public function resolvePHPParserTypes(TypeScope $typeScope, NodeAbstract ...$nodes): array + { + $types = []; + foreach ($nodes as $node) { + $types[] = $this->resolvePHPParserType($typeScope, $node); + } + + return array_merge([], ...$types); + } + + private function resolvePHPParserType(TypeScope $typeScope, NodeAbstract $node): array + { + if ($node instanceof Node\Name && $node->isSpecialClassName()) { + return []; + } + + if ($node instanceof Node\Name) { + return $this->resolveString($node->toCodeString(), $typeScope); + } + + if ($node instanceof Node\NullableType) { + return $this->resolvePHPParserType($typeScope, $node->type); + } + + if ($node instanceof Node\UnionType) { + return $this->resolvePHPParserTypes($typeScope, ...$node->types); + } + + return []; + } + + /** + * @return string[] + */ + public function resolvePHPStanDocParserType(TypeNode $type, TypeScope $nameScope): array { if ($type instanceof IdentifierTypeNode) { return $this->resolveString($type->name, $nameScope); } if ($type instanceof NullableTypeNode) { - return $this->resolveType($type->type, $nameScope); + return $this->resolvePHPStanDocParserType($type->type, $nameScope); } if ($type instanceof ArrayTypeNode) { - return $this->resolveType($type->type, $nameScope); + return $this->resolvePHPStanDocParserType($type->type, $nameScope); } if ($type instanceof UnionTypeNode || $type instanceof IntersectionTypeNode) { return array_merge([], ...array_map(function (TypeNode $typeNode) use ($nameScope) { - return $this->resolveType($typeNode, $nameScope); + return $this->resolvePHPStanDocParserType($typeNode, $nameScope); }, $type->types)); } return $this->resolveString((string) $type, $nameScope); } - public function resolveString(string $type, NameScope $nameScope): array + public function resolveString(string $type, TypeScope $nameScope): array { $context = new Context($nameScope->getNamespace(), $nameScope->getUses()); $resolvedType = $this->typeResolver->resolve($type, $context); diff --git a/src/AstRunner/Resolver/NameScope.php b/src/AstRunner/Resolver/TypeScope.php similarity index 94% rename from src/AstRunner/Resolver/NameScope.php rename to src/AstRunner/Resolver/TypeScope.php index ee01f06a6..bac4cca28 100644 --- a/src/AstRunner/Resolver/NameScope.php +++ b/src/AstRunner/Resolver/TypeScope.php @@ -4,10 +4,10 @@ namespace SensioLabs\Deptrac\AstRunner\Resolver; -class NameScope +class TypeScope { /** - * @var string|null + * @var string */ private $namespace; diff --git a/src/ClassNameLayerResolver.php b/src/ClassNameLayerResolver.php index b8750b8da..a35ba7e39 100644 --- a/src/ClassNameLayerResolver.php +++ b/src/ClassNameLayerResolver.php @@ -9,7 +9,6 @@ use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\Collector\Registry; use SensioLabs\Deptrac\Configuration\Configuration; -use SensioLabs\Deptrac\Configuration\ConfigurationLayer; class ClassNameLayerResolver implements ClassNameLayerResolverInterface { @@ -59,14 +58,4 @@ public function getLayersByClassName(ClassLikeName $className): array return $layerNames; } - - public function getLayers(): array - { - return array_map( - static function (ConfigurationLayer $configurationLayer): string { - return $configurationLayer->getName(); - }, - $this->configuration->getLayers() - ); - } } diff --git a/src/ClassNameLayerResolverCacheDecorator.php b/src/ClassNameLayerResolverCacheDecorator.php index 9f7058dae..894396ce9 100644 --- a/src/ClassNameLayerResolverCacheDecorator.php +++ b/src/ClassNameLayerResolverCacheDecorator.php @@ -29,13 +29,4 @@ public function getLayersByClassName(ClassLikeName $className): array return $this->layerNamesByClassCache[$className->toString()]; } - - public function getLayers(): array - { - if (empty($this->layerNamesCache)) { - $this->layerNamesCache = $this->classNameLayerResolver->getLayers(); - } - - return $this->layerNamesCache; - } } diff --git a/src/ClassNameLayerResolverInterface.php b/src/ClassNameLayerResolverInterface.php index 1c7456367..cbd3406e9 100644 --- a/src/ClassNameLayerResolverInterface.php +++ b/src/ClassNameLayerResolverInterface.php @@ -12,9 +12,4 @@ interface ClassNameLayerResolverInterface * @return string[] */ public function getLayersByClassName(ClassLikeName $className): array; - - /** - * @return string[] - */ - public function getLayers(): array; } diff --git a/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php b/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php deleted file mode 100644 index ce7c21517..000000000 --- a/tests/AstRunner/AstMap/ClassReferenceBuilderTest.php +++ /dev/null @@ -1,20 +0,0 @@ -extends('Bar', 12) - ->implements('Baz', 12) - ->build(); - } -} diff --git a/tests/AstRunner/AstMapFlattenGeneratorTest.php b/tests/AstRunner/AstMapFlattenGeneratorTest.php index 22ff1a336..1afb53fd5 100644 --- a/tests/AstRunner/AstMapFlattenGeneratorTest.php +++ b/tests/AstRunner/AstMapFlattenGeneratorTest.php @@ -12,6 +12,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\AstRunner; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use Symfony\Component\EventDispatcher\EventDispatcher; use Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\FixtureBasicInheritanceA; use Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\FixtureBasicInheritanceB; @@ -42,7 +43,8 @@ private function getAstMap(string $fixture): AstMap new EventDispatcher(), new NikicPhpParser( new FileParser(ParserFactory::createParser()), - new AstFileReferenceInMemoryCache() + new AstFileReferenceInMemoryCache(), + new TypeResolver() ) ); diff --git a/tests/AstRunner/AstMapGeneratorTest.php b/tests/AstRunner/AstMapGeneratorTest.php index 947dcfab4..890514166 100644 --- a/tests/AstRunner/AstMapGeneratorTest.php +++ b/tests/AstRunner/AstMapGeneratorTest.php @@ -12,6 +12,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\AstRunner; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use Symfony\Component\EventDispatcher\EventDispatcher; use Tests\SensioLabs\Deptrac\AstRunner\ArrayAsserts; use Tests\SensioLabs\Deptrac\AstRunner\Visitor\Fixtures\BasicDependency\BasicDependencyClassB; @@ -32,7 +33,8 @@ private function getAstMap(string $fixture): AstMap new EventDispatcher(), new NikicPhpParser( new FileParser(ParserFactory::createParser()), - new AstFileReferenceInMemoryCache() + new AstFileReferenceInMemoryCache(), + new TypeResolver() ) ); diff --git a/tests/AstRunner/AstParser/NikicPhpParser/NikicPhpParserTest.php b/tests/AstRunner/AstParser/NikicPhpParser/NikicPhpParserTest.php index 9061e649a..61e27442c 100644 --- a/tests/AstRunner/AstParser/NikicPhpParser/NikicPhpParserTest.php +++ b/tests/AstRunner/AstParser/NikicPhpParser/NikicPhpParserTest.php @@ -8,6 +8,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\AstFileReferenceCache; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\FileParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; class NikicPhpParserTest extends TestCase { @@ -16,26 +17,16 @@ class NikicPhpParserTest extends TestCase protected function setUp(): void { - parent::setUp(); - $this->parser = new NikicPhpParser( $this->createMock(FileParser::class), - $this->createMock(AstFileReferenceCache::class) + $this->createMock(AstFileReferenceCache::class), + $this->createMock(TypeResolver::class) ); } - public function testSupport(): void - { - static::assertTrue($this->parser->supports(new \SplFileInfo('foo.php'))); - static::assertTrue($this->parser->supports(new \SplFileInfo('FOO.PHP'))); - static::assertFalse($this->parser->supports(new \SplFileInfo('FOO.html'))); - static::assertFalse($this->parser->supports(new \stdClass())); - } - public function testParseWithInvalidData(): void { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('data not supported'); + $this->expectException(\TypeError::class); $this->parser->parse(new \stdClass()); } } diff --git a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php index 127d08944..938158cf1 100644 --- a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php +++ b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php @@ -17,10 +17,12 @@ class AnnotationDependencyResolverTest extends TestCase { public function testPropertyDependencyResolving(): void { + $typeResolver = new TypeResolver(); $parser = new NikicPhpParser( new FileParser(ParserFactory::createParser()), new AstFileReferenceInMemoryCache(), - new AnnotationDependencyResolver(new TypeResolver()) + new TypeResolver(), + new AnnotationDependencyResolver($typeResolver) ); $filePath = __DIR__.'/fixtures/AnnotationDependency.php'; diff --git a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php index 0cbee92f4..e6a89874e 100644 --- a/tests/AstRunner/Resolver/AnonymousClassResolverTest.php +++ b/tests/AstRunner/Resolver/AnonymousClassResolverTest.php @@ -10,6 +10,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\Resolver\AnonymousClassResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use SplFileInfo; class AnonymousClassResolverTest extends TestCase @@ -19,6 +20,7 @@ public function testPropertyDependencyResolving(): void $parser = new NikicPhpParser( new FileParser(ParserFactory::createParser()), new AstFileReferenceInMemoryCache(), + new TypeResolver(), new AnonymousClassResolver() ); diff --git a/tests/AstRunner/Resolver/ClassConstantResolverTest.php b/tests/AstRunner/Resolver/ClassConstantResolverTest.php index 2c121ed30..eeb258a4a 100644 --- a/tests/AstRunner/Resolver/ClassConstantResolverTest.php +++ b/tests/AstRunner/Resolver/ClassConstantResolverTest.php @@ -10,6 +10,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\Resolver\ClassConstantResolver; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use SplFileInfo; class ClassConstantResolverTest extends TestCase @@ -19,6 +20,7 @@ public function testPropertyDependencyResolving(): void $parser = new NikicPhpParser( new FileParser(ParserFactory::createParser()), new AstFileReferenceInMemoryCache(), + new TypeResolver(), new ClassConstantResolver() ); diff --git a/tests/DependencyEmitter/EmitterTrait.php b/tests/DependencyEmitter/EmitterTrait.php index 9fea3f1af..00a46c1b3 100644 --- a/tests/DependencyEmitter/EmitterTrait.php +++ b/tests/DependencyEmitter/EmitterTrait.php @@ -9,6 +9,7 @@ use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\NikicPhpParser; use SensioLabs\Deptrac\AstRunner\AstParser\NikicPhpParser\ParserFactory; use SensioLabs\Deptrac\AstRunner\AstRunner; +use SensioLabs\Deptrac\AstRunner\Resolver\TypeResolver; use SensioLabs\Deptrac\Dependency\DependencyInterface; use SensioLabs\Deptrac\Dependency\Result; use SensioLabs\Deptrac\DependencyEmitter\DependencyEmitterInterface; @@ -20,7 +21,8 @@ public function getDeps(DependencyEmitterInterface $emitter, \SplFileInfo $fileI { $parser = new NikicPhpParser( new FileParser(ParserFactory::createParser()), - new AstFileReferenceInMemoryCache() + new AstFileReferenceInMemoryCache(), + new TypeResolver() ); $astMap = (new AstRunner(new EventDispatcher(), $parser))->createAstMapByFiles([$fileInfo]); $result = new Result(); From 3fcff20b90f6ce863ed81f831736a9ad8a11e593 Mon Sep 17 00:00:00 2001 From: smoench Date: Mon, 17 Feb 2020 10:34:35 +0100 Subject: [PATCH 5/6] phpstan fixes --- src/AstRunner/AstMap.php | 2 +- src/AstRunner/AstMap/AstFileReference.php | 4 ++++ src/AstRunner/Resolver/TypeResolver.php | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/AstRunner/AstMap.php b/src/AstRunner/AstMap.php index 00d698adb..ab47f41e5 100644 --- a/src/AstRunner/AstMap.php +++ b/src/AstRunner/AstMap.php @@ -72,7 +72,7 @@ public function getClassInherits(ClassLikeName $classLikeName): iterable } /** - * @param ArrayObject|null $alreadyResolved + * @param ArrayObject|null $alreadyResolved * * @return iterable */ diff --git a/src/AstRunner/AstMap/AstFileReference.php b/src/AstRunner/AstMap/AstFileReference.php index 0575426d6..1ac52fe3c 100644 --- a/src/AstRunner/AstMap/AstFileReference.php +++ b/src/AstRunner/AstMap/AstFileReference.php @@ -21,6 +21,10 @@ public function __construct(string $filepath) $this->dependencies = []; } + /** + * @param AstInherit[] $inherits + * @param AstDependency[] $dependencies + */ public function addClassReference(ClassLikeName $className, array $inherits = [], array $dependencies = []): AstClassReference { $astClassReference = new AstClassReference($className, $this, $inherits, $dependencies); diff --git a/src/AstRunner/Resolver/TypeResolver.php b/src/AstRunner/Resolver/TypeResolver.php index 52b7d5145..b24a06196 100644 --- a/src/AstRunner/Resolver/TypeResolver.php +++ b/src/AstRunner/Resolver/TypeResolver.php @@ -43,6 +43,9 @@ public function resolvePHPParserTypes(TypeScope $typeScope, NodeAbstract ...$nod return array_merge([], ...$types); } + /** + * @return string[] + */ private function resolvePHPParserType(TypeScope $typeScope, NodeAbstract $node): array { if ($node instanceof Node\Name && $node->isSpecialClassName()) { @@ -87,6 +90,9 @@ public function resolvePHPStanDocParserType(TypeNode $type, TypeScope $nameScope return $this->resolveString((string) $type, $nameScope); } + /** + * @return string[] + */ public function resolveString(string $type, TypeScope $nameScope): array { $context = new Context($nameScope->getNamespace(), $nameScope->getUses()); @@ -95,6 +101,9 @@ public function resolveString(string $type, TypeScope $nameScope): array return $this->resolveReflectionType($resolvedType); } + /** + * @return string[] + */ private function resolveReflectionType(Type $resolvedType): array { if ($resolvedType instanceof Object_) { From 4d7b157ac9a2d02ae6cfde69efcacb5337b07cdc Mon Sep 17 00:00:00 2001 From: smoench Date: Mon, 17 Feb 2020 10:34:55 +0100 Subject: [PATCH 6/6] cs fixes --- src/AstRunner/AstMap/AstFileReference.php | 2 +- src/OutputFormatter/XMLOutputFormatter.php | 4 +- .../XMLOutputFormatterTest.php | 45 ++++++++++--------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/AstRunner/AstMap/AstFileReference.php b/src/AstRunner/AstMap/AstFileReference.php index 1ac52fe3c..7c76af5f2 100644 --- a/src/AstRunner/AstMap/AstFileReference.php +++ b/src/AstRunner/AstMap/AstFileReference.php @@ -22,7 +22,7 @@ public function __construct(string $filepath) } /** - * @param AstInherit[] $inherits + * @param AstInherit[] $inherits * @param AstDependency[] $dependencies */ public function addClassReference(ClassLikeName $className, array $inherits = [], array $dependencies = []): AstClassReference diff --git a/src/OutputFormatter/XMLOutputFormatter.php b/src/OutputFormatter/XMLOutputFormatter.php index 19393b10b..6d140939c 100644 --- a/src/OutputFormatter/XMLOutputFormatter.php +++ b/src/OutputFormatter/XMLOutputFormatter.php @@ -90,8 +90,8 @@ private function addRule(string $type, \DOMElement $rootEntry, \DOMDocument $xml $entry->appendChild($xmlDoc->createElement('LayerB', $rule->getLayerB())); $dependency = $rule->getDependency(); - $entry->appendChild($xmlDoc->createElement('ClassA', $dependency->getClassA())); - $entry->appendChild($xmlDoc->createElement('ClassB', $dependency->getClassB())); + $entry->appendChild($xmlDoc->createElement('ClassA', $dependency->getClassLikeNameA()->toString())); + $entry->appendChild($xmlDoc->createElement('ClassB', $dependency->getClassLikeNameB()->toString())); $fileOccurrence = $dependency->getFileOccurrence(); $occurrence = $xmlDoc->createElement('occurrence'); diff --git a/tests/OutputFormatter/XMLOutputFormatterTest.php b/tests/OutputFormatter/XMLOutputFormatterTest.php index b28521122..d64a025d8 100644 --- a/tests/OutputFormatter/XMLOutputFormatterTest.php +++ b/tests/OutputFormatter/XMLOutputFormatterTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use SensioLabs\Deptrac\AstRunner\AstMap\AstFileReference; use SensioLabs\Deptrac\AstRunner\AstMap\AstInherit; +use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName; use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence; use SensioLabs\Deptrac\Dependency\Dependency; use SensioLabs\Deptrac\Dependency\InheritDependency; @@ -40,13 +41,13 @@ public function basicDataProvider(): iterable [ new Violation( new InheritDependency( - 'ClassA', - 'ClassB', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('ClassA.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), + ClassLikeName::fromFQCN('ClassA'), + ClassLikeName::fromFQCN('ClassB'), + new Dependency(ClassLikeName::fromFQCN('OriginalA'), ClassLikeName::fromFQCN('OriginalB'), new FileOccurrence(new AstFileReference('ClassA.php'), 12)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritA'), new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritB'), new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritC'), new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritD'), new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), ]) ), 'LayerA', @@ -59,7 +60,7 @@ public function basicDataProvider(): iterable yield [ [ new Violation( - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('ClassA.php'), 12)), + new Dependency(ClassLikeName::fromFQCN('OriginalA'), ClassLikeName::fromFQCN('OriginalB'), new FileOccurrence(new AstFileReference('ClassA.php'), 12)), 'LayerA', 'LayerB' ), @@ -76,13 +77,13 @@ public function basicDataProvider(): iterable [ $violations = new SkippedViolation( new InheritDependency( - 'ClassA', - 'ClassB', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('ClassA.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), + ClassLikeName::fromFQCN('ClassA'), + ClassLikeName::fromFQCN('ClassB'), + new Dependency(ClassLikeName::fromFQCN('OriginalA'), ClassLikeName::fromFQCN('OriginalB'), new FileOccurrence(new AstFileReference('ClassA.php'), 12)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritA'), new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritB'), new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritC'), new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritD'), new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), ]) ), 'LayerA', @@ -90,13 +91,13 @@ public function basicDataProvider(): iterable ), new SkippedViolation( new InheritDependency( - 'ClassC', - 'ClassD', - new Dependency('OriginalA', 'OriginalB', new FileOccurrence(new AstFileReference('ClassA.php'), 12)), - AstInherit::newExtends('ClassInheritA', new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ - AstInherit::newExtends('ClassInheritB', new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), - AstInherit::newExtends('ClassInheritC', new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), - AstInherit::newExtends('ClassInheritD', new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), + ClassLikeName::fromFQCN('ClassC'), + ClassLikeName::fromFQCN('ClassD'), + new Dependency(ClassLikeName::fromFQCN('OriginalA'), ClassLikeName::fromFQCN('OriginalB'), new FileOccurrence(new AstFileReference('ClassA.php'), 12)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritA'), new FileOccurrence(new AstFileReference('ClassA.php'), 3))->withPath([ + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritB'), new FileOccurrence(new AstFileReference('ClassInheritA.php'), 4)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritC'), new FileOccurrence(new AstFileReference('ClassInheritB.php'), 5)), + AstInherit::newExtends(ClassLikeName::fromFQCN('ClassInheritD'), new FileOccurrence(new AstFileReference('ClassInheritC.php'), 6)), ]) ), 'LayerA',