Skip to content

Commit a5aea3c

Browse files
Rename and use RuleLevelHelper
1 parent 154bb87 commit a5aea3c

File tree

7 files changed

+186
-17
lines changed

7 files changed

+186
-17
lines changed

conf/config.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ parameters:
6565
reportStaticMethodSignatures: false
6666
reportWrongPhpDocTypeInVarTag: false
6767
reportAnyTypeWideningInVarTag: false
68-
reportCastedArrayKey: false
68+
reportArrayKeyCast: false
6969
reportPossiblyNonexistentGeneralArrayOffset: false
7070
reportPossiblyNonexistentConstantArrayOffset: false
7171
checkMissingOverrideMethodAttribute: false

conf/parametersSchema.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ parametersSchema:
7575
reportStaticMethodSignatures: bool()
7676
reportWrongPhpDocTypeInVarTag: bool()
7777
reportAnyTypeWideningInVarTag: bool()
78-
reportCastedArrayKey: bool()
78+
reportArrayKeyCast: bool()
7979
reportPossiblyNonexistentGeneralArrayOffset: bool()
8080
reportPossiblyNonexistentConstantArrayOffset: bool()
8181
checkMissingOverrideMethodAttribute: bool()

src/Rules/Arrays/InvalidKeyInArrayDimFetchRule.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct(
2727
#[AutowiredParameter]
2828
private bool $reportMaybes,
2929
#[AutowiredParameter]
30-
private bool $reportCastedArrayKey,
30+
private bool $reportArrayKeyCast,
3131
)
3232
{
3333
}
@@ -43,24 +43,28 @@ public function processNode(Node $node, Scope $scope): array
4343
return [];
4444
}
4545

46-
$dimensionType = $scope->getType($node->dim);
47-
if ($dimensionType instanceof MixedType) {
48-
return [];
49-
}
50-
51-
$reportCastedArrayKey = $this->reportCastedArrayKey;
5246
$varType = $this->ruleLevelHelper->findTypeToCheck(
5347
$scope,
5448
$node->var,
5549
'',
56-
static fn (Type $varType): bool => $varType->isArray()->no() || AllowedArrayKeysTypes::getType($reportCastedArrayKey)->isSuperTypeOf($dimensionType)->yes(),
50+
static fn (Type $varType): bool => $varType->isArray()->no(),
5751
)->getType();
58-
5952
if ($varType instanceof ErrorType || $varType->isArray()->no()) {
6053
return [];
6154
}
6255

63-
$isSuperType = AllowedArrayKeysTypes::getType($this->reportCastedArrayKey)->isSuperTypeOf($dimensionType);
56+
$reportArrayKeyCast = $this->reportArrayKeyCast;
57+
$dimensionType = $this->ruleLevelHelper->findTypeToCheck(
58+
$scope,
59+
$node->dim,
60+
'',
61+
static fn (Type $dimType): bool => AllowedArrayKeysTypes::getType($reportArrayKeyCast)->isSuperTypeOf($dimType)->yes(),
62+
)->getType();
63+
if ($dimensionType instanceof MixedType) {
64+
return [];
65+
}
66+
67+
$isSuperType = AllowedArrayKeysTypes::getType($this->reportArrayKeyCast)->isSuperTypeOf($dimensionType);
6468
if ($isSuperType->yes() || ($isSuperType->maybe() && !$this->reportMaybes)) {
6569
return [];
6670
}

src/Rules/Arrays/InvalidKeyInArrayItemRule.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use PHPStan\DependencyInjection\RegisteredRule;
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
11+
use PHPStan\Rules\RuleLevelHelper;
1112
use PHPStan\Type\MixedType;
13+
use PHPStan\Type\Type;
1214
use PHPStan\Type\VerbosityLevel;
1315
use function sprintf;
1416

