diff --git a/src/Analyzer/ClassDescription.php b/src/Analyzer/ClassDescription.php index d5536f27..f57cdba6 100644 --- a/src/Analyzer/ClassDescription.php +++ b/src/Analyzer/ClassDescription.php @@ -26,7 +26,7 @@ class ClassDescription /** @var bool */ private $abstract; - /** @var string */ + /** @var list */ private $docBlock; /** @var list */ @@ -45,7 +45,7 @@ public function __construct( ?FullyQualifiedClassName $extends, bool $final, bool $abstract, - string $docBlock = '', + array $docBlock = [], array $attributes = [] ) { $this->FQCN = $FQCN; @@ -163,15 +163,17 @@ public function isAbstract(): bool return $this->abstract; } - public function getDocBlock(): string + public function getDocBlock(): array { return $this->docBlock; } public function containsDocBlock(string $search): bool { - if (str_contains($this->docBlock, $search)) { - return true; + foreach ($this->docBlock as $docBlock) { + if (str_contains($docBlock, $search)) { + return true; + } } return false; diff --git a/src/Analyzer/ClassDescriptionBuilder.php b/src/Analyzer/ClassDescriptionBuilder.php index 572a2832..9e052a23 100644 --- a/src/Analyzer/ClassDescriptionBuilder.php +++ b/src/Analyzer/ClassDescriptionBuilder.php @@ -26,7 +26,7 @@ class ClassDescriptionBuilder /** @var bool */ private $abstract; - /** @var string */ + /** @var list */ private $docBlock; /** @var list */ @@ -44,7 +44,7 @@ private function __construct( array $interfaces, bool $final, bool $abstract, - string $docBlock = '', + array $docBlock = [], array $attributes = [] ) { $this->FQCN = $FQCN; @@ -66,7 +66,7 @@ public static function create(string $FQCN): self [], false, false, - '', + [], [] ); } @@ -132,9 +132,9 @@ public function setAbstract(bool $abstract): self return $this; } - public function setDocBlock(string $docBlock): self + public function addDocBlock(string $docBlock): self { - $this->docBlock = $docBlock; + $this->docBlock[] = $docBlock; return $this; } diff --git a/src/Analyzer/FileVisitor.php b/src/Analyzer/FileVisitor.php index 4d432481..8d263a8f 100644 --- a/src/Analyzer/FileVisitor.php +++ b/src/Analyzer/FileVisitor.php @@ -47,12 +47,6 @@ public function enterNode(Node $node): void $this->classDescriptionBuilder->setAbstract(true); } - if (null !== $node->getDocComment()) { - /** @var Doc $docComment */ - $docComment = $node->getDocComment(); - $this->classDescriptionBuilder->setDocBlock($docComment->getText()); - } - foreach ($node->attrGroups as $attributeGroup) { foreach ($attributeGroup->attrs as $attribute) { $this->classDescriptionBuilder @@ -133,6 +127,12 @@ public function enterNode(Node $node): void ); } + if (null !== $this->classDescriptionBuilder && null !== $node->getDocComment()) { + /** @var Doc $docComment */ + $docComment = $node->getDocComment(); + $this->classDescriptionBuilder->addDocBlock($docComment->getText()); + } + /** * matches parameters dependency in functions and method definitions like * public function __construct(Symfony\Component\HttpFoundation\Request $request). diff --git a/tests/Unit/Analyzer/ClassDescriptionBuilderTest.php b/tests/Unit/Analyzer/ClassDescriptionBuilderTest.php index f5b2fcb6..f817e32e 100644 --- a/tests/Unit/Analyzer/ClassDescriptionBuilderTest.php +++ b/tests/Unit/Analyzer/ClassDescriptionBuilderTest.php @@ -86,7 +86,7 @@ public function test_it_should_create_annotated_class(): void { $FQCN = 'HappyIsland'; $classDescriptionBuilder = ClassDescriptionBuilder::create($FQCN); - $classDescriptionBuilder->setDocBlock('/** + $classDescriptionBuilder->addDocBlock('/** * @psalm-immutable */'); @@ -95,9 +95,9 @@ public function test_it_should_create_annotated_class(): void $this->assertInstanceOf(ClassDescription::class, $classDescription); $this->assertEquals( - '/** + ['/** * @psalm-immutable - */', + */'], $classDescription->getDocBlock() ); } diff --git a/tests/Unit/Analyzer/ClassDescriptionTest.php b/tests/Unit/Analyzer/ClassDescriptionTest.php index 12a32725..b37b8498 100644 --- a/tests/Unit/Analyzer/ClassDescriptionTest.php +++ b/tests/Unit/Analyzer/ClassDescriptionTest.php @@ -62,7 +62,7 @@ public function test_should_return_true_if_there_class_is_in_namespace_array(): public function test_should_return_true_if_is_annotated_with(): void { $cd = $this->builder - ->setDocBlock('/** + ->addDocBlock('/** * @psalm-immutable */') ->get(); @@ -73,7 +73,7 @@ public function test_should_return_true_if_is_annotated_with(): void public function test_should_return_false_if_not_annotated_with(): void { $cd = $this->builder - ->setDocBlock('/** + ->addDocBlock('/** * @psalm-immutable */') ->get(); diff --git a/tests/Unit/Analyzer/FileVisitorTest.php b/tests/Unit/Analyzer/FileVisitorTest.php index f349c3d9..733e6432 100644 --- a/tests/Unit/Analyzer/FileVisitorTest.php +++ b/tests/Unit/Analyzer/FileVisitorTest.php @@ -10,6 +10,7 @@ use Arkitect\Analyzer\FullyQualifiedClassName; use Arkitect\CLI\TargetPhpVersion; use Arkitect\Expression\ForClasses\DependsOnlyOnTheseNamespaces; +use Arkitect\Expression\ForClasses\DocBlockNotContains; use Arkitect\Expression\ForClasses\Implement; use Arkitect\Expression\ForClasses\NotHaveDependencyOutsideNamespace; use Arkitect\Rules\ParsingError; @@ -448,4 +449,44 @@ enum Enum $this->assertCount(1, $violations); } + + public function test_it_parse_docblocks(): void + { + $code = <<< 'EOF' +parse($code, 'relativePathName'); + + $cd = $fp->getClassDescriptions(); + + $violations = new Violations(); + + $notHaveDependencyOutsideNamespace = new DocBlockNotContains('ItemNotFound'); + $notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software'); + + $this->assertCount(1, $violations); + + $notHaveDependencyOutsideNamespace = new DocBlockNotContains('Exception'); + $notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software'); + + $this->assertCount(2, $violations); + } } diff --git a/tests/Unit/Expressions/ForClasses/DocBlockContainsTest.php b/tests/Unit/Expressions/ForClasses/DocBlockContainsTest.php index 7e81bc9b..a2f6e337 100644 --- a/tests/Unit/Expressions/ForClasses/DocBlockContainsTest.php +++ b/tests/Unit/Expressions/ForClasses/DocBlockContainsTest.php @@ -23,7 +23,7 @@ public function test_it_should_return_true_if_contains_doc_block(): void null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $because = 'we want to add this rule for our software'; $violations = new Violations(); @@ -47,7 +47,7 @@ public function test_it_should_return_true_if_contains_doc_block_without_because null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $violations = new Violations(); $expression->evaluate($classDescription, $violations, ''); @@ -70,7 +70,7 @@ public function test_it_should_return_false_if_not_contains_doc_block(): void null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $because = 'we want to add this rule for our software'; $violations = new Violations(); diff --git a/tests/Unit/Expressions/ForClasses/DocBlockNotContainsTest.php b/tests/Unit/Expressions/ForClasses/DocBlockNotContainsTest.php index 1e76045d..437dc899 100644 --- a/tests/Unit/Expressions/ForClasses/DocBlockNotContainsTest.php +++ b/tests/Unit/Expressions/ForClasses/DocBlockNotContainsTest.php @@ -23,7 +23,7 @@ public function test_it_should_return_true_if_not_contains_doc_block(): void null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $because = 'we want to add this rule for our software'; $violations = new Violations(); @@ -47,7 +47,7 @@ public function test_it_should_return_false_if_contains_doc_block_without_becaus null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $violations = new Violations(); $expression->evaluate($classDescription, $violations, ''); @@ -70,7 +70,7 @@ public function test_it_should_return_false_if_contains_doc_block(): void null, false, false, - '/** */myDocBlock with other information' + ['/** */myDocBlock with other information'] ); $because = 'we want to add this rule for our software'; $violations = new Violations(); diff --git a/tests/Unit/Expressions/ForClasses/HaveAttributeTest.php b/tests/Unit/Expressions/ForClasses/HaveAttributeTest.php index 1cc15961..077330a6 100644 --- a/tests/Unit/Expressions/ForClasses/HaveAttributeTest.php +++ b/tests/Unit/Expressions/ForClasses/HaveAttributeTest.php @@ -23,7 +23,7 @@ public function test_it_should_return_true_if_contains_doc_block(): void null, false, false, - '', + [], [FullyQualifiedClassName::fromString('myAttribute')] ); $because = 'we want to add this rule for our software'; @@ -48,7 +48,7 @@ public function test_it_should_return_true_if_contains_doc_block_without_because null, false, false, - '', + [], [FullyQualifiedClassName::fromString('myAttribute')] ); $violations = new Violations(); @@ -72,7 +72,7 @@ public function test_it_should_return_false_if_not_contains_doc_block(): void null, false, false, - '', + [], [FullyQualifiedClassName::fromString('myAttribute')] ); $because = 'we want to add this rule for our software';