Failed Conditions
Push — new-parser-ast-metadata ( 17d881...53b3e3 )
by Michael
02:35
created

GrammarTest::testValidGrammar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\Annotations\Parser;
6
7
use Hoa\Compiler\Exception\UnrecognizedToken;
8
use Hoa\Compiler\Llk\Llk;
9
use Hoa\Compiler\Llk\Parser as LlkParser;
10
use Hoa\Compiler\Visitor\Dump;
11
use Hoa\File\Read;
12
use PHPUnit\Framework\TestCase;
13
14
final class GrammarTest extends TestCase
15
{
16
    /** @var LlkParser */
17
    private $compiler;
18
19
    protected function setUp() : void
20
    {
21
        $this->compiler = Llk::load(new Read(__DIR__ . '/../../../../../lib/Doctrine/Annotations/Parser/grammar.pp'));
22
    }
23
24
    /**
25
     * @dataProvider validDocBlocksProvider()
26
     * @dataProvider validParityDocBlocksProvider()
27
     */
28
    public function testValidGrammar(string $docBlock, string $expectedTrace) : void
29
    {
30
        $ast   = $this->compiler->parse($docBlock);
31
        $trace = (new Dump())->visit($ast);
32
33
        self::assertSame($expectedTrace, $trace);
34
    }
35
36
    /**
37
     * @dataProvider invalidGrammarProvider()
38
     */
39
    public function testInvalidGrammar(string $docBlock, string $expectedError) : void
40
    {
41
        $this->expectException(UnrecognizedToken::class);
42
        $this->expectExceptionMessage($expectedError);
43
44
        $this->compiler->parse($docBlock);
45
    }
46
47
    /**
48
     * @return string[][]
49
     */
50
    public function validDocBlocksProvider() : iterable
51
    {
52
        yield 'simple with no parenthesis' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'simple with no pa...ntifier, Annotation) ') returns the type Generator which is incompatible with the documented return type array<mixed,string[]>.
Loading history...
53
            <<<'DOCBLOCK'
54
/**
55
* @Annotation
56
*/
57
DOCBLOCK
58
            ,
59
            <<<'TRACE'
60
>  #annotations
61
>  >  #annotation
62
>  >  >  token(annot:simple_identifier, Annotation)
63
64
TRACE
65
            ,
66
        ];
67
68
        yield 'simple with empty parenthesis' => [
69
            <<<'DOCBLOCK'
70
/**
71
* @Annotation()
72
*/
73
DOCBLOCK
74
            ,
75
            <<<'TRACE'
76
>  #annotations
77
>  >  #annotation
78
>  >  >  token(annot:valued_identifier, Annotation)
79
80
TRACE
81
            ,
82
        ];
83
84
        yield 'multiple without parameters' => [
85
            <<<'DOCBLOCK'
86
/** @Annotation1 @Annotation2 @Annotation3 */
87
DOCBLOCK
88
            ,
89
            <<<'TRACE'
90
>  #annotations
91
>  >  #annotation
92
>  >  >  token(annot:simple_identifier, Annotation1)
93
>  >  #annotation
94
>  >  >  token(annot:simple_identifier, Annotation2)
95
>  >  #annotation
96
>  >  >  token(annot:simple_identifier, Annotation3)
97
98
TRACE
99
            ,
100
        ];
101
102
        yield 'multiple with comments' => [
103
            <<<'DOCBLOCK'
104
/**
105
 * Hello world
106
 * @Annotation1
107
 * Hola mundo
108
 * @Annotation2
109
 */
110
DOCBLOCK
111
            ,
112
            <<<'TRACE'
113
>  #annotations
114
>  >  #annotation
115
>  >  >  token(annot:simple_identifier, Annotation1)
116
>  >  #annotation
117
>  >  >  token(annot:simple_identifier, Annotation2)
118
119
TRACE
120
            ,
121
        ];
122
123
        yield 'fully qualified with parameter' => [
124
            <<<'DOCBLOCK'
125
/**
126
* @\Ns\Annotation("value")
127
*/
128
DOCBLOCK
129
            ,
130
            <<<'TRACE'
131
>  #annotations
132
>  >  #annotation
133
>  >  >  token(annot:valued_identifier, \Ns\Annotation)
134
>  >  >  #parameters
135
>  >  >  >  #unnamed_parameter
136
>  >  >  >  >  #value
137
>  >  >  >  >  >  #string
138
>  >  >  >  >  >  >  token(string:string, value)
139
140
TRACE
141
            ,
142
        ];
143
144
        yield 'with array' => [
145
            <<<'DOCBLOCK'
146
/**
147
* @return array<string>
148
*/
149
DOCBLOCK
150
            ,
151
            <<<'TRACE'
152
>  #annotations
153
>  >  #annotation
154
>  >  >  token(annot:simple_identifier, return)
155
156
TRACE
157
            ,
158
        ];
159
160
        yield 'fully qualified, nested, multiple parameters' => [
161
            <<<'DOCBLOCK'
162
/**
163
* @\Ns\Name(int=1, annot=@Annot, float=1.2)
164
*/
165
DOCBLOCK
166
            ,
167
            <<<'TRACE'
168
>  #annotations
169
>  >  #annotation
170
>  >  >  token(annot:valued_identifier, \Ns\Name)
171
>  >  >  #parameters
172
>  >  >  >  #named_parameter
173
>  >  >  >  >  token(value:identifier, int)
174
>  >  >  >  >  #value
175
>  >  >  >  >  >  token(value:integer, 1)
176
>  >  >  >  #named_parameter
177
>  >  >  >  >  token(value:identifier, annot)
178
>  >  >  >  >  #value
179
>  >  >  >  >  >  #annotation
180
>  >  >  >  >  >  >  token(annot:simple_identifier, Annot)
181
>  >  >  >  #named_parameter
182
>  >  >  >  >  token(value:identifier, float)
183
>  >  >  >  >  #value
184
>  >  >  >  >  >  token(value:float, 1.2)
185
186
TRACE
187
            ,
188
        ];
