Skip to content

Commit fbe1290

Browse files
Add a configuration to skip DocBlock Custom Annotations detection (#336) (#337)
1 parent a9e6e0d commit fbe1290

File tree

7 files changed

+68
-4
lines changed

7 files changed

+68
-4
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ return static function (Config $config): void {
123123
->add($mvcClassSet, ...$rules);
124124
};
125125
```
126+
PHPArkitect can detect violations also on DocBlocks custom annotations (like `@Assert\NotBlank` or `@Serializer\Expose`).
127+
If you want to disable this feature you can add this simple configuration:
128+
```php
129+
$config->skipParsingCustomAnnotations();
130+
```
126131

127132
# Available rules
128133

src/Analyzer/FileParserFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010
class FileParserFactory
1111
{
12-
public static function createFileParser(TargetPhpVersion $targetPhpVersion): FileParser
12+
public static function createFileParser(TargetPhpVersion $targetPhpVersion, bool $parseCustomAnnotations = true): FileParser
1313
{
1414
return new FileParser(
1515
new NodeTraverser(),
1616
new FileVisitor(ClassDescriptionBuilder::create()),
17-
new NameResolver(),
17+
new NameResolver(null, ['parseCustomAnnotations' => $parseCustomAnnotations]),
1818
$targetPhpVersion
1919
);
2020
}

src/Analyzer/NameResolver.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class NameResolver extends NodeVisitorAbstract
3131
/** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */
3232
protected $replaceNodes;
3333

34+
/** @var bool Whether to parse DocBlock Custom Annotations */
35+
protected $parseCustomAnnotations;
36+
3437
/**
3538
* Constructs a name resolution visitor.
3639
*
@@ -40,6 +43,7 @@ class NameResolver extends NodeVisitorAbstract
4043
* * replaceNodes (default true): Resolved names are replaced in-place. Otherwise, a
4144
* resolvedName attribute is added. (Names that cannot be statically resolved receive a
4245
* namespacedName attribute, as usual.)
46+
* * parseCustomAnnotations (default true): Whether to parse DocBlock Custom Annotations.
4347
*
4448
* @param ErrorHandler|null $errorHandler Error handler
4549
* @param array $options Options
@@ -49,6 +53,7 @@ public function __construct(ErrorHandler $errorHandler = null, array $options =
4953
$this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing());
5054
$this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false;
5155
$this->replaceNodes = $options['replaceNodes'] ?? true;
56+
$this->parseCustomAnnotations = $options['parseCustomAnnotations'] ?? true;
5257
}
5358

5459
/**
@@ -148,7 +153,7 @@ public function enterNode(Node $node)
148153
break;
149154
}
150155

151-
if (!($node->type instanceof FullyQualified)) {
156+
if ($this->parseCustomAnnotations && !($node->type instanceof FullyQualified)) {
152157
foreach ($phpDocNode->getTags() as $tagValue) {
153158
if ('@' === $tagValue->name[0] && false === strpos($tagValue->name, '@var')) {
154159
$customTag = str_replace('@', '', $tagValue->name);

src/CLI/Config.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ class Config
1313
private $classSetRules;
1414
/** @var bool */
1515
private $runOnlyARule;
16+
/** @var bool */
17+
private $parseCustomAnnotations;
1618

1719
public function __construct()
1820
{
1921
$this->classSetRules = [];
2022
$this->runOnlyARule = false;
23+
$this->parseCustomAnnotations = true;
2124
}
2225

2326
public function add(ClassSet $classSet, ArchRule ...$rules): self
@@ -46,4 +49,16 @@ public function getClassSetRules(): array
4649
{
4750
return $this->classSetRules;
4851
}
52+
53+
public function skipParsingCustomAnnotations(): self
54+
{
55+
$this->parseCustomAnnotations = false;
56+
57+
return $this;
58+
}
59+
60+
public function isParseCustomAnnotationsEnabled(): bool
61+
{
62+
return $this->parseCustomAnnotations;
63+
}
4964
}

src/CLI/Runner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function __construct(bool $stopOnFailure = false)
3131
public function run(Config $config, Progress $progress, TargetPhpVersion $targetPhpVersion): void
3232
{
3333
/** @var FileParser $fileParser */
34-
$fileParser = FileParserFactory::createFileParser($targetPhpVersion);
34+
$fileParser = FileParserFactory::createFileParser($targetPhpVersion, $config->isParseCustomAnnotationsEnabled());
3535

3636
/** @var ClassSetRules $classSetRule */
3737
foreach ($config->getClassSetRules() as $classSetRule) {

tests/Unit/Analyzer/FileVisitorTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,4 +767,34 @@ public function getRequest(): Request //the violations is reported here
767767

768768
$this->assertCount(0, $violations);
769769
}
770+
771+
public function test_it_skip_custom_annotations_in_docblocks_if_the_option_parse_custom_annotation_is_false(): void
772+
{
773+
$code = <<< 'EOF'
774+
<?php
775+
namespace MyProject\AppBundle\Application;
776+
use Symfony\Component\Validator\Constraints as Assert;
777+
class ApplicationLevelDto
778+
{
779+
/**
780+
* @Assert\NotBlank
781+
*/
782+
public $foo;
783+
784+
}
785+
EOF;
786+
787+
/** @var FileParser $fp */
788+
$fp = FileParserFactory::createFileParser(TargetPhpVersion::create('8.1'), false);
789+
$fp->parse($code, 'relativePathName');
790+
791+
$cd = $fp->getClassDescriptions();
792+
793+
$violations = new Violations();
794+
795+
$dependsOnlyOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
796+
$dependsOnlyOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
797+
798+
$this->assertCount(0, $violations);
799+
}
770800
}

tests/Unit/CLI/ConfigTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,13 @@ public function test_it_should_create_config_with_only_one_rule_to_run(): void
5555
$classSetRulesExpected[] = ClassSetRules::create($classSet, ...[$rule2]);
5656
$this->assertEquals($classSetRulesExpected, $config->getClassSetRules());
5757
}
58+
59+
public function test_it_should_allow_to_change_the_default_value_for_parsing_custom_annotations(): void
60+
{
61+
$config = new Config();
62+
$this->assertTrue($config->isParseCustomAnnotationsEnabled());
63+
64+
$config->skipParsingCustomAnnotations();
65+
$this->assertFalse($config->isParseCustomAnnotationsEnabled());
66+
}
5867
}

0 commit comments

Comments
 (0)