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

Fix #486 - skip first reconciliation in loop checker for do stmts

This commit is contained in:
Matt Brown 2018-02-06 11:07:27 -05:00
parent beb4993736
commit d88eadbb0e
4 changed files with 35 additions and 21 deletions

View File

@ -121,7 +121,8 @@ class DoChecker
[$stmt->cond],
[],
$loop_scope,
$inner_loop_context
$inner_loop_context,
true
);
foreach ($do_context->vars_in_scope as $var_id => $type) {

View File

@ -24,6 +24,7 @@ class LoopChecker
* @param PhpParser\Node\Expr[] $post_expressions
* @param Context $loop_scope->loop_context
* @param Context $loop_scope->loop_parent_context
* @param bool $is_do
*
* @return false|null
*/
@ -33,7 +34,8 @@ class LoopChecker
array $pre_conditions,
array $post_expressions,
LoopScope $loop_scope,
Context &$inner_context = null
Context &$inner_context = null,
$is_do = false
) {
$traverser = new PhpParser\NodeTraverser;
@ -86,14 +88,16 @@ class LoopChecker
$inner_context->parent_context = $loop_scope->loop_context;
foreach ($pre_conditions as $pre_condition) {
self::applyPreConditionToLoopContext(
$statements_checker,
$pre_condition,
$pre_condition_clauses,
$inner_context,
$loop_scope->loop_parent_context
);
if (!$is_do) {
foreach ($pre_conditions as $pre_condition) {
self::applyPreConditionToLoopContext(
$statements_checker,
$pre_condition,
$pre_condition_clauses,
$inner_context,
$loop_scope->loop_parent_context
);
}
}
$inner_context->protected_var_ids = $loop_scope->protected_var_ids;
@ -121,17 +125,19 @@ class LoopChecker
IssueBuffer::startRecording();
foreach ($pre_conditions as $pre_condition) {
$asserted_var_ids = array_merge(
self::applyPreConditionToLoopContext(
$statements_checker,
$pre_condition,
$pre_condition_clauses,
$loop_scope->loop_context,
$loop_scope->loop_parent_context
),
$asserted_var_ids
);
if (!$is_do) {
foreach ($pre_conditions as $pre_condition) {
$asserted_var_ids = array_merge(
self::applyPreConditionToLoopContext(
$statements_checker,
$pre_condition,
$pre_condition_clauses,
$loop_scope->loop_context,
$loop_scope->loop_parent_context
),
$asserted_var_ids
);
}
}
// record all the vars that existed before we did the first pass through the loop

View File

@ -126,6 +126,7 @@ class Reconciler
if ($result_type->getId() !== $before_adjustment
|| $result_type->from_docblock !== $from_docblock
|| $failed_reconciliation
) {
$changed_var_ids[] = $key;
}

View File

@ -866,6 +866,12 @@ class LoopScopeTest extends TestCase
'$a' => 'null',
],
],
'doWhileFirstGood' => [
'<?php
do {
$done = rand(0, 1) > 0;
} while (!$done);'
],
];
}