mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Remove some logic that didn't need to be there (#9209)
* Remove check to see what breaks * Simplify following logic * Add tests from @kkmuffme‘s branch * Reduce scope of fix * Clean up logic a little * Add failing test * Improvements * Fix for non-Paradoxical Condition result
This commit is contained in:
parent
498cc45e90
commit
d450b40da8
@ -5,11 +5,7 @@ Emitted when a paradox is encountered in your programs logic that could not be c
|
||||
```php
|
||||
<?php
|
||||
|
||||
function foo($a, $b) : void {
|
||||
if ($a && $b) {
|
||||
echo "a";
|
||||
} elseif ($a && $b) {
|
||||
echo "cannot happen";
|
||||
}
|
||||
function foo(string $input) : string {
|
||||
return $input === "a" ? "bar" : ($input === "a" ? "foo" : "b");
|
||||
}
|
||||
```
|
||||
|
@ -373,21 +373,17 @@ class Algebra
|
||||
$things_that_can_be_said = [];
|
||||
|
||||
foreach ($possible_types as $assertion) {
|
||||
if ($assertion instanceof Falsy || !$assertion->isNegation()) {
|
||||
$things_that_can_be_said[(string)$assertion] = $assertion;
|
||||
}
|
||||
$things_that_can_be_said[(string)$assertion] = $assertion;
|
||||
}
|
||||
|
||||
if ($things_that_can_be_said && count($things_that_can_be_said) === count($possible_types)) {
|
||||
if ($clause->generated && count($possible_types) > 1) {
|
||||
unset($cond_referenced_var_ids[$var]);
|
||||
}
|
||||
if ($clause->generated && count($possible_types) > 1) {
|
||||
unset($cond_referenced_var_ids[$var]);
|
||||
}
|
||||
|
||||
$truths[$var] = [array_values($things_that_can_be_said)];
|
||||
$truths[$var] = [array_values($things_that_can_be_said)];
|
||||
|
||||
if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
|
||||
$active_truths[$var] = [array_values($things_that_can_be_said)];
|
||||
}
|
||||
if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
|
||||
$active_truths[$var] = [array_values($things_that_can_be_said)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,6 +272,9 @@ class IfElseAnalyzer
|
||||
// this has to go on a separate line because the phar compactor messes with precedence
|
||||
$scope_to_clone = $if_scope->post_leaving_if_context ?? $post_if_context;
|
||||
$else_context = clone $scope_to_clone;
|
||||
$else_context->clauses = Algebra::simplifyCNF(
|
||||
[...$else_context->clauses, ...$if_scope->negated_clauses],
|
||||
);
|
||||
|
||||
// check the elseifs
|
||||
foreach ($stmt->elseifs as $elseif) {
|
||||
|
@ -151,7 +151,10 @@ class AndAnalyzer
|
||||
$right_context = clone $left_context;
|
||||
}
|
||||
|
||||
$partitioned_clauses = Context::removeReconciledClauses($left_clauses, $changed_var_ids);
|
||||
$partitioned_clauses = Context::removeReconciledClauses(
|
||||
[...$left_context->clauses, ...$left_clauses],
|
||||
$changed_var_ids
|
||||
);
|
||||
|
||||
$right_context->clauses = $partitioned_clauses[0];
|
||||
|
||||
|
@ -2110,6 +2110,22 @@ class AssertAnnotationTest extends TestCase
|
||||
consumeAOrB($abc);
|
||||
',
|
||||
],
|
||||
'assertDocblockTypeContradictionCorrectType' => [
|
||||
'code' => '<?php
|
||||
function takesAnInt(int $i): void {}
|
||||
|
||||
function takesAFloat(float $i): void {}
|
||||
|
||||
$foo = rand() / 2;
|
||||
|
||||
/** @psalm-suppress TypeDoesNotContainType */
|
||||
if (is_int($foo) || !is_float($foo)) {
|
||||
takesAnInt($foo);
|
||||
exit;
|
||||
}
|
||||
|
||||
takesAFloat($foo);',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1211,6 +1211,40 @@ class TypeAlgebraTest extends TestCase
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
'subclassAfterNegation' => [
|
||||
'code' => '<?php
|
||||
abstract class Base {}
|
||||
class A extends Base {}
|
||||
class AChild extends A {}
|
||||
class B extends Base {
|
||||
public string $s = "";
|
||||
}
|
||||
|
||||
function foo(Base $base): void {
|
||||
if (!$base instanceof A || $base instanceof AChild) {
|
||||
if ($base instanceof B && rand(0, 1)) {
|
||||
echo $base->s;
|
||||
}
|
||||
}
|
||||
}'
|
||||
],
|
||||
'subclassAfterElseifNegation' => [
|
||||
'code' => '<?php
|
||||
abstract class Base {}
|
||||
class A extends Base {}
|
||||
class AChild extends A {}
|
||||
class B extends Base {
|
||||
public string $s = "";
|
||||
}
|
||||
|
||||
function foo(Base $base): void {
|
||||
if ($base instanceof A && !($base instanceof AChild)) {
|
||||
// do nothing
|
||||
} elseif ($base instanceof B && rand(0, 1)) {
|
||||
echo $base->s;
|
||||
}
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -1347,14 +1381,15 @@ class TypeAlgebraTest extends TestCase
|
||||
],
|
||||
'repeatedAndConditional' => [
|
||||
'code' => '<?php
|
||||
function foo(string $a, string $b): void {
|
||||
class C {}
|
||||
function foo(?C $a, ?C $b): void {
|
||||
if ($a && $b) {
|
||||
echo "a";
|
||||
} elseif ($a && $b) {
|
||||
echo "b";
|
||||
}
|
||||
}',
|
||||
'error_message' => 'ParadoxicalCondition',
|
||||
'error_message' => 'TypeDoesNotContainType',
|
||||
],
|
||||
'andConditionalAfterOrConditional' => [
|
||||
'code' => '<?php
|
||||
|
Loading…
Reference in New Issue
Block a user