Skip to content

Commit

Permalink
Avoid false positif for namespaced Xpath
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet authored and ondrejmirtes committed Feb 10, 2021
1 parent b7d6080 commit 4f7ac53
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 12 deletions.
15 changes: 4 additions & 11 deletions src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\MixedType;
use PHPStan\Type\NeverType;
use PHPStan\Type\Type;
Expand Down Expand Up @@ -37,26 +36,20 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method

$xmlElement = new \SimpleXMLElement('<foo />');

$result = null;
foreach (TypeUtils::getConstantStrings($argType) as $constantString) {
$newResult = @$xmlElement->xpath($constantString->getValue());

if ($result !== null && gettype($result) !== gettype($newResult)) {
$result = @$xmlElement->xpath($constantString->getValue());
if ($result === false) {
// We can't be sure since it's maybe a namespaced xpath
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
}

$result = $newResult;
$argType = TypeCombinator::remove($argType, $constantString);
}

if ($result === null || !$argType instanceof NeverType) {
if (!$argType instanceof NeverType) {
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
}

if ($result === false) {
return new ConstantBooleanType(false);
}

return new ArrayType(new MixedType(), $scope->getType($methodCall->var));
}

Expand Down
6 changes: 5 additions & 1 deletion tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3231,13 +3231,17 @@ public function dataBinaryOperations(): array
'$simpleXMLRightXpath',
],
[
'false',
'array<SimpleXMLElement>|false',
'$simpleXMLWrongXpath',
],
[
'array<SimpleXMLElement>|false',
'$simpleXMLUnknownXpath',
],
[
'array<SimpleXMLElement>|false',
'$namespacedXpath',
],
];
}

Expand Down
4 changes: 4 additions & 0 deletions tests/PHPStan/Analyser/data/binary.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ public function doFoo(array $generalArray)
$simpleXMLWrongXpath = $simpleXML->xpath('[foo]');
$simpleXMLUnknownXpath = $simpleXML->xpath($stringForXpath);

$namespacedXML = new \SimpleXMLElement('<a><b><c/></b></a>');
$namespacedXML->registerXPathNamespace('ns', 'namespace');
$namespacedXpath = $namespacedXML->xpath('/ns:node');

if (rand(0, 1)) {
$maybeDefinedVariable = 'foo';
}
Expand Down

0 comments on commit 4f7ac53

Please sign in to comment.