Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3c99850

Browse files
VincentLangletondrejmirtes
authored andcommitted
Fix ArrayType::hasOffsetValueType
1 parent f23422c commit 3c99850

File tree

8 files changed

+104
-1
lines changed

8 files changed

+104
-1
lines changed

‎src/Type/ArrayType.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
272272
if ($offsetArrayKeyType instanceof ErrorType) {
273273
$allowedArrayKeys = AllowedArrayKeysTypes::getType();
274274
$offsetArrayKeyType = TypeCombinator::intersect($allowedArrayKeys, $offsetType)->toArrayKey();
275+
if ($offsetArrayKeyType instanceof NeverType) {
276+
return TrinaryLogic::createNo();
277+
}
275278
}
276279
$offsetType = $offsetArrayKeyType;
277280

‎src/Type/Constant/ConstantArrayType.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
586586
if ($offsetArrayKeyType instanceof ErrorType) {
587587
$allowedArrayKeys = AllowedArrayKeysTypes::getType();
588588
$offsetArrayKeyType = TypeCombinator::intersect($allowedArrayKeys, $offsetType)->toArrayKey();
589+
if ($offsetArrayKeyType instanceof NeverType) {
590+
return TrinaryLogic::createNo();
591+
}
589592
}
590593

591594
return $this->recursiveHasOffsetValueType($offsetArrayKeyType);

‎tests/PHPStan/Levels/data/arrayOffsetAccess-3.json‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,10 @@
33
"message": "Invalid array key type DateTimeImmutable.",
44
"line": 17,
55
"ignorable": true
6+
},
7+
{
8+
"message": "Offset DateTimeImmutable does not exist on array.",
9+
"line": 17,
10+
"ignorable": true
611
}
7-
]
12+
]

‎tests/PHPStan/Levels/data/arrayOffsetAccess-7.json‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,49 @@
11
[
2+
{
3+
"message": "Offset int|object might not exist on array.",
4+
"line": 19,
5+
"ignorable": true
6+
},
27
{
38
"message": "Possibly invalid array key type int|object.",
49
"line": 19,
510
"ignorable": true
611
},
12+
{
13+
"message": "Offset object|null might not exist on array.",
14+
"line": 20,
15+
"ignorable": true
16+
},
717
{
818
"message": "Possibly invalid array key type object|null.",
919
"line": 20,
1020
"ignorable": true
1121
},
22+
{
23+
"message": "Offset DateTimeImmutable might not exist on array|ArrayAccess.",
24+
"line": 26,
25+
"ignorable": true
26+
},
1227
{
1328
"message": "Possibly invalid array key type DateTimeImmutable.",
1429
"line": 26,
1530
"ignorable": true
1631
},
32+
{
33+
"message": "Offset int|object might not exist on array|ArrayAccess.",
34+
"line": 28,
35+
"ignorable": true
36+
},
1737
{
1838
"message": "Possibly invalid array key type int|object.",
1939
"line": 28,
2040
"ignorable": true
2141
},
42+
{
43+
"message": "Offset object|null might not exist on array|ArrayAccess.",
44+
"line": 29,
45+
"ignorable": true
46+
},
2247
{
2348
"message": "Possibly invalid array key type object|null.",
2449
"line": 29,

‎tests/PHPStan/Levels/data/stringOffsetAccess-3.json‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,10 @@
1818
"message": "Invalid array key type stdClass.",
1919
"line": 59,
2020
"ignorable": true
21+
},
22+
{
23+
"message": "Offset stdClass does not exist on array{baz: 21}|array{foo: 17, bar: 19}.",
24+
"line": 59,
25+
"ignorable": true
2126
}
2227
]

‎tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,10 @@ public function testBugObject(): void
949949
'Offset int|object does not exist on array{baz: 21}|array{foo: 17, bar: 19}.',
950950
12,
951951
],
952+
[
953+
'Offset object does not exist on array<string, int>.',
954+
21,
955+
],
952956
]);
953957
}
954958

‎tests/PHPStan/Type/ArrayTypeTest.php‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,36 @@ public function testResolveTemplateTypes(Type $received, Type $template, array $
269269
);
270270
}
271271

272+
public static function dataHasOffsetValueType(): array
273+
{
274+
return [
275+
[
276+
new ArrayType(new BenevolentUnionType([
277+
new IntegerType(),
278+
new StringType(),
279+
]), new IntegerType()),
280+
new ArrayType(new BenevolentUnionType([
281+
new IntegerType(),
282+
new StringType(),
283+
]), new IntegerType()),
284+
TrinaryLogic::createNo(),
285+
],
286+
];
287+
}
288+
289+
#[DataProvider('dataHasOffsetValueType')]
290+
public function testHasOffsetValueType(
291+
ArrayType $type,
292+
Type $offsetType,
293+
TrinaryLogic $expectedResult,
294+
): void
295+
{
296+
$actualResult = $type->hasOffsetValueType($offsetType);
297+
$this->assertSame(
298+
$expectedResult->describe(),
299+
$actualResult->describe(),
300+
sprintf('%s -> hasOffsetValueType(%s)', $type->describe(VerbosityLevel::precise()), $offsetType->describe(VerbosityLevel::precise())),
301+
);
302+
}
303+
272304
}

‎tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,4 +1044,30 @@ public function testValuesArray(ConstantArrayType $type, ConstantArrayType $expe
10441044
$this->assertSame($expectedType->getNextAutoIndexes(), $actualType->getNextAutoIndexes());
10451045
}
10461046

1047+
public static function dataHasOffsetValueType(): array
1048+
{
1049+
return [
1050+
[
1051+
new ConstantArrayType([new ConstantIntegerType(0)], [new ConstantStringType('a')]),
1052+
new ConstantArrayType([new ConstantIntegerType(0)], [new ConstantStringType('a')]),
1053+
TrinaryLogic::createNo(),
1054+
],
1055+
];
1056+
}
1057+
1058+
#[DataProvider('dataHasOffsetValueType')]
1059+
public function testHasOffsetValueType(
1060+
ConstantArrayType $type,
1061+
Type $offsetType,
1062+
TrinaryLogic $expectedResult,
1063+
): void
1064+
{
1065+
$actualResult = $type->hasOffsetValueType($offsetType);
1066+
$this->assertSame(
1067+
$expectedResult->describe(),
1068+
$actualResult->describe(),
1069+
sprintf('%s -> hasOffsetValueType(%s)', $type->describe(VerbosityLevel::precise()), $offsetType->describe(VerbosityLevel::precise())),
1070+
);
1071+
}
1072+
10471073
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /