    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 }