189
190
        yield 'nested, with arrays' => [
191
            <<<'DOCBLOCK'
192
/**
193
* @Annot(
194
*  v1={1,2,3},
195
*  v2={@one,@two,@three},
196
*  v3={one=1,two=2,three=3},
197
*  v4={one=@one(1),two=@two(2),three=@three(3)}
198
* )
199
*/
200
DOCBLOCK
201
            ,
202
            <<<'TRACE'
203
>  #annotations
204
>  >  #annotation
205
>  >  >  token(annot:valued_identifier, Annot)
206
>  >  >  #parameters
207
>  >  >  >  #named_parameter
208
>  >  >  >  >  token(value:identifier, v1)
209
>  >  >  >  >  #value
210
>  >  >  >  >  >  #list
211
>  >  >  >  >  >  >  #value
212
>  >  >  >  >  >  >  >  token(value:integer, 1)
213
>  >  >  >  >  >  >  #value
214
>  >  >  >  >  >  >  >  token(value:integer, 2)
215
>  >  >  >  >  >  >  #value
216
>  >  >  >  >  >  >  >  token(value:integer, 3)
217
>  >  >  >  #named_parameter
218
>  >  >  >  >  token(value:identifier, v2)
219
>  >  >  >  >  #value
220
>  >  >  >  >  >  #list
221
>  >  >  >  >  >  >  #value
222
>  >  >  >  >  >  >  >  #annotation
223
>  >  >  >  >  >  >  >  >  token(annot:simple_identifier, one)
224
>  >  >  >  >  >  >  #value
225
>  >  >  >  >  >  >  >  #annotation
226
>  >  >  >  >  >  >  >  >  token(annot:simple_identifier, two)
227
>  >  >  >  >  >  >  #value
228
>  >  >  >  >  >  >  >  #annotation
229
>  >  >  >  >  >  >  >  >  token(annot:simple_identifier, three)
230
>  >  >  >  #named_parameter
231
>  >  >  >  >  token(value:identifier, v3)
232
>  >  >  >  >  #value
233
>  >  >  >  >  >  #map
234
>  >  >  >  >  >  >  #pair
235
>  >  >  >  >  >  >  >  token(value:identifier, one)
236
>  >  >  >  >  >  >  >  #value
237
>  >  >  >  >  >  >  >  >  token(value:integer, 1)
238
>  >  >  >  >  >  >  #pair
239
>  >  >  >  >  >  >  >  token(value:identifier, two)
240
>  >  >  >  >  >  >  >  #value
241
>  >  >  >  >  >  >  >  >  token(value:integer, 2)
242
>  >  >  >  >  >  >  #pair
243
>  >  >  >  >  >  >  >  token(value:identifier, three)
244
>  >  >  >  >  >  >  >  #value
245
>  >  >  >  >  >  >  >  >  token(value:integer, 3)
246
>  >  >  >  #named_parameter
247
>  >  >  >  >  token(value:identifier, v4)
248
>  >  >  >  >  #value
249
>  >  >  >  >  >  #map
250
>  >  >  >  >  >  >  #pair
251
>  >  >  >  >  >  >  >  token(value:identifier, one)
252
>  >  >  >  >  >  >  >  #value
253
>  >  >  >  >  >  >  >  >  #annotation
254
>  >  >  >  >  >  >  >  >  >  token(annot:valued_identifier, one)
255
>  >  >  >  >  >  >  >  >  >  #parameters
256
>  >  >  >  >  >  >  >  >  >  >  #unnamed_parameter
257
>  >  >  >  >  >  >  >  >  >  >  >  #value
258
>  >  >  >  >  >  >  >  >  >  >  >  >  token(value:integer, 1)
259
>  >  >  >  >  >  >  #pair
260
>  >  >  >  >  >  >  >  token(value:identifier, two)
261
>  >  >  >  >  >  >  >  #value
262
>  >  >  >  >  >  >  >  >  #annotation
263
>  >  >  >  >  >  >  >  >  >  token(annot:valued_identifier, two)
264
>  >  >  >  >  >  >  >  >  >  #parameters
265
>  >  >  >  >  >  >  >  >  >  >  #unnamed_parameter
266
>  >  >  >  >  >  >  >  >  >  >  >  #value
267
>  >  >  >  >  >  >  >  >  >  >  >  >  token(value:integer, 2)
268
>  >  >  >  >  >  >  #pair
269
>  >  >  >  >  >  >  >  token(value:identifier, three)
270
>  >  >  >  >  >  >  >  #value
271
>  >  >  >  >  >  >  >  >  #annotation
272
>  >  >  >  >  >  >  >  >  >  token(annot:valued_identifier, three)
273
>  >  >  >  >  >  >  >  >  >  #parameters
274
>  >  >  >  >  >  >  >  >  >  >  #unnamed_parameter
275
>  >  >  >  >  >  >  >  >  >  >  >  #value
276
>  >  >  >  >  >  >  >  >  >  >  >  >  token(value:integer, 3)
277
278
TRACE
279
            ,
280
        ];
281
282
        yield 'ORM Id example' => [
283
            <<<'DOCBLOCK'
284
/**
285
 * @ORM\Id @ORM\Column(type="integer")
286
 * @ORM\GeneratedValue
287
 */
288
DOCBLOCK
289
            ,
290
            <<<'TRACE'
291
>  #annotations
292
>  >  #annotation
293
>  >  >  token(annot:simple_identifier, ORM\Id)
294
>  >  #annotation
295
>  >  >  token(annot:valued_identifier, ORM\Column)
296
>  >  >  #parameters
297
>  >  >  >  #named_parameter
298
>  >  >  >  >  token(value:identifier, type)
299
>  >  >  >  >  #value
300
>  >  >  >  >  >  #string
301
>  >  >  >  >  >  >  token(string:string, integer)
302
>  >  #annotation
303
>  >  >  token(annot:simple_identifier, ORM\GeneratedValue)
304
305
TRACE
306
            ,
307
        ];
