1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix parsing of class-string-map<T of Foo, T>

This commit is contained in:
robchett 2023-10-26 13:24:00 +01:00 committed by Robert Chettleburgh
parent 934383e036
commit 39ac69b643
3 changed files with 14 additions and 5 deletions

View File

@ -143,6 +143,7 @@ final class ParseTreeCreator
case 'is':
case 'as':
case 'of':
$this->handleIsOrAs($type_token);
break;
@ -771,7 +772,7 @@ final class ParseTreeCreator
array_pop($current_parent->children);
}
if ($type_token[0] === 'as') {
if ($type_token[0] === 'as' || $type_token[0] == 'of') {
$next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
if (!$this->current_leaf instanceof Value

View File

@ -9,9 +9,11 @@ use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Type\TypeAlias\InlineTypeAlias;
use Psalm\Type;
use function array_slice;
use function array_splice;
use function array_unshift;
use function count;
use function implode;
use function in_array;
use function is_numeric;
use function preg_match;
@ -146,11 +148,9 @@ final class TypeTokenizer
$type_tokens[++$rtc] = [' ', $i - 1];
$type_tokens[++$rtc] = ['', $i];
} elseif ($was_space
&& ($char === 'a' || $char === 'i')
&& ($chars[$i + 1] ?? null) === 's'
&& ($chars[$i + 2] ?? null) === ' '
&& in_array(implode('', array_slice($chars, $i, 3)), ['as ', 'is ', 'of '])
) {
$type_tokens[++$rtc] = [$char . 's', $i - 1];
$type_tokens[++$rtc] = [$char . $chars[$i+1], $i - 1];
$type_tokens[++$rtc] = ['', ++$i];
$was_char = false;
continue;

View File

@ -935,6 +935,14 @@ class TypeParseTest extends TestCase
);
}
public function testClassStringMapOf(): void
{
$this->assertSame(
'class-string-map<T as Foo, T>',
Type::parseString('class-string-map<T of Foo, T>')->getId(false),
);
}
public function testVeryLargeType(): void
{
$very_large_type = 'array{a: Closure():(array<array-key, mixed>|null), b?: Closure():array<array-key, mixed>, c?: Closure():array<array-key, mixed>, d?: Closure():array<array-key, mixed>, e?: Closure():(array{f: null|string, g: null|string, h: null|string, i: string, j: mixed, k: mixed, l: mixed, m: mixed, n: bool, o?: array{0: string}}|null), p?: Closure():(array{f: null|string, g: null|string, h: null|string, i: string, j: mixed, k: mixed, l: mixed, m: mixed, n: bool, o?: array{0: string}}|null), q: string, r?: Closure():(array<array-key, mixed>|null), s: array<array-key, mixed>}|null';