1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Add support for some dependent types

This commit is contained in:
Matt Brown 2020-11-24 14:50:35 -05:00
parent 27b7de285e
commit 41af653bd4
2 changed files with 67 additions and 0 deletions

View File

@ -472,6 +472,32 @@ class AssignmentAnalyzer
}
}
}
if ($assign_value_type->getId() === 'bool'
&& ($assign_value instanceof PhpParser\Node\Expr\BinaryOp
|| ($assign_value instanceof PhpParser\Node\Expr\BooleanNot
&& $assign_value->expr instanceof PhpParser\Node\Expr\BinaryOp))
) {
$var_object_id = \spl_object_id($assign_var);
$cond_object_id = \spl_object_id($assign_value);
$right_clauses = \Psalm\Internal\Algebra\FormulaGenerator::getFormula(
$cond_object_id,
$cond_object_id,
$assign_value,
$context->self,
$statements_analyzer,
$codebase
);
$assignment_clauses = \Psalm\Internal\Algebra::combineOredClauses(
[new \Psalm\Internal\Clause([$var_id => ['falsy']], $var_object_id, $var_object_id)],
$right_clauses,
$cond_object_id
);
$context->clauses = array_merge($context->clauses, $assignment_clauses);
}
}
} else {
$was_inside_use = $context->inside_use;

View File

@ -1034,6 +1034,24 @@ class TypeAlgebraTest extends \Psalm\Tests\TestCase
return $c;
}'
],
'dependentType' => [
'<?php
class A {
public function isValid() : bool {
return (bool) rand(0, 1);
}
public function foo() : void {}
}
function takesA(?A $a) : void {
$is_valid_a = $a && $a->isValid();
if ($is_valid_a) {
$a->foo();
}
}'
],
];
}
@ -1255,6 +1273,29 @@ class TypeAlgebraTest extends \Psalm\Tests\TestCase
}',
'error_message' => 'RedundantCondition',
],
'dependentTypeInvalidated' => [
'<?php
class A {
public function isValid() : bool {
return (bool) rand(0, 1);
}
public function foo() : void {}
}
function takesA(?A $a) : void {
$is_valid_a = $a && $a->isValid();
if (rand(0, 1)) {
$is_valid_a = false;
}
if ($is_valid_a) {
$a->foo();
}
}',
'error_message' => 'PossiblyNullReference',
],
];
}
}