diff --git a/build/target-repository/composer.json b/build/target-repository/composer.json index 02630bbc841..65314d3d6ee 100644 --- a/build/target-repository/composer.json +++ b/build/target-repository/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": "^7.4|^8.0", - "phpstan/phpstan": "^2.2.6" + "phpstan/phpstan": "^2.2.10" }, "autoload": { "files": [ diff --git a/composer.json b/composer.json index a4ac4f76ad7..7e3ccb6ca15 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "nikic/php-parser": "^5.8", "ondram/ci-detector": "^4.2", "phpstan/phpdoc-parser": "^2.3.3", - "phpstan/phpstan": "^2.2.6", + "phpstan/phpstan": "^2.2.10", "react/child-process": "^0.6.5", "react/event-loop": "^1.6", "react/socket": "^1.17", diff --git a/rules/DeadCode/NodeAnalyzer/CallCollectionAnalyzer.php b/rules/DeadCode/NodeAnalyzer/CallCollectionAnalyzer.php index 44b06b5d5c1..7871693cf6f 100644 --- a/rules/DeadCode/NodeAnalyzer/CallCollectionAnalyzer.php +++ b/rules/DeadCode/NodeAnalyzer/CallCollectionAnalyzer.php @@ -12,6 +12,7 @@ use PhpParser\Node\Name; use PHPStan\Type\MixedType; use PHPStan\Type\NeverType; +use PHPStan\Type\TypeCombinator; use Rector\Enum\ObjectReference; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\NodeTypeResolver; @@ -34,6 +35,11 @@ public function isExists(array $calls, string $classMethodName, string $classNam $callerRoot = $call instanceof StaticCall ? $call->class : $call->var; $callerType = $this->nodeTypeResolver->getType($callerRoot); + // a nullsafe call caller is nullable by design; drop null to resolve the object class + if ($call instanceof NullsafeMethodCall) { + $callerType = TypeCombinator::removeNull($callerType); + } + $callerTypeClassName = ClassNameFromObjectTypeResolver::resolve($callerType); if ($callerTypeClassName === null) { // the caller scope is unreachable, e.g. behind mutual recursion, so the type diff --git a/rules/Php81/NodeManipulator/NullToStrictStringIntConverter.php b/rules/Php81/NodeManipulator/NullToStrictStringIntConverter.php index 390b4a7f695..6a2c3454d66 100644 --- a/rules/Php81/NodeManipulator/NullToStrictStringIntConverter.php +++ b/rules/Php81/NodeManipulator/NullToStrictStringIntConverter.php @@ -17,7 +17,6 @@ use PhpParser\Node\Scalar\Int_; use PhpParser\Node\Scalar\InterpolatedString; use PhpParser\Node\Scalar\String_; -use PHPStan\Analyser\Fiber\FiberScope; use PHPStan\Analyser\Scope; use PHPStan\Reflection\Native\ExtendedNativeParameterReflection; use PHPStan\Reflection\ParametersAcceptor; @@ -247,10 +246,6 @@ private function isAnErrorType(Expr $expr, Type $type, Scope $scope): bool } $parentScope = $scope->getParentScope(); - if ($parentScope instanceof FiberScope) { - $parentScope = $parentScope->toMutatingScope(); - } - if ($parentScope instanceof Scope) { return $parentScope->getType($expr) instanceof ErrorType; } diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index 97a09faf9a3..f05f87dc7e8 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -84,8 +84,8 @@ use PhpParser\Node\Stmt\While_; use PhpParser\Node\UnionType; use PhpParser\NodeTraverser; -use PHPStan\Analyser\Fiber\FiberScope; use PHPStan\Analyser\MutatingScope; +use PHPStan\Analyser\NodeCallbackScope; use PHPStan\Analyser\NodeScopeResolver; use PHPStan\Analyser\ScopeContext; use PHPStan\Analyser\UndefinedVariableException; @@ -157,8 +157,8 @@ public function processNodes( &$nodeCallback, $filePath, ): void { - if ($mutatingScope instanceof FiberScope) { - $mutatingScope = $mutatingScope->toMutatingScope(); + if ($mutatingScope instanceof NodeCallbackScope) { + $mutatingScope = $mutatingScope->toWalkScope(); } // the class reflection is resolved AFTER entering to class node @@ -226,7 +226,6 @@ public function processNodes( $node instanceof Eval_ || $node instanceof Print_ || $node instanceof Exit_ || - $node instanceof ArrowFunction || $node instanceof Include_ || $node instanceof Instanceof_ ) && $node->expr instanceof Expr) { @@ -637,8 +636,13 @@ private function processProperty(Property $property, MutatingScope $mutatingScop private function processBinaryOp(BinaryOp $binaryOp, MutatingScope $mutatingScope): void { - $binaryOp->left->setAttribute(AttributeKey::SCOPE, $mutatingScope); - $binaryOp->right->setAttribute(AttributeKey::SCOPE, $mutatingScope); + if (! $binaryOp->left->getAttribute(AttributeKey::SCOPE) instanceof MutatingScope) { + $binaryOp->left->setAttribute(AttributeKey::SCOPE, $mutatingScope); + } + + if (! $binaryOp->right->getAttribute(AttributeKey::SCOPE) instanceof MutatingScope) { + $binaryOp->right->setAttribute(AttributeKey::SCOPE, $mutatingScope); + } } private function processTernary(Ternary $ternary, MutatingScope $mutatingScope): void