From 055fe551c18a33322ef02a9c1f2341452af84b0c Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Sat, 17 Oct 2020 18:35:55 -0400 Subject: [PATCH] Suppress errors from fake statements --- .../Analyzer/Statements/Block/IfAnalyzer.php | 22 +++++++++++++++++++ src/Psalm/Type/Reconciler.php | 19 +++++++++++++--- tests/TypeReconciliation/ConditionalTest.php | 18 ++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php index f39ee1b2821..1f33e9a9d98 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php @@ -1859,6 +1859,18 @@ public static function addConditionallyAssignedVarsToContext( $old_node_data = $statements_analyzer->node_data; $statements_analyzer->node_data = clone $old_node_data; + $suppressed_issues = $statements_analyzer->getSuppressedIssues(); + + if (!in_array('RedundantCondition', $suppressed_issues, true)) { + $statements_analyzer->addSuppressedIssues(['RedundantCondition']); + } + if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, true)) { + $statements_analyzer->addSuppressedIssues(['RedundantConditionGivenDocblockType']); + } + if (!in_array('TypeDoesNotContainType', $suppressed_issues, true)) { + $statements_analyzer->addSuppressedIssues(['TypeDoesNotContainType']); + } + foreach ($exprs as $expr) { $fake_negated_expr = new PhpParser\Node\Expr\FuncCall( new PhpParser\Node\Name\FullyQualified('assert'), @@ -1882,6 +1894,16 @@ public static function addConditionallyAssignedVarsToContext( $mic_drop_context->inside_negation = !$mic_drop_context->inside_negation; } + if (!in_array('RedundantCondition', $suppressed_issues, true)) { + $statements_analyzer->removeSuppressedIssues(['RedundantCondition']); + } + if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, true)) { + $statements_analyzer->removeSuppressedIssues(['RedundantConditionGivenDocblockType']); + } + if (!in_array('TypeDoesNotContainType', $suppressed_issues, true)) { + $statements_analyzer->removeSuppressedIssues(['TypeDoesNotContainType']); + } + $statements_analyzer->node_data = $old_node_data; foreach ($cond_assigned_var_ids as $var_id => $_) { diff --git a/src/Psalm/Type/Reconciler.php b/src/Psalm/Type/Reconciler.php index ad3cd286c96..163e726e180 100644 --- a/src/Psalm/Type/Reconciler.php +++ b/src/Psalm/Type/Reconciler.php @@ -15,6 +15,7 @@ use Psalm\Issue\PsalmInternalError; use Psalm\Issue\RedundantCondition; use Psalm\Issue\RedundantConditionGivenDocblockType; +use Psalm\Issue\TypeDoesNotContainNull; use Psalm\Issue\TypeDoesNotContainType; use Psalm\IssueBuffer; use Psalm\Type; @@ -867,14 +868,26 @@ protected static function triggerIssueForImpossible( // fall through } } else { - if (IssueBuffer::accepts( - new TypeDoesNotContainType( + if ($assertion === 'null') { + $issue = new TypeDoesNotContainNull( 'Type ' . $old_var_type_string . ' for ' . $key . ' is ' . ($never ? 'always ' : 'never ') . $assertion, $code_location, $old_var_type_string . ' ' . $assertion - ), + ); + } else { + $issue = new TypeDoesNotContainType( + 'Type ' . $old_var_type_string + . ' for ' . $key + . ' is ' . ($never ? 'always ' : 'never ') . $assertion, + $code_location, + $old_var_type_string . ' ' . $assertion + ); + } + + if (IssueBuffer::accepts( + $issue, $suppressed_issues )) { // fall through diff --git a/tests/TypeReconciliation/ConditionalTest.php b/tests/TypeReconciliation/ConditionalTest.php index d129a19be69..02cba9cc21f 100644 --- a/tests/TypeReconciliation/ConditionalTest.php +++ b/tests/TypeReconciliation/ConditionalTest.php @@ -258,7 +258,7 @@ function foo($a) { 'assertions' => [ '$b' => 'null', ], - 'error_levels' => ['TypeDoesNotContainType', 'RedundantCondition'], + 'error_levels' => ['TypeDoesNotContainNull', 'RedundantCondition'], ], 'ignoreNullCheckAndMaintainNullableValue' => [ ' [ + 'bar($arr)) { + return; + } + }' + ], ]; }