diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniff.php index 8f259c97f..17f25b0a1 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniff.php @@ -12,8 +12,10 @@ use SlevomatCodingStandard\Helpers\NamespaceHelper; use SlevomatCodingStandard\Helpers\PhpDocParserHelper; use SlevomatCodingStandard\Helpers\ReferencedName; +use SlevomatCodingStandard\Helpers\SniffSettingsHelper; use SlevomatCodingStandard\Helpers\TypeHelper; use SlevomatCodingStandard\Helpers\TypeHintHelper; +use function in_array; use function sprintf; use function strtolower; use const T_DOC_COMMENT_OPEN_TAG; @@ -23,6 +25,9 @@ class FullyQualifiedClassNameInAnnotationSniff implements Sniff public const CODE_NON_FULLY_QUALIFIED_CLASS_NAME = 'NonFullyQualifiedClassName'; + /** @var list */ + public $ignoredAnnotationNames = []; + /** * @return array */ @@ -40,11 +45,14 @@ public function register(): array public function process(File $phpcsFile, $docCommentOpenPointer): void { $annotations = AnnotationHelper::getAnnotations($phpcsFile, $docCommentOpenPointer); + $this->ignoredAnnotationNames = SniffSettingsHelper::normalizeArray($this->ignoredAnnotationNames); foreach ($annotations as $annotation) { /** @var list $identifierTypeNodes */ $identifierTypeNodes = AnnotationHelper::getAnnotationNodesByType($annotation->getNode(), IdentifierTypeNode::class); + $annotationName = $annotation->getName(); + foreach ($identifierTypeNodes as $typeHintNode) { $typeHint = $typeHintNode->name; @@ -58,6 +66,10 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void continue; } + if (in_array($annotationName, $this->ignoredAnnotationNames, true)) { + continue; + } + $fullyQualifiedTypeHint = TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $docCommentOpenPointer, $typeHint); if ($fullyQualifiedTypeHint === $typeHint) { continue; @@ -66,7 +78,7 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void $fix = $phpcsFile->addFixableError(sprintf( 'Class name %s in %s should be referenced via a fully qualified name.', $fullyQualifiedTypeHint, - $annotation->getName() + $annotationName ), $annotation->getStartPointer(), self::CODE_NON_FULLY_QUALIFIED_CLASS_NAME); if (!$fix) { @@ -120,7 +132,7 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void '%s name %s in %s should be referenced via a fully qualified name.', $isClassConstant ? 'Class' : 'Constant', $fullyQualifiedTypeHint, - $annotation->getName() + $annotationName ), $annotation->getStartPointer(), self::CODE_NON_FULLY_QUALIFIED_CLASS_NAME); if (!$fix) { diff --git a/doc/namespaces.md b/doc/namespaces.md index 6490b000f..3c5d6cd69 100644 --- a/doc/namespaces.md +++ b/doc/namespaces.md @@ -84,6 +84,10 @@ Sniff provides the following settings: Enforces fully qualified names of classes and interfaces in phpDocs - in annotations. This results in unambiguous phpDocs. +Sniff provides the following settings: + +* `ignoredAnnotationNames`: case-sensitive list of annotation names that the sniff should ignore. Useful for custom annotation names like `@apiParam` + #### SlevomatCodingStandard.Namespaces.MultipleUsesPerLine Prohibits multiple uses separated by commas: diff --git a/tests/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniffTest.php b/tests/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniffTest.php index c558d151f..1fec675e7 100644 --- a/tests/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniffTest.php +++ b/tests/Sniffs/Namespaces/FullyQualifiedClassNameInAnnotationSniffTest.php @@ -528,4 +528,13 @@ public function testErrors(): void self::assertAllFixedInFile($report); } + public function testIgnoredAnnotationNames(): void + { + $report = self::checkFile(__DIR__ . '/data/fullyQualifiedClassNameInAnnotationErrors.php', [ + 'ignoredAnnotationNames' => ['@return', '@param', '@var'], + ]); + + self::assertSame(41, $report->getErrorCount()); + } + }