308
309
        yield 'unicode' => [
310
            <<<'DOCBLOCK'
311
/**
312
 * @Fancy😊Annotation
313
 */
314
DOCBLOCK
315
            ,
316
            <<<'TRACE'
317
>  #annotations
318
>  >  #annotation
319
>  >  >  token(annot:simple_identifier, Fancy😊Annotation)
320
321
TRACE
322
            ,
323
        ];
324
325
        yield 'spaces after @' => [
326
            <<<'DOCBLOCK'
327
/**
328
 * @
329
 * @ Hello world
330
 */
331
DOCBLOCK
332
            ,
333
            <<<'TRACE'
334
>  #annotations
335
336
TRACE
337
            ,
338
        ];
339
340
        yield 'numbers' => [
341
            <<<'DOCBLOCK'
342
/**
343
 * @Annotation(1, 123, -123, 1.2, 123.456, -123.456, 1e2, 123e456, 1.2e-3, -123.456E-789)
344
 */
345
DOCBLOCK
346
            ,
347
            <<<'TRACE'
348
>  #annotations
349
>  >  #annotation
350
>  >  >  token(annot:valued_identifier, Annotation)
351
>  >  >  #parameters
352
>  >  >  >  #unnamed_parameter
353
>  >  >  >  >  #value
354
>  >  >  >  >  >  token(value:integer, 1)
355
>  >  >  >  #unnamed_parameter
356
>  >  >  >  >  #value
357
>  >  >  >  >  >  token(value:integer, 123)
358
>  >  >  >  #unnamed_parameter
359
>  >  >  >  >  #value
360
>  >  >  >  >  >  token(value:integer, -123)
361
>  >  >  >  #unnamed_parameter
362
>  >  >  >  >  #value
363
>  >  >  >  >  >  token(value:float, 1.2)
364
>  >  >  >  #unnamed_parameter
365
>  >  >  >  >  #value
366
>  >  >  >  >  >  token(value:float, 123.456)
367
>  >  >  >  #unnamed_parameter
368
>  >  >  >  >  #value
369
>  >  >  >  >  >  token(value:float, -123.456)
370
>  >  >  >  #unnamed_parameter
371
>  >  >  >  >  #value
372
>  >  >  >  >  >  token(value:float, 1e2)
373
>  >  >  >  #unnamed_parameter
374
>  >  >  >  >  #value
375
>  >  >  >  >  >  token(value:float, 123e456)
376
>  >  >  >  #unnamed_parameter
377
>  >  >  >  >  #value
378
>  >  >  >  >  >  token(value:float, 1.2e-3)
379
>  >  >  >  #unnamed_parameter
380
>  >  >  >  >  #value
381
>  >  >  >  >  >  token(value:float, -123.456E-789)
382
383
TRACE
384
            ,
385
        ];
386
387
        yield 'ORM Column example' => [
388
            <<<'DOCBLOCK'
389
/** @ORM\Column(type="string", length=50, nullable=true) */
390
DOCBLOCK
391
            ,
392
            <<<'TRACE'
393
>  #annotations
394
>  >  #annotation
395
>  >  >  token(annot:valued_identifier, ORM\Column)
396
>  >  >  #parameters
397
>  >  >  >  #named_parameter
398
>  >  >  >  >  token(value:identifier, type)
399
>  >  >  >  >  #value
400
>  >  >  >  >  >  #string
401
>  >  >  >  >  >  >  token(string:string, string)
402
>  >  >  >  #named_parameter
403
>  >  >  >  >  token(value:identifier, length)
404
>  >  >  >  >  #value
405
>  >  >  >  >  >  token(value:integer, 50)
406
>  >  >  >  #named_parameter
407
>  >  >  >  >  token(value:identifier, nullable)
408
>  >  >  >  >  #value
409
>  >  >  >  >  >  token(value:boolean, true)
410
411
TRACE
412
            ,
413
        ];
