mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Don’t call reconciliation on empty vars
This commit is contained in:
parent
699d763cc1
commit
ca1a615026
@ -546,17 +546,19 @@ class LoopAnalyzer
|
||||
|
||||
$changed_var_ids = [];
|
||||
|
||||
$pre_condition_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_while_types,
|
||||
$loop_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
true,
|
||||
new CodeLocation($statements_analyzer->getSource(), $pre_condition)
|
||||
);
|
||||
if ($reconcilable_while_types) {
|
||||
$pre_condition_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_while_types,
|
||||
$loop_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
true,
|
||||
new CodeLocation($statements_analyzer->getSource(), $pre_condition)
|
||||
);
|
||||
|
||||
$loop_context->vars_in_scope = $pre_condition_vars_in_scope_reconciled;
|
||||
$loop_context->vars_in_scope = $pre_condition_vars_in_scope_reconciled;
|
||||
}
|
||||
|
||||
foreach ($asserted_var_ids as $var_id) {
|
||||
$loop_context->clauses = Context::filterClauses(
|
||||
|
@ -108,20 +108,23 @@ class BinaryOpAnalyzer
|
||||
|
||||
$changed_var_ids = [];
|
||||
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$left_type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
|
||||
$op_context = clone $context;
|
||||
$op_context->vars_in_scope = $op_vars_in_scope;
|
||||
|
||||
if ($left_type_assertions) {
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$left_type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
|
||||
$op_context->vars_in_scope = $op_vars_in_scope;
|
||||
}
|
||||
|
||||
$op_context->removeReconciledClauses($changed_var_ids);
|
||||
|
||||
@ -216,21 +219,25 @@ class BinaryOpAnalyzer
|
||||
|
||||
$changed_var_ids = [];
|
||||
|
||||
// while in an or, we allow scope to boil over to support
|
||||
// statements of the form if ($x === null || $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$negated_type_assertions,
|
||||
$pre_op_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$pre_op_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
|
||||
$op_context = clone $pre_op_context;
|
||||
|
||||
if ($negated_type_assertions) {
|
||||
// while in an or, we allow scope to boil over to support
|
||||
// statements of the form if ($x === null || $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$negated_type_assertions,
|
||||
$pre_op_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$pre_op_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
$op_context->vars_in_scope = $op_vars_in_scope;
|
||||
}
|
||||
|
||||
$op_context->clauses = $clauses_for_right_analysis;
|
||||
$op_context->vars_in_scope = $op_vars_in_scope;
|
||||
|
||||
|
||||
if ($changed_var_ids) {
|
||||
$op_context->removeReconciledClauses($changed_var_ids);
|
||||
@ -359,17 +366,20 @@ class BinaryOpAnalyzer
|
||||
|
||||
$changed_var_ids = [];
|
||||
|
||||
$t_if_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_if_types,
|
||||
$t_if_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
[],
|
||||
$statements_analyzer,
|
||||
$t_if_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt->left)
|
||||
);
|
||||
if ($reconcilable_if_types) {
|
||||
$t_if_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_if_types,
|
||||
$t_if_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
[],
|
||||
$statements_analyzer,
|
||||
$t_if_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt->left)
|
||||
);
|
||||
|
||||
$t_if_context->vars_in_scope = $t_if_vars_in_scope_reconciled;
|
||||
}
|
||||
|
||||
$t_if_context->vars_in_scope = $t_if_vars_in_scope_reconciled;
|
||||
$t_if_context->inside_isset = true;
|
||||
|
||||
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $t_if_context) === false) {
|
||||
|
@ -421,27 +421,29 @@ class FunctionCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expressio
|
||||
|
||||
$assert_type_assertions = Algebra::getTruthsFromFormula($simplified_clauses);
|
||||
|
||||
$changed_vars = [];
|
||||
if ($assert_type_assertions) {
|
||||
$changed_vars = [];
|
||||
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$assert_type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_vars,
|
||||
[],
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = Reconciler::reconcileKeyedTypes(
|
||||
$assert_type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_vars,
|
||||
[],
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
|
||||
foreach ($changed_vars as $changed_var) {
|
||||
if (isset($op_vars_in_scope[$changed_var])) {
|
||||
$op_vars_in_scope[$changed_var]->from_docblock = true;
|
||||
foreach ($changed_vars as $changed_var) {
|
||||
if (isset($op_vars_in_scope[$changed_var])) {
|
||||
$op_vars_in_scope[$changed_var]->from_docblock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$context->vars_in_scope = $op_vars_in_scope;
|
||||
$context->vars_in_scope = $op_vars_in_scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2245,24 +2245,26 @@ class CallAnalyzer
|
||||
$asserted_keys[$var_id] = true;
|
||||
}
|
||||
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = \Psalm\Type\Reconciler::reconcileKeyedTypes(
|
||||
$type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_vars,
|
||||
$asserted_keys,
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $expr)
|
||||
);
|
||||
if ($type_assertions) {
|
||||
// while in an and, we allow scope to boil over to support
|
||||
// statements of the form if ($x && $x->foo())
|
||||
$op_vars_in_scope = \Psalm\Type\Reconciler::reconcileKeyedTypes(
|
||||
$type_assertions,
|
||||
$context->vars_in_scope,
|
||||
$changed_vars,
|
||||
$asserted_keys,
|
||||
$statements_analyzer,
|
||||
$context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $expr)
|
||||
);
|
||||
|
||||
foreach ($changed_vars as $changed_var) {
|
||||
if (isset($op_vars_in_scope[$changed_var])) {
|
||||
$op_vars_in_scope[$changed_var]->from_docblock = true;
|
||||
foreach ($changed_vars as $changed_var) {
|
||||
if (isset($op_vars_in_scope[$changed_var])) {
|
||||
$op_vars_in_scope[$changed_var]->from_docblock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$context->vars_in_scope = $op_vars_in_scope;
|
||||
$context->vars_in_scope = $op_vars_in_scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,17 +102,20 @@ class TernaryAnalyzer
|
||||
|
||||
$changed_var_ids = [];
|
||||
|
||||
$t_if_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_if_types,
|
||||
$t_if_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$t_if_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt->cond)
|
||||
);
|
||||
if ($reconcilable_if_types) {
|
||||
$t_if_vars_in_scope_reconciled = Reconciler::reconcileKeyedTypes(
|
||||
$reconcilable_if_types,
|
||||
$t_if_context->vars_in_scope,
|
||||
$changed_var_ids,
|
||||
$new_referenced_var_ids,
|
||||
$statements_analyzer,
|
||||
$t_if_context->inside_loop,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt->cond)
|
||||
);
|
||||
|
||||
$t_if_context->vars_in_scope = $t_if_vars_in_scope_reconciled;
|
||||
}
|
||||
|
||||
$t_if_context->vars_in_scope = $t_if_vars_in_scope_reconciled;
|
||||
$t_else_context = clone $context;
|
||||
|
||||
if ($stmt->if) {
|
||||
|
@ -63,6 +63,10 @@ class Reconciler
|
||||
bool $inside_loop = false,
|
||||
CodeLocation $code_location = null
|
||||
) {
|
||||
if (!$new_types) {
|
||||
return $existing_types;
|
||||
}
|
||||
|
||||
$suppressed_issues = $statements_analyzer->getSuppressedIssues();
|
||||
|
||||
foreach ($new_types as $nk => $type) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user