Skip to content

Commit 61ead7b

Browse files
committed
Move determining the union and intersection with new lines to a proper place and handle them
1 parent 122bb31 commit 61ead7b

File tree

3 files changed

+93
-61
lines changed

3 files changed

+93
-61
lines changed

src/Parser/TokenIterator.php

+4
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ public function tryConsumeTokenType(int $tokenType): bool
208208
/** @phpstan-impure */
209209
public function skipNewLineTokens(): void
210210
{
211+
if (!$this->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
212+
return;
213+
}
214+
211215
do {
212216
$foundNewLine = $this->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
213217
} while ($foundNewLine === true);

src/Parser/TypeParser.php

+31-6
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,44 @@ public function parse(TokenIterator $tokens): Ast\Type\TypeNode
4040
} else {
4141
$type = $this->parseAtomic($tokens);
4242

43-
if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
44-
$type = $this->parseUnion($tokens, $type);
43+
$tokens->pushSavePoint();
44+
$tokens->skipNewLineTokens();
45+
46+
try {
47+
$enrichedType = $this->enrichTypeOnUnionOrIntersection($tokens, $type);
48+
49+
} catch (ParserException $parserException) {
50+
$enrichedType = null;
51+
}
52+
53+
if ($enrichedType !== null) {
54+
$type = $enrichedType;
55+
$tokens->dropSavePoint();
4556

46-
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
47-
$type = $this->parseIntersection($tokens, $type);
57+
} else {
58+
$tokens->rollback();
59+
$type = $this->enrichTypeOnUnionOrIntersection($tokens, $type) ?? $type;
4860
}
4961
}
5062

5163
return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex);
5264
}
5365

66+
/** @phpstan-impure */
67+
private function enrichTypeOnUnionOrIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): ?Ast\Type\TypeNode
68+
{
69+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
70+
return $this->parseUnion($tokens, $type);
71+
72+
}
73+
74+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
75+
return $this->parseIntersection($tokens, $type);
76+
}
77+
78+
return null;
79+
}
80+
5481
/**
5582
* @internal
5683
* @template T of Ast\Node
@@ -412,8 +439,6 @@ public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode
412439
while (
413440
$isFirst
414441
|| $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)
415-
|| $tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)
416-
|| $tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)
417442
) {
418443
$tokens->skipNewLineTokens();
419444

tests/PHPStan/Parser/PhpDocParserTest.php

+58-55
Original file line numberDiff line numberDiff line change
@@ -4053,20 +4053,21 @@ public function provideMultiLinePhpDocData(): iterable
40534053
new IdentifierTypeNode('array'),
40544054
[
40554055
new IdentifierTypeNode('string'),
4056-
ArrayShapeNode::createSealed([
4057-
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4058-
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4059-
]),
4060-
ArrayShapeNode::createSealed([
4061-
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4062-
new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')),
4063-
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4056+
new UnionTypeNode([
4057+
ArrayShapeNode::createSealed([
4058+
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4059+
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4060+
]),
4061+
ArrayShapeNode::createSealed([
4062+
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4063+
new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')),
4064+
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4065+
]),
40644066
]),
40654067
],
40664068
[
40674069
GenericTypeNode::VARIANCE_INVARIANT,
40684070
GenericTypeNode::VARIANCE_INVARIANT,
4069-
GenericTypeNode::VARIANCE_INVARIANT,
40704071
],
40714072
)),
40724073
]),
@@ -4111,20 +4112,21 @@ public function provideMultiLinePhpDocData(): iterable
41114112
new IdentifierTypeNode('array'),
41124113
[
41134114
new IdentifierTypeNode('string'),
4114-
ArrayShapeNode::createSealed([
4115-
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4116-
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4117-
]),
4118-
ArrayShapeNode::createSealed([
4119-
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4120-
new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')),
4121-
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4115+
new UnionTypeNode([
4116+
ArrayShapeNode::createSealed([
4117+
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4118+
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4119+
]),
4120+
ArrayShapeNode::createSealed([
4121+
new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')),
4122+
new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')),
4123+
new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')),
4124+
]),
41224125
]),
41234126
],
41244127
[
41254128
GenericTypeNode::VARIANCE_INVARIANT,
41264129
GenericTypeNode::VARIANCE_INVARIANT,
4127-
GenericTypeNode::VARIANCE_INVARIANT,
41284130
],
41294131
)),
41304132
]),
@@ -4159,49 +4161,50 @@ public function provideMultiLinePhpDocData(): iterable
41594161
[
41604162
new IdentifierTypeNode('string'),
41614163
new UnionTypeNode([
4162-
new GenericTypeNode(
4163-
new IdentifierTypeNode('class-string'),
4164-
[new IdentifierTypeNode('Factory\\FactoryInterface')],
4165-
[GenericTypeNode::VARIANCE_INVARIANT],
4166-
),
4167-
new IdentifierTypeNode('Factory\\FactoryInterface'),
4168-
]),
4169-
new CallableTypeNode(
4170-
new IdentifierTypeNode('callable'),
4171-
[
4172-
new CallableTypeParameterNode(new IdentifierTypeNode('ContainerInterface'), false, false, '', false),
4173-
new CallableTypeParameterNode(
4174-
new NullableTypeNode(
4175-
new IdentifierTypeNode('string'),
4176-
),
4177-
false,
4178-
false,
4179-
'',
4180-
false,
4164+
new UnionTypeNode([
4165+
new GenericTypeNode(
4166+
new IdentifierTypeNode('class-string'),
4167+
[new IdentifierTypeNode('Factory\\FactoryInterface')],
4168+
[GenericTypeNode::VARIANCE_INVARIANT],
41814169
),
4182-
new CallableTypeParameterNode(
4183-
new UnionTypeNode([
4184-
new GenericTypeNode(
4185-
new IdentifierTypeNode('array'),
4186-
[new IdentifierTypeNode('mixed')],
4187-
[GenericTypeNode::VARIANCE_INVARIANT],
4170+
new IdentifierTypeNode('Factory\\FactoryInterface'),
4171+
]),
4172+
new CallableTypeNode(
4173+
new IdentifierTypeNode('callable'),
4174+
[
4175+
new CallableTypeParameterNode(new IdentifierTypeNode('ContainerInterface'), false, false, '', false),
4176+
new CallableTypeParameterNode(
4177+
new NullableTypeNode(
4178+
new IdentifierTypeNode('string'),
41884179
),
4189-
new IdentifierTypeNode('null'),
4190-
]),
4191-
false,
4192-
false,
4193-
'',
4194-
false,
4195-
),
4196-
],
4197-
new IdentifierTypeNode('object'),
4198-
[],
4199-
),
4180+
false,
4181+
false,
4182+
'',
4183+
false,
4184+
),
4185+
new CallableTypeParameterNode(
4186+
new UnionTypeNode([
4187+
new GenericTypeNode(
4188+
new IdentifierTypeNode('array'),
4189+
[new IdentifierTypeNode('mixed')],
4190+
[GenericTypeNode::VARIANCE_INVARIANT],
4191+
),
4192+
new IdentifierTypeNode('null'),
4193+
]),
4194+
false,
4195+
false,
4196+
'',
4197+
false,
4198+
),
4199+
],
4200+
new IdentifierTypeNode('object'),
4201+
[],
4202+
),
4203+
]),
42004204
],
42014205
[
42024206
GenericTypeNode::VARIANCE_INVARIANT,
42034207
GenericTypeNode::VARIANCE_INVARIANT,
4204-
GenericTypeNode::VARIANCE_INVARIANT,
42054208
],
42064209
),
42074210
)),

0 commit comments

Comments
 (0)