Skip to content

Commit ea9b6c3

Browse files
pepakrizondrejmirtes
authored andcommitted
Support for array access on objects with ArrayAccess interface
1 parent 7addaf1 commit ea9b6c3

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

src/Analyser/Scope.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,11 @@ function (Expr\ArrayItem $item): Type {
631631

632632
if ($node instanceof Expr\ArrayDimFetch && $node->dim !== null) {
633633
$arrayType = $this->getType($node->var);
634-
if ($arrayType instanceof ArrayType) {
635-
return $arrayType->getItemType();
634+
if (
635+
$arrayType->isIterable()->yes()
636+
&& ($arrayType instanceof ArrayType || $arrayType->hasMethod('offsetGet')
637+
)) {
638+
return $arrayType->getIterableValueType();
636639
}
637640
}
638641

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,46 @@ public function testIterable(
32853285
);
32863286
}
32873287

3288+
public function dataArrayAccess(): array
3289+
{
3290+
return [
3291+
[
3292+
'string',
3293+
'$this->returnArrayOfStrings()[0]',
3294+
],
3295+
[
3296+
'string',
3297+
'$this->returnArrayObjectOfStrings()[0]',
3298+
],
3299+
[
3300+
'mixed',
3301+
'$this->returnMixed()[0]',
3302+
],
3303+
[
3304+
'mixed',
3305+
'$this->returnTraversableOnlyStrings()[0]',
3306+
],
3307+
];
3308+
}
3309+
3310+
/**
3311+
* @requires PHP 7.1
3312+
* @dataProvider dataArrayAccess
3313+
* @param string $description
3314+
* @param string $expression
3315+
*/
3316+
public function testArrayAccess(
3317+
string $description,
3318+
string $expression
3319+
)
3320+
{
3321+
$this->assertTypes(
3322+
__DIR__ . '/data/array-accessable.php',
3323+
$description,
3324+
$expression
3325+
);
3326+
}
3327+
32883328
public function dataVoid(): array
32893329
{
32903330
return [
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php // lint >= 7.1
2+
3+
namespace ArrayAccesable;
4+
5+
class Foo
6+
{
7+
8+
public function __construct()
9+
{
10+
die;
11+
}
12+
13+
/**
14+
* @return string[]
15+
*/
16+
public function returnArrayOfStrings(): array
17+
{
18+
}
19+
20+
/**
21+
* @return \ArrayObject|string[]
22+
*/
23+
public function returnArrayObjectOfStrings(): \ArrayObject
24+
{
25+
26+
}
27+
28+
/**
29+
* @return mixed
30+
*/
31+
public function returnMixed()
32+
{
33+
34+
}
35+
36+
/**
37+
* @return \Traversable|string[]
38+
*/
39+
public function returnTraversableOnlyStrings(): \Traversable
40+
{
41+
42+
}
43+
44+
}

0 commit comments

Comments
 (0)