1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-02 09:37:59 +01:00

Fix #371 - improve handling of do statements broken in loop refactor

This commit is contained in:
Matt Brown 2017-12-05 11:05:10 -05:00
parent a8a1489a8f
commit 98085b2267
3 changed files with 18 additions and 2 deletions

View File

@ -32,7 +32,8 @@ class LoopChecker
array $stmts, array $stmts,
array $pre_conditions, array $pre_conditions,
array $post_conditions, array $post_conditions,
LoopScope $loop_scope LoopScope $loop_scope,
Context &$inner_context = null
) { ) {
$traverser = new PhpParser\NodeTraverser; $traverser = new PhpParser\NodeTraverser;

View File

@ -677,7 +677,7 @@ class StatementsChecker extends SourceChecker implements StatementsSource
{ {
$do_context = clone $context; $do_context = clone $context;
LoopChecker::analyze($this, $stmt->stmts, [], [], new LoopScope($do_context, $context)); LoopChecker::analyze($this, $stmt->stmts, [], [], new LoopScope($do_context, $context), $inner_loop_context);
foreach ($context->vars_in_scope as $var => $type) { foreach ($context->vars_in_scope as $var => $type) {
if ($type->isMixed()) { if ($type->isMixed()) {
@ -701,6 +701,15 @@ class StatementsChecker extends SourceChecker implements StatementsSource
} }
} }
// because it's a do {} while, inner loop vars belong to the main context
if ($inner_loop_context) {
foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
if (!isset($context->vars_in_scope[$var_id])) {
$context->vars_in_scope[$var_id] = $type;
}
}
}
$context->vars_possibly_in_scope = array_merge( $context->vars_possibly_in_scope = array_merge(
$context->vars_possibly_in_scope, $context->vars_possibly_in_scope,
$do_context->vars_possibly_in_scope $do_context->vars_possibly_in_scope

View File

@ -111,6 +111,12 @@ class LoopScopeTest extends TestCase
'$worked' => 'bool', '$worked' => 'bool',
], ],
], ],
'doWhileUndefinedVar' => [
'<?php
do {
$result = rand(0,1);
} while (!$result);',
],
'doWhileVarAndBreak' => [ 'doWhileVarAndBreak' => [
'<?php '<?php
/** @return void */ /** @return void */