From 2d81f7e368e69a8515486190c2bc6020e93aa575 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 24 May 2026 15:34:40 +0200 Subject: [PATCH 1/2] Cleanup `instanceof ConstantStringType` calls --- src/Analyser/TypeSpecifier.php | 66 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index a945627ef6..f9bb5ea449 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -3095,7 +3095,7 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope && in_array(strtolower($unwrappedLeftExpr->name->toString()), ['get_class', 'get_debug_type'], true) && isset($unwrappedLeftExpr->getArgs()[0]) ) { - if ($rightType instanceof ConstantStringType && $this->reflectionProvider->hasClass($rightType->getValue())) { + if (count($rightType->getConstantStrings()) === 1 && $this->reflectionProvider->hasClass($rightType->getValue())) { return $this->create( $unwrappedLeftExpr->getArgs()[0]->value, new ObjectType($rightType->getValue(), classReflection: $this->reflectionProvider->getClass($rightType->getValue())->asFinal()), @@ -3217,26 +3217,27 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope $unwrappedLeftExpr->class instanceof Expr && $unwrappedLeftExpr->name instanceof Node\Identifier && $unwrappedRightExpr instanceof ClassConstFetch && - $rightType instanceof ConstantStringType && - $rightType->getValue() !== '' && strtolower($unwrappedLeftExpr->name->toString()) === 'class' ) { - if ($this->reflectionProvider->hasClass($rightType->getValue())) { - return $this->create( - $unwrappedLeftExpr->class, - new ObjectType($rightType->getValue(), classReflection: $this->reflectionProvider->getClass($rightType->getValue())->asFinal()), - $context, + $constantStrings = $rightType->getConstantStrings(); + if (count($constantStrings) === 1) { + if ($this->reflectionProvider->hasClass($constantStrings[0]->getValue())) { + return $this->create( + $unwrappedLeftExpr->class, + new ObjectType($constantStrings[0]->getValue(), classReflection: $this->reflectionProvider->getClass($constantStrings[0]->getValue())->asFinal()), + $context, + $scope, + )->unionWith($this->create($leftExpr, $rightType, $context, $scope))->setRootExpr($expr); + } + return $this->specifyTypesInCondition( $scope, + new Instanceof_( + $unwrappedLeftExpr->class, + new Name($constantStrings[0]->getValue()), + ), + $context, )->unionWith($this->create($leftExpr, $rightType, $context, $scope))->setRootExpr($expr); } - return $this->specifyTypesInCondition( - $scope, - new Instanceof_( - $unwrappedLeftExpr->class, - new Name($rightType->getValue()), - ), - $context, - )->unionWith($this->create($leftExpr, $rightType, $context, $scope))->setRootExpr($expr); } $leftType = $scope->getType($leftExpr); @@ -3248,27 +3249,28 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope $unwrappedRightExpr->class instanceof Expr && $unwrappedRightExpr->name instanceof Node\Identifier && $unwrappedLeftExpr instanceof ClassConstFetch && - $leftType instanceof ConstantStringType && - $leftType->getValue() !== '' && strtolower($unwrappedRightExpr->name->toString()) === 'class' ) { - if ($this->reflectionProvider->hasClass($leftType->getValue())) { - return $this->create( - $unwrappedRightExpr->class, - new ObjectType($leftType->getValue(), classReflection: $this->reflectionProvider->getClass($leftType->getValue())->asFinal()), - $context, + $constantStrings = $leftType->getConstantStrings(); + if (count($constantStrings) === 1) { + if ($this->reflectionProvider->hasClass($constantStrings[0]->getValue())) { + return $this->create( + $unwrappedRightExpr->class, + new ObjectType($constantStrings[0]->getValue(), classReflection: $this->reflectionProvider->getClass($constantStrings[0]->getValue())->asFinal()), + $context, + $scope, + )->unionWith($this->create($rightExpr, $leftType, $context, $scope)->setRootExpr($expr)); + } + + return $this->specifyTypesInCondition( $scope, + new Instanceof_( + $unwrappedRightExpr->class, + new Name($constantStrings[0]->getValue()), + ), + $context, )->unionWith($this->create($rightExpr, $leftType, $context, $scope)->setRootExpr($expr)); } - - return $this->specifyTypesInCondition( - $scope, - new Instanceof_( - $unwrappedRightExpr->class, - new Name($leftType->getValue()), - ), - $context, - )->unionWith($this->create($rightExpr, $leftType, $context, $scope)->setRootExpr($expr)); } if ($context->false()) { From 1c9043b53c81ab858ca08d30e6051f64927851a5 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 24 May 2026 15:41:52 +0200 Subject: [PATCH 2/2] fix build --- phpstan-baseline.neon | 2 +- src/Analyser/TypeSpecifier.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 8cb0e04e95..b33f771b9c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -117,7 +117,7 @@ parameters: - rawMessage: 'Doing instanceof PHPStan\Type\Constant\ConstantStringType is error-prone and deprecated. Use Type::getConstantStrings() instead.' identifier: phpstanApi.instanceofType - count: 5 + count: 2 path: src/Analyser/TypeSpecifier.php - diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index f9bb5ea449..334b96f68e 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -3095,10 +3095,11 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope && in_array(strtolower($unwrappedLeftExpr->name->toString()), ['get_class', 'get_debug_type'], true) && isset($unwrappedLeftExpr->getArgs()[0]) ) { - if (count($rightType->getConstantStrings()) === 1 && $this->reflectionProvider->hasClass($rightType->getValue())) { + $constantStringTypes = $rightType->getConstantStrings(); + if (count($constantStringTypes) === 1 && $this->reflectionProvider->hasClass($constantStringTypes[0]->getValue())) { return $this->create( $unwrappedLeftExpr->getArgs()[0]->value, - new ObjectType($rightType->getValue(), classReflection: $this->reflectionProvider->getClass($rightType->getValue())->asFinal()), + new ObjectType($constantStringTypes[0]->getValue(), classReflection: $this->reflectionProvider->getClass($constantStringTypes[0]->getValue())->asFinal()), $context, $scope, )->unionWith($this->create($leftExpr, $rightType, $context, $scope))->setRootExpr($expr); @@ -3220,7 +3221,7 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope strtolower($unwrappedLeftExpr->name->toString()) === 'class' ) { $constantStrings = $rightType->getConstantStrings(); - if (count($constantStrings) === 1) { + if (count($constantStrings) === 1 && $constantStrings[0]->getValue() !== '') { if ($this->reflectionProvider->hasClass($constantStrings[0]->getValue())) { return $this->create( $unwrappedLeftExpr->class, @@ -3252,7 +3253,7 @@ private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope strtolower($unwrappedRightExpr->name->toString()) === 'class' ) { $constantStrings = $leftType->getConstantStrings(); - if (count($constantStrings) === 1) { + if (count($constantStrings) === 1 && $constantStrings[0]->getValue() !== '') { if ($this->reflectionProvider->hasClass($constantStrings[0]->getValue())) { return $this->create( $unwrappedRightExpr->class,