From 62dacaf97b3ee49ebc130de4ad4bd89742e31fe3 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Fri, 24 May 2019 17:34:40 -0400 Subject: [PATCH] =?UTF-8?q?Also=20replace=20templated=20intersection=20typ?= =?UTF-8?q?es=20that=20aren=E2=80=99t=20direct=20templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ref #1675 --- src/Psalm/Type/Atomic.php | 2 +- src/Psalm/Type/Atomic/CallableTrait.php | 6 ++-- src/Psalm/Type/Atomic/GenericTrait.php | 6 ++-- .../Type/Atomic/HasIntersectionTrait.php | 4 ++- src/Psalm/Type/Atomic/ObjectLike.php | 2 +- src/Psalm/Type/Atomic/TNamedObject.php | 5 +-- src/Psalm/Type/Atomic/TTemplateParam.php | 5 +-- src/Psalm/Type/Union.php | 2 +- tests/Template/TemplateTest.php | 31 +++++++++++++++++++ 9 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index d65d55759b4..7f8b383df90 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -802,7 +802,7 @@ public function replaceTemplateTypesWithStandins( * * @return void */ - public function replaceTemplateTypesWithArgTypes(array $template_types) + public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase) { // do nothing } diff --git a/src/Psalm/Type/Atomic/CallableTrait.php b/src/Psalm/Type/Atomic/CallableTrait.php index ad498fef82a..00173a71a54 100644 --- a/src/Psalm/Type/Atomic/CallableTrait.php +++ b/src/Psalm/Type/Atomic/CallableTrait.php @@ -230,7 +230,7 @@ public function replaceTemplateTypesWithStandins( * * @return void */ - public function replaceTemplateTypesWithArgTypes(array $template_types) + public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase) { if ($this->params) { foreach ($this->params as $param) { @@ -238,12 +238,12 @@ public function replaceTemplateTypesWithArgTypes(array $template_types) continue; } - $param->type->replaceTemplateTypesWithArgTypes($template_types); + $param->type->replaceTemplateTypesWithArgTypes($template_types, $codebase); } } if ($this->return_type) { - $this->return_type->replaceTemplateTypesWithArgTypes($template_types); + $this->return_type->replaceTemplateTypesWithArgTypes($template_types, $codebase); } } diff --git a/src/Psalm/Type/Atomic/GenericTrait.php b/src/Psalm/Type/Atomic/GenericTrait.php index 576afb40cd9..c3102d89c6a 100644 --- a/src/Psalm/Type/Atomic/GenericTrait.php +++ b/src/Psalm/Type/Atomic/GenericTrait.php @@ -192,14 +192,14 @@ public function replaceTemplateTypesWithStandins( * * @return void */ - public function replaceTemplateTypesWithArgTypes(array $template_types) + public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase) { foreach ($this->type_params as $type_param) { - $type_param->replaceTemplateTypesWithArgTypes($template_types); + $type_param->replaceTemplateTypesWithArgTypes($template_types, $codebase); } if ($this instanceof TGenericObject || $this instanceof TIterable) { - $this->replaceIntersectionTemplateTypesWithArgTypes($template_types); + $this->replaceIntersectionTemplateTypesWithArgTypes($template_types, $codebase); } } } diff --git a/src/Psalm/Type/Atomic/HasIntersectionTrait.php b/src/Psalm/Type/Atomic/HasIntersectionTrait.php index e0b7bd880c8..32c6f5c2634 100644 --- a/src/Psalm/Type/Atomic/HasIntersectionTrait.php +++ b/src/Psalm/Type/Atomic/HasIntersectionTrait.php @@ -3,6 +3,7 @@ use Psalm\Type; use Psalm\Type\Atomic; +use Psalm\Codebase; trait HasIntersectionTrait { @@ -73,7 +74,7 @@ public function getIntersectionTypes() * * @return void */ - public function replaceIntersectionTemplateTypesWithArgTypes(array $template_types) + public function replaceIntersectionTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase) { if (!$this->extra_types) { return; @@ -91,6 +92,7 @@ public function replaceIntersectionTemplateTypesWithArgTypes(array $template_typ } } } else { + $extra_type->replaceTemplateTypesWithArgTypes($template_types, $codebase); $new_types[] = $extra_type; } } diff --git a/src/Psalm/Type/Atomic/ObjectLike.php b/src/Psalm/Type/Atomic/ObjectLike.php index 5001efa746c..172d0216cc5 100644 --- a/src/Psalm/Type/Atomic/ObjectLike.php +++ b/src/Psalm/Type/Atomic/ObjectLike.php @@ -328,7 +328,7 @@ public function replaceTemplateTypesWithStandins( * * @return void */ - public function replaceTemplateTypesWithArgTypes(array $template_types) + public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase) { foreach ($this->properties as $property) { $property->replaceTemplateTypesWithArgTypes($template_types); diff --git a/src/Psalm/Type/Atomic/TNamedObject.php b/src/Psalm/Type/Atomic/TNamedObject.php index e5c0cbf636b..a0c282c10c6 100644 --- a/src/Psalm/Type/Atomic/TNamedObject.php +++ b/src/Psalm/Type/Atomic/TNamedObject.php @@ -1,6 +1,7 @@ replaceIntersectionTemplateTypesWithArgTypes($template_types); + $this->replaceIntersectionTemplateTypesWithArgTypes($template_types, $codebase); } } diff --git a/src/Psalm/Type/Atomic/TTemplateParam.php b/src/Psalm/Type/Atomic/TTemplateParam.php index 6fe27bd80c8..cd86506adcf 100644 --- a/src/Psalm/Type/Atomic/TTemplateParam.php +++ b/src/Psalm/Type/Atomic/TTemplateParam.php @@ -1,6 +1,7 @@ replaceIntersectionTemplateTypesWithArgTypes($template_types); + $this->replaceIntersectionTemplateTypesWithArgTypes($template_types, $codebase); } } diff --git a/src/Psalm/Type/Union.php b/src/Psalm/Type/Union.php index acc1ebe5d4d..2c5aff13901 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -1247,7 +1247,7 @@ public function replaceTemplateTypesWithArgTypes(array $template_types, Codebase $is_mixed = false; foreach ($this->types as $key => $atomic_type) { - $atomic_type->replaceTemplateTypesWithArgTypes($template_types); + $atomic_type->replaceTemplateTypesWithArgTypes($template_types, $codebase); if ($atomic_type instanceof Type\Atomic\TTemplateParam) { $keys_to_unset[] = $key; diff --git a/tests/Template/TemplateTest.php b/tests/Template/TemplateTest.php index 583ae917128..6616b373dd4 100644 --- a/tests/Template/TemplateTest.php +++ b/tests/Template/TemplateTest.php @@ -2507,6 +2507,37 @@ public function foo() { '$a' => 'C', ] ], + 'returnTemplateIntersectionGenericObjectAndTemplate' => [ + ' $className + * + * @psalm-return T&I + */ + function makeConcrete(string $className) : object + { + return new class() extends C implements I { + public function getMe() { + return $this; + } + }; + } + + $a = makeConcrete(C::class);', + [ + '$a' => 'C&I' + ] + ], ]; }