Skip to content

Commit 2ecc683

Browse files
VincentLangletondrejmirtes
authored andcommitted
Support switch on ::class
1 parent b657d6c commit 2ecc683

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,13 +1682,11 @@ private function findTypeExpressionsFromBinaryOperation(Scope $scope, Node\Expr\
16821682
if (
16831683
$leftType instanceof ConstantScalarType
16841684
&& !$rightExpr instanceof ConstFetch
1685-
&& !$rightExpr instanceof ClassConstFetch
16861685
) {
16871686
return [$binaryOperation->right, $leftType, $rightType];
16881687
} elseif (
16891688
$rightType instanceof ConstantScalarType
16901689
&& !$leftExpr instanceof ConstFetch
1691-
&& !$leftExpr instanceof ClassConstFetch
16921690
) {
16931691
return [$binaryOperation->left, $rightType, $leftType];
16941692
}
@@ -2087,6 +2085,16 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
20872085
) {
20882086
return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context)->setRootExpr($expr);
20892087
}
2088+
2089+
if (
2090+
$context->true()
2091+
&& $exprNode instanceof ClassConstFetch
2092+
&& $exprNode->name instanceof Node\Identifier
2093+
&& strtolower($exprNode->name->toString()) === 'class'
2094+
&& $constantType->isString()->yes()
2095+
) {
2096+
return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context)->setRootExpr($expr);
2097+
}
20902098
}
20912099

20922100
$leftType = $scope->getType($expr->left);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Bug13069;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
interface ResourceInterface {}
8+
9+
class Person implements ResourceInterface
10+
{
11+
public function getName(): string { return 'Name'; }
12+
}
13+
14+
class Account implements ResourceInterface
15+
{
16+
public function getMail(): string { return 'Mail'; }
17+
}
18+
19+
function foo(?ResourceInterface $object = null): void
20+
{
21+
switch ($object::class) {
22+
case Person::class:
23+
assertType(Person::class, $object);
24+
echo $object->getName();
25+
break;
26+
case Account::class:
27+
assertType(Account::class, $object);
28+
echo $object->getMail();
29+
break;
30+
}
31+
}

0 commit comments

Comments
 (0)