From 91543680c598dfbc5db010874aebd538c9ba7af3 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 24 May 2025 11:58:28 +0200 Subject: [PATCH] Support switch on ::class --- src/Analyser/TypeSpecifier.php | 12 +++++++-- tests/PHPStan/Analyser/nsrt/bug-13069.php | 31 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/PHPStan/Analyser/nsrt/bug-13069.php diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 761aa267ae..9a2b558030 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -1656,13 +1656,11 @@ private function findTypeExpressionsFromBinaryOperation(Scope $scope, Node\Expr\ if ( $leftType instanceof ConstantScalarType && !$rightExpr instanceof ConstFetch - && !$rightExpr instanceof ClassConstFetch ) { return [$binaryOperation->right, $leftType, $rightType]; } elseif ( $rightType instanceof ConstantScalarType && !$leftExpr instanceof ConstFetch - && !$leftExpr instanceof ClassConstFetch ) { return [$binaryOperation->left, $rightType, $leftType]; } @@ -2061,6 +2059,16 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif ) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context)->setRootExpr($expr); } + + if ( + $context->true() + && $exprNode instanceof ClassConstFetch + && $exprNode->name instanceof Node\Identifier + && strtolower($exprNode->name->toString()) === 'class' + && $constantType->isString()->yes() + ) { + return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context)->setRootExpr($expr); + } } $leftType = $scope->getType($expr->left); diff --git a/tests/PHPStan/Analyser/nsrt/bug-13069.php b/tests/PHPStan/Analyser/nsrt/bug-13069.php new file mode 100644 index 0000000000..3e0a3f1271 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-13069.php @@ -0,0 +1,31 @@ +getName(); + break; + case Account::class: + assertType(Account::class, $object); + echo $object->getMail(); + break; + } +}