diff --git a/SlevomatCodingStandard/Sniffs/PHP/RequireExplicitAssertionSniff.php b/SlevomatCodingStandard/Sniffs/PHP/RequireExplicitAssertionSniff.php index 75f53c52e..0fb0ad611 100644 --- a/SlevomatCodingStandard/Sniffs/PHP/RequireExplicitAssertionSniff.php +++ b/SlevomatCodingStandard/Sniffs/PHP/RequireExplicitAssertionSniff.php @@ -105,6 +105,15 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void continue; } + /** @var IdentifierTypeNode|ThisTypeNode|UnionTypeNode $variableAnnotationType */ + $variableAnnotationType = $variableAnnotationType; + + $assertion = $this->createAssert($variableAnnotation->getVariableName(), $variableAnnotationType); + + if ($assertion === null) { + continue; + } + if ($tokens[$codePointer]['code'] === T_VARIABLE) { $pointerAfterVariable = TokenHelper::findNextEffective($phpcsFile, $codePointer + 1); if ($tokens[$pointerAfterVariable]['code'] !== T_EQUAL) { @@ -245,11 +254,6 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void } } - /** @var IdentifierTypeNode|ThisTypeNode|UnionTypeNode $variableAnnotationType */ - $variableAnnotationType = $variableAnnotationType; - - $assertion = $this->createAssert($variableAnnotation->getVariableName(), $variableAnnotationType); - if ( $pointerToAddAssertion < $docCommentClosePointer && array_key_exists($pointerAfterDocComment + 1, $tokens) @@ -265,15 +269,7 @@ public function process(File $phpcsFile, $docCommentOpenPointer): void private function isValidTypeNode(TypeNode $typeNode): bool { - if ($typeNode instanceof ThisTypeNode) { - return true; - } - - if (!$typeNode instanceof IdentifierTypeNode) { - return false; - } - - return !in_array($typeNode->name, ['mixed', 'static'], true); + return $typeNode instanceof ThisTypeNode || $typeNode instanceof IdentifierTypeNode; } private function getNextSemicolonInSameScope(File $phpcsFile, int $scopePointer, int $searchAt): int @@ -297,7 +293,7 @@ private function getNextSemicolonInSameScope(File $phpcsFile, int $scopePointer, /** * @param IdentifierTypeNode|ThisTypeNode|UnionTypeNode|IntersectionTypeNode $typeNode */ - private function createAssert(string $variableName, TypeNode $typeNode): string + private function createAssert(string $variableName, TypeNode $typeNode): ?string { $conditions = []; @@ -310,6 +306,10 @@ private function createAssert(string $variableName, TypeNode $typeNode): string } } + if ($conditions === []) { + return null; + } + $operator = $typeNode instanceof IntersectionTypeNode ? '&&' : '||'; return sprintf('\assert(%s);', implode(sprintf(' %s ', $operator), array_unique($conditions))); @@ -357,6 +357,10 @@ private function createConditions(string $variableName, TypeNode $typeNode): arr ]; } + if (TypeHintHelper::isSimpleUnofficialTypeHints($typeNode->name)) { + return []; + } + return [sprintf('%s instanceof %s', $variableName, $typeNode->name)]; } diff --git a/tests/Sniffs/PHP/data/requireExplicitAssertionNoErrors.php b/tests/Sniffs/PHP/data/requireExplicitAssertionNoErrors.php index c4f385bcb..c8f4ea262 100644 --- a/tests/Sniffs/PHP/data/requireExplicitAssertionNoErrors.php +++ b/tests/Sniffs/PHP/data/requireExplicitAssertionNoErrors.php @@ -51,3 +51,6 @@ function (int $a) { /** @var $m invalid annotation */ $m = 0; + +/** @var class-string $n */ +$n = 'SomeClass';