1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Expand magic properties

Fixes vimeo/psalm#4344
Fixes vimeo/psalm#5663
Fixes vimeo/psalm#5639
Fixes vimeo/psalm#5955
Fixes vimeo/psalm#3272
This commit is contained in:
Bruce Weirdan 2021-07-18 23:43:33 +03:00
parent b589525eb1
commit d992331125
No known key found for this signature in database
GPG Key ID: CFC3AAB181751B0D
3 changed files with 48 additions and 3 deletions

View File

@ -19,6 +19,7 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedProperty;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\ImpurePropertyAssignment;
@ -994,8 +995,13 @@ class InstancePropertyAssignmentAnalyzer
if ($var_id) {
if (isset($class_storage->pseudo_property_set_types['$' . $prop_name])) {
$class_property_type =
clone $class_storage->pseudo_property_set_types['$' . $prop_name];
$class_property_type = TypeExpander::expandUnion(
$codebase,
clone $class_storage->pseudo_property_set_types['$' . $prop_name],
$fq_class_name,
$fq_class_name,
$class_storage->parent_class
);
$has_regular_setter = true;

View File

@ -16,6 +16,7 @@ use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedProperty;
use Psalm\Issue\ImpurePropertyFetch;
use Psalm\Issue\InternalProperty;
@ -550,7 +551,13 @@ class AtomicPropertyFetchAnalyzer
$has_magic_getter = true;
if (isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
$stmt_type = clone $class_storage->pseudo_property_get_types['$' . $prop_name];
$stmt_type = TypeExpander::expandUnion(
$codebase,
clone $class_storage->pseudo_property_get_types['$' . $prop_name],
$class_storage->name,
$class_storage->name,
$class_storage->parent_class
);
if ($class_storage->template_types) {
if (!$lhs_type_part instanceof TGenericObject) {

View File

@ -695,6 +695,38 @@ class MagicPropertyTest extends TestCase
}
}'
],
'propertyReadIsExpanded' => [
'<?php
/** @property self::TYPE_* $type */
class A {
public const TYPE_A = 1;
public const TYPE_B = 2;
public function __get(string $_prop) {}
/** @param mixed $_value */
public function __set(string $_prop, $_value) {}
}
$a = (new A)->type;
',
'assertions' => [
'$a===' => '1|2',
],
],
'propertyWriteIsExpanded' => [
'<?php
/** @property self::TYPE_* $type */
class A {
public const TYPE_A = 1;
public const TYPE_B = 2;
public function __get(string $_prop) {}
/** @param mixed $_value */
public function __set(string $_prop, $_value) {}
}
$a = (new A);
$a->type = A::TYPE_B;
',
],
];
}