Skip to content

Commit 7cfcf61

Browse files
committed
ReturnTypeHintSniff: Fixed false positive
1 parent 85c3791 commit 7cfcf61

File tree

5 files changed

+40
-2
lines changed

5 files changed

+40
-2
lines changed

SlevomatCodingStandard/Sniffs/TypeHints/ReturnTypeHintSniff.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ private function checkFunctionTypeHint(
185185
$typeHints[] = AnnotationTypeHelper::getTypeHintFromOneType($returnTypeNode);
186186

187187
} elseif ($returnTypeNode instanceof UnionTypeNode || $returnTypeNode instanceof IntersectionTypeNode) {
188+
$traversableTypeHints = [];
188189
foreach ($returnTypeNode->types as $typeNode) {
189190
if (!AnnotationTypeHelper::containsOneType($typeNode)) {
190191
return;
@@ -193,7 +194,22 @@ private function checkFunctionTypeHint(
193194
/** @var ArrayTypeNode|ArrayShapeNode|IdentifierTypeNode|ThisTypeNode|GenericTypeNode|CallableTypeNode $typeNode */
194195
$typeNode = $typeNode;
195196

196-
$typeHints[] = AnnotationTypeHelper::getTypeHintFromOneType($typeNode);
197+
$typeHint = AnnotationTypeHelper::getTypeHintFromOneType($typeNode);
198+
199+
if (
200+
!$typeNode instanceof ArrayTypeNode
201+
&& !$typeNode instanceof ArrayShapeNode
202+
&& TypeHintHelper::isTraversableType(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $functionPointer, $typeHint), $this->getTraversableTypeHints())
203+
) {
204+
$traversableTypeHints[] = $typeHint;
205+
}
206+
207+
$typeHints[] = $typeHint;
208+
}
209+
210+
$traversableTypeHints = array_values(array_unique($traversableTypeHints));
211+
if (count($traversableTypeHints) > 1) {
212+
return;
197213
}
198214
}
199215

tests/Sniffs/TypeHints/ReturnTypeHintSniffTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function testErrors(): void
2222
'traversableTypeHints' => ['Traversable'],
2323
]);
2424

25-
self::assertSame(30, $report->getErrorCount());
25+
self::assertSame(31, $report->getErrorCount());
2626

2727
self::assertSniffError($report, 6, ReturnTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT);
2828
self::assertSniffError($report, 14, ReturnTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
@@ -54,6 +54,7 @@ public function testErrors(): void
5454
self::assertSniffError($report, 177, ReturnTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
5555
self::assertSniffError($report, 184, ReturnTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
5656
self::assertSniffError($report, 191, ReturnTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
57+
self::assertSniffError($report, 198, ReturnTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
5758

5859
self::assertAllFixedInFile($report);
5960
}

tests/Sniffs/TypeHints/data/returnTypeHintErrors.fixed.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,11 @@ public function nullable(): ?int
187187
{
188188
}
189189

190+
/**
191+
* @return mixed[]|array
192+
*/
193+
public function traversableArray(): array
194+
{
195+
}
196+
190197
}

tests/Sniffs/TypeHints/data/returnTypeHintErrors.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,11 @@ public function nullable()
192192
{
193193
}
194194

195+
/**
196+
* @return mixed[]|array
197+
*/
198+
public function traversableArray()
199+
{
200+
}
201+
195202
}

tests/Sniffs/TypeHints/data/returnTypeHintNoErrors.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,11 @@ public function unionWithDifferentNullableBase($a)
193193
{
194194
}
195195

196+
/**
197+
* @return mixed[]|array|Traversable
198+
*/
199+
public function moreTraverasableTypes()
200+
{
201+
}
202+
196203
}

0 commit comments

Comments
 (0)