|
60 | 60 | use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
|
61 | 61 | use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
62 | 62 | use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
| 63 | +use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode; |
63 | 64 | use PHPStan\PhpDocParser\Ast\Type\InvalidTypeNode;
|
64 | 65 | use PHPStan\PhpDocParser\Ast\Type\NullableTypeNode;
|
65 | 66 | use PHPStan\PhpDocParser\Ast\Type\ObjectShapeItemNode;
|
|
71 | 72 | use PHPUnit\Framework\TestCase;
|
72 | 73 | use function count;
|
73 | 74 | use function sprintf;
|
| 75 | +use const DIRECTORY_SEPARATOR; |
74 | 76 | use const PHP_EOL;
|
75 | 77 |
|
76 | 78 | class PhpDocParserTest extends TestCase
|
@@ -4211,6 +4213,176 @@ public function provideMultiLinePhpDocData(): iterable
|
4211 | 4213 | ]),
|
4212 | 4214 | ];
|
4213 | 4215 |
|
| 4216 | + yield [ |
| 4217 | + 'Multiline PHPDoc with multiple new line within union type declaration', |
| 4218 | + '/**' . PHP_EOL . |
| 4219 | + ' * @param array<string, array{' . PHP_EOL . |
| 4220 | + ' * foo: int,' . PHP_EOL . |
| 4221 | + ' * bar?: array<string,' . PHP_EOL . |
| 4222 | + ' * array{foo1: int, bar1?: true}' . PHP_EOL . |
| 4223 | + ' * | array{foo1: int, foo2: true, bar1?: true}' . PHP_EOL . |
| 4224 | + ' * | array{foo2: int, foo3: bool, bar2?: true}' . PHP_EOL . |
| 4225 | + ' * | array{foo1: int, foo3: true, bar3?: false}' . PHP_EOL . |
| 4226 | + ' * >,' . PHP_EOL . |
| 4227 | + ' * }> $a' . PHP_EOL . |
| 4228 | + ' */', |
| 4229 | + new PhpDocNode([ |
| 4230 | + new PhpDocTagNode('@param', new ParamTagValueNode( |
| 4231 | + new GenericTypeNode( |
| 4232 | + new IdentifierTypeNode('array'), |
| 4233 | + [ |
| 4234 | + new IdentifierTypeNode('string'), |
| 4235 | + ArrayShapeNode::createSealed([ |
| 4236 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo'), false, new IdentifierTypeNode('int')), |
| 4237 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar'), true, new GenericTypeNode( |
| 4238 | + new IdentifierTypeNode('array'), |
| 4239 | + [ |
| 4240 | + new IdentifierTypeNode('string'), |
| 4241 | + new UnionTypeNode([ |
| 4242 | + ArrayShapeNode::createSealed([ |
| 4243 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4244 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')), |
| 4245 | + ]), |
| 4246 | + ArrayShapeNode::createSealed([ |
| 4247 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4248 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')), |
| 4249 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')), |
| 4250 | + ]), |
| 4251 | + ArrayShapeNode::createSealed([ |
| 4252 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('int')), |
| 4253 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo3'), false, new IdentifierTypeNode('bool')), |
| 4254 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar2'), true, new IdentifierTypeNode('true')), |
| 4255 | + ]), |
| 4256 | + ArrayShapeNode::createSealed([ |
| 4257 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4258 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo3'), false, new IdentifierTypeNode('true')), |
| 4259 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar3'), true, new IdentifierTypeNode('false')), |
| 4260 | + ]), |
| 4261 | + ]), |
| 4262 | + ], |
| 4263 | + [ |
| 4264 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4265 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4266 | + ], |
| 4267 | + )), |
| 4268 | + ]), |
| 4269 | + ], |
| 4270 | + [ |
| 4271 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4272 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4273 | + ], |
| 4274 | + ), |
| 4275 | + false, |
| 4276 | + '$a', |
| 4277 | + '', |
| 4278 | + false, |
| 4279 | + )), |
| 4280 | + ]), |
| 4281 | + ]; |
| 4282 | + |
| 4283 | + yield [ |
| 4284 | + 'Multiline PHPDoc with multiple new line within intersection type declaration', |
| 4285 | + '/**' . PHP_EOL . |
| 4286 | + ' * @param array<string, array{' . PHP_EOL . |
| 4287 | + ' * foo: int,' . PHP_EOL . |
| 4288 | + ' * bar?: array<string,' . PHP_EOL . |
| 4289 | + ' * array{foo1: int, bar1?: true}' . PHP_EOL . |
| 4290 | + ' * & array{foo1: int, foo2: true, bar1?: true}' . PHP_EOL . |
| 4291 | + ' * & array{foo2: int, foo3: bool, bar2?: true}' . PHP_EOL . |
| 4292 | + ' * & array{foo1: int, foo3: true, bar3?: false}' . PHP_EOL . |
| 4293 | + ' * >,' . PHP_EOL . |
| 4294 | + ' * }> $a' . PHP_EOL . |
| 4295 | + ' */', |
| 4296 | + new PhpDocNode([ |
| 4297 | + new PhpDocTagNode('@param', new ParamTagValueNode( |
| 4298 | + new GenericTypeNode( |
| 4299 | + new IdentifierTypeNode('array'), |
| 4300 | + [ |
| 4301 | + new IdentifierTypeNode('string'), |
| 4302 | + ArrayShapeNode::createSealed([ |
| 4303 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo'), false, new IdentifierTypeNode('int')), |
| 4304 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar'), true, new GenericTypeNode( |
| 4305 | + new IdentifierTypeNode('array'), |
| 4306 | + [ |
| 4307 | + new IdentifierTypeNode('string'), |
| 4308 | + new IntersectionTypeNode([ |
| 4309 | + ArrayShapeNode::createSealed([ |
| 4310 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4311 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')), |
| 4312 | + ]), |
| 4313 | + ArrayShapeNode::createSealed([ |
| 4314 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4315 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('true')), |
| 4316 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar1'), true, new IdentifierTypeNode('true')), |
| 4317 | + ]), |
| 4318 | + ArrayShapeNode::createSealed([ |
| 4319 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo2'), false, new IdentifierTypeNode('int')), |
| 4320 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo3'), false, new IdentifierTypeNode('bool')), |
| 4321 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar2'), true, new IdentifierTypeNode('true')), |
| 4322 | + ]), |
| 4323 | + ArrayShapeNode::createSealed([ |
| 4324 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo1'), false, new IdentifierTypeNode('int')), |
| 4325 | + new ArrayShapeItemNode(new IdentifierTypeNode('foo3'), false, new IdentifierTypeNode('true')), |
| 4326 | + new ArrayShapeItemNode(new IdentifierTypeNode('bar3'), true, new IdentifierTypeNode('false')), |
| 4327 | + ]), |
| 4328 | + ]), |
| 4329 | + ], |
| 4330 | + [ |
| 4331 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4332 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4333 | + ], |
| 4334 | + )), |
| 4335 | + ]), |
| 4336 | + ], |
| 4337 | + [ |
| 4338 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4339 | + GenericTypeNode::VARIANCE_INVARIANT, |
| 4340 | + ], |
| 4341 | + ), |
| 4342 | + false, |
| 4343 | + '$a', |
| 4344 | + '', |
| 4345 | + false, |
| 4346 | + )), |
| 4347 | + ]), |
| 4348 | + ]; |
| 4349 | + |
| 4350 | + yield [ |
| 4351 | + 'Multiline PHPDoc with multiple new line being invalid due to union and intersection type declaration', |
| 4352 | + '/**' . PHP_EOL . |
| 4353 | + ' * @param array<string, array{' . PHP_EOL . |
| 4354 | + ' * foo: int,' . PHP_EOL . |
| 4355 | + ' * bar?: array<string,' . PHP_EOL . |
| 4356 | + ' * array{foo1: int, bar1?: true}' . PHP_EOL . |
| 4357 | + ' * & array{foo1: int, foo2: true, bar1?: true}' . PHP_EOL . |
| 4358 | + ' * | array{foo2: int, foo3: bool, bar2?: true}' . PHP_EOL . |
| 4359 | + ' * & array{foo1: int, foo3: true, bar3?: false}' . PHP_EOL . |
| 4360 | + ' * >,' . PHP_EOL . |
| 4361 | + ' * }> $a' . PHP_EOL . |
| 4362 | + ' */', |
| 4363 | + new PhpDocNode([ |
| 4364 | + new PhpDocTagNode('@param', new InvalidTagValueNode( |
| 4365 | + 'array<string, array{' . PHP_EOL . |
| 4366 | + ' foo: int,' . PHP_EOL . |
| 4367 | + ' bar?: array<string,' . PHP_EOL . |
| 4368 | + ' array{foo1: int, bar1?: true}' . PHP_EOL . |
| 4369 | + ' & array{foo1: int, foo2: true, bar1?: true}' . PHP_EOL . |
| 4370 | + ' | array{foo2: int, foo3: bool, bar2?: true}' . PHP_EOL . |
| 4371 | + ' & array{foo1: int, foo3: true, bar3?: false}' . PHP_EOL . |
| 4372 | + ' >,' . PHP_EOL . |
| 4373 | + '}> $a', |
| 4374 | + new ParserException( |
| 4375 | + '?', |
| 4376 | + Lexer::TOKEN_NULLABLE, |
| 4377 | + DIRECTORY_SEPARATOR === '\\' ? 65 : 62, |
| 4378 | + Lexer::TOKEN_CLOSE_CURLY_BRACKET, |
| 4379 | + null, |
| 4380 | + 4, |
| 4381 | + ), |
| 4382 | + )), |
| 4383 | + ]), |
| 4384 | + ]; |
| 4385 | + |
4214 | 4386 | /**
|
4215 | 4387 | * @return object{
|
4216 | 4388 | * a: int,
|
|
0 commit comments