Skip to content

Commit

Permalink
Allow using imported types in other types within the same file
Browse files Browse the repository at this point in the history
In the test case (from issue #7116) both the type definition and the
import of the typed lived in the same file. This caused `OpeningTypes`
to be an `InlineTypeAlias` instead of a `LinkableTypeAlias`, in turn
causing an 'Invalid type alias' exception[^1].

By replacing the array union (+) with an array_merge, the import of the
type overrides the initial type declaration within the `Main` class.
This means type imports within one file act more like they would when in
separate files.

Fixes #7116

[^1]: [src/Psalm/Type/Atomic.php:407](https://github.com/vimeo/psalm/blob/1986c8b4a8018b1819bc4b83b0f7e69c2c936792/src/Psalm/Type/Atomic.php#L407)
  • Loading branch information
annervisser committed Nov 15, 2022
1 parent 2a29fd7 commit d10b1f9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php
Expand Up @@ -32,6 +32,7 @@
use Psalm\Type;
use UnexpectedValueException;

use function array_merge;
use function array_pop;
use function end;
use function explode;
Expand Down Expand Up @@ -187,7 +188,7 @@ public function enterNode(PhpParser\Node $node): ?int
return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
}

$this->type_aliases += $classlike_node_scanner->type_aliases;
$this->type_aliases = array_merge($this->type_aliases, $classlike_node_scanner->type_aliases);
} elseif ($node instanceof PhpParser\Node\Stmt\TryCatch) {
foreach ($node->catches as $catch) {
foreach ($catch->types as $catch_type) {
Expand Down
26 changes: 26 additions & 0 deletions tests/TypeAnnotationTest.php
Expand Up @@ -629,6 +629,32 @@ private function assertFoo($value): void {
'assertions' => [
'$output' => 'string',
]
],
'importedTypeUsedInOtherType' => [
'code' => '<?php
/** @psalm-type OpeningTypes=self::TYPE_A|self::TYPE_B */
class Foo {
public const TYPE_A = 1;
public const TYPE_B = 2;
}
/**
* @psalm-import-type OpeningTypes from Foo
* @psalm-type OpeningTypeAssignment=list<OpeningTypes>
*/
class Main {
/** @return OpeningTypeAssignment */
public function doStuff(): array {
return [];
}
}
$instance = new Main();
$output = $instance->doStuff();
',
'assertions' => [
'$output===' => 'list<1|2>',
]
]
];
}
Expand Down

0 comments on commit d10b1f9

Please sign in to comment.