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 }