1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 12:55:26 +01:00

Clone isset type before contradicting

This commit is contained in:
Brown 2020-01-14 18:28:32 -05:00
parent 3fd70a9c88
commit 0f6b61d62d
3 changed files with 49 additions and 10 deletions

View File

@ -777,7 +777,7 @@ class BinaryOpAnalyzer
if ($stmt_left_type = $statements_analyzer->node_data->getType($stmt->left)) { if ($stmt_left_type = $statements_analyzer->node_data->getType($stmt->left)) {
$if_return_type_reconciled = AssertionReconciler::reconcile( $if_return_type_reconciled = AssertionReconciler::reconcile(
'!null', '!null',
$stmt_left_type, clone $stmt_left_type,
'', '',
$statements_analyzer, $statements_analyzer,
$context->inside_loop, $context->inside_loop,
@ -786,7 +786,7 @@ class BinaryOpAnalyzer
$statements_analyzer->getSuppressedIssues() $statements_analyzer->getSuppressedIssues()
); );
$lhs_type = $if_return_type_reconciled; $lhs_type = clone $if_return_type_reconciled;
} }
$stmt_right_type = null; $stmt_right_type = null;

View File

@ -9,6 +9,7 @@ use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer; use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Analyzer\TypeAnalyzer; use Psalm\Internal\Analyzer\TypeAnalyzer;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\ParadoxicalCondition; use Psalm\Issue\ParadoxicalCondition;
use Psalm\Issue\RedundantCondition; use Psalm\Issue\RedundantCondition;
use Psalm\Issue\TypeDoesNotContainType; use Psalm\Issue\TypeDoesNotContainType;
@ -104,14 +105,28 @@ class NegatedAssertionReconciler extends Reconciler
$failed_reconciliation = 2; $failed_reconciliation = 2;
if ($code_location) { if ($code_location) {
if (IssueBuffer::accepts( if ($existing_var_type->from_docblock) {
new TypeDoesNotContainType( if (IssueBuffer::accepts(
'Cannot resolve types for ' . $key . ' and !isset assertion', new DocblockTypeContradiction(
$code_location 'Cannot resolve types for ' . $key . ' with docblock-defined type '
), . $existing_var_type . ' and !isset assertion',
$suppressed_issues $code_location
)) { ),
// fall through $suppressed_issues
)) {
// fall through
}
} else {
if (IssueBuffer::accepts(
new TypeDoesNotContainType(
'Cannot resolve types for ' . $key . ' with type '
. $existing_var_type . ' and !isset assertion',
$code_location
),
$suppressed_issues
)) {
}
} }
} }

View File

@ -742,6 +742,30 @@ class IssetTest extends \Psalm\Tests\TestCase
return "bar"; return "bar";
}', }',
], ],
'issetOnMethodCallInsideFunctionCall' => [
'<?php
class C {
public function foo() : ?string {
return null;
}
}
function foo(C $c) : void {
strlen($c->foo() ?? "");
}'
],
'issetOnMethodCallInsideMethodCall' => [
'<?php
class C {
public function foo() : ?string {
return null;
}
}
function foo(C $c) : void {
new DateTime($c->foo() ?? "");
}'
],
]; ];
} }