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

Fix switch handling

This commit is contained in:
Brown 2019-11-25 11:27:53 -05:00
parent 0bcb7863f3
commit 1add42b691
3 changed files with 45 additions and 3 deletions

View File

@ -34,7 +34,7 @@ class PreventFloatAssignmentChecker implements AfterExpressionAnalysisInterface
array &$file_replacements = []
) {
if ($expr instanceof PhpParser\Node\Expr\Assign
&& ($expr_type = $statements_source->getNodeTypeProvider()->getType($expr))
&& ($expr_type = $statements_source->getNodeTypeProvider()->getType($expr->expr))
&& $expr_type->hasFloat()
) {
if (\Psalm\IssueBuffer::accepts(

View File

@ -444,8 +444,6 @@ class SwitchAnalyzer
);
}
$statements_analyzer->node_data = $old_node_data;
if ($switch_scope->negated_clauses) {
$entry_clauses = Algebra::simplifyCNF(
array_merge(
@ -537,6 +535,18 @@ class SwitchAnalyzer
$statements_analyzer->analyze($case_stmts, $case_context);
$traverser = new PhpParser\NodeTraverser;
$traverser->addVisitor(
new \Psalm\Internal\Visitor\TypeMappingVisitor(
$statements_analyzer->node_data,
$old_node_data
)
);
$traverser->traverse([$case]);
$statements_analyzer->node_data = $old_node_data;
/** @var array<string, bool> */
$new_case_assigned_var_ids = $case_context->assigned_var_ids;
$case_context->assigned_var_ids = $pre_assigned_var_ids + $new_case_assigned_var_ids;

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Psalm\Internal\Visitor;
use function array_map;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
class TypeMappingVisitor extends NodeVisitorAbstract
{
private $fake_type_provider;
private $real_type_provider;
public function __construct(
\Psalm\Internal\Provider\NodeDataProvider $fake_type_provider,
\Psalm\Internal\Provider\NodeDataProvider $real_type_provider
) {
$this->fake_type_provider = $fake_type_provider;
$this->real_type_provider = $real_type_provider;
}
public function enterNode(Node $origNode)
{
/** @psalm-suppress ArgumentTypeCoercion */
$node_type = $this->fake_type_provider->getType($origNode);
if ($node_type) {
/** @psalm-suppress ArgumentTypeCoercion */
$this->real_type_provider->setType($origNode, clone $node_type);
}
}
}