diff --git a/src/Type/BenevolentUnionType.php b/src/Type/BenevolentUnionType.php index 65301394ed..6f5756662a 100644 --- a/src/Type/BenevolentUnionType.php +++ b/src/Type/BenevolentUnionType.php @@ -42,4 +42,13 @@ public function isAcceptedBy(Type $acceptingType, bool $strictTypes): TrinaryLog return TrinaryLogic::createNo(); } + /** + * @param callable(Type $type): TrinaryLogic $getResult + * @return TrinaryLogic + */ + protected function unionResults(callable $getResult): TrinaryLogic + { + return TrinaryLogic::maxMin(...array_map($getResult, $this->getTypes())); + } + } diff --git a/src/Type/Php/SimpleXMLElementClassPropertyReflectionExtension.php b/src/Type/Php/SimpleXMLElementClassPropertyReflectionExtension.php index 0b2feb187b..4278a4e2ab 100644 --- a/src/Type/Php/SimpleXMLElementClassPropertyReflectionExtension.php +++ b/src/Type/Php/SimpleXMLElementClassPropertyReflectionExtension.php @@ -6,6 +6,8 @@ use PHPStan\Reflection\Php\SimpleXMLElementProperty; use PHPStan\Reflection\PropertiesClassReflectionExtension; use PHPStan\Reflection\PropertyReflection; +use PHPStan\Type\BenevolentUnionType; +use PHPStan\Type\NullType; use PHPStan\Type\ObjectType; class SimpleXMLElementClassPropertyReflectionExtension implements PropertiesClassReflectionExtension @@ -19,7 +21,7 @@ public function hasProperty(ClassReflection $classReflection, string $propertyNa public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection { - return new SimpleXMLElementProperty($classReflection, new ObjectType('SimpleXMLElement')); + return new SimpleXMLElementProperty($classReflection, new BenevolentUnionType([new ObjectType('SimpleXMLElement'), new NullType()])); } } diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index 2d20b91b6d..938340f5ef 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -620,7 +620,7 @@ public static function __set_state(array $properties): Type * @param callable(Type $type): TrinaryLogic $getResult * @return TrinaryLogic */ - private function unionResults(callable $getResult): TrinaryLogic + protected function unionResults(callable $getResult): TrinaryLogic { return TrinaryLogic::extremeIdentity(...array_map($getResult, $this->types)); } diff --git a/tests/PHPStan/Rules/Classes/data/impossible-instanceof.php b/tests/PHPStan/Rules/Classes/data/impossible-instanceof.php index 0c7716dbd4..3e3bc1f9cb 100644 --- a/tests/PHPStan/Rules/Classes/data/impossible-instanceof.php +++ b/tests/PHPStan/Rules/Classes/data/impossible-instanceof.php @@ -375,3 +375,13 @@ public function doTest($int, $objectWithoutClass, $object, $intOrObject, $string } } } + +class InstanceofBenevolentUnionType +{ + public function doFoo(\SimpleXMLElement $xml) + { + echo $xml->branch1 instanceof \SimpleXMLElement; + echo $xml->branch2->branch3 instanceof \SimpleXMLElement; + } + +}