@@ -20,10 +22,11 @@ final class InvalidKeyInArrayItemRule implements Rule
2022
{
2123

2224
public function __construct(
25+
private RuleLevelHelper $ruleLevelHelper,
2326
#[AutowiredParameter]
2427
private bool $reportMaybes,
2528
#[AutowiredParameter]
26-
private bool $reportCastedArrayKey,
29+
private bool $reportArrayKeyCast,
2730
)
2831
{
2932
}
@@ -39,8 +42,15 @@ public function processNode(Node $node, Scope $scope): array
3942
return [];
4043
}
4144

42-
$dimensionType = $scope->getType($node->key);
43-
$isSuperType = AllowedArrayKeysTypes::getType($this->reportCastedArrayKey)->isSuperTypeOf($dimensionType);
45+
$reportArrayKeyCast = $this->reportArrayKeyCast;
46+
$dimensionType = $this->ruleLevelHelper->findTypeToCheck(
47+
$scope,
48+
$node->key,
49+
'',
50+
static fn (Type $dimType): bool => AllowedArrayKeysTypes::getType($reportArrayKeyCast)->isSuperTypeOf($dimType)->yes(),
51+
)->getType();
52+
53+
$isSuperType = AllowedArrayKeysTypes::getType($reportArrayKeyCast)->isSuperTypeOf($dimensionType);
4454
if ($isSuperType->no()) {
4555
return [
4656
RuleErrorBuilder::message(

tests/PHPStan/Rules/Arrays/InvalidKeyInArrayDimFetchRuleTest.php

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ class InvalidKeyInArrayDimFetchRuleTest extends RuleTestCase
1515

1616
private bool $reportCastedArrayKey = false;
1717

18+
private bool $checkUnionType = true;
19+
20+
private bool $checkNullable = true;
21+
1822
protected function getRule(): Rule
1923
{
20-
$ruleLevelHelper = new RuleLevelHelper(self::createReflectionProvider(), true, false, true, false, false, false, true);
24+
$ruleLevelHelper = new RuleLevelHelper(self::createReflectionProvider(), $this->checkNullable, false, $this->checkUnionType, false, false, false, true);
2125
return new InvalidKeyInArrayDimFetchRule($ruleLevelHelper, true, $this->reportCastedArrayKey);
2226
}
2327

@@ -63,6 +67,46 @@ public function testInvalidKey(): void
6367
]);
6468
}
6569

70+
public function testInvalidKeyOnLevel6(): void
71+
{
72+
$this->checkNullable = false;
73+
$this->checkUnionType = false;
74+
$this->analyse([__DIR__ . '/data/invalid-key-array-dim-fetch.php'], [
75+
[
76+
'Invalid array key type DateTimeImmutable.',
77+
7,
78+
],
79+
[
80+
'Invalid array key type array.',
81+
8,
82+
],
83+
[
84+
'Invalid array key type DateTimeImmutable.',
85+
31,
86+
],
87+
[
88+
'Invalid array key type DateTimeImmutable.',
89+
45,
90+
],
91+
[
92+
'Invalid array key type DateTimeImmutable.',
93+
46,
94+
],
95+
[
96+
'Invalid array key type DateTimeImmutable.',
97+
47,
98+
],
99+
[
100+
'Invalid array key type stdClass.',
101+
47,
102+
],
103+
[
104+
'Invalid array key type DateTimeImmutable.',
105+
48,
106+
],
107+
]);
108+
}
109+
66110
public function testInvalidKeyReportingCastedArrayKey(): void
67111
{
68112
$this->reportCastedArrayKey = true;
@@ -126,6 +170,63 @@ public function testInvalidKeyReportingCastedArrayKey(): void
126170
]);
127171
}
128172