414
415
        yield 'complex ORM M:N' => [
416
            <<<'DOCBLOCK'
417
/**
418
 * @ORM\ManyToMany(targetEntity=CmsGroup::class, inversedBy="users", cascade={"persist"})
419
 * @ORM\JoinTable(name="cms_users_groups",
420
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
421
 *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
422
 * )
423
 */
424
DOCBLOCK
425
            ,
426
            <<<'TRACE'
427
>  #annotations
428
>  >  #annotation
429
>  >  >  token(annot:valued_identifier, ORM\ManyToMany)
430
>  >  >  #parameters
431
>  >  >  >  #named_parameter
432
>  >  >  >  >  token(value:identifier, targetEntity)
433
>  >  >  >  >  #value
434
>  >  >  >  >  >  #class_constant
435
>  >  >  >  >  >  >  #reference
436
>  >  >  >  >  >  >  >  token(value:identifier, CmsGroup)
437
>  >  >  >  >  >  >  token(value:identifier, class)
438
>  >  >  >  #named_parameter
439
>  >  >  >  >  token(value:identifier, inversedBy)
440
>  >  >  >  >  #value
441
>  >  >  >  >  >  #string
442
>  >  >  >  >  >  >  token(string:string, users)
443
>  >  >  >  #named_parameter
444
>  >  >  >  >  token(value:identifier, cascade)
445
>  >  >  >  >  #value
446
>  >  >  >  >  >  #list
447
>  >  >  >  >  >  >  #value
448
>  >  >  >  >  >  >  >  #string
449
>  >  >  >  >  >  >  >  >  token(string:string, persist)
450
>  >  #annotation
451
>  >  >  token(annot:valued_identifier, ORM\JoinTable)
452
>  >  >  #parameters
453
>  >  >  >  #named_parameter
454
>  >  >  >  >  token(value:identifier, name)
455
>  >  >  >  >  #value
456
>  >  >  >  >  >  #string
457
>  >  >  >  >  >  >  token(string:string, cms_users_groups)
458
>  >  >  >  #named_parameter
459
>  >  >  >  >  token(value:identifier, joinColumns)
460
>  >  >  >  >  #value
461
>  >  >  >  >  >  #list
462
>  >  >  >  >  >  >  #value
463
>  >  >  >  >  >  >  >  #annotation
464
>  >  >  >  >  >  >  >  >  token(annot:valued_identifier, ORM\JoinColumn)
465
>  >  >  >  >  >  >  >  >  #parameters
466
>  >  >  >  >  >  >  >  >  >  #named_parameter
467
>  >  >  >  >  >  >  >  >  >  >  token(value:identifier, name)
468
>  >  >  >  >  >  >  >  >  >  >  #value
469
>  >  >  >  >  >  >  >  >  >  >  >  #string
470
>  >  >  >  >  >  >  >  >  >  >  >  >  token(string:string, user_id)
471
>  >  >  >  >  >  >  >  >  >  #named_parameter
472
>  >  >  >  >  >  >  >  >  >  >  token(value:identifier, referencedColumnName)
473
>  >  >  >  >  >  >  >  >  >  >  #value
474
>  >  >  >  >  >  >  >  >  >  >  >  #string
475
>  >  >  >  >  >  >  >  >  >  >  >  >  token(string:string, id)
476
>  >  >  >  #named_parameter
477
>  >  >  >  >  token(value:identifier, inverseJoinColumns)
478
>  >  >  >  >  #value
479
>  >  >  >  >  >  #list
480
>  >  >  >  >  >  >  #value
481
>  >  >  >  >  >  >  >  #annotation
482
>  >  >  >  >  >  >  >  >  token(annot:valued_identifier, ORM\JoinColumn)
483
>  >  >  >  >  >  >  >  >  #parameters
484
>  >  >  >  >  >  >  >  >  >  #named_parameter
485
>  >  >  >  >  >  >  >  >  >  >  token(value:identifier, name)
486
>  >  >  >  >  >  >  >  >  >  >  #value
487
>  >  >  >  >  >  >  >  >  >  >  >  #string
488
>  >  >  >  >  >  >  >  >  >  >  >  >  token(string:string, group_id)
489
>  >  >  >  >  >  >  >  >  >  #named_parameter
490
>  >  >  >  >  >  >  >  >  >  >  token(value:identifier, referencedColumnName)
491
>  >  >  >  >  >  >  >  >  >  >  #value
492
>  >  >  >  >  >  >  >  >  >  >  >  #string
493
>  >  >  >  >  >  >  >  >  >  >  >  >  token(string:string, id)
494
495
TRACE
496
            ,
497
        ];
498
499
        yield 'Symfony route' => [
500
            <<<'DOCBLOCK'
501
/**
502
 * @Route("/argument_with_route_param_and_default/{value}", defaults={"value": "value"}, name="argument_with_route_param_and_default")
503
 */
504
DOCBLOCK
505
            ,
506
            <<<'TRACE'
507
>  #annotations
508
>  >  #annotation
509
>  >  >  token(annot:valued_identifier, Route)
510
>  >  >  #parameters
511
>  >  >  >  #unnamed_parameter
512
>  >  >  >  >  #value
513
>  >  >  >  >  >  #string
514
>  >  >  >  >  >  >  token(string:string, /argument_with_route_param_and_default/{value})
515
>  >  >  >  #named_parameter
516
>  >  >  >  >  token(value:identifier, defaults)
517
>  >  >  >  >  #value
518
>  >  >  >  >  >  #map
519
>  >  >  >  >  >  >  #pair
520
>  >  >  >  >  >  >  >  #string
521
>  >  >  >  >  >  >  >  >  token(string:string, value)
522
>  >  >  >  >  >  >  >  #value
523
>  >  >  >  >  >  >  >  >  #string
524
>  >  >  >  >  >  >  >  >  >  token(string:string, value)
525
>  >  >  >  #named_parameter
526
>  >  >  >  >  token(value:identifier, name)
527
>  >  >  >  >  #value
528
>  >  >  >  >  >  #string
529
>  >  >  >  >  >  >  token(string:string, argument_with_route_param_and_default)
530
531
TRACE
532
            ,
533
        ];
534
535
        yield 'SymfonyFrameworkExtraBundle annotations' => [
536
            <<<'DOCBLOCK'
537
/**
538
 * @Route("/is_granted/resolved/conflict")
539
 * @IsGranted("ISGRANTED_VOTER", subject="request")
540
 * @Security("is_granted('ISGRANTED_VOTER', request)")
541
 */
542
DOCBLOCK
543
            ,
544
            <<<'TRACE'
545
>  #annotations
546
>  >  #annotation
547
>  >  >  token(annot:valued_identifier, Route)
548
>  >  >  #parameters
549
>  >  >  >  #unnamed_parameter
550
>  >  >  >  >  #value
551
>  >  >  >  >  >  #string
552
>  >  >  >  >  >  >  token(string:string, /is_granted/resolved/conflict)
553
>  >  #annotation
554
>  >  >  token(annot:valued_identifier, IsGranted)
555
>  >  >  #parameters
556
>  >  >  >  #unnamed_parameter
557
>  >  >  >  >  #value
558
>  >  >  >  >  >  #string
559
>  >  >  >  >  >  >  token(string:string, ISGRANTED_VOTER)
560
>  >  >  >  #named_parameter
561
>  >  >  >  >  token(value:identifier, subject)
562
>  >  >  >  >  #value
563
>  >  >  >  >  >  #string
564
>  >  >  >  >  >  >  token(string:string, request)
565
>  >  #annotation
566
>  >  >  token(annot:valued_identifier, Security)
567
>  >  >  #parameters
568
>  >  >  >  #unnamed_parameter
569
>  >  >  >  >  #value
570
>  >  >  >  >  >  #string
571
>  >  >  >  >  >  >  token(string:string, is_granted('ISGRANTED_VOTER', request))
572
573
TRACE
574
            ,
575
        ];
