1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Create fake get_class/gettype statements where necessary

This commit is contained in:
Matt Brown 2017-12-13 15:56:05 -05:00
parent 885ccb4fae
commit 4b8c242f5d
2 changed files with 56 additions and 2 deletions

View File

@ -85,7 +85,47 @@ class SwitchChecker
return false;
}
$fake_equality = new PhpParser\Node\Expr\BinaryOp\Equal($stmt->cond, $case->cond);
$switch_condition = $stmt->cond;
if ($switch_condition instanceof PhpParser\Node\Expr\Variable
&& is_string($switch_condition->name)
&& isset($context->vars_in_scope['$' . $switch_condition->name])
) {
$switch_var_type = $context->vars_in_scope['$' . $switch_condition->name];
$type_statements = [];
foreach ($switch_var_type->types as $type) {
if ($type instanceof Type\Atomic\GetClassT) {
$type_statements[] = new PhpParser\Node\Expr\FuncCall(
new PhpParser\Node\Name(['get_class']),
[
new PhpParser\Node\Arg(
new PhpParser\Node\Expr\Variable(substr($type->typeof, 1))
)
]
);
} elseif ($type instanceof Type\Atomic\GetTypeT) {
$type_statements[] = new PhpParser\Node\Expr\FuncCall(
new PhpParser\Node\Name(['gettype']),
[
new PhpParser\Node\Arg(
new PhpParser\Node\Expr\Variable(substr($type->typeof, 1))
)
]
);
} else {
$type_statements = null;
break;
}
}
if ($type_statements && count($type_statements) === 1) {
$switch_condition = $type_statements[0];
}
}
$fake_equality = new PhpParser\Node\Expr\BinaryOp\Equal($switch_condition, $case->cond);
$case_clauses = AlgebraChecker::getFormula(
$fake_equality,

View File

@ -106,9 +106,23 @@ class SwitchTypeTest extends TestCase
$e->getMessage();
break;
}
}',
],
'switchGetClassVar' => [
'<?php
class A {}
class B extends A {
public function foo() : void {}
}
',
function takesA(A $a) : void {
$class = get_class($a);
switch ($class) {
case B::class:
$a->foo();
break;
}
}',
],
'getTypeArg' => [
'<?php