mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Merge pull request #9685 from Nicelocal/avoid_wrong_assertions
Avoid wrong assertions when working with objects returned by methods
This commit is contained in:
commit
a97b6b8a5e
@ -42,10 +42,13 @@ use Psalm\Type\Atomic\TTemplateParam;
|
||||
use Psalm\Type\Union;
|
||||
use UnexpectedValueException;
|
||||
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
|
||||
/**
|
||||
@ -422,30 +425,48 @@ class ExistingAtomicMethodCallAnalyzer extends CallAnalyzer
|
||||
}
|
||||
|
||||
if ($method_storage->if_true_assertions) {
|
||||
$possibilities = array_map(
|
||||
static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy(
|
||||
$template_result,
|
||||
$lhs_var_id,
|
||||
$codebase,
|
||||
),
|
||||
$method_storage->if_true_assertions,
|
||||
);
|
||||
if ($lhs_var_id === null) {
|
||||
$possibilities = array_filter(
|
||||
$possibilities,
|
||||
static fn(Possibilities $assertion): bool => !(is_string($assertion->var_id)
|
||||
&& strpos($assertion->var_id, '$this->') === 0
|
||||
)
|
||||
);
|
||||
}
|
||||
$statements_analyzer->node_data->setIfTrueAssertions(
|
||||
$stmt,
|
||||
array_map(
|
||||
static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy(
|
||||
$template_result,
|
||||
$lhs_var_id,
|
||||
$codebase,
|
||||
),
|
||||
$method_storage->if_true_assertions,
|
||||
),
|
||||
$possibilities,
|
||||
);
|
||||
}
|
||||
|
||||
if ($method_storage->if_false_assertions) {
|
||||
$possibilities = array_map(
|
||||
static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy(
|
||||
$template_result,
|
||||
$lhs_var_id,
|
||||
$codebase,
|
||||
),
|
||||
$method_storage->if_false_assertions,
|
||||
);
|
||||
if ($lhs_var_id === null) {
|
||||
$possibilities = array_filter(
|
||||
$possibilities,
|
||||
static fn(Possibilities $assertion): bool => !(is_string($assertion->var_id)
|
||||
&& strpos($assertion->var_id, '$this->') === 0
|
||||
)
|
||||
);
|
||||
}
|
||||
$statements_analyzer->node_data->setIfFalseAssertions(
|
||||
$stmt,
|
||||
array_map(
|
||||
static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy(
|
||||
$template_result,
|
||||
$lhs_var_id,
|
||||
$codebase,
|
||||
),
|
||||
$method_storage->if_false_assertions,
|
||||
),
|
||||
$possibilities,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2007,6 +2007,30 @@ class AssertAnnotationTest extends TestCase
|
||||
function requiresString(string $_str): void {}
|
||||
',
|
||||
],
|
||||
'assertionOnPropertyReturnedByMethod' => [
|
||||
'code' => '<?php
|
||||
class a {
|
||||
public ?int $id = null;
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*
|
||||
* @psalm-assert-if-true !null $this->id
|
||||
*/
|
||||
public function isExists(): bool {
|
||||
return $this->id !== null;
|
||||
}
|
||||
}
|
||||
|
||||
class b {
|
||||
public ?int $id = null;
|
||||
public function __construct(private a $a) {
|
||||
if ($this->getA()->isExists()) {
|
||||
/** @psalm-check-type-exact $this->id = ?int */
|
||||
}
|
||||
}
|
||||
public function getA(): a { return $this->a; }
|
||||
}',
|
||||
],
|
||||
'assertWithEmptyStringOnKeyedArray' => [
|
||||
'code' => '<?php
|
||||
class A
|
||||
|
Loading…
Reference in New Issue
Block a user