1 package org.codehaus.groovy.syntax.parser;
2
3 import groovy.util.GroovyTestCase;
4
5 import org.codehaus.groovy.control.CompilationFailedException;
6 import org.codehaus.groovy.control.SourceUnit;
7
8 /*
9 import org.codehaus.groovy.syntax.lexer.CharStream;
10 import org.codehaus.groovy.syntax.lexer.StringCharStream;
11 import org.codehaus.groovy.syntax.lexer.Lexer;
12 import org.codehaus.groovy.syntax.lexer.LexerTokenStream;
13 import org.codehaus.groovy.syntax.Token;
14 import org.codehaus.groovy.syntax.TokenStream;
15 import org.codehaus.groovy.tools.ExceptionCollector;
16 */
17
18 public class ParserTest extends GroovyTestCase {
19
20 private int tolerance = 0;
21
22
23 /***
24 * This test case performs the same logic as the interactive shell to
25 * decide if a statement is complete or not
26 */
27 public void testParserThrowsTheRightException() throws Exception {
28 String code = "class Cheese {";
29 SourceUnit parser = null;
30
31 try {
32 parser = SourceUnit.create("groovysh script", code, tolerance);
33 parser.parse();
34 parser.getCST();
35 }
36 catch (CompilationFailedException e) {
37 assertTrue("Parser should have failed with Unexpected EOF flag", parser.failedWithUnexpectedEOF());
38 assertTrue("Parser should have an error count of 1 or less", parser.getErrorCount() <= 1);
39 }
40 }
41
42
43 /*
44 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45 // package
46 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47
48 public void testEmptyScript() throws Exception {
49 Parser parser = newParser("");
50
51 CSTNode root = parser.compilationUnit();
52
53 assertEquals(null, root.getToken());
54
55 System.out.println("Root: " + root);
56 {
57 CSTNode child = root.getChild(0);
58
59 System.out.println("Child: "+ child);
60
61 //assertEquals(null, child);
62 }
63 }
64
65 public void testPackageDeclaration_NoDots() throws Exception {
66 Parser parser = newParser("package cheese");
67
68 CSTNode root = parser.packageDeclaration();
69
70 assertNode(root, "package", Token.KEYWORD_PACKAGE, 1);
71
72 {
73 assertNode(root.getChild(0), "cheese", Token.IDENTIFIER, 0);
74 }
75 }
76
77 public void testPackageDeclaration_OneDot() throws Exception {
78 Parser parser = newParser("package cheese.toast");
79
80 CSTNode root = parser.packageDeclaration();
81
82 assertNode(root, "package", Token.KEYWORD_PACKAGE, 1);
83
84 {
85 assertNode(root.getChild(0), ".", Token.DOT, 2);
86
87 {
88 assertNode(root.getChild(0).getChild(0), "cheese", Token.IDENTIFIER, 0);
89
90 assertNode(root.getChild(0).getChild(1), "toast", Token.IDENTIFIER, 0);
91 }
92 }
93 }
94
95 public void testPackageDeclaration_MultipleDots() throws Exception {
96 Parser parser = newParser("package cheddar.cheese.toast");
97
98 CSTNode root = parser.packageDeclaration();
99
100 assertNode(root, "package", Token.KEYWORD_PACKAGE, 1);
101
102 {
103 assertNode(root.getChild(0), ".", Token.DOT, 2);
104
105 {
106 assertNode(root.getChild(0).getChild(0), ".", Token.DOT, 2);
107 {
108 assertNode(root.getChild(0).getChild(0).getChild(0), "cheddar", Token.IDENTIFIER, 0);
109
110 assertNode(root.getChild(0).getChild(0).getChild(1), "cheese", Token.IDENTIFIER, 0);
111 }
112
113 assertNode(root.getChild(0).getChild(1), "toast", Token.IDENTIFIER, 0);
114 }
115 }
116 }
117
118 public void testPackageDeclaration_UnexpectedToken_NoInitialIdentifier() throws Exception {
119 Parser parser = newParser("package .");
120
121 try {
122 try {
123 parser.packageDeclaration();
124 fail("should have thrown UnexpectedTokenException");
125 }
126 catch( ExceptionCollector e ) {
127 e.throwFirstChild();
128 }
129 }
130 catch (UnexpectedTokenException e) {
131 // expected and correct
132 assertToken(e.getUnexpectedToken(), ".", Token.DOT);
133
134 assertLength(1, e.getExpectedTypes());
135
136 assertContains(Token.IDENTIFIER, e.getExpectedTypes());
137 }
138 }
139
140 public void testPackageDeclaration_UnexpectedToken_NoIdentifierFollowingDot() throws Exception {
141 Parser parser = newParser("package cheese.");
142
143 try {
144 try {
145 parser.packageDeclaration();
146 fail("should have thrown UnexpectedTokenException");
147 }
148 catch( ExceptionCollector e ) {
149 e.throwFirstChild();
150 }
151 }
152 catch (UnexpectedTokenException e) {
153 // expected and correct
154 assertNull(e.getUnexpectedToken());
155
156 assertLength(1, e.getExpectedTypes());
157
158 assertContains(Token.IDENTIFIER, e.getExpectedTypes());
159 }
160 }
161
162 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163 // import
164 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
165
166 public void testImportStatement_NoDots() throws Exception {
167 Parser parser = newParser("import Cheese");
168
169 CSTNode root = parser.importStatement();
170
171 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
172
173 {
174 assertNullNode(root.getChild(0), 0);
175
176 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
177 }
178 }
179
180 public void testImportStatement_As_NoDots() throws Exception {
181 Parser parser = newParser("import Cheese as Toast");
182
183 CSTNode root = parser.importStatement();
184
185 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
186
187 {
188 assertNullNode(root.getChild(0), 0);
189
190 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 1);
191
192 assertNode(root.getChild(1).getChild(0), "Toast", Token.IDENTIFIER, 0);
193 }
194 }
195
196 public void testImportStatement_OneDot() throws Exception {
197 Parser parser = newParser("import cheese.Toast");
198
199 CSTNode root = parser.importStatement();
200
201 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
202
203 {
204 assertNode(root.getChild(0), "cheese", Token.IDENTIFIER, 0);
205 assertNode(root.getChild(1), "Toast", Token.IDENTIFIER, 0);
206 }
207 }
208
209 public void testImportStatement_As_OneDot() throws Exception {
210 Parser parser = newParser("import cheese.Toast as Bread");
211
212 CSTNode root = parser.importStatement();
213
214 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
215
216 {
217 assertNode(root.getChild(0), "cheese", Token.IDENTIFIER, 0);
218
219 assertNode(root.getChild(1), "Toast", Token.IDENTIFIER, 1);
220
221 assertNode(root.getChild(1).getChild(0), "Bread", Token.IDENTIFIER, 0);
222 }
223 }
224
225 public void testImportStatement_MultipleDots() throws Exception {
226 Parser parser = newParser("import cheddar.cheese.Toast");
227
228 CSTNode root = parser.importStatement();
229
230 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
231
232 {
233 assertNode(root.getChild(0), ".", Token.DOT, 2);
234 {
235 assertNode(root.getChild(0).getChild(0), "cheddar", Token.IDENTIFIER, 0);
236 assertNode(root.getChild(0).getChild(1), "cheese", Token.IDENTIFIER, 0);
237 }
238
239 assertNode(root.getChild(1), "Toast", Token.IDENTIFIER, 0);
240 }
241 }
242
243 public void testImportStatement_As_MultipleDots() throws Exception {
244 Parser parser = newParser("import cheddar.cheese.Toast as Bread");
245
246 CSTNode root = parser.importStatement();
247
248 assertNode(root, "import", Token.KEYWORD_IMPORT, 2);
249
250 {
251 assertNode(root.getChild(0), ".", Token.DOT, 2);
252 {
253 assertNode(root.getChild(0).getChild(0), "cheddar", Token.IDENTIFIER, 0);
254 assertNode(root.getChild(0).getChild(1), "cheese", Token.IDENTIFIER, 0);
255 }
256
257 assertNode(root.getChild(1), "Toast", Token.IDENTIFIER, 1);
258 assertNode(root.getChild(1).getChild(0), "Bread", Token.IDENTIFIER, 0);
259 }
260 }
261
262 public void testImportStatement_UnexpectedToken_NoInitialIdentifier() throws Exception {
263 Parser parser = newParser("import .");
264
265 try {
266 try {
267 parser.importStatement();
268 fail("should have thrown UnexpectedTokenException");
269 }
270 catch( ExceptionCollector e ) {
271 e.throwFirstChild();
272 }
273 }
274 catch (UnexpectedTokenException e) {
275 // expected and correct
276 assertToken(e.getUnexpectedToken(), ".", Token.DOT);
277
278 assertLength(1, e.getExpectedTypes());
279
280 assertContains(Token.IDENTIFIER, e.getExpectedTypes());
281 }
282 }
283
284 public void testImportStatement_UnexpectedToken_NoIdentifierFollowingDot() throws Exception {
285 Parser parser = newParser("import cheese.");
286
287 try {
288 try {
289 parser.importStatement();
290 fail("should have thrown UnexpectedTokenException");
291 }
292 catch( ExceptionCollector e ) {
293 e.throwFirstChild();
294 }
295 }
296 catch (UnexpectedTokenException e) {
297 // expected and correct
298 assertNull(e.getUnexpectedToken());
299
300 assertLength(1, e.getExpectedTypes());
301
302 assertContains(Token.IDENTIFIER, e.getExpectedTypes());
303 }
304 }
305
306 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
307 // class
308 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
309
310 public void testClassDeclaration_NoModifiers_NoBody_NoExtendsOrImplements() throws Exception {
311 Parser parser = newParser("class Cheese { }");
312
313 CSTNode modifiers = new CSTNode();
314
315 CSTNode root = parser.classDeclaration(modifiers);
316
317 assertNode(root, "class", Token.KEYWORD_CLASS, 5);
318
319 {
320 assertSame(modifiers, root.getChild(0));
321
322 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
323
324 assertNullNode(root.getChild(2), 0);
325
326 assertNullNode(root.getChild(3), 0);
327
328 assertNullNode(root.getChild(4), 0);
329 }
330 }
331
332 public void testClassDeclaration_NoIdentifier() throws Exception {
333 Parser parser = newParser("class {");
334
335 CSTNode modifiers = new CSTNode();
336
337 try {
338 try {
339 parser.classDeclaration(modifiers);
340 }
341 catch( ExceptionCollector e ) {
342 e.throwFirstChild();
343 }
344 }
345 catch (UnexpectedTokenException e) {
346 // expected and correct
347 assertToken(e.getUnexpectedToken(), "{", Token.LEFT_CURLY_BRACE);
348
349 assertLength(1, e.getExpectedTypes());
350
351 assertContains(Token.IDENTIFIER, e.getExpectedTypes());
352 }
353 }
354
355 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
356 // interface
357 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
358
359 public void testInterfaceDeclaration_NoModifiers_NoBody_NoExtendsOrImplements() throws Exception {
360 Parser parser = newParser("interface Cheese { }");
361
362 CSTNode modifiers = new CSTNode();
363
364 CSTNode root = parser.interfaceDeclaration(modifiers);
365
366 assertNode(root, "interface", Token.KEYWORD_INTERFACE, 5);
367
368 {
369 assertSame(modifiers, root.getChild(0));
370
371 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
372
373 assertNullNode(root.getChild(2), 0);
374 }
375 }
376
377 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
378 // <type declaration>
379 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
380
381 public void testTypeDeclaration_Class_NoModifiers_NoBody_NoExtendsOrImplements() throws Exception {
382 Parser parser = newParser("class Cheese { }");
383
384 CSTNode root = parser.typeDeclaration();
385
386 assertNode(root, "class", Token.KEYWORD_CLASS, 5);
387
388 {
389 assertNullNode(root.getChild(0), 0);
390
391 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
392
393 assertNullNode(root.getChild(2), 0);
394
395 assertNullNode(root.getChild(3), 0);
396
397 assertNullNode(root.getChild(4), 0);
398 }
399 }
400
401 public void testTypeDeclaration_Class_WithModifiers_NoBody_NoExtendsOrImplements() throws Exception {
402 Parser parser = newParser("public class Cheese { }");
403
404 CSTNode root = parser.typeDeclaration();
405
406 assertNode(root, "class", Token.KEYWORD_CLASS, 5);
407
408 {
409 assertNullNode(root.getChild(0), 1);
410 {
411 assertNode(root.getChild(0).getChild(0), "public", Token.KEYWORD_PUBLIC, 0);
412 }
413
414 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
415
416 assertNullNode(root.getChild(2), 0);
417
418 assertNullNode(root.getChild(3), 0);
419
420 assertNullNode(root.getChild(4), 0);
421 }
422 }
423
424 public void testTypeDeclaration_Interface_NoModifiers_NoBody_NoExtendsOrImplements() throws Exception {
425 Parser parser = newParser("interface Cheese { }");
426
427 CSTNode root = parser.typeDeclaration();
428
429 assertNode(root, "interface", Token.KEYWORD_INTERFACE, 5);
430
431 {
432 assertNullNode(root.getChild(0), 0);
433
434 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
435
436 assertNullNode(root.getChild(2), 0);
437 }
438 }
439
440 public void testTypeDeclaration_Interface_WithModifiers_NoBody_NoExtendsOrImplements() throws Exception {
441 Parser parser = newParser("public interface Cheese { }");
442
443 CSTNode root = parser.typeDeclaration();
444
445 assertNode(root, "interface", Token.KEYWORD_INTERFACE, 5);
446
447 {
448 assertNullNode(root.getChild(0), 1);
449 {
450 assertNode(root.getChild(0).getChild(0), "public", Token.KEYWORD_PUBLIC, 0);
451 }
452
453 assertNode(root.getChild(1), "Cheese", Token.IDENTIFIER, 0);
454
455 assertNullNode(root.getChild(2), 0);
456 }
457 }
458
459 /* /*
460
461 The following is actually now valid...
462
463 public void testTypeDeclaration_UnexpectedToken()
464 throws Exception
465 {
466 Parser parser = newParser( "cheese" );
467
468 try
469 {
470 try {
471 parser.typeDeclaration();
472 fail( "should have thrown UnexpectedTokenException" );
473 }
474 catch( ExceptionCollector e ) {
475 e.throwFirstChild();
476 }
477 }
478 catch (UnexpectedTokenException e)
479 {
480 assertToken( e.getToken(),
481 "cheese",
482 Token.IDENTIFIER );
483
484 assertLength( 2,
485 e.getExpectedTypes() );
486
487 assertContains( Token.KEYWORD_CLASS,
488 e.getExpectedTypes() );
489
490 assertContains( Token.KEYWORD_INTERFACE,
491 e.getExpectedTypes() );
492 }
493 }
494 */
495 /*
496
497 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
498 // <compilation unit>
499 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
500
501 public void testCompilationUnit_NoImports_OneClass() throws Exception {
502 Parser parser = newParser("package cheese; public class Cheese{}");
503
504 CSTNode root = parser.compilationUnit();
505
506 assertNullNode(root, 3);
507
508 {
509 assertNode(root.getChild(0), "package", Token.KEYWORD_PACKAGE, 1);
510
511 {
512 assertNode(root.getChild(0).getChild(0), "cheese", Token.IDENTIFIER, 0);
513 }
514
515 assertNullNode(root.getChild(1), 0);
516
517 assertNode(root.getChild(2), "class", Token.KEYWORD_CLASS, 5);
518 }
519 }
520
521 public void testCompilationUnit_NoImports_OneInterface() throws Exception {
522 Parser parser = newParser("package cheese; public interface Cheese{}");
523
524 CSTNode root = parser.compilationUnit();
525
526 assertNullNode(root, 3);
527
528 {
529 assertNode(root.getChild(0), "package", Token.KEYWORD_PACKAGE, 1);
530
531 {
532 assertNode(root.getChild(0).getChild(0), "cheese", Token.IDENTIFIER, 0);
533 }
534
535 assertNullNode(root.getChild(1), 0);
536
537 assertNode(root.getChild(2), "interface", Token.KEYWORD_INTERFACE, 5);
538 }
539 }
540
541 public void testCompilationUnit_WithImports_OneClass() throws Exception {
542 Parser parser = newParser("package cheese; import com.Toast; import com.Jelly; public class Cheese{}");
543
544 CSTNode root = parser.compilationUnit();
545
546 assertNullNode(root, 3);
547
548 {
549 assertNode(root.getChild(0), "package", Token.KEYWORD_PACKAGE, 1);
550
551 {
552 assertNode(root.getChild(0).getChild(0), "cheese", Token.IDENTIFIER, 0);
553 }
554
555 assertNullNode(root.getChild(1), 2);
556
557 {
558 assertNode(root.getChild(1).getChild(0), "import", Token.KEYWORD_IMPORT, 2);
559
560 assertNode(root.getChild(1).getChild(1), "import", Token.KEYWORD_IMPORT, 2);
561 }
562
563 assertNode(root.getChild(2), "class", Token.KEYWORD_CLASS, 5);
564 }
565 }
566
567 public void testCompilationUnit_WithImports_TwoClasses() throws Exception {
568 Parser parser =
569 newParser("package cheese; import com.Toast; import com.Jelly; public class Cheese{} public class Goober {}");
570
571 CSTNode root = parser.compilationUnit();
572
573 assertNullNode(root, 4);
574
575 {
576 assertNode(root.getChild(0), "package", Token.KEYWORD_PACKAGE, 1);
577
578 {
579 assertNode(root.getChild(0).getChild(0), "cheese", Token.IDENTIFIER, 0);
580 }
581
582 assertNullNode(root.getChild(1), 2);
583
584 {
585 assertNode(root.getChild(1).getChild(0), "import", Token.KEYWORD_IMPORT, 2);
586
587 assertNode(root.getChild(1).getChild(1), "import", Token.KEYWORD_IMPORT, 2);
588 }
589
590 assertNode(root.getChild(2), "class", Token.KEYWORD_CLASS, 5);
591 {
592 assertNode(root.getChild(2).getChild(1), "Cheese", Token.IDENTIFIER, 0);
593 }
594
595 assertNode(root.getChild(3), "class", Token.KEYWORD_CLASS, 5);
596 {
597 assertNode(root.getChild(3).getChild(1), "Goober", Token.IDENTIFIER, 0);
598 }
599 }
600 }
601
602 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
603 // <body statement>
604 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
605
606 public void testBodyStatement_PropertyDeclaration_NoModifiers_NoType() throws Exception {
607 Parser parser = newParser("property cheese;");
608
609 CSTNode root = parser.bodyStatement();
610
611 System.out.println("Got: " + root);
612
613 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
614
615 {
616 assertNullNode(root.getChild(0), 0);
617
618 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
619
620 assertNullNode(root.getChild(2), 0);
621 }
622 }
623
624 public void testBodyStatement_PropertyDeclaration_OneModifier_NoType() throws Exception {
625 Parser parser = newParser("static property cheese;");
626
627 CSTNode root = parser.bodyStatement();
628
629 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
630
631 {
632 assertNullNode(root.getChild(0), 1);
633
634 {
635 assertNode(root.getChild(0).getChild(0), "static", Token.KEYWORD_STATIC, 0);
636 }
637
638 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
639
640 assertNullNode(root.getChild(2), 0);
641 }
642 }
643
644 public void testBodyStatement_PropertyDeclaration_TwoModifiers_NoType() throws Exception {
645 Parser parser = newParser("static synchronized property cheese;");
646
647 CSTNode root = parser.bodyStatement();
648
649 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
650
651 {
652 assertNullNode(root.getChild(0), 2);
653
654 {
655 assertNode(root.getChild(0).getChild(0), "static", Token.KEYWORD_STATIC, 0);
656
657 assertNode(root.getChild(0).getChild(1), "synchronized", Token.KEYWORD_SYNCHRONIZED, 0);
658 }
659
660 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
661
662 assertNullNode(root.getChild(2), 0);
663 }
664 }
665
666 public void testBodyStatement_PropertyDeclaration_NoProperty_NoModifiers_NoType() throws Exception {
667 Parser parser = newParser("cheese;");
668
669 CSTNode root = parser.bodyStatement();
670
671 System.out.println("Got: " + root);
672
673 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
674
675 {
676 assertNullNode(root.getChild(0), 0);
677
678 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
679
680 assertNullNode(root.getChild(2), 0);
681 }
682 }
683
684 public void testBodyStatement_PropertyDeclaration_NoProperty_OneModifier_NoType() throws Exception {
685 Parser parser = newParser("static cheese;");
686
687 CSTNode root = parser.bodyStatement();
688
689 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
690
691 {
692 assertNullNode(root.getChild(0), 1);
693
694 {
695 assertNode(root.getChild(0).getChild(0), "static", Token.KEYWORD_STATIC, 0);
696 }
697
698 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
699
700 assertNullNode(root.getChild(2), 0);
701 }
702 }
703
704 public void testBodyStatement_PropertyDeclaration_NoProperty_TwoModifiers_NoType() throws Exception {
705 Parser parser = newParser("static synchronized cheese;");
706
707 CSTNode root = parser.bodyStatement();
708
709 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
710
711 {
712 assertNullNode(root.getChild(0), 2);
713
714 {
715 assertNode(root.getChild(0).getChild(0), "static", Token.KEYWORD_STATIC, 0);
716
717 assertNode(root.getChild(0).getChild(1), "synchronized", Token.KEYWORD_SYNCHRONIZED, 0);
718 }
719
720 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
721
722 assertNullNode(root.getChild(2), 0);
723 }
724 }
725
726 public void testBodyStatement_PropertyDeclaration_NoType_WithExpression() throws Exception {
727 Parser parser = newParser("cheese = 1234");
728
729 CSTNode root = parser.bodyStatement();
730
731 assertNode(root, "property", Token.KEYWORD_PROPERTY, 4);
732
733 {
734 assertNullNode(root.getChild(0), 0);
735
736 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
737
738 assertNullNode(root.getChild(2), 0);
739
740 assertNode(root.getChild(3), "1234", Token.INTEGER_NUMBER, 0);
741 }
742 }
743
744 public void testBodyStatement_PropertyDeclaration_Type_WithExpression() throws Exception {
745 Parser parser = newParser("Food cheese = defaultValue()");
746
747 CSTNode root = parser.bodyStatement();
748
749 assertNode(root, "property", Token.KEYWORD_PROPERTY, 4);
750
751 {
752 assertNullNode(root.getChild(0), 0);
753
754 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
755
756 assertNode(root.getChild(2), "Food", Token.IDENTIFIER, 0);
757
758 assertNode(root.getChild(3), "(", Token.LEFT_PARENTHESIS, 3);
759 }
760 }
761
762 public void testBodyStatement_MethodDeclaration_NoReturnType_NoParameters() throws Exception {
763 Parser parser = newParser("cheeseIt() { } ");
764
765 CSTNode root = parser.bodyStatement();
766
767 assertNode(root, "<synthetic>", Token.SYNTH_METHOD, 6);
768
769 {
770 assertNullNode(root.getChild(0), 0);
771
772 assertNode(root.getChild(1), "cheeseIt", Token.IDENTIFIER, 0);
773
774 assertNullNode(root.getChild(2), 0);
775
776 assertNode(root.getChild(3), "(", Token.LEFT_PARENTHESIS, 0);
777 }
778 }
779
780 public void testBodyStatement_MethodDeclaration_WithReturnType_NoParameters() throws Exception {
781 Parser parser = newParser("String cheeseIt() { }");
782
783 CSTNode root = parser.bodyStatement();
784
785 assertNode(root, "<synthetic>", Token.SYNTH_METHOD, 6);
786
787 {
788 assertNullNode(root.getChild(0), 0);
789
790 assertNode(root.getChild(1), "cheeseIt", Token.IDENTIFIER, 0);
791
792 assertNode(root.getChild(2), "String", Token.IDENTIFIER, 0);
793
794 assertNode(root.getChild(3), "(", Token.LEFT_PARENTHESIS, 0);
795 }
796 }
797
798 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
799 // <parameter>
800 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
801
802 public void testParameterList() throws Exception {
803 }
804
805 public void testParameterDeclarationWithoutDatatype() throws Exception {
806 Parser parser = newParser("cheese");
807
808 CSTNode root = parser.parameterDeclaration();
809
810 assertNode(root, "<synthetic>", Token.SYNTH_PARAMETER_DECLARATION, 2);
811
812 {
813 assertNullNode(root.getChild(0), 0);
814
815 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
816 }
817 }
818
819 public void testParameterDeclarationWithDatatype_Simple() throws Exception {
820 Parser parser = newParser("String cheese");
821
822 CSTNode root = parser.parameterDeclaration();
823
824 assertNode(root, "<synthetic>", Token.SYNTH_PARAMETER_DECLARATION, 2);
825
826 {
827 assertNode(root.getChild(0), "String", Token.IDENTIFIER, 0);
828
829 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
830 }
831 }
832
833 public void testParameterDeclarationWithDatatype_Qualified() throws Exception {
834 Parser parser = newParser("java.lang.String cheese");
835
836 CSTNode root = parser.parameterDeclaration();
837
838 assertNode(root, "<synthetic>", Token.SYNTH_PARAMETER_DECLARATION, 2);
839
840 {
841 assertNode(root.getChild(0), ".", Token.DOT, 2);
842 {
843 assertNode(root.getChild(0).getChild(0), ".", Token.DOT, 2);
844
845 {
846 assertNode(root.getChild(0).getChild(0).getChild(0), "java", Token.IDENTIFIER, 0);
847
848 assertNode(root.getChild(0).getChild(0).getChild(1), "lang", Token.IDENTIFIER, 0);
849 }
850
851 assertNode(root.getChild(0).getChild(1), "String", Token.IDENTIFIER, 0);
852 }
853
854 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
855 }
856 }
857
858 public void testParameterDeclaration_General_WithoutDatatype() throws Exception {
859 Parser parser = newParser("cheese");
860
861 CSTNode root = parser.parameterDeclaration();
862
863 assertNode(root, "<synthetic>", Token.SYNTH_PARAMETER_DECLARATION, 2);
864
865 {
866 assertNullNode(root.getChild(0), 0);
867
868 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
869 }
870 }
871
872 public void testParameterDeclaration_General_WithDatatype() throws Exception {
873 Parser parser = newParser("String cheese");
874
875 CSTNode root = parser.parameterDeclaration();
876
877 assertNode(root, "<synthetic>", Token.SYNTH_PARAMETER_DECLARATION, 2);
878
879 {
880 assertNode(root.getChild(0), "String", Token.IDENTIFIER, 0);
881
882 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
883 }
884 }
885
886 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
887 // <parameter list>
888 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
889
890 public void testParameterList_Empty() throws Exception {
891 Parser parser = newParser("");
892
893 CSTNode root = parser.parameterDeclarationList();
894
895 assertNullNode(root, 0);
896 }
897
898 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
899 // method
900 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
901
902 public void testMethod_NoModifiers_NoReturnType_NoParameters() throws Exception {
903 Parser parser = newParser("cheeseIt() { }");
904
905 CSTNode root = parser.bodyStatement();
906
907 assertNode(root, "<synthetic>", Token.SYNTH_METHOD, 6);
908
909 {
910 assertNullNode(root.getChild(0), 0);
911
912 assertNode(root.getChild(1), "cheeseIt", Token.IDENTIFIER, 0);
913
914 assertNullNode(root.getChild(2), 0);
915
916 assertNode(root.getChild(3), "(", Token.LEFT_PARENTHESIS, 0);
917 }
918 }
919
920 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
921 // property
922 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
923
924 public void testProperty_NoModifiers_NoType() throws Exception {
925 Parser parser = newParser("property cheese");
926
927 CSTNode root = parser.bodyStatement();
928
929 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
930
931 {
932 assertNullNode(root.getChild(0), 0);
933
934 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
935
936 assertNullNode(root.getChild(2), 0);
937 }
938 }
939
940 public void testProperty_NoModifiers_NoProperty_NoType() throws Exception {
941 Parser parser = newParser("cheese");
942
943 CSTNode root = parser.bodyStatement();
944
945 assertNode(root, "property", Token.KEYWORD_PROPERTY, 3);
946
947 {
948 assertNullNode(root.getChild(0), 0);
949
950 assertNode(root.getChild(1), "cheese", Token.IDENTIFIER, 0);
951
952 assertNullNode(root.getChild(2), 0);
953 }
954 }
955
956 // ((misc))
957 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
958
959 public void testIsModifier() throws Exception {
960 assertTrue(Token.isModifier(Token.KEYWORD_PUBLIC));
961 assertTrue(Token.isModifier(Token.KEYWORD_PROTECTED));
962 assertTrue(Token.isModifier(Token.KEYWORD_PRIVATE));
963 assertTrue(Token.isModifier(Token.KEYWORD_STATIC));
964 assertTrue(Token.isModifier(Token.KEYWORD_FINAL));
965 assertTrue(Token.isModifier(Token.KEYWORD_SYNCHRONIZED));
966 assertFalse(Token.isModifier(Token.IDENTIFIER));
967 }
968
969 public void testConsumeUntil_Found() throws Exception {
970 Parser parser = newParser("cheese toast is; bread");
971
972 assertToken(parser.la(), "cheese", Token.IDENTIFIER);
973
974 parser.consumeUntil(Token.SEMICOLON);
975
976 assertToken(parser.la(), "bread", Token.IDENTIFIER);
977 }
978
979 public void testConsumeUntil_NotFound() throws Exception {
980 Parser parser = newParser("cheese toast");
981
982 assertToken(parser.la(), "cheese", Token.IDENTIFIER);
983
984 parser.consumeUntil(Token.SEMICOLON);
985
986 assertNull(parser.la());
987 }
988
989 public void testAssignmentExpression() throws Exception {
990 Parser parser = newParser("answer = list.collect( { item | return item * 2 } )");
991
992 CSTNode root = parser.expression();
993 }
994
995 public void testSafeMethodCallExpression() throws Exception {
996 Parser parser = newParser("answer = foo->someMethod()");
997
998 CSTNode root = parser.expression();
999
1000 System.out.println("Got: " + root);
1001 }
1002
1003 public void testLogicalAndExpression() throws Exception {
1004 Parser parser = newParser("x > 1 && \n y < 2");
1005
1006 CSTNode root = parser.expression();
1007
1008 System.out.println("Got: " + root);
1009 }
1010
1011 public void testStatement_CharacterizeMePlease() throws Exception {
1012 Parser parser = newParser("callBlock(5, { owner | owner.incrementCallCount() })");
1013
1014 CSTNode root = parser.statement();
1015 }
1016
1017 public void testStatementBlock_CharacterizeMePlease() throws Exception {
1018 Parser parser =
1019 newParser("keys = answer.collect( { entry | return entry.key } ); values = answer.collect( { entry | return entry.value })");
1020
1021 CSTNode root = parser.statement();
1022
1023 root = parser.statement();
1024 }
1025
1026 public void testStatementBlock_MissingSemicolon() throws Exception {
1027 Parser parser =
1028 newParser("keys = answer.collect( { entry | return entry.key } ) values = answer.collect( { entry | return entry.value })");
1029
1030 try {
1031 try {
1032 parser.statement();
1033 fail("should have thrown UnexpectedTokenException");
1034 }
1035 catch( ExceptionCollector e ) {
1036 e.throwFirstChild();
1037 }
1038 }
1039 catch (UnexpectedTokenException e) {
1040 }
1041 }
1042
1043 public void testNewExpression() throws Exception {
1044 Parser parser = newParser("new Cheese()");
1045
1046 CSTNode root = parser.newExpression();
1047
1048 assertNode(root, "new", Token.KEYWORD_NEW, 2);
1049
1050 {
1051 assertNode(root.getChild(0), "Cheese", Token.IDENTIFIER, 0);
1052
1053 assertNode(root.getChild(1), "<synthetic>", Token.SYNTH_LIST, 0);
1054 }
1055 }
1056
1057 public void testDatatype_NoDots() throws Exception {
1058 Parser parser = newParser("Cheese");
1059
1060 CSTNode root = parser.datatype();
1061
1062 assertNode(root, "Cheese", Token.IDENTIFIER, 0);
1063 }
1064
1065 public void testDatatype_OneDot() throws Exception {
1066 Parser parser = newParser("cheese.Toast");
1067
1068 CSTNode root = parser.datatype();
1069
1070 assertNode(root, ".", Token.DOT, 2);
1071 {
1072 assertNode(root.getChild(0), "cheese", Token.IDENTIFIER, 0);
1073
1074 assertNode(root.getChild(1), "Toast", Token.IDENTIFIER, 0);
1075 }
1076 }
1077
1078 public void testDatatype_TwoDots() throws Exception {
1079 Parser parser = newParser("toast.is.Bread");
1080
1081 CSTNode root = parser.datatype();
1082
1083 assertNode(root, ".", Token.DOT, 2);
1084 {
1085 assertNode(root.getChild(0), ".", Token.DOT, 2);
1086 {
1087 assertNode(root.getChild(0).getChild(0), "toast", Token.IDENTIFIER, 0);
1088
1089 assertNode(root.getChild(0).getChild(1), "is", Token.IDENTIFIER, 0);
1090 }
1091
1092 assertNode(root.getChild(1), "Bread", Token.IDENTIFIER, 0);
1093 }
1094 }
1095
1096 // ----------------------------------------------------------------------
1097 // ----------------------------------------------------------------------
1098
1099 protected void assertNullNode(CSTNode node, int numChildren) {
1100 assertNotNull(node);
1101 assertNull(node.getToken());
1102 assertLength(numChildren, node.getChildren());
1103 }
1104
1105 protected void assertNode(CSTNode node, String text, int type) {
1106 assertNotNull(node);
1107 assertNotNull(node.getToken());
1108 assertEquals(text, node.getToken().getText());
1109 assertEquals(type, node.getToken().getType());
1110 }
1111
1112 protected void assertNode(CSTNode node, String text, int type, int numChildren) {
1113 assertNotNull("Node should not be null!", node);
1114 assertNotNull(node.getToken());
1115 assertEquals(text, node.getToken().getText());
1116 assertEquals(type, node.getToken().getType());
1117 assertLength(numChildren, node.getChildren());
1118 }
1119
1120 protected void assertToken(Token token, String text, int type) {
1121 assertNotNull(token);
1122 assertEquals(text, token.getText());
1123 assertEquals(type, token.getType());
1124 }
1125
1126 protected Parser newParser(String text) {
1127 CharStream chars = new StringCharStream(text);
1128 Lexer lexer = new Lexer(chars);
1129 TokenStream tokens = new LexerTokenStream(lexer);
1130
1131 return new Parser(tokens);
1132 }
1133 */
1134 }