576
577
        yield 'JMS Serializer field' => [
578
            <<<'DOCBLOCK'
579
/**
580
 * @Type("array<string,string>")
581
 * @SerializedName("addresses")
582
 * @XmlElement(namespace="http://example.com/namespace2")
583
 * @XmlMap(inline = false, entry = "address", keyAttribute = "id", namespace="http://example.com/namespace2")
584
 */
585
DOCBLOCK
586
            ,
587
            <<<'TRACE'
588
>  #annotations
589
>  >  #annotation
590
>  >  >  token(annot:valued_identifier, Type)
591
>  >  >  #parameters
592
>  >  >  >  #unnamed_parameter
593
>  >  >  >  >  #value
594
>  >  >  >  >  >  #string
595
>  >  >  >  >  >  >  token(string:string, array<string,string>)
596
>  >  #annotation
597
>  >  >  token(annot:valued_identifier, SerializedName)
598
>  >  >  #parameters
599
>  >  >  >  #unnamed_parameter
600
>  >  >  >  >  #value
601
>  >  >  >  >  >  #string
602
>  >  >  >  >  >  >  token(string:string, addresses)
603
>  >  #annotation
604
>  >  >  token(annot:valued_identifier, XmlElement)
605
>  >  >  #parameters
606
>  >  >  >  #named_parameter
607
>  >  >  >  >  token(value:identifier, namespace)
608
>  >  >  >  >  #value
609
>  >  >  >  >  >  #string
610
>  >  >  >  >  >  >  token(string:string, http://example.com/namespace2)
611
>  >  #annotation
612
>  >  >  token(annot:valued_identifier, XmlMap)
613
>  >  >  #parameters
614
>  >  >  >  #named_parameter
615
>  >  >  >  >  token(value:identifier, inline)
616
>  >  >  >  >  #value
617
>  >  >  >  >  >  token(value:boolean, false)
618
>  >  >  >  #named_parameter
619
>  >  >  >  >  token(value:identifier, entry)
620
>  >  >  >  >  #value
621
>  >  >  >  >  >  #string
622
>  >  >  >  >  >  >  token(string:string, address)
623
>  >  >  >  #named_parameter
624
>  >  >  >  >  token(value:identifier, keyAttribute)
625
>  >  >  >  >  #value
626
>  >  >  >  >  >  #string
627
>  >  >  >  >  >  >  token(string:string, id)
628
>  >  >  >  #named_parameter
629
>  >  >  >  >  token(value:identifier, namespace)
630
>  >  >  >  >  #value
631
>  >  >  >  >  >  #string
632
>  >  >  >  >  >  >  token(string:string, http://example.com/namespace2)
633
634
TRACE
635
            ,
636
        ];
637
638
        yield 'string escaping' => [
639
            <<<'DOCBLOCK'
640
/**
641
 * @Annotation("", "foo", "b\"a\"r", "ba\\z", "bla\h", "\\\\hello\\\\")
642
 */
643
DOCBLOCK
644
            ,
645
            <<<'TRACE'
646
>  #annotations
647
>  >  #annotation
648
>  >  >  token(annot:valued_identifier, Annotation)
649
>  >  >  #parameters
650
>  >  >  >  #unnamed_parameter
651
>  >  >  >  >  #value
652
>  >  >  >  >  >  #string
653
>  >  >  >  #unnamed_parameter
654
>  >  >  >  >  #value
655
>  >  >  >  >  >  #string
656
>  >  >  >  >  >  >  token(string:string, foo)
657
>  >  >  >  #unnamed_parameter
658
>  >  >  >  >  #value
659
>  >  >  >  >  >  #string
660
>  >  >  >  >  >  >  token(string:string, b\"a\"r)
661
>  >  >  >  #unnamed_parameter
662
>  >  >  >  >  #value
663
>  >  >  >  >  >  #string
664
>  >  >  >  >  >  >  token(string:string, ba\\z)
665
>  >  >  >  #unnamed_parameter
666
>  >  >  >  >  #value
667
>  >  >  >  >  >  #string
668
>  >  >  >  >  >  >  token(string:string, bla\h)
669
>  >  >  >  #unnamed_parameter
670
>  >  >  >  >  #value
671
>  >  >  >  >  >  #string
672
>  >  >  >  >  >  >  token(string:string, \\\\hello\\\\)
673
674
TRACE
675
            ,
676
        ];
677
678
        yield 'constants' => [
679
            <<<'DOCBLOCK'
680
/**
681
 * @Annotation(Foo\Bar::BAZ, \Foo\Bar\Baz::BLAH, PHP_EOL)
682
 */
683
DOCBLOCK
684
            ,
685
            <<<'TRACE'
686
>  #annotations
687
>  >  #annotation
688
>  >  >  token(annot:valued_identifier, Annotation)
689
>  >  >  #parameters
690
>  >  >  >  #unnamed_parameter
691
>  >  >  >  >  #value
692
>  >  >  >  >  >  #class_constant
693
>  >  >  >  >  >  >  #reference
694
>  >  >  >  >  >  >  >  token(value:identifier_ns, Foo\Bar)
695
>  >  >  >  >  >  >  token(value:identifier, BAZ)
696
>  >  >  >  #unnamed_parameter
697
>  >  >  >  >  #value
698
>  >  >  >  >  >  #class_constant
699
>  >  >  >  >  >  >  #reference
700
>  >  >  >  >  >  >  >  token(value:identifier_ns, \Foo\Bar\Baz)
701
>  >  >  >  >  >  >  token(value:identifier, BLAH)
702
>  >  >  >  #unnamed_parameter
703
>  >  >  >  >  #value
704
>  >  >  >  >  >  #standalone_constant
705
>  >  >  >  >  >  >  token(value:identifier, PHP_EOL)
706
707
TRACE
708
            ,
709
        ];
710
711
        yield [
712
            <<<'DOCBLOCK'
713
/**
714
 * @TrailingComma(
715
 *     123,
716
 *     @Foo(1, 2, 3,),
717
 *     @Bar,
718
 * )
719
 */
720
DOCBLOCK
721
            ,
722
            <<<'TRACE'
723
>  #annotations
724
>  >  #annotation
725
>  >  >  token(annot:valued_identifier, TrailingComma)
726
>  >  >  #parameters
727
>  >  >  >  #unnamed_parameter
728
>  >  >  >  >  #value
729
>  >  >  >  >  >  token(value:integer, 123)
730
>  >  >  >  #unnamed_parameter
731
>  >  >  >  >  #value
732
>  >  >  >  >  >  #annotation
733
>  >  >  >  >  >  >  token(annot:valued_identifier, Foo)
734
>  >  >  >  >  >  >  #parameters
735
>  >  >  >  >  >  >  >  #unnamed_parameter
736
>  >  >  >  >  >  >  >  >  #value
737
>  >  >  >  >  >  >  >  >  >  token(value:integer, 1)
738
>  >  >  >  >  >  >  >  #unnamed_parameter
739
>  >  >  >  >  >  >  >  >  #value
740
>  >  >  >  >  >  >  >  >  >  token(value:integer, 2)
741
>  >  >  >  >  >  >  >  #unnamed_parameter
742
>  >  >  >  >  >  >  >  >  #value
743
>  >  >  >  >  >  >  >  >  >  token(value:integer, 3)
744
>  >  >  >  #unnamed_parameter
745
>  >  >  >  >  #value
746
>  >  >  >  >  >  #annotation
747
>  >  >  >  >  >  >  token(annot:simple_identifier, Bar)
748
749
TRACE
750
            ,
751
        ];
752
753
        yield 'inline annotation' => [
754
            <<<'DOCBLOCK'
755
/**
756
 * Hello world from @Annotation
757
 */
758
DOCBLOCK
759
            ,
760
            <<<'TRACE'
761
>  #annotations
762
>  >  #annotation
763
>  >  >  token(annot:simple_identifier, Annotation)
764
765
TRACE
766
            ,
767
        ];
768
769
        yield 'oneline annotation' => [
770
            <<<'DOCBLOCK'
771
/** @var string */
772
DOCBLOCK
773
            ,
774
            <<<'TRACE'
775
>  #annotations
776
>  >  #annotation
777
>  >  >  token(annot:simple_identifier, var)
778
779
TRACE
780
            ,
781
        ];
782
    }
783
784
    /**
785
     * @return string[][]
786
     */
787
    public function validParityDocBlocksProvider() : iterable
788
    {
789
        /** @see DocParserTest::testNestedArraysWithNestedAnnotation() */
790
        yield 'Nested arrays with nested annotations' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'Nested arrays wit...le_identifier, Name) ') returns the type Generator which is incompatible with the documented return type array<mixed,string[]>.
Loading history...
791
            <<<'DOCBLOCK'
792
/**
793
 * @Name(foo={1,2, {"key"=@Name}})
794
 */
795
DOCBLOCK,
796
            <<<'TRACE'
797
>  #annotations
798
>  >  #annotation
799
>  >  >  token(annot:valued_identifier, Name)
800
>  >  >  #parameters
801
>  >  >  >  #named_parameter
802
>  >  >  >  >  token(value:identifier, foo)
803
>  >  >  >  >  #value
804
>  >  >  >  >  >  #list
805
>  >  >  >  >  >  >  #value
806
>  >  >  >  >  >  >  >  token(value:integer, 1)
807
>  >  >  >  >  >  >  #value
808
>  >  >  >  >  >  >  >  token(value:integer, 2)
809
>  >  >  >  >  >  >  #value
810
>  >  >  >  >  >  >  >  #map
811
>  >  >  >  >  >  >  >  >  #pair
812
>  >  >  >  >  >  >  >  >  >  #string
813
>  >  >  >  >  >  >  >  >  >  >  token(string:string, key)
814
>  >  >  >  >  >  >  >  >  >  #value
815
>  >  >  >  >  >  >  >  >  >  >  #annotation
816
>  >  >  >  >  >  >  >  >  >  >  >  token(annot:simple_identifier, Name)
817
818
TRACE
819
        ];
820
821
        /** @see DocParserTest::testBasicAnnotations() */
822
        yield 'Basic annotations: Marker annotation' => [
823
            <<<'DOCBLOCK'
824
/**
825
 * @Name
826
 */
827
DOCBLOCK
828
            ,
829
            <<<'TRACE'
830
>  #annotations
831
>  >  #annotation
832
>  >  >  token(annot:simple_identifier, Name)
833
834
TRACE
835
        ];
836
837
        /** @see DocParserTest::testBasicAnnotations() */
838
        yield 'Basic annotations: Associative arrays' => [
839
            <<<'DOCBLOCK'
840
/**
841
 * @Name(foo={"key1" = "value1"})
842
 */
843
DOCBLOCK
844
            ,
845
            <<<'TRACE'
846
>  #annotations
847
>  >  #annotation
848
>  >  >  token(annot:valued_identifier, Name)
849
>  >  >  #parameters
850
>  >  >  >  #named_parameter
851
>  >  >  >  >  token(value:identifier, foo)
852
>  >  >  >  >  #value
853
>  >  >  >  >  >  #map
854
>  >  >  >  >  >  >  #pair
855
>  >  >  >  >  >  >  >  #string
856
>  >  >  >  >  >  >  >  >  token(string:string, key1)
857
>  >  >  >  >  >  >  >  #value
858
>  >  >  >  >  >  >  >  >  #string
859
>  >  >  >  >  >  >  >  >  >  token(string:string, value1)
860
861
TRACE
862
        ];
863
864
        /** @see DocParserTest::testBasicAnnotations() */
865
        yield 'Basic annotations: Numerical arrays' => [
866
            <<<'DOCBLOCK'
867
/**
868
 * @Name({2="foo", 4="bar"})
869
 */
870
DOCBLOCK
871
            ,
872
            <<<'TRACE'
873
>  #annotations
874
>  >  #annotation
875
>  >  >  token(annot:valued_identifier, Name)
876
>  >  >  #parameters
877
>  >  >  >  #unnamed_parameter
878
>  >  >  >  >  #value
879
>  >  >  >  >  >  #map
880
>  >  >  >  >  >  >  #pair
881
>  >  >  >  >  >  >  >  token(value:integer, 2)
882
>  >  >  >  >  >  >  >  #value
883
>  >  >  >  >  >  >  >  >  #string
884
>  >  >  >  >  >  >  >  >  >  token(string:string, foo)
885
>  >  >  >  >  >  >  #pair
886
>  >  >  >  >  >  >  >  token(value:integer, 4)
887
>  >  >  >  >  >  >  >  #value
888
>  >  >  >  >  >  >  >  >  #string
889
>  >  >  >  >  >  >  >  >  >  token(string:string, bar)
890
891
TRACE
892
        ];
893
894
        /** @see DocParserTest::testBasicAnnotations() */
895
        yield 'Basic annotations: Multiple values' => [
896
            <<<'DOCBLOCK'
897
/**
898
 * @Name(@Name, @Name)
899
 */
900
DOCBLOCK
901
            ,
902
            <<<'TRACE'
903
>  #annotations
904
>  >  #annotation
905
>  >  >  token(annot:valued_identifier, Name)
906
>  >  >  #parameters
907
>  >  >  >  #unnamed_parameter
908
>  >  >  >  >  #value
909
>  >  >  >  >  >  #annotation
910
>  >  >  >  >  >  >  token(annot:simple_identifier, Name)
911
>  >  >  >  #unnamed_parameter
912
>  >  >  >  >  #value
913
>  >  >  >  >  >  #annotation
914
>  >  >  >  >  >  >  token(annot:simple_identifier, Name)
915
916
TRACE
917
        ];
918
919
        /** @see DocParserTest::testBasicAnnotations() */
920
        yield 'Basic annotations: Multiple types as values' => [
921
            <<<'DOCBLOCK'
922
/**
923
 * @Name(foo="Bar", @Name, {"key1"="value1", "key2"="value2"})
924
 */
925
DOCBLOCK
926
            ,
927
            <<<'TRACE'
928
>  #annotations
929
>  >  #annotation
930
>  >  >  token(annot:valued_identifier, Name)
931
>  >  >  #parameters
932
>  >  >  >  #named_parameter
933
>  >  >  >  >  token(value:identifier, foo)
934
>  >  >  >  >  #value
935
>  >  >  >  >  >  #string
936
>  >  >  >  >  >  >  token(string:string, Bar)
937
>  >  >  >  #unnamed_parameter
938
>  >  >  >  >  #value
939
>  >  >  >  >  >  #annotation
940
>  >  >  >  >  >  >  token(annot:simple_identifier, Name)
941
>  >  >  >  #unnamed_parameter
942
>  >  >  >  >  #value
943
>  >  >  >  >  >  #map
944
>  >  >  >  >  >  >  #pair
945
>  >  >  >  >  >  >  >  #string
946
>  >  >  >  >  >  >  >  >  token(string:string, key1)
947
>  >  >  >  >  >  >  >  #value
948
>  >  >  >  >  >  >  >  >  #string
949
>  >  >  >  >  >  >  >  >  >  token(string:string, value1)
950
>  >  >  >  >  >  >  #pair
951
>  >  >  >  >  >  >  >  #string
952
>  >  >  >  >  >  >  >  >  token(string:string, key2)
953
>  >  >  >  >  >  >  >  #value
954
>  >  >  >  >  >  >  >  >  #string
955
>  >  >  >  >  >  >  >  >  >  token(string:string, value2)
956
957
TRACE
958
        ];
959
960
        /** @see DocParserTest::testBasicAnnotations() */
961
        yield 'Basic annotations: Complete docblock' => [
962
            <<<'DOCBLOCK'
963
/**
964
 * Some nifty class.
965
 *
966
 * @author Mr.X
967
 * @Name(foo="bar")
968
 */
969
DOCBLOCK
970
            ,
971
            <<<'TRACE'
972
>  #annotations
973
>  >  #annotation
974
>  >  >  token(annot:simple_identifier, author)
975
>  >  #annotation
976
>  >  >  token(annot:valued_identifier, Name)
977
>  >  >  #parameters
978
>  >  >  >  #named_parameter
979
>  >  >  >  >  token(value:identifier, foo)
980
>  >  >  >  >  #value
981
>  >  >  >  >  >  #string
982
>  >  >  >  >  >  >  token(string:string, bar)
983
984
TRACE
985
        ];
986
987
        /** @see DocParserTest::testDefaultValueAnnotations() */
988
        yield 'Default value annotations: Array as first value' => [
989
            <<<'DOCBLOCK'
990
/**
991
 * @Name({"key1"="value1"})
992
 */
993
DOCBLOCK
994
            ,
995
            <<<'TRACE'
996
>  #annotations
997
>  >  #annotation
998
>  >  >  token(annot:valued_identifier, Name)
999
>  >  >  #parameters
1000
>  >  >  >  #unnamed_parameter
1001
>  >  >  >  >  #value
1002
>  >  >  >  >  >  #map
1003
>  >  >  >  >  >  >  #pair
1004
>  >  >  >  >  >  >  >  #string
1005
>  >  >  >  >  >  >  >  >  token(string:string, key1)
1006
>  >  >  >  >  >  >  >  #value
1007
>  >  >  >  >  >  >  >  >  #string
1008
>  >  >  >  >  >  >  >  >  >  token(string:string, value1)
1009
1010
TRACE
1011
        ];
1012
1013
        /** @see DocParserTest::testDefaultValueAnnotations() */
1014
        yield 'Default value annotations: Array as first value and additional values' => [
1015
            <<<'DOCBLOCK'
1016
/**
1017
 * @Name({"key1"="value1"}, foo="bar")
1018
 */
1019
DOCBLOCK
1020
            ,
1021
            <<<'TRACE'
1022
>  #annotations
1023
>  >  #annotation
1024
>  >  >  token(annot:valued_identifier, Name)
1025
>  >  >  #parameters
1026
>  >  >  >  #unnamed_parameter
1027
>  >  >  >  >  #value
1028
>  >  >  >  >  >  #map
1029
>  >  >  >  >  >  >  #pair
1030
>  >  >  >  >  >  >  >  #string
1031
>  >  >  >  >  >  >  >  >  token(string:string, key1)
1032
>  >  >  >  >  >  >  >  #value
1033
>  >  >  >  >  >  >  >  >  #string
1034
>  >  >  >  >  >  >  >  >  >  token(string:string, value1)
1035
>  >  >  >  #named_parameter
1036
>  >  >  >  >  token(value:identifier, foo)
1037
>  >  >  >  >  #value
1038
>  >  >  >  >  >  #string
1039
>  >  >  >  >  >  >  token(string:string, bar)
1040
1041
TRACE
1042
        ];
1043
1044
        /** @see DocParserTest::testDefaultValueAnnotations() */
1045
        yield 'Namespaced annotations' => [
1046
            <<<'DOCBLOCK'
1047
/**
1048
 * Some nifty class.
1049
 *
1050
 * @package foo
1051
 * @subpackage bar
1052
 * @author Mr.X <[email protected]>
1053
 * @Doctrine\Tests\Annotations\Name(foo="bar")
1054
 * @ignore
1055
 */
1056
DOCBLOCK
1057
            ,
1058
            <<<'TRACE'
1059
>  #annotations
1060
>  >  #annotation
1061
>  >  >  token(annot:simple_identifier, package)
1062
>  >  #annotation
1063
>  >  >  token(annot:simple_identifier, subpackage)
1064
>  >  #annotation
1065
>  >  >  token(annot:simple_identifier, author)
1066
>  >  #annotation
1067
>  >  >  token(annot:simple_identifier, x)
1068
>  >  #annotation
1069
>  >  >  token(annot:valued_identifier, Doctrine\Tests\Annotations\Name)
1070
>  >  >  #parameters
1071
>  >  >  >  #named_parameter
1072
>  >  >  >  >  token(value:identifier, foo)
1073
>  >  >  >  >  #value
1074
>  >  >  >  >  >  #string
1075
>  >  >  >  >  >  >  token(string:string, bar)
1076
>  >  #annotation
1077
>  >  >  token(annot:simple_identifier, ignore)
1078
1079
TRACE
1080
        ];
1081
1082
        /** @see DocParserTest::testTypicalMethodDocBlock() */
1083
        yield 'Namespaced annotations' => [
1084
            <<<'DOCBLOCK'
1085
/**
1086
 * Some nifty method.
1087
 *
1088
 * @since 2.0
1089
 * @Doctrine\Tests\Annotations\Name(foo="bar")
1090
 * @param string \$foo This is foo.
1091
 * @param mixed \$bar This is bar.
1092
 * @return string Foo and bar.
1093
 * @This is irrelevant
1094
 * @Marker
1095
 */
1096
DOCBLOCK
1097
            ,
1098
            <<<'TRACE'
1099
>  #annotations
1100
>  >  #annotation
1101
>  >  >  token(annot:simple_identifier, since)
1102
>  >  #annotation
1103
>  >  >  token(annot:valued_identifier, Doctrine\Tests\Annotations\Name)
1104
>  >  >  #parameters
1105
>  >  >  >  #named_parameter
1106
>  >  >  >  >  token(value:identifier, foo)
1107
>  >  >  >  >  #value
1108
>  >  >  >  >  >  #string
1109
>  >  >  >  >  >  >  token(string:string, bar)
1110
>  >  #annotation
1111
>  >  >  token(annot:simple_identifier, param)
1112
>  >  #annotation
1113
>  >  >  token(annot:simple_identifier, param)
1114
>  >  #annotation
1115
>  >  >  token(annot:simple_identifier, return)
1116
>  >  #annotation
1117
>  >  >  token(annot:simple_identifier, This)
1118
>  >  #annotation
1119
>  >  >  token(annot:simple_identifier, Marker)
1120
1121
TRACE
1122
        ];
1123
    }
1124
1125
    /**
1126
     * @return string[][]
1127
     */
1128
    public function invalidGrammarProvider() : iterable
1129
    {
1130
        yield 'broken unpaired parenthesis' => [
0 ignored issues
show
Bug Best Practice introduced by
The expression yield 'broken unpaired p...Foo( */ ↑') returns the type Generator which is incompatible with the documented return type array<mixed,string[]>.
Loading history...
1131
            <<<'DOCBLOCK'
1132
/** @Foo( */
1133
DOCBLOCK
1134
            ,
1135
            <<<'ERROR'
1136
/** @Foo( */
1137
1138
ERROR
1139
        ];
1140
1141
        /** @see DocParserTest::testAnnotationDontAcceptSingleQuotes() */
1142
        yield 'single quotes' => [
1143
            <<<'DOCBLOCK'
1144
/** @Name(foo='bar') */
1145
DOCBLOCK
1146
            ,
1147
            <<<'ERROR'
1148
/** @Name(foo='bar') */
1149
1150
ERROR
1151
        ];
1152
    }
1153
}
1154