Fix incorrect analyzing of array_shift with non-empty-list property#4294
Fix incorrect analyzing of array_shift with non-empty-list property#4294ondrejmirtes merged 12 commits intophpstan:2.1.xfrom
Conversation
|
This pull request has been marked as ready for review. |
ondrejmirtes
left a comment
There was a problem hiding this comment.
- I'm worried that other virtual nodes still not fire for this, like VariableAssignNode.
- This is still not going to work on
$this->foo[$x]for example. This will still have a false positive: https://phpstan.org/r/a6e895c1-0e8e-4e49-8cd9-e7a51655a506
Correct solution in these places is to construct proper $this->processAssignVar call. Which might be a bit complicated to get right but here's the easiest inspiration probably:
phpstan-src/src/Analyser/NodeScopeResolver.php
Lines 5382 to 5397 in 02116b7
| $isArrayPop ? $arrayArgType->popArray() : $arrayArgType->shiftArray(), | ||
| $isArrayPop ? $arrayArgNativeType->popArray() : $arrayArgNativeType->shiftArray(), | ||
| ); | ||
|
|
There was a problem hiding this comment.
I have also tried removing aboves $scope->invalidateExpression($arrayArg)->assignExpression($arrayArg, ...) but this leads to different native vs. phpdoc type results
--- a/src/Analyser/NodeScopeResolver.php
+++ b/src/Analyser/NodeScopeResolver.php
@@ -2659,22 +2659,14 @@ final class NodeScopeResolver
&& count($expr->getArgs()) >= 1
) {
$arrayArg = $expr->getArgs()[0]->value;
-
$arrayArgType = $scope->getType($arrayArg);
- $arrayArgNativeType = $scope->getNativeType($arrayArg);
-
$isArrayPop = $functionReflection->getName() === 'array_pop';
- $scope = $scope->invalidateExpression($arrayArg)->assignExpression(
- $arrayArg,
- $isArrayPop ? $arrayArgType->popArray() : $arrayArgType->shiftArray(),
- $isArrayPop ? $arrayArgNativeType->popArray() : $arrayArgNativeType->shiftArray(),
- );
$scope = $this->processAssignVar(
$scope,
$stmt,
$arrayArg,
- $arrayArg,
+ new TypeExpr($isArrayPop ? $arrayArgType->popArray() : $arrayArgType->shiftArray()),
static function (Node $node, Scope $scope) use ($nodeCallback): void {
if (!$node instanceof PropertyAssignNode && !$node instanceof VariableAssignNode) {There was a problem hiding this comment.
I'm fine with that as a temporary step.
Maybe we can experiment with a new TypeExpr-like class in another PR that would carry $type and $nativeType - two constructor arguments. A bunch of places that currently do new TypeExpr might get better behaviour from that.
There was a problem hiding this comment.
after doing #4294 (comment) we get the same type changes, as I saw with the above suggestion.
so I went ahead and did this simplification in a53b7a9
if you are not fine with it, I can revert the changes (but it does not affect results of tests)
Maybe we can experiment with a new
TypeExpr-like class in another PR that would carry$typeand$nativeType- two constructor arguments
agree 👍
There was a problem hiding this comment.
I don't want this simplification. We'd have to put the code back anyway after we do the "TypeExpr with native type" again. Please revert it.
|
Issue bot jackpot 🎉 Isn't phpstan/phpstan#11846 also fixed? |
I wasn't sure, because the reporter wanted it to dump so we are better but not perfect yet. will add a test |
src/Analyser/NodeScopeResolver.php
Outdated
| $scope, | ||
| $stmt, | ||
| $arrayArg, | ||
| $arrayArg, |
There was a problem hiding this comment.
These arguments would mean that we're doing $foo = $foo; which is weird.
It might not influence anything but $assignedExpr should be new TypeExpr with the thing passed to 2nd parameter of assignExpression. In this case it's $isArrayPop ? $arrayArgType->popArray() : $arrayArgType->shiftArray() (but of course first save it into a variable).
There was a problem hiding this comment.
ok, so it seems you are fine with what I suggested in #4294 (comment) ?
src/Analyser/NodeScopeResolver.php
Outdated
| $scope, | ||
| $stmt, | ||
| $arrayArg, | ||
| $arrayArg, |
There was a problem hiding this comment.
For example here it should be new TypeExpr($arrayType)
51555c7 to
a53b7a9
Compare
ca8bacf to
2f5e06a
Compare
|
Perfect, thank you! |
|
Good job @staabm you're really good to close issues by batch ! |
closes phpstan/phpstan#13438
closes phpstan/phpstan#2888
closes phpstan/phpstan#3387
closes phpstan/phpstan#2560
closes phpstan/phpstan#2457
closes phpstan/phpstan#11846