mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Fix #477 - make sure that isset applies to property object
This commit is contained in:
parent
8ad863614c
commit
5200a25efa
@ -86,40 +86,53 @@ class AlgebraChecker
|
||||
if ($assertions) {
|
||||
$clauses = [];
|
||||
|
||||
|
||||
|
||||
foreach ($assertions as $var => $type) {
|
||||
if ($type === 'isset' || $type === '!empty') {
|
||||
$key_parts = preg_split(
|
||||
'/(\]|\[)/',
|
||||
$var,
|
||||
-1,
|
||||
PREG_SPLIT_NO_EMPTY
|
||||
);
|
||||
$key_parts = preg_split('/(->|\[|\])/', $var, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$base = array_shift($key_parts);
|
||||
$base_key = array_shift($key_parts);
|
||||
|
||||
if ($type === 'isset') {
|
||||
$clauses[] = new Clause([$base => ['^isset']]);
|
||||
$clauses[] = new Clause([$base_key => ['^isset']]);
|
||||
} else {
|
||||
$clauses[] = new Clause([$base => ['^!empty']]);
|
||||
$clauses[] = new Clause([$base_key => ['^!empty']]);
|
||||
}
|
||||
|
||||
if (!empty($key_parts)) {
|
||||
$clauses[] = new Clause([$base => ['!false']]);
|
||||
$clauses[] = new Clause([$base => ['!int']]);
|
||||
$clauses[] = new Clause([$base_key => ['!false']]);
|
||||
$clauses[] = new Clause([$base_key => ['!int']]);
|
||||
}
|
||||
|
||||
foreach ($key_parts as $i => $key_part_dim) {
|
||||
$base .= '[' . $key_part_dim . ']';
|
||||
while ($key_parts) {
|
||||
$divider = array_shift($key_parts);
|
||||
|
||||
if ($type === 'isset') {
|
||||
$clauses[] = new Clause([$base => ['^isset']]);
|
||||
if ($divider === '[') {
|
||||
$array_key = array_shift($key_parts);
|
||||
array_shift($key_parts);
|
||||
|
||||
$new_base_key = $base_key . '[' . $array_key . ']';
|
||||
|
||||
$base_key = $new_base_key;
|
||||
} elseif ($divider === '->') {
|
||||
$property_name = array_shift($key_parts);
|
||||
$new_base_key = $base_key . '->' . $property_name;
|
||||
|
||||
$base_key = $new_base_key;
|
||||
} else {
|
||||
$clauses[] = new Clause([$base => ['^!empty']]);
|
||||
throw new \InvalidArgumentException('Unexpected divider ' . $divider);
|
||||
}
|
||||
|
||||
if ($i < count($key_parts) - 1) {
|
||||
$clauses[] = new Clause([$base => ['!false']]);
|
||||
$clauses[] = new Clause([$base => ['!int']]);
|
||||
if ($type === 'isset') {
|
||||
$clauses[] = new Clause([$base_key => ['^isset']]);
|
||||
} else {
|
||||
$clauses[] = new Clause([$base_key => ['^!empty']]);
|
||||
}
|
||||
|
||||
if (count($key_parts)) {
|
||||
$clauses[] = new Clause([$base_key => ['!false']]);
|
||||
$clauses[] = new Clause([$base_key => ['!int']]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -116,6 +116,21 @@ class IssetTest extends TestCase
|
||||
if (!isset($item["hide"]) || !$item["hide"]) {}
|
||||
}',
|
||||
],
|
||||
'issetPropertyAffirmsObject' => [
|
||||
'<?php
|
||||
class A {
|
||||
/** @var ?int */
|
||||
public $id;
|
||||
}
|
||||
|
||||
function takesA(?A $a): A {
|
||||
if (isset($a->id)) {
|
||||
return $a;
|
||||
}
|
||||
|
||||
return new A();
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user