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