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:
parent
b589525eb1
commit
d992331125
@ -19,6 +19,7 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer;
|
|||||||
use Psalm\Internal\Codebase\TaintFlowGraph;
|
use Psalm\Internal\Codebase\TaintFlowGraph;
|
||||||
use Psalm\Internal\DataFlow\DataFlowNode;
|
use Psalm\Internal\DataFlow\DataFlowNode;
|
||||||
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
|
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
|
||||||
|
use Psalm\Internal\Type\TypeExpander;
|
||||||
use Psalm\Issue\DeprecatedProperty;
|
use Psalm\Issue\DeprecatedProperty;
|
||||||
use Psalm\Issue\ImplicitToStringCast;
|
use Psalm\Issue\ImplicitToStringCast;
|
||||||
use Psalm\Issue\ImpurePropertyAssignment;
|
use Psalm\Issue\ImpurePropertyAssignment;
|
||||||
@ -994,8 +995,13 @@ class InstancePropertyAssignmentAnalyzer
|
|||||||
|
|
||||||
if ($var_id) {
|
if ($var_id) {
|
||||||
if (isset($class_storage->pseudo_property_set_types['$' . $prop_name])) {
|
if (isset($class_storage->pseudo_property_set_types['$' . $prop_name])) {
|
||||||
$class_property_type =
|
$class_property_type = TypeExpander::expandUnion(
|
||||||
clone $class_storage->pseudo_property_set_types['$' . $prop_name];
|
$codebase,
|
||||||
|
clone $class_storage->pseudo_property_set_types['$' . $prop_name],
|
||||||
|
$fq_class_name,
|
||||||
|
$fq_class_name,
|
||||||
|
$class_storage->parent_class
|
||||||
|
);
|
||||||
|
|
||||||
$has_regular_setter = true;
|
$has_regular_setter = true;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use Psalm\Internal\Codebase\TaintFlowGraph;
|
|||||||
use Psalm\Internal\DataFlow\DataFlowNode;
|
use Psalm\Internal\DataFlow\DataFlowNode;
|
||||||
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
|
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
|
||||||
use Psalm\Internal\Type\TemplateResult;
|
use Psalm\Internal\Type\TemplateResult;
|
||||||
|
use Psalm\Internal\Type\TypeExpander;
|
||||||
use Psalm\Issue\DeprecatedProperty;
|
use Psalm\Issue\DeprecatedProperty;
|
||||||
use Psalm\Issue\ImpurePropertyFetch;
|
use Psalm\Issue\ImpurePropertyFetch;
|
||||||
use Psalm\Issue\InternalProperty;
|
use Psalm\Issue\InternalProperty;
|
||||||
@ -550,7 +551,13 @@ class AtomicPropertyFetchAnalyzer
|
|||||||
$has_magic_getter = true;
|
$has_magic_getter = true;
|
||||||
|
|
||||||
if (isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
|
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 ($class_storage->template_types) {
|
||||||
if (!$lhs_type_part instanceof TGenericObject) {
|
if (!$lhs_type_part instanceof TGenericObject) {
|
||||||
|
@ -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;
|
||||||
|
',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user