Skip to content

Commit

Permalink
Also replace templated intersection types that aren’t direct templates
Browse files Browse the repository at this point in the history
Ref #1675
  • Loading branch information
muglug committed May 24, 2019
1 parent 569d826 commit 62dacaf
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic.php
Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions src/Psalm/Type/Atomic/CallableTrait.php
Expand Up @@ -230,20 +230,20 @@ 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) {
if (!$param->type) {
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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Psalm/Type/Atomic/GenericTrait.php
Expand Up @@ -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);
}
}
}
4 changes: 3 additions & 1 deletion src/Psalm/Type/Atomic/HasIntersectionTrait.php
Expand Up @@ -3,6 +3,7 @@

use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Codebase;

trait HasIntersectionTrait
{
Expand Down Expand Up @@ -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;
Expand All @@ -91,6 +92,7 @@ public function replaceIntersectionTemplateTypesWithArgTypes(array $template_typ
}
}
} else {
$extra_type->replaceTemplateTypesWithArgTypes($template_types, $codebase);
$new_types[] = $extra_type;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/ObjectLike.php
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/Psalm/Type/Atomic/TNamedObject.php
@@ -1,6 +1,7 @@
<?php
namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
Expand Down Expand Up @@ -125,8 +126,8 @@ public function canBeFullyExpressedInPhp()
*
* @return void
*/
public function replaceTemplateTypesWithArgTypes(array $template_types)
public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase)
{
$this->replaceIntersectionTemplateTypesWithArgTypes($template_types);
$this->replaceIntersectionTemplateTypesWithArgTypes($template_types, $codebase);
}
}
5 changes: 3 additions & 2 deletions src/Psalm/Type/Atomic/TTemplateParam.php
@@ -1,6 +1,7 @@
<?php
namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Type;
use Psalm\Type\Union;

Expand Down Expand Up @@ -120,8 +121,8 @@ public function canBeFullyExpressedInPhp()
*
* @return void
*/
public function replaceTemplateTypesWithArgTypes(array $template_types)
public function replaceTemplateTypesWithArgTypes(array $template_types, ?Codebase $codebase)
{
$this->replaceIntersectionTemplateTypesWithArgTypes($template_types);
$this->replaceIntersectionTemplateTypesWithArgTypes($template_types, $codebase);
}
}
2 changes: 1 addition & 1 deletion src/Psalm/Type/Union.php
Expand Up @@ -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;
Expand Down
31 changes: 31 additions & 0 deletions tests/Template/TemplateTest.php
Expand Up @@ -2507,6 +2507,37 @@ public function foo() {
'$a' => 'C',
]
],
'returnTemplateIntersectionGenericObjectAndTemplate' => [
'<?php
/** @psalm-template Tp */
interface I {
/** @psalm-return Tp */
function getMe();
}
class C {}
/**
* @psalm-template T as object
*
* @psalm-param class-string<T> $className
*
* @psalm-return T&I<T>
*/
function makeConcrete(string $className) : object
{
return new class() extends C implements I {
public function getMe() {
return $this;
}
};
}
$a = makeConcrete(C::class);',
[
'$a' => 'C&I<C>'
]
],
];
}

Expand Down

0 comments on commit 62dacaf

Please sign in to comment.