Skip to content

Commit 1207efc

Browse files
committed
PropertyTypeHintSniff: Fixed false positive
1 parent 7cfcf61 commit 1207efc

File tree

5 files changed

+32
-2
lines changed

5 files changed

+32
-2
lines changed

SlevomatCodingStandard/Sniffs/TypeHints/PropertyTypeHintSniff.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ private function checkTypeHint(
153153
$typeHints[] = AnnotationTypeHelper::getTypeHintFromOneType($typeNode);
154154

155155
} elseif ($typeNode instanceof UnionTypeNode || $typeNode instanceof IntersectionTypeNode) {
156+
$traversableTypeHints = [];
156157
foreach ($typeNode->types as $innerTypeNode) {
157158
if (!AnnotationTypeHelper::containsOneType($innerTypeNode)) {
158159
return;
@@ -161,7 +162,22 @@ private function checkTypeHint(
161162
/** @var ArrayTypeNode|ArrayShapeNode|IdentifierTypeNode|ThisTypeNode|GenericTypeNode|CallableTypeNode $innerTypeNode */
162163
$innerTypeNode = $innerTypeNode;
163164

164-
$typeHints[] = AnnotationTypeHelper::getTypeHintFromOneType($innerTypeNode);
165+
$typeHint = AnnotationTypeHelper::getTypeHintFromOneType($innerTypeNode);
166+
167+
if (
168+
!$innerTypeNode instanceof ArrayTypeNode
169+
&& !$innerTypeNode instanceof ArrayShapeNode
170+
&& TypeHintHelper::isTraversableType(TypeHintHelper::getFullyQualifiedTypeHint($phpcsFile, $propertyPointer, $typeHint), $this->getTraversableTypeHints())
171+
) {
172+
$traversableTypeHints[] = $typeHint;
173+
}
174+
175+
$typeHints[] = $typeHint;
176+
}
177+
178+
$traversableTypeHints = array_values(array_unique($traversableTypeHints));
179+
if (count($traversableTypeHints) > 1) {
180+
return;
165181
}
166182
}
167183

tests/Sniffs/TypeHints/PropertyTypeHintSniffTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function testEnabledNativeErrors(): void
4949
'traversableTypeHints' => ['Traversable'],
5050
]);
5151

52-
self::assertSame(30, $report->getErrorCount());
52+
self::assertSame(31, $report->getErrorCount());
5353

5454
self::assertSniffError($report, 6, PropertyTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT);
5555
self::assertSniffError($report, 11, PropertyTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
@@ -81,6 +81,7 @@ public function testEnabledNativeErrors(): void
8181
self::assertSniffError($report, 111, PropertyTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
8282
self::assertSniffError($report, 114, PropertyTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
8383
self::assertSniffError($report, 117, PropertyTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
84+
self::assertSniffError($report, 122, PropertyTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
8485

8586
self::assertAllFixedInFile($report);
8687
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,9 @@ class Whatever
103103
/** @var ?int */
104104
public ?int $nullable = null;
105105

106+
/**
107+
* @var mixed[]|array
108+
*/
109+
public array $traversableArray;
110+
106111
}

tests/Sniffs/TypeHints/data/propertyTypeHintEnabledNativeErrors.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,9 @@ class Whatever
116116
/** @var ?int */
117117
public $nullable;
118118

119+
/**
120+
* @var mixed[]|array
121+
*/
122+
public $traversableArray;
123+
119124
}

tests/Sniffs/TypeHints/data/propertyTypeHintEnabledNativeNoErrors.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,7 @@ class Whatever
118118
*/
119119
public $unionWithDifferentNullableBase;
120120

121+
/** @var mixed[]|array|Traversable */
122+
public $moreTraverasableTypes;
123+
121124
}

0 commit comments

Comments
 (0)