diff --git a/SlevomatCodingStandard/Helpers/AnnotationTypeHelper.php b/SlevomatCodingStandard/Helpers/AnnotationTypeHelper.php index 972b47337..c8eeb3c40 100644 --- a/SlevomatCodingStandard/Helpers/AnnotationTypeHelper.php +++ b/SlevomatCodingStandard/Helpers/AnnotationTypeHelper.php @@ -227,6 +227,10 @@ public static function containsItemsSpecificationForTraversable( ); } + if ($typeNode instanceof ThisTypeNode) { + return $inTraversable; + } + if ($typeNode instanceof ConstTypeNode) { return $inTraversable; } diff --git a/tests/Sniffs/TypeHints/ReturnTypeHintSniffTest.php b/tests/Sniffs/TypeHints/ReturnTypeHintSniffTest.php index f44ad418f..01ed5cb4f 100644 --- a/tests/Sniffs/TypeHints/ReturnTypeHintSniffTest.php +++ b/tests/Sniffs/TypeHints/ReturnTypeHintSniffTest.php @@ -240,4 +240,18 @@ public function testWithNullTrueFalseErrors(): void self::assertAllFixedInFile($report); } + public function testWithThisInGenericsNoErrors(): void + { + $report = self::checkFile(__DIR__ . '/data/returnTypeHintWithTraversableNoErrors.php', [ + 'enableObjectTypeHint' => true, + 'enableMixedTypeHint' => true, + 'enableUnionTypeHint' => false, + 'enableIntersectionTypeHint' => false, + 'enableNeverTypeHint' => false, + 'enableStandaloneNullTrueFalseTypeHints' => false, + 'traversableTypeHints' => ['Generic'], + ]); + self::assertNoSniffErrorInFile($report); + } + } diff --git a/tests/Sniffs/TypeHints/data/returnTypeHintWithTraversableNoErrors.php b/tests/Sniffs/TypeHints/data/returnTypeHintWithTraversableNoErrors.php new file mode 100644 index 000000000..2cb0b7b02 --- /dev/null +++ b/tests/Sniffs/TypeHints/data/returnTypeHintWithTraversableNoErrors.php @@ -0,0 +1,51 @@ += 8.0 + +namespace FooNamespace; + +/** + * @template T + * @template U + */ +class Generic +{ +} + +class Bar +{ +} + +class Whatever +{ + + /** + * @return Generic + */ + public function withThisTemplateType(): Generic + { + return new Generic(); + } + + /** + * @return Generic + */ + public function withSelfTemplateType(): Generic + { + return new Generic(); + } + + /** + * @return Generic + */ + public function withStaticTemplateType(): Generic + { + return new Generic(); + } + + /** + * @return Generic<$this, Bar> + */ + public function withThisAsFirstParam(): Generic + { + return new Generic(); + } +}