diff --git a/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php b/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php index 9b45ba7f8..d3f13a734 100644 --- a/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php +++ b/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php @@ -192,8 +192,20 @@ private function checkParametersTypeHints(\PHP_CodeSniffer_File $phpcsFile, int } } elseif ($this->definitionContainsTraversableTypeHint($phpcsFile, $functionPointer, $parameterTypeHintDefinition)) { $parameterTypeHintDefinitionParts = explode('|', $parameterTypeHintDefinition); - $possibleParameterTypeHint = $this->isTraversableTypeHint(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $parameterTypeHintDefinitionParts[0])) ? $parameterTypeHintDefinitionParts[0] : $parameterTypeHintDefinitionParts[1]; $nullableParameterTypeHint = false; + + if ($this->isTraversableTypeHint(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $parameterTypeHintDefinitionParts[0]))) { + $possibleParameterTypeHint = $parameterTypeHintDefinitionParts[0]; + $itemsTypeHintDefinition = $parameterTypeHintDefinitionParts[1]; + } else { + $possibleParameterTypeHint = $parameterTypeHintDefinitionParts[1]; + $itemsTypeHintDefinition = $parameterTypeHintDefinitionParts[0]; + } + + if (!$this->definitionContainsTraversableTypeHintSpeficication($itemsTypeHintDefinition)) { + return; + } + } else { return; } @@ -398,8 +410,20 @@ private function checkReturnTypeHints(\PHP_CodeSniffer_File $phpcsFile, int $fun } } elseif ($this->definitionContainsTraversableTypeHint($phpcsFile, $functionPointer, $returnTypeHintDefinition)) { $returnTypeHintDefinitionParts = explode('|', $returnTypeHintDefinition); - $possibleReturnTypeHint = $this->isTraversableTypeHint(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $returnTypeHintDefinitionParts[0])) ? $returnTypeHintDefinitionParts[0] : $returnTypeHintDefinitionParts[1]; $nullableReturnTypeHint = false; + + if ($this->isTraversableTypeHint(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $returnTypeHintDefinitionParts[0]))) { + $possibleReturnTypeHint = $returnTypeHintDefinitionParts[0]; + $itemsTypeHintDefinition = $returnTypeHintDefinitionParts[1]; + } else { + $possibleReturnTypeHint = $returnTypeHintDefinitionParts[1]; + $itemsTypeHintDefinition = $returnTypeHintDefinitionParts[0]; + } + + if (!$this->definitionContainsTraversableTypeHintSpeficication($itemsTypeHintDefinition)) { + return; + } + } else { return; } diff --git a/tests/Sniffs/TypeHints/data/typeHintDeclarationNoErrors.php b/tests/Sniffs/TypeHints/data/typeHintDeclarationNoErrors.php index 533b0775f..aa9bd1ba9 100644 --- a/tests/Sniffs/TypeHints/data/typeHintDeclarationNoErrors.php +++ b/tests/Sniffs/TypeHints/data/typeHintDeclarationNoErrors.php @@ -554,4 +554,21 @@ private function nullableMultidimensionalArrayParameter($a) */ abstract public function invalidAnnotations(); + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification + * @param string|array $a + */ + public function mixedContainingTraversable($a) + { + } + + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification + * @return string|array + */ + public function returnsMixedContainingTraversable() + { + return []; + } + }