Skip to content

Commit 97288da

Browse files
authored
Bleeding edge - Require generics for Iterator, IteratorAggregate, Generator
1 parent 2512510 commit 97288da

32 files changed

+144
-27
lines changed

conf/bleedingEdge.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ parameters:
1010
internalTag: true
1111
newStaticInAbstractClassStaticMethod: true
1212
checkExtensionsForComparisonOperators: true
13+
checkGenericIterableClasses: true
1314
reportTooWideBool: true
1415
rawMessageInBaseline: true
1516
reportNestedTooWideType: false # tmp

conf/config.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ parameters:
3737
internalTag: false
3838
newStaticInAbstractClassStaticMethod: false
3939
checkExtensionsForComparisonOperators: false
40+
checkGenericIterableClasses: false
4041
reportTooWideBool: false
4142
rawMessageInBaseline: false
4243
reportNestedTooWideType: false

conf/parametersSchema.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ parametersSchema:
3939
internalTag: bool()
4040
newStaticInAbstractClassStaticMethod: bool()
4141
checkExtensionsForComparisonOperators: bool()
42+
checkGenericIterableClasses: bool()
4243
reportTooWideBool: bool()
4344
rawMessageInBaseline: bool()
4445
reportNestedTooWideType: bool()

src/Rules/MissingTypehintCheck.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public function __construct(
5454
private bool $checkMissingCallableSignature,
5555
#[AutowiredParameter(ref: '%featureToggles.skipCheckGenericClasses%')]
5656
private array $skipCheckGenericClasses,
57+
#[AutowiredParameter(ref: '%featureToggles.checkGenericIterableClasses%')]
58+
private bool $checkGenericIterableClasses,
5759
)
5860
{
5961
}
@@ -118,7 +120,13 @@ public function getNonGenericObjectTypesWithGenericClass(Type $type): array
118120
if ($classReflection === null) {
119121
return $type;
120122
}
121-
if (in_array($classReflection->getName(), self::ITERABLE_GENERIC_CLASS_NAMES, true)) {
123+
if (
124+
$classReflection->getName() === Traversable::class // already covered by getIterableTypesWithMissingValueTypehint
125+
|| (
126+
!$this->checkGenericIterableClasses &&
127+
in_array($classReflection->getName(), self::ITERABLE_GENERIC_CLASS_NAMES, true)
128+
)
129+
) {
122130
// checked by getIterableTypesWithMissingValueTypehint() already
123131
return $type;
124132
}

stubs/PDOStatement.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class PDOStatement implements Traversable, IteratorAggregate
2121
public function getColumnMeta(int $column) {}
2222

2323
/**
24-
* @return Iterator
24+
* @return Iterator<mixed, array<int|string, mixed>>
2525
*/
2626
public function getIterator() {}
2727
}

stubs/runtime/ReflectionAttribute.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public function isRepeated(): bool
2222
{
2323
}
2424

25+
/**
26+
* @return array<array-key, mixed>
27+
*/
2528
public function getArguments(): array
2629
{
2730
}

tests/PHPStan/Analyser/nsrt/bug-8886.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ function testPDOStatementGetIterator(): void {
99
$pdo = new PDO('sqlite::memory:');
1010
$stmt = $pdo->query('SELECT 1');
1111

12-
assertType('Iterator', $stmt->getIterator());
12+
assertType('Iterator<mixed, array<int|string, mixed>>', $stmt->getIterator());
1313
}

tests/PHPStan/Rules/Classes/LocalTypeAliasesRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected function getRule(): Rule
2929
['GlobalTypeAlias' => 'int|string'],
3030
self::createReflectionProvider(),
3131
$container->getByType(TypeNodeResolver::class),
32-
new MissingTypehintCheck(true, []),
32+
new MissingTypehintCheck(true, [], true),
3333
new ClassNameCheck(
3434
new ClassCaseSensitivityCheck($reflectionProvider, true),
3535
new ClassForbiddenNameCheck($container),

tests/PHPStan/Rules/Classes/LocalTypeTraitAliasesRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function getRule(): Rule
2828
['GlobalTypeAlias' => 'int|string'],
2929
self::createReflectionProvider(),
3030
$container->getByType(TypeNodeResolver::class),
31-
new MissingTypehintCheck(true, []),
31+
new MissingTypehintCheck(true, [], true),
3232
new ClassNameCheck(
3333
new ClassCaseSensitivityCheck($reflectionProvider, true),
3434
new ClassForbiddenNameCheck($container),

tests/PHPStan/Rules/Classes/LocalTypeTraitUseAliasesRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function getRule(): Rule
2828
['GlobalTypeAlias' => 'int|string'],
2929
self::createReflectionProvider(),
3030
$container->getByType(TypeNodeResolver::class),
31-
new MissingTypehintCheck(true, []),
31+
new MissingTypehintCheck(true, [], true),
3232
new ClassNameCheck(
3333
new ClassCaseSensitivityCheck($reflectionProvider, true),
3434
new ClassForbiddenNameCheck($container),

0 commit comments

Comments
 (0)