1
0
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:
Brown 2018-12-17 15:23:56 -05:00
parent 699d763cc1
commit ca1a615026
6 changed files with 112 additions and 89 deletions

View File

@ -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(

View File

@ -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) {

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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) {

View File

@ -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) {