Skip to content

Commit 707f57a

Browse files
committed
Fix SimpleXMLElement issue
1 parent ee4e929 commit 707f57a

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

src/Type/ObjectType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ public function getIterableKeyType(): Type
696696
}
697697
}
698698

699-
if ($this->isInstanceOf(Traversable::class)->yes()) {
699+
if ($this->isInstanceOf(Traversable::class)->yes() && !$this->isExtraOffsetAccessibleClass()->yes()) {
700700
$isTraversable = true;
701701
$tKey = GenericTypeVariableResolver::getType($this, Traversable::class, 'TKey');
702702
if ($tKey !== null) {
@@ -732,7 +732,7 @@ public function getIterableValueType(): Type
732732
}
733733
}
734734

735-
if ($this->isInstanceOf(Traversable::class)->yes()) {
735+
if ($this->isInstanceOf(Traversable::class)->yes() && !$this->isExtraOffsetAccessibleClass()->yes()) {
736736
$isTraversable = true;
737737
$tValue = GenericTypeVariableResolver::getType($this, Traversable::class, 'TValue');
738738
if ($tValue !== null) {

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ public function dataFileAsserts(): iterable
821821
yield from $this->gatherAssertTypes(__DIR__ . '/data/array-search-type-specifying.php');
822822
yield from $this->gatherAssertTypes(__DIR__ . '/data/array-replace.php');
823823
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6889.php');
824+
yield from $this->gatherAssertTypes(__DIR__ . '/data/simplexml.php');
824825
}
825826

826827
/**
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace SimpleXMLIteratorBug;
4+
5+
use SimpleXMLElement;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
11+
public function getAddressByGps()
12+
{
13+
/** @var SimpleXMLElement|null $data */
14+
$data = doFoo();
15+
16+
if ($data === null) {
17+
return;
18+
}
19+
20+
assertType('(SimpleXMLElement|null)', $data->item);
21+
foreach ($data->item as $item) {
22+
assertType('SimpleXMLElement', $item);
23+
assertType('SimpleXMLElement|null', $item['name']);
24+
}
25+
}
26+
27+
}
28+
29+
class Bar extends SimpleXMLElement
30+
{
31+
32+
public function getAddressByGps()
33+
{
34+
/** @var self|null $data */
35+
$data = doFoo();
36+
37+
if ($data === null) {
38+
return;
39+
}
40+
41+
assertType('(SimpleXMLIteratorBug\Bar|null)', $data->item);
42+
foreach ($data->item as $item) {
43+
assertType(self::class, $item);
44+
assertType('SimpleXMLIteratorBug\Bar|null', $item['name']);
45+
}
46+
}
47+
48+
}
49+
50+
class Baz
51+
{
52+
53+
public function getAddressByGps()
54+
{
55+
/** @var Bar|null $data */
56+
$data = doFoo();
57+
58+
if ($data === null) {
59+
return;
60+
}
61+
62+
assertType('(SimpleXMLIteratorBug\Bar|null)', $data->item);
63+
foreach ($data->item as $item) {
64+
assertType(Bar::class, $item);
65+
assertType('SimpleXMLIteratorBug\Bar|null', $item['name']);
66+
}
67+
}
68+
69+
}

0 commit comments

Comments
 (0)