diff --git a/config/services.xml b/config/services.xml
index e4a601858..524e886c2 100644
--- a/config/services.xml
+++ b/config/services.xml
@@ -29,12 +29,17 @@
+
-
+
+
+
+
+
diff --git a/src/AstRunner/AstMap.php b/src/AstRunner/AstMap.php
index b4273e0bc..ab47f41e5 100644
--- a/src/AstRunner/AstMap.php
+++ b/src/AstRunner/AstMap.php
@@ -4,9 +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
{
@@ -46,17 +49,17 @@ 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[$className->toString()] ?? null;
}
/**
* @return AstInherit[]|iterable
*/
- public function getClassInherits(string $className): iterable
+ public function getClassInherits(ClassLikeName $classLikeName): iterable
{
- $classReference = $this->getClassReferenceByClassName($className);
+ $classReference = $this->getClassReferenceByClassName($classLikeName);
if (null === $classReference) {
return [];
@@ -69,36 +72,38 @@ public function getClassInherits(string $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);
}
- if (isset($alreadyResolved[$inheritDependency->getClassName()])) {
+ $className = $inheritDependency->getClassLikeName()->toString();
+
+ if (isset($alreadyResolved[$className])) {
$path->pop();
return [];
}
- $classReference = $this->getClassReferenceByClassName($inheritDependency->getClassName());
+ $classReference = $this->getClassReferenceByClassName($inheritDependency->getClassLikeName());
if (null === $classReference) {
return [];
}
foreach ($classReference->getInherits() as $inherit) {
- $alreadyResolved[$inheritDependency->getClassName()] = true;
+ $alreadyResolved[$className] = true;
yield $inherit->withPath(iterator_to_array($path));
@@ -106,14 +111,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[$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 b5fad1ae2..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[] */
@@ -15,22 +15,26 @@ class AstClassReference
/** @var AstInherit[] */
private $inherits;
- public function __construct(string $className, AstFileReference $fileReference = null)
+ /**
+ * @param AstInherit[] $inherits
+ * @param AstDependency[] $dependencies
+ */
+ public function __construct(ClassLikeName $classLikeName, AstFileReference $fileReference = null, array $inherits = [], array $dependencies = [])
{
- $this->className = $className;
+ $this->classLikeName = $classLikeName;
$this->fileReference = $fileReference;
- $this->dependencies = [];
- $this->inherits = [];
+ $this->dependencies = $dependencies;
+ $this->inherits = $inherits;
}
public function getFileReference(): ?AstFileReference
{
- return $this->fileReference;
+ return $this->fileReference ? clone $this->fileReference : null;
}
- public function getClassName(): string
+ public function getClassLikeName(): ClassLikeName
{
- return $this->className;
+ return $this->classLikeName;
}
/**
@@ -48,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 720e362fe..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;
- public function __construct(string $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 getClass(): string
+ 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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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(string $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/AstFileReference.php b/src/AstRunner/AstMap/AstFileReference.php
index 9d2eaf8f1..7c76af5f2 100644
--- a/src/AstRunner/AstMap/AstFileReference.php
+++ b/src/AstRunner/AstMap/AstFileReference.php
@@ -21,9 +21,13 @@ public function __construct(string $filepath)
$this->dependencies = [];
}
- public function addClassReference(string $className): AstClassReference
+ /**
+ * @param AstInherit[] $inherits
+ * @param AstDependency[] $dependencies
+ */
+ 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/AstInherit.php b/src/AstRunner/AstMap/AstInherit.php
index 58c0b2f0c..3ce933d54 100644
--- a/src/AstRunner/AstMap/AstInherit.php
+++ b/src/AstRunner/AstMap/AstInherit.php
@@ -10,32 +10,32 @@ class AstInherit
private const TYPE_IMPLEMENTS = 2;
private const TYPE_USES = 3;
- private $className;
+ private $classLikeName;
private $fileOccurrence;
private $type;
/** @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->classLikeName = $className;
$this->fileOccurrence = $fileOccurrence;
$this->type = $type;
$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);
}
@@ -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(): string
+ 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
new file mode 100644
index 000000000..6dad0093a
--- /dev/null
+++ b/src/AstRunner/AstMap/ClassLikeName.php
@@ -0,0 +1,33 @@
+className = $className;
+ }
+
+ public static function fromFQCN(string $className): self
+ {
+ return new self(ltrim($className, '\\'));
+ }
+
+ public function match(string $pattern): bool
+ {
+ return 1 === preg_match($pattern, $this->className);
+ }
+
+ public function toString(): string
+ {
+ return $this->className;
+ }
+}
diff --git a/src/AstRunner/AstMap/ClassReferenceBuilder.php b/src/AstRunner/AstMap/ClassReferenceBuilder.php
new file mode 100644
index 000000000..ca5d7de06
--- /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::fromFQCN($this->classLikeName),
+ $this->inherits,
+ $this->dependencies
+ );
+ }
+
+ public function extends(string $classLikeName, int $occursAtLine): self
+ {
+ $this->inherits[] = AstInherit::newExtends(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function implements(string $classLikeName, int $occursAtLine): self
+ {
+ $this->inherits[] = AstInherit::newImplements(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function trait(string $classLikeName, int $occursAtLine): self
+ {
+ $this->inherits[] = AstInherit::newTraitUse(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function instanceof(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::instanceofExpr(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function parameter(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::parameter(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function newStatement(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::newStmt(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function staticProperty(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::staticProperty(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function staticMethod(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::staticMethod(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function returnType(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::returnType(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function catchStmt(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::catchStmt(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function variable(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::variable(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function throwStatement(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::throwStmt(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function anonymousClassExtends(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::anonymousClassExtends(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function anonymousClassImplements(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::anonymousClassImplements(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+
+ public function constFetch(string $classLikeName, int $occursAtLine): self
+ {
+ $this->dependencies[] = AstDependency::constFetch(
+ ClassLikeName::fromFQCN($classLikeName),
+ new FileOccurrence($this->fileReference, $occursAtLine)
+ );
+
+ return $this;
+ }
+}
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/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/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/AstClassReferenceResolver.php
deleted file mode 100644
index 3895829d4..000000000
--- a/src/AstRunner/AstParser/NikicPhpParser/AstClassReferenceResolver.php
+++ /dev/null
@@ -1,187 +0,0 @@
-fileReference = $fileReference;
- $this->classDependencyResolvers = $classDependencyResolvers;
- }
-
- public function enterNode(Node $node)
- {
- if (!$node instanceof Node\Stmt\ClassLike) {
- return null;
- }
-
- if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) {
- $className = $node->namespacedName->toString();
- } elseif ($node->name instanceof Node\Identifier) {
- $className = $node->name->toString();
- } else {
- return null; // map anonymous classes on current class
- }
-
- $this->currentClassReference = $this->fileReference->addClassReference($className);
-
- if ($node instanceof Node\Stmt\Class_) {
- if ($node->extends instanceof Node\Name) {
- $this->currentClassReference->addInherit(
- AstInherit::newExtends(
- $node->extends->toString(),
- new FileOccurrence($this->fileReference, $node->extends->getLine())
- )
- );
- }
- foreach ($node->implements as $implement) {
- $this->currentClassReference->addInherit(
- AstInherit::newImplements(
- $implement->toString(),
- new FileOccurrence($this->fileReference, $implement->getLine())
- )
- );
- }
- }
-
- if ($node instanceof Node\Stmt\Interface_) {
- foreach ($node->extends as $extend) {
- $this->currentClassReference->addInherit(
- AstInherit::newExtends(
- $extend->toString(),
- new FileOccurrence($this->fileReference, $extend->getLine())
- )
- );
- }
- }
-
- return null;
- }
-
- public function leaveNode(Node $node)
- {
- if ($node instanceof Node\Stmt\UseUse) {
- $this->fileReference->addDependency(
- AstDependency::useStmt(
- $node->name->toString(),
- new FileOccurrence($this->fileReference, $node->name->getLine())
- )
- );
- }
-
- if (null === $this->currentClassReference) {
- return null;
- }
-
- if ($node instanceof Node\Stmt\TraitUse) {
- foreach ($node->traits as $trait) {
- $this->currentClassReference->addInherit(
- AstInherit::newTraitUse(
- $trait->toString(),
- new FileOccurrence($this->fileReference, $trait->getLine())
- )
- );
- }
- }
-
- if ($node instanceof Node\Expr\Instanceof_ && $node->class instanceof Node\Name) {
- $this->currentClassReference->addDependency(
- AstDependency::instanceofExpr(
- $node->class->toString(),
- new FileOccurrence($this->fileReference, $node->class->getLine())
- )
- );
- }
-
- if ($node instanceof Node\Param && $node->type instanceof Node\Name) {
- $this->currentClassReference->addDependency(
- AstDependency::parameter(
- $node->type->toString(),
- new FileOccurrence($this->fileReference, $node->type->getLine())
- )
- );
- }
-
- if ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) {
- $this->currentClassReference->addDependency(
- AstDependency::newStmt(
- $node->class->toString(),
- new FileOccurrence($this->fileReference, $node->class->getLine())
- )
- );
- }
-
- if ($node instanceof Node\Expr\StaticPropertyFetch && $node->class instanceof Node\Name) {
- $this->currentClassReference->addDependency(
- AstDependency::staticProperty(
- $node->class->toString(),
- new FileOccurrence($this->fileReference, $node->class->getLine())
- )
- );
- }
-
- if ($node instanceof Node\Expr\StaticCall && $node->class instanceof Node\Name) {
- $this->currentClassReference->addDependency(
- AstDependency::staticMethod(
- $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) {
- $this->currentClassReference->addDependency(
- AstDependency::returnType(
- $node->returnType->toString(),
- new FileOccurrence($this->fileReference, $node->returnType->getLine())
- )
- );
- } elseif ($node->returnType instanceof Node\NullableType) {
- $this->currentClassReference->addDependency(
- AstDependency::returnType(
- (string) $node->returnType->type,
- new FileOccurrence($this->fileReference, $node->returnType->getLine())
- )
- );
- }
- }
-
- if ($node instanceof Node\Stmt\Catch_) {
- foreach ($node->types as $type) {
- $this->currentClassReference->addDependency(
- AstDependency::catchStmt(
- $type->toString(),
- new FileOccurrence($this->fileReference, $type->getLine())
- )
- );
- }
- }
-
- foreach ($this->classDependencyResolvers as $resolver) {
- $resolver->processNode($node, $this->fileReference, $this->currentClassReference);
- }
-
- return null;
- }
-}
diff --git a/src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php b/src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php
new file mode 100644
index 000000000..fe8cb0e6e
--- /dev/null
+++ b/src/AstRunner/AstParser/NikicPhpParser/ClassReferenceVisitor.php
@@ -0,0 +1,163 @@
+currentTypeScope = new TypeScope('');
+ $this->fileReference = $fileReference;
+ $this->classDependencyResolvers = $classDependencyResolvers;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function enterNode(Node $node)
+ {
+ if ($node instanceof Node\Stmt\Namespace_) {
+ $this->currentTypeScope = new TypeScope($node->name ? $node->name->toCodeString() : '');
+ }
+
+ if (!$node instanceof Node\Stmt\ClassLike) {
+ return null;
+ }
+
+ if (isset($node->namespacedName) && $node->namespacedName instanceof Node\Name) {
+ $className = $node->namespacedName->toCodeString();
+ } elseif ($node->name instanceof Node\Identifier) {
+ $className = $node->name->toString();
+ } else {
+ return null; // map anonymous classes on current class
+ }
+
+ 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->currentClassReferenceBuilder->extends($node->extends->toCodeString(), $node->extends->getLine());
+ }
+ foreach ($node->implements as $implement) {
+ $this->currentClassReferenceBuilder->implements($implement->toCodeString(), $implement->getLine());
+ }
+ }
+
+ if ($node instanceof Node\Stmt\Interface_) {
+ foreach ($node->extends as $extend) {
+ $this->currentClassReferenceBuilder->extends($extend->toCodeString(), $extend->getLine());
+ }
+ }
+
+ return null;
+ }
+
+ public function leaveNode(Node $node)
+ {
+ if ($node instanceof Node\Stmt\UseUse) {
+ $this->currentTypeScope->addUse($node->name->toCodeString(), $node->getAlias()->toString());
+ $this->fileReference->addDependency(
+ AstDependency::useStmt(
+ ClassLikeName::fromFQCN($node->name->toCodeString()),
+ new FileOccurrence($this->fileReference, $node->name->getLine())
+ )
+ );
+ }
+
+ if (null === $this->currentClassReferenceBuilder) {
+ return null;
+ }
+
+ if ($node instanceof Node\Stmt\TraitUse) {
+ foreach ($this->typeResolver->resolvePHPParserTypes($this->currentTypeScope, ...$node->traits) as $classLikeName) {
+ $this->currentClassReferenceBuilder->trait($classLikeName, $node->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 && 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_ && $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 && $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 && $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) && 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 ($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->currentTypeScope);
+ }
+
+ return null;
+ }
+
+ public function afterTraverse(array $nodes)
+ {
+ if (null !== $this->currentClassReferenceBuilder) {
+ $this->currentClassReferenceBuilder->build();
+ }
+
+ return null;
+ }
+}
diff --git a/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php b/src/AstRunner/AstParser/NikicPhpParser/NikicPhpParser.php
index 7e9184b16..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);
@@ -82,29 +83,30 @@ 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 = $classReference->getClassLikeName()->toString();
+
+ if (isset(self::$classAstMap[$classLikeName])) {
+ return self::$classAstMap[$classLikeName];
}
if (null === $classReference->getFileReference()) {
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) {
@@ -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/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 6e71541c0..52bf18b5e 100644
--- a/src/AstRunner/Resolver/AnnotationDependencyResolver.php
+++ b/src/AstRunner/Resolver/AnnotationDependencyResolver.php
@@ -11,23 +11,26 @@
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\FileOccurrence;
+use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder;
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, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void
{
if (!$node instanceof Node\Stmt\Property
&& !$node instanceof Node\Expr\Variable
@@ -41,59 +44,38 @@ 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->resolvePHPStanDocParserType($tag->type, $typeScope);
foreach ($types as $type) {
- $astClassReference->addDependency(
- AstDependency::parameter(
- $type,
- new FileOccurrence($fileReference, $docComment->getLine())
- )
- );
+ $classReferenceBuilder->parameter($type, $docComment->getLine());
}
}
foreach ($docNode->getVarTagValues() as $tag) {
- $types = $typeResolver->resolveType($tag->type);
+ $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope);
foreach ($types as $type) {
- $astClassReference->addDependency(
- AstDependency::variable(
- $type,
- new FileOccurrence($fileReference, $docComment->getLine())
- )
- );
+ $classReferenceBuilder->variable($type, $docComment->getLine());
}
}
foreach ($docNode->getReturnTagValues() as $tag) {
- $types = $typeResolver->resolveType($tag->type);
+ $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope);
foreach ($types as $type) {
- $astClassReference->addDependency(
- AstDependency::returnType(
- $type,
- new FileOccurrence($fileReference, $docComment->getLine())
- )
- );
+ $classReferenceBuilder->returnType($type, $docComment->getLine());
}
}
foreach ($docNode->getThrowsTagValues() as $tag) {
- $types = $typeResolver->resolveType($tag->type);
+ $types = $this->typeResolver->resolvePHPStanDocParserType($tag->type, $typeScope);
foreach ($types as $type) {
- $astClassReference->addDependency(
- AstDependency::throwStmt(
- $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 14a57dbc1..3a29970b2 100644
--- a/src/AstRunner/Resolver/AnonymousClassResolver.php
+++ b/src/AstRunner/Resolver/AnonymousClassResolver.php
@@ -5,34 +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\FileOccurrence;
+use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder;
class AnonymousClassResolver implements ClassDependencyResolver
{
- public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference): void
+ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void
{
if (!$node instanceof Node\Stmt\Class_ || null !== $node->name) {
return;
}
if ($node->extends instanceof Node\Name) {
- $astClassReference->addDependency(
- AstDependency::anonymousClassExtends(
- $node->extends->toString(),
- new FileOccurrence($astFileReference, $node->extends->getLine())
- )
- );
+ $classReferenceBuilder->anonymousClassExtends($node->extends->toCodeString(), $node->extends->getLine());
}
foreach ($node->implements as $implement) {
- $astClassReference->addDependency(
- AstDependency::anonymousClassImplements(
- $implement->toString(),
- new FileOccurrence($astFileReference, $implement->getLine())
- )
- );
+ $classReferenceBuilder->anonymousClassImplements($implement->toCodeString(), $implement->getLine());
}
}
}
diff --git a/src/AstRunner/Resolver/ClassConstantResolver.php b/src/AstRunner/Resolver/ClassConstantResolver.php
index 2038de2fd..21d30e7f6 100644
--- a/src/AstRunner/Resolver/ClassConstantResolver.php
+++ b/src/AstRunner/Resolver/ClassConstantResolver.php
@@ -6,24 +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\FileOccurrence;
+use SensioLabs\Deptrac\AstRunner\AstMap\ClassReferenceBuilder;
class ClassConstantResolver implements ClassDependencyResolver
{
- public function processNode(Node $node, AstFileReference $astFileReference, AstClassReference $astClassReference): void
+ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): 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(),
- new FileOccurrence($astFileReference, $node->class->getLine())
- )
- );
+ $classReferenceBuilder->constFetch($node->class->toCodeString(), $node->class->getLine());
}
}
diff --git a/src/AstRunner/Resolver/ClassDependencyResolver.php b/src/AstRunner/Resolver/ClassDependencyResolver.php
index d1dc0e0a2..99e47051a 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): void;
+ public function processNode(Node $node, ClassReferenceBuilder $classReferenceBuilder, TypeScope $typeScope): void;
}
diff --git a/src/AstRunner/Resolver/NameScope.php b/src/AstRunner/Resolver/NameScope.php
deleted file mode 100644
index 2f9a92ec9..000000000
--- a/src/AstRunner/Resolver/NameScope.php
+++ /dev/null
@@ -1,95 +0,0 @@
- fullName(string)
- */
- private $uses;
-
- public function __construct(AstClassReference $classReference)
- {
- $this->namespace = $this->resolveNamespace($classReference->getClassName());
- $this->uses = $this->normalizeUses($classReference);
- }
-
- public function resolveStringName(string $name): string
- {
- 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;
- }
-
- private function resolveNamespace(string $className): ?string
- {
- $className = ltrim($className, '\\');
- $nameParts = explode('\\', $className);
-
- if (1 === count($nameParts)) {
- return null;
- }
-
- array_pop($nameParts);
-
- return implode('\\', $nameParts);
- }
-
- /**
- * @return string[] alias(string) => fullName(string)
- */
- private function normalizeUses(AstClassReference $astClassReference): 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;
- }
-}
diff --git a/src/AstRunner/Resolver/TypeResolver.php b/src/AstRunner/Resolver/TypeResolver.php
index ce1609962..b24a06196 100644
--- a/src/AstRunner/Resolver/TypeResolver.php
+++ b/src/AstRunner/Resolver/TypeResolver.php
@@ -4,54 +4,118 @@
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 PhpParser\Node;
+use PhpParser\NodeAbstract;
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 resolvePHPParserTypes(TypeScope $typeScope, NodeAbstract ...$nodes): array
+ {
+ $types = [];
+ foreach ($nodes as $node) {
+ $types[] = $this->resolvePHPParserType($typeScope, $node);
+ }
+
+ return array_merge([], ...$types);
}
/**
* @return string[]
*/
- public function resolveType(TypeNode $type): array
+ private function resolvePHPParserType(TypeScope $typeScope, NodeAbstract $node): array
{
- if ($type instanceof IdentifierTypeNode && !$this->isBuiltinType($type->name)) {
- return [$this->nameScope->resolveStringName($type->name)];
+ 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);
+ return $this->resolvePHPStanDocParserType($type->type, $nameScope);
}
if ($type instanceof ArrayTypeNode) {
- return $this->resolveType($type->type);
+ 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->resolvePHPStanDocParserType($typeNode, $nameScope);
+ }, $type->types));
}
- return [];
+ return $this->resolveString((string) $type, $nameScope);
}
- private function isBuiltinType(string $type): bool
+ /**
+ * @return string[]
+ */
+ public function resolveString(string $type, TypeScope $nameScope): array
{
- return in_array($type, self::BUILTIN_TYPES, true);
+ $context = new Context($nameScope->getNamespace(), $nameScope->getUses());
+ $resolvedType = $this->typeResolver->resolve($type, $context);
+
+ return $this->resolveReflectionType($resolvedType);
+ }
+
+ /**
+ * @return string[]
+ */
+ private function resolveReflectionType(Type $resolvedType): array
+ {
+ 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/AstRunner/Resolver/TypeScope.php b/src/AstRunner/Resolver/TypeScope.php
new file mode 100644
index 000000000..bac4cca28
--- /dev/null
+++ b/src/AstRunner/Resolver/TypeScope.php
@@ -0,0 +1,42 @@
+ alias => className
+ */
+ private $uses;
+
+ public function __construct(string $namespace)
+ {
+ $this->namespace = $namespace;
+ $this->uses = [];
+ }
+
+ public function addUse(string $className, ?string $alias): void
+ {
+ $this->uses[$alias ?: $className] = $className;
+ }
+
+ public function getNamespace(): string
+ {
+ return $this->namespace;
+ }
+
+ /**
+ * @return array
+ */
+ public function getUses(): array
+ {
+ return $this->uses;
+ }
+}
diff --git a/src/ClassNameLayerResolver.php b/src/ClassNameLayerResolver.php
index 5b4ee8607..a35ba7e39 100644
--- a/src/ClassNameLayerResolver.php
+++ b/src/ClassNameLayerResolver.php
@@ -6,9 +6,9 @@
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;
class ClassNameLayerResolver implements ClassNameLayerResolverInterface
{
@@ -29,7 +29,7 @@ public function __construct(
/**
* @return string[]
*/
- public function getLayersByClassName(string $className): array
+ public function getLayersByClassName(ClassLikeName $className): array
{
/** @var array $layers */
$layers = [];
@@ -44,7 +44,7 @@ public function getLayersByClassName(string $className): array
if ($collector->satisfy(
$configurationCollector->getArgs(),
- clone $astClassReference,
+ $astClassReference,
$this->astMap,
$this->collectorRegistry
)) {
@@ -58,14 +58,4 @@ public function getLayersByClassName(string $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 1cf9a588a..894396ce9 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,21 +21,12 @@ public function __construct(ClassNameLayerResolverInterface $classNameLayerResol
$this->classNameLayerResolver = $classNameLayerResolver;
}
- public function getLayersByClassName(string $className): array
- {
- if (!isset($this->layerNamesByClassCache[$className])) {
- $this->layerNamesByClassCache[$className] = $this->classNameLayerResolver->getLayersByClassName($className);
- }
-
- return $this->layerNamesByClassCache[$className];
- }
-
- public function getLayers(): array
+ public function getLayersByClassName(ClassLikeName $className): array
{
- if (empty($this->layerNamesCache)) {
- $this->layerNamesCache = $this->classNameLayerResolver->getLayers();
+ if (!isset($this->layerNamesByClassCache[$className->toString()])) {
+ $this->layerNamesByClassCache[$className->toString()] = $this->classNameLayerResolver->getLayersByClassName($className);
}
- return $this->layerNamesCache;
+ return $this->layerNamesByClassCache[$className->toString()];
}
}
diff --git a/src/ClassNameLayerResolverInterface.php b/src/ClassNameLayerResolverInterface.php
index d8c330ae9..cbd3406e9 100644
--- a/src/ClassNameLayerResolverInterface.php
+++ b/src/ClassNameLayerResolverInterface.php
@@ -4,15 +4,12 @@
namespace SensioLabs\Deptrac;
+use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName;
+
interface ClassNameLayerResolverInterface
{
/**
* @return string[]
*/
- public function getLayersByClassName(string $className): array;
-
- /**
- * @return string[]
- */
- public function getLayers(): array;
+ public function getLayersByClassName(ClassLikeName $className): array;
}
diff --git a/src/Collector/ClassNameCollector.php b/src/Collector/ClassNameCollector.php
index a8dd1b1b7..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 1 === preg_match($this->getPattern($configuration), $astClassReference->getClassName());
+ return $astClassReference->getClassLikeName()->match($this->getPattern($configuration));
}
/**
diff --git a/src/Collector/ClassNameRegexCollector.php b/src/Collector/ClassNameRegexCollector.php
index 81e6e64d0..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 1 === preg_match($this->getPattern($configuration), $astClassReference->getClassName());
+ 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 ed55fc665..9d3126b74 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,9 @@ private function __construct(array $classesDeps)
$this->classesDeps = $classesDeps;
}
- public function isViolationSkipped(string $classA, string $classB): bool
+ public function isViolationSkipped(ClassLikeName $classLikeNameA, ClassLikeName $classLikeNameB): bool
{
- return isset($this->classesDeps[$classA]) && \in_array($classB, $this->classesDeps[$classA], 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 34f921338..4390b5a48 100644
--- a/src/Dependency/Dependency.php
+++ b/src/Dependency/Dependency.php
@@ -4,29 +4,30 @@
namespace SensioLabs\Deptrac\Dependency;
+use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName;
use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence;
class Dependency implements DependencyInterface
{
- private $classB;
- private $classA;
+ private $classLikeNameB;
+ private $classLikeNameA;
private $fileOccurrence;
- public function __construct(string $classA, string $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(): string
+ public function getClassLikeNameA(): ClassLikeName
{
- return $this->classA;
+ return $this->classLikeNameA;
}
- public function getClassB(): string
+ 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 c39781a19..db5840516 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 getClassLikeNameA(): ClassLikeName;
- public function getClassB(): string;
+ public function getClassLikeNameB(): ClassLikeName;
public function getFileOccurrence(): FileOccurrence;
}
diff --git a/src/Dependency/InheritDependency.php b/src/Dependency/InheritDependency.php
index 63d43d50e..9a2e665d1 100644
--- a/src/Dependency/InheritDependency.php
+++ b/src/Dependency/InheritDependency.php
@@ -5,26 +5,27 @@
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
{
- private $classA;
- private $classB;
+ private $classLikeNameA;
+ private $classLikeNameB;
private $path;
private $originalDependency;
- public function __construct(string $classA, string $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(): string
+ public function getClassLikeNameA(): ClassLikeName
{
- return $this->classA;
+ return $this->classLikeNameA;
}
public function getFileOccurrence(): FileOccurrence
@@ -32,9 +33,9 @@ public function getFileOccurrence(): FileOccurrence
return $this->getOriginalDependency()->getFileOccurrence();
}
- public function getClassB(): string
+ 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 1016fe3b7..80b4cd307 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 = $dependency->getClassLikeNameA()->toString();
+ 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 = $dependency->getClassLikeNameA()->toString();
+ 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 $classLikeName): array
{
- return $this->dependencies[$className] ?? [];
+ return $this->dependencies[$classLikeName->toString()] ?? [];
}
/**
diff --git a/src/DependencyEmitter/BasicDependencyEmitter.php b/src/DependencyEmitter/BasicDependencyEmitter.php
index 81825162a..71bf40067 100644
--- a/src/DependencyEmitter/BasicDependencyEmitter.php
+++ b/src/DependencyEmitter/BasicDependencyEmitter.php
@@ -28,8 +28,8 @@ public function applyDependencies(AstMap $astMap, Result $dependencyResult): voi
foreach ($dependencies as $emittedDependency) {
$dependencyResult->addDependency(
new Dependency(
- $astClassReference->getClassName(),
- $emittedDependency->getClass(),
+ $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 19cc46960..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[$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/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/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 cd0c0af73..1afb53fd5 100644
--- a/tests/AstRunner/AstMapFlattenGeneratorTest.php
+++ b/tests/AstRunner/AstMapFlattenGeneratorTest.php
@@ -6,11 +6,13 @@
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;
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;
@@ -41,7 +43,8 @@ private function getAstMap(string $fixture): AstMap
new EventDispatcher(),
new NikicPhpParser(
new FileParser(ParserFactory::createParser()),
- new AstFileReferenceInMemoryCache()
+ new AstFileReferenceInMemoryCache(),
+ new TypeResolver()
)
);
@@ -53,7 +56,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::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 e01faf199..890514166 100644
--- a/tests/AstRunner/AstMapGeneratorTest.php
+++ b/tests/AstRunner/AstMapGeneratorTest.php
@@ -6,11 +6,13 @@
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;
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;
@@ -31,7 +33,8 @@ private function getAstMap(string $fixture): AstMap
new EventDispatcher(),
new NikicPhpParser(
new FileParser(ParserFactory::createParser()),
- new AstFileReferenceInMemoryCache()
+ new AstFileReferenceInMemoryCache(),
+ new TypeResolver()
)
);
@@ -49,7 +52,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()
+ $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyClassB::class)))
);
static::assertArrayValuesEquals(
@@ -57,7 +60,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()
+ $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyClassC::class)))
);
}
@@ -67,17 +70,17 @@ public function testBasicTraitsClass(): void
static::assertArrayValuesEquals(
[],
- $astMap->getClassReferenceByClassName(BasicDependencyTraitA::class)->getInherits()
+ $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitA::class)))
);
static::assertArrayValuesEquals(
[],
- $astMap->getClassReferenceByClassName(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(BasicDependencyTraitC::class)->getInherits()
+ $this->getInheritsAsString($astMap->getClassReferenceByClassName(ClassLikeName::fromFQCN(BasicDependencyTraitC::class)))
);
static::assertArrayValuesEquals(
@@ -85,12 +88,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(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(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/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/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..938158cf1 100644
--- a/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php
+++ b/tests/AstRunner/Resolver/AnnotationDependencyResolverTest.php
@@ -10,16 +10,19 @@
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
{
public function testPropertyDependencyResolving(): void
{
+ $typeResolver = new TypeResolver();
$parser = new NikicPhpParser(
new FileParser(ParserFactory::createParser()),
new AstFileReferenceInMemoryCache(),
- new AnnotationDependencyResolver()
+ new TypeResolver(),
+ new AnnotationDependencyResolver($typeResolver)
);
$filePath = __DIR__.'/fixtures/AnnotationDependency.php';
@@ -34,7 +37,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild',
- $annotationDependency[0]->getClass()
+ $annotationDependency[0]->getClassLikeName()->toString()
);
static::assertSame($filePath, $annotationDependency[0]->getFileOccurrence()->getFilenpath());
static::assertSame(9, $annotationDependency[0]->getFileOccurrence()->getLine());
@@ -42,7 +45,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild',
- $annotationDependency[1]->getClass()
+ $annotationDependency[1]->getClassLikeName()->toString()
);
static::assertSame($filePath, $annotationDependency[1]->getFileOccurrence()->getFilenpath());
static::assertSame(23, $annotationDependency[1]->getFileOccurrence()->getLine());
@@ -50,7 +53,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild',
- $annotationDependency[2]->getClass()
+ $annotationDependency[2]->getClassLikeName()->toString()
);
static::assertSame($filePath, $annotationDependency[2]->getFileOccurrence()->getFilenpath());
static::assertSame(26, $annotationDependency[2]->getFileOccurrence()->getLine());
@@ -58,7 +61,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Symfony\Component\Console\Exception\RuntimeException',
- $annotationDependency[3]->getClass()
+ $annotationDependency[3]->getClassLikeName()->toString()
);
static::assertSame($filePath, $annotationDependency[3]->getFileOccurrence()->getFilenpath());
static::assertSame(29, $annotationDependency[3]->getFileOccurrence()->getLine());
@@ -66,7 +69,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Symfony\Component\Finder\SplFileInfo',
- $annotationDependency[4]->getClass()
+ $annotationDependency[4]->getClassLikeName()->toString()
);
static::assertSame($filePath, $annotationDependency[4]->getFileOccurrence()->getFilenpath());
static::assertSame(14, $annotationDependency[4]->getFileOccurrence()->getLine());
@@ -74,7 +77,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\Integration\fixtures\AnnotationDependencyChild',
- $annotationDependency[5]->getClass()
+ $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 a79e286f4..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()
);
@@ -36,7 +38,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\ClassA',
- $dependencies[0]->getClass()
+ $dependencies[0]->getClassLikeName()->toString()
);
static::assertSame($filePath, $dependencies[0]->getFileOccurrence()->getFilenpath());
static::assertSame(19, $dependencies[0]->getFileOccurrence()->getLine());
@@ -44,7 +46,7 @@ public function testPropertyDependencyResolving(): void
static::assertSame(
'Tests\SensioLabs\Deptrac\AstRunner\Resolver\fixtures\InterfaceC',
- $dependencies[1]->getClass()
+ $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 5e0e8a431..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()
);
@@ -34,7 +36,7 @@ public function testPropertyDependencyResolving(): void
$dependencies = $astClassReferences[1]->getDependencies();
static::assertSame(
'Tests\SensioLabs\Deptrac\Integration\fixtures\ClassA',
- $dependencies[0]->getClass()
+ $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 9843b7bd4..d90d82591 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::fromFQCN('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..30dc20bdf 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::fromFQCN('classA'))
);
}
}
diff --git a/tests/Collector/ClassNameCollectorTest.php b/tests/Collector/ClassNameCollectorTest.php
index 0f9e8de28..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($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'],
- $this->prophesize(AstClassReference::class)->reveal(),
+ 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 bde5c8d8b..166684230 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::fromFQCN($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::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 498c1fcd3..13a231d65 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::fromFQCN('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::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 acf5ddeb2..689788e48 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;
@@ -35,16 +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()]);
- $classReference = $this->prophesize(AstClassReference::class);
- $classReference->getClassName()
- ->willReturn(AstInherit::class);
-
$stat = (new InheritanceLevelCollector())->satisfy(
['level' => $levelConfig],
- $classReference->reveal(),
+ 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 1e591f2cb..2ac3de549 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::fromFQCN('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::fromFQCN('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::fromFQCN('foo'));
$parser = $this->createMock(NikicPhpParser::class);
$this->expectException(\LogicException::class);
diff --git a/tests/Configuration/ConfigurationSkippedViolationTest.php b/tests/Configuration/ConfigurationSkippedViolationTest.php
index a95f11f85..af9f72041 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::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()
+ public function testFromArrayWithEmptyArrayAcceptable(): void
{
$configuration = ConfigurationSkippedViolation::fromArray([]);
- $this->assertFalse($configuration->isViolationSkipped('AnyClass', 'AnotherAnyClass'));
+ static::assertFalse($configuration->isViolationSkipped(ClassLikeName::fromFQCN('AnyClass'), ClassLikeName::fromFQCN('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..479847fee 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::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 c6e5b4685..a1b142d2a 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,10 +14,10 @@ class DependencyTest extends TestCase
{
public function testGetSet(): void
{
- $dependency = new Dependency('a', '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 125b914d5..7d3ef2ae3 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,18 +16,21 @@ class InheritDependencyTest extends TestCase
{
public function testGetSet(): void
{
+ $classLikeNameA = ClassLikeName::fromFQCN('a');
+ $classLikeNameB = ClassLikeName::fromFQCN('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)
+ $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 74c4e1837..d0e9ed3e9 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;
@@ -17,10 +18,10 @@
class InheritanceFlatterTest extends TestCase
{
- private function getAstReference($className)
+ private function getAstClassReference($className)
{
$astClass = $this->prophesize(AstClassReference::class);
- $astClass->getClassName()->willReturn($className);
+ $astClass->getClassLikeName()->willReturn(ClassLikeName::fromFQCN($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->getClassLikeNameA()->willReturn(ClassLikeName::fromFQCN($className));
+ $dep->getClassLikeNameB()->willReturn(ClassLikeName::fromFQCN($className.'_b'));
return $dep->reveal();
}
@@ -39,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('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('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('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 90de4acb8..4bb57ad70 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::fromFQCN('A');
+ $classB = ClassLikeName::fromFQCN('B');
+ $classC = ClassLikeName::fromFQCN('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::fromFQCN('A');
+ $classB = ClassLikeName::fromFQCN('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/DependencyEmitter/EmitterTrait.php b/tests/DependencyEmitter/EmitterTrait.php
index 89161c3bd..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();
@@ -29,7 +31,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 f5c16750c..e2c0a5dff 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::fromFQCN('OriginalA');
+ $originalB = ClassLikeName::fromFQCN('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::fromFQCN('ClassA'),
+ ClassLikeName::fromFQCN('ClassB'),
+ new Dependency($originalA, $originalB, new FileOccurrence(new AstFileReference('originalA.php'), 12)),
+ AstInherit::newExtends(ClassLikeName::fromFQCN('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::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',
@@ -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..b9f4ef796 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::fromFQCN('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::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 1b21d77c1..49dd84a4c 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::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(
- '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::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)),
+ 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::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)),
+ 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::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)),
+ 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/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',
diff --git a/tests/RulesetEngineTest.php b/tests/RulesetEngineTest.php
index b847ff7ee..2e31a96a2 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::fromFQCN($from),
+ ClassLikeName::fromFQCN($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::fromFQCN($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::fromFQCN($classInLayer))->willReturn($layers);
}
$configuration = Configuration::fromArray([