173+
public function testInvalidKeyReportingCastedArrayKeyOnLevel6(): void
174+
{
175+
$this->checkNullable = false;
176+
$this->checkUnionType = false;
177+
$this->reportCastedArrayKey = true;
178+
$this->analyse([__DIR__ . '/data/invalid-key-array-dim-fetch.php'], [
179+
[
180+
'Invalid array key type null.',
181+
6,
182+
],
183+
[
184+
'Invalid array key type DateTimeImmutable.',
185+
7,
186+
],
187+
[
188+
'Invalid array key type array.',
189+
8,
190+
],
191+
[
192+
'Invalid array key type float.',
193+
10,
194+
],
195+
[
196+
'Invalid array key type true.',
197+
12,
198+
],
199+
[
200+
'Invalid array key type false.',
201+
13,
202+
],
203+
[
204+
'Invalid array key type DateTimeImmutable.',
205+
31,
206+
],
207+
[
208+
'Invalid array key type DateTimeImmutable.',
209+
45,
210+
],
211+
[
212+
'Invalid array key type DateTimeImmutable.',
213+
46,
214+
],
215+
[
216+
'Invalid array key type DateTimeImmutable.',
217+
47,
218+
],
219+
[
220+
'Invalid array key type stdClass.',
221+
47,
222+
],
223+
[
224+
'Invalid array key type DateTimeImmutable.',
225+
48,
226+
],
227+
]);
228+
}
229+
129230
#[RequiresPhp('>= 8.1')]
130231
public function testBug6315(): void
131232
{

tests/PHPStan/Rules/Arrays/InvalidKeyInArrayItemRuleTest.php

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Rules\Arrays;
44

55
use PHPStan\Rules\Rule;
6+
use PHPStan\Rules\RuleLevelHelper;
67
use PHPStan\Testing\RuleTestCase;
78
use PHPUnit\Framework\Attributes\RequiresPhp;
89

@@ -14,9 +15,14 @@ class InvalidKeyInArrayItemRuleTest extends RuleTestCase
1415

1516
private bool $reportCastedArrayKey = false;
1617

18+
private bool $checkUnionType = true;
19+
20+
private bool $checkNullable = true;
21+
1722
protected function getRule(): Rule
1823
{
19-
return new InvalidKeyInArrayItemRule(true, $this->reportCastedArrayKey);
24+
$ruleLevelHelper = new RuleLevelHelper(self::createReflectionProvider(), $this->checkNullable, false, $this->checkUnionType, false, false, false, true);
25+
return new InvalidKeyInArrayItemRule($ruleLevelHelper, true, $this->reportCastedArrayKey);
2026
}
2127

2228
public function testInvalidKey(): void
@@ -37,6 +43,22 @@ public function testInvalidKey(): void
3743
]);
3844
}
3945

46+
public function testInvalidKeyOnLevel6(): void
47+
{
48+
$this->checkNullable = false;
49+
$this->checkUnionType = false;
50+
$this->analyse([__DIR__ . '/data/invalid-key-array-item.php'], [
51+
[
52+
'Invalid array key type DateTimeImmutable.',
53+
13,
54+
],
55+
[
56+
'Invalid array key type array.',
57+
14,
58+
],
59+
]);
60+
}
61+
4062
public function testInvalidKeyReportingCastedArrayKey(): void
4163
{
4264
$this->reportCastedArrayKey = true;
@@ -57,6 +79,31 @@ public function testInvalidKeyReportingCastedArrayKey(): void
5779
'Possibly invalid array key type stdClass|string.',
5880
15,
5981
],
82+
[
83+
'Possibly invalid array key type string|null.',
84+
22,
85+
],
86+
]);
87+
}
88+
89+
public function testInvalidKeyReportingCastedArrayKeyOnLevel6(): void
90+
{
91+
$this->checkNullable = false;
92+
$this->checkUnionType = false;
93+
$this->reportCastedArrayKey = true;
94+
$this->analyse([__DIR__ . '/data/invalid-key-array-item.php'], [
95+
[
96+
'Invalid array key type null.',
97+
12,
98+
],
99+
[
100+
'Invalid array key type DateTimeImmutable.',
101+
13,
102+
],
103+
[
104+
'Invalid array key type array.',
105+
14,
106+
],
60107
]);
61108
}
62109

tests/PHPStan/Rules/Arrays/data/invalid-key-array-item.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@
1414
[] => 'bbb',
1515
$stringOrObject => 'aaa',
1616
];
17+
18+
/** @var string|null $stringOrNull */
19+
$stringOrNull = doFoo();
20+
21+
$b = [
22+
$stringOrNull => 'aaa',
23+
];

0 commit comments

Comments
 (0)