Skip to content

Commit

Permalink
Fix get_class in match expression
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 19, 2023
1 parent e4ef00c commit 106526d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
28 changes: 19 additions & 9 deletions src/Analyser/TypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,7 @@ public function specifyTypesInCondition(
&& isset($exprNode->getArgs()[0])
&& $constantType instanceof ConstantStringType
) {
return $this->specifyTypesInCondition(
$scope,
new Instanceof_(
$exprNode->getArgs()[0]->value,
new Name($constantType->getValue()),
),
$context,
$rootExpr,
);
return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context, $rootExpr);
}
}

Expand Down Expand Up @@ -1118,6 +1110,24 @@ private function specifyTypesForConstantStringBinaryExpression(
}
}

if (
$context->true()
&& $unwrappedExprNode instanceof FuncCall
&& $unwrappedExprNode->name instanceof Name
&& strtolower($unwrappedExprNode->name->toString()) === 'get_class'
&& isset($unwrappedExprNode->getArgs()[0])
) {
return $this->specifyTypesInCondition(
$scope,
new Instanceof_(
$unwrappedExprNode->getArgs()[0]->value,
new Name($constantType->getValue()),
),
$context,
$rootExpr,
)->unionWith($this->create($exprNode, $constantType, $context, false, $scope, $rootExpr));
}

if (
$context->true()
&& $exprNode instanceof FuncCall
Expand Down
8 changes: 4 additions & 4 deletions tests/PHPStan/Analyser/TypeSpecifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ public function dataCondition(): array
]),
new String_('Foo'),
),
['$foo' => 'Foo'],
['$foo' => '~Foo'],
['$foo' => 'Foo', 'get_class($foo)' => '\'Foo\''],
['get_class($foo)' => '~\'Foo\''],
],
[
new Equal(
Expand All @@ -203,8 +203,8 @@ public function dataCondition(): array
new Arg(new Variable('foo')),
]),
),
['$foo' => 'Foo'],
['$foo' => '~Foo'],
['$foo' => 'Foo', 'get_class($foo)' => '\'Foo\''],
['get_class($foo)' => '~\'Foo\''],
],
[
new BooleanNot(
Expand Down
24 changes: 24 additions & 0 deletions tests/PHPStan/Analyser/data/match-expr.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace MatchExpr;

use function get_class;
use function PHPStan\Testing\assertType;

class Foo
Expand Down Expand Up @@ -77,3 +78,26 @@ public function doGettype(int|float|bool|string|object|array $value): void
}

}

final class FinalFoo
{

}

final class FinalBar
{

}

class TestGetClass
{

public function doMatch(FinalFoo|FinalBar $class): void
{
match (get_class($class)) {
FinalFoo::class => assertType(FinalFoo::class, $class),
FinalBar::class => assertType(FinalBar::class, $class),
};
}

}
23 changes: 23 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/match-expr.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,26 @@ function (): string {
-1 => 'down',
};
};

final class FinalFoo
{

}

final class FinalBar
{

}

class TestGetClass
{

public function doMatch(FinalFoo|FinalBar $class): void
{
match (get_class($class)) {
FinalFoo::class => 1,
FinalBar::class => 2,
};
}

}

0 comments on commit 106526d

Please sign in to comment.