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], [$stmt->cond],
[], [],
$loop_scope, $loop_scope,
$inner_loop_context $inner_loop_context,
true
); );
foreach ($do_context->vars_in_scope as $var_id => $type) { 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 PhpParser\Node\Expr[] $post_expressions
* @param Context $loop_scope->loop_context * @param Context $loop_scope->loop_context
* @param Context $loop_scope->loop_parent_context * @param Context $loop_scope->loop_parent_context
* @param bool $is_do
* *
* @return false|null * @return false|null
*/ */
@ -33,7 +34,8 @@ class LoopChecker
array $pre_conditions, array $pre_conditions,
array $post_expressions, array $post_expressions,
LoopScope $loop_scope, LoopScope $loop_scope,
Context &$inner_context = null Context &$inner_context = null,
$is_do = false
) { ) {
$traverser = new PhpParser\NodeTraverser; $traverser = new PhpParser\NodeTraverser;
@ -86,14 +88,16 @@ class LoopChecker
$inner_context->parent_context = $loop_scope->loop_context; $inner_context->parent_context = $loop_scope->loop_context;
foreach ($pre_conditions as $pre_condition) { if (!$is_do) {
self::applyPreConditionToLoopContext( foreach ($pre_conditions as $pre_condition) {
$statements_checker, self::applyPreConditionToLoopContext(
$pre_condition, $statements_checker,
$pre_condition_clauses, $pre_condition,
$inner_context, $pre_condition_clauses,
$loop_scope->loop_parent_context $inner_context,
); $loop_scope->loop_parent_context
);
}
} }
$inner_context->protected_var_ids = $loop_scope->protected_var_ids; $inner_context->protected_var_ids = $loop_scope->protected_var_ids;
@ -121,17 +125,19 @@ class LoopChecker
IssueBuffer::startRecording(); IssueBuffer::startRecording();
foreach ($pre_conditions as $pre_condition) { if (!$is_do) {
$asserted_var_ids = array_merge( foreach ($pre_conditions as $pre_condition) {
self::applyPreConditionToLoopContext( $asserted_var_ids = array_merge(
$statements_checker, self::applyPreConditionToLoopContext(
$pre_condition, $statements_checker,
$pre_condition_clauses, $pre_condition,
$loop_scope->loop_context, $pre_condition_clauses,
$loop_scope->loop_parent_context $loop_scope->loop_context,
), $loop_scope->loop_parent_context
$asserted_var_ids ),
); $asserted_var_ids
);
}
} }
// record all the vars that existed before we did the first pass through the loop // 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 if ($result_type->getId() !== $before_adjustment
|| $result_type->from_docblock !== $from_docblock || $result_type->from_docblock !== $from_docblock
|| $failed_reconciliation
) { ) {
$changed_var_ids[] = $key; $changed_var_ids[] = $key;
} }

View File

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