mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
more consistency
This commit is contained in:
parent
7c99878f58
commit
df34daee52
@ -29,7 +29,7 @@ class DoAnalyzer
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
PhpParser\Node\Stmt\Do_ $stmt,
|
||||
Context $context
|
||||
): void {
|
||||
): ?bool {
|
||||
$do_context = clone $context;
|
||||
$do_context->break_types[] = 'loop';
|
||||
$do_context->inside_loop = true;
|
||||
@ -89,20 +89,22 @@ class DoAnalyzer
|
||||
$while_clauses = [new Clause([], $cond_id, $cond_id, true)];
|
||||
}
|
||||
|
||||
LoopAnalyzer::analyze(
|
||||
if (LoopAnalyzer::analyze(
|
||||
$statements_analyzer,
|
||||
$stmt->stmts,
|
||||
[$stmt->cond],
|
||||
WhileAnalyzer::getAndExpressions($stmt->cond),
|
||||
[],
|
||||
$loop_scope,
|
||||
$inner_loop_context,
|
||||
true,
|
||||
true
|
||||
);
|
||||
) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// because it's a do {} while, inner loop vars belong to the main context
|
||||
if (!$inner_loop_context) {
|
||||
throw new \UnexpectedValueException('Should never be null');
|
||||
throw new \UnexpectedValueException('There should be an inner loop context');
|
||||
}
|
||||
|
||||
$negated_while_clauses = Algebra::negateFormula($while_clauses);
|
||||
@ -113,8 +115,6 @@ class DoAnalyzer
|
||||
)
|
||||
);
|
||||
|
||||
//var_dump($do_context->vars_in_scope);
|
||||
|
||||
if ($negated_while_types) {
|
||||
$changed_var_ids = [];
|
||||
|
||||
@ -132,22 +132,6 @@ class DoAnalyzer
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
|
||||
// if there are break statements in the loop it's not certain
|
||||
// that the loop has finished executing, so the assertions at the end
|
||||
// the loop in the while conditional may not hold
|
||||
if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, true)) {
|
||||
if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
|
||||
$context->vars_in_scope[$var_id] = Type::combineUnionTypes(
|
||||
$type,
|
||||
$loop_scope->possibly_defined_loop_parent_vars[$var_id]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$context->vars_in_scope[$var_id] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
$do_context->loop_scope = null;
|
||||
|
||||
$context->vars_possibly_in_scope = array_merge(
|
||||
@ -163,6 +147,8 @@ class DoAnalyzer
|
||||
if ($context->collect_exceptions) {
|
||||
$context->mergeExceptions($inner_loop_context);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function analyzeDoNaively(
|
||||
|
@ -78,14 +78,16 @@ class ForAnalyzer
|
||||
$context->protected_var_ids
|
||||
);
|
||||
|
||||
LoopAnalyzer::analyze(
|
||||
if (LoopAnalyzer::analyze(
|
||||
$statements_analyzer,
|
||||
$stmt->stmts,
|
||||
$stmt->cond,
|
||||
$stmt->loop,
|
||||
$loop_scope,
|
||||
$inner_loop_context
|
||||
);
|
||||
) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$inner_loop_context) {
|
||||
throw new \UnexpectedValueException('There should be an inner loop context');
|
||||
@ -142,7 +144,8 @@ class ForAnalyzer
|
||||
if ($always_enters_loop && $can_leave_loop) {
|
||||
foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
|
||||
// if there are break statements in the loop it's not certain
|
||||
// that the loop has finished executing
|
||||
// that the loop has finished executing, so the assertions at the end
|
||||
// the loop in the while conditional may not hold
|
||||
if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, true)
|
||||
|| in_array(ScopeAnalyzer::ACTION_CONTINUE, $loop_scope->final_actions, true)
|
||||
) {
|
||||
|
@ -309,7 +309,7 @@ class ForeachAnalyzer
|
||||
|
||||
$loop_scope->protected_var_ids = $context->protected_var_ids;
|
||||
|
||||
LoopAnalyzer::analyze(
|
||||
if (LoopAnalyzer::analyze(
|
||||
$statements_analyzer,
|
||||
$stmt->stmts,
|
||||
[],
|
||||
@ -318,7 +318,9 @@ class ForeachAnalyzer
|
||||
$inner_loop_context,
|
||||
false,
|
||||
$always_non_empty_array
|
||||
);
|
||||
) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$inner_loop_context) {
|
||||
throw new \UnexpectedValueException('There should be an inner loop context');
|
||||
|
@ -60,7 +60,7 @@ class WhileAnalyzer
|
||||
}
|
||||
|
||||
if (!$inner_loop_context) {
|
||||
throw new \UnexpectedValueException('Should always enter loop');
|
||||
throw new \UnexpectedValueException('There should be an inner loop context');
|
||||
}
|
||||
|
||||
$always_enters_loop = false;
|
||||
@ -122,7 +122,7 @@ class WhileAnalyzer
|
||||
/**
|
||||
* @return list<PhpParser\Node\Expr>
|
||||
*/
|
||||
private static function getAndExpressions(
|
||||
public static function getAndExpressions(
|
||||
PhpParser\Node\Expr $expr
|
||||
) : array {
|
||||
if ($expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
|
||||
|
@ -509,7 +509,9 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
return false;
|
||||
}
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Do_) {
|
||||
DoAnalyzer::analyze($statements_analyzer, $stmt, $context);
|
||||
if (DoAnalyzer::analyze($statements_analyzer, $stmt, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Const_) {
|
||||
ConstFetchAnalyzer::analyzeConstAssignment($statements_analyzer, $stmt, $context);
|
||||
} elseif ($stmt instanceof PhpParser\Node\Stmt\Unset_) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user