1 18 package org.codehaus.groovy.antlr; 19 20 import antlr.RecognitionException; 21 import antlr.TokenStreamException; 22 import antlr.TokenStreamRecognitionException; 23 import antlr.collections.AST; 24 import com.thoughtworks.xstream.XStream; 25 26 import org.codehaus.groovy.GroovyBugError; 27 import org.codehaus.groovy.antlr.parser.GroovyLexer; 28 import org.codehaus.groovy.antlr.parser.GroovyRecognizer; 29 import org.codehaus.groovy.antlr.parser.GroovyTokenTypes; 30 import org.codehaus.groovy.ast.*; 31 import org.codehaus.groovy.ast.expr.*; 32 import org.codehaus.groovy.ast.stmt.*; 33 import org.codehaus.groovy.control.CompilationFailedException; 34 import org.codehaus.groovy.control.ParserPlugin; 35 import org.codehaus.groovy.control.SourceUnit; 36 import org.codehaus.groovy.syntax.Numbers; 37 import org.codehaus.groovy.syntax.Reduction; 38 import org.codehaus.groovy.syntax.SyntaxException; 39 import org.codehaus.groovy.syntax.Token; 40 import org.codehaus.groovy.syntax.Types; 41 import org.codehaus.groovy.syntax.ASTHelper; 42 import org.codehaus.groovy.syntax.ParserException; 43 import org.objectweb.asm.Opcodes; 44 45 import java.io.FileWriter ; 46 import java.io.Reader ; 47 import java.util.ArrayList ; 48 import java.util.Iterator ; 49 import java.util.List ; 50 51 57 public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, GroovyTokenTypes { 58 private static final Type OBJECT_TYPE = new Type("java.lang.Object", true); 59 60 private AST ast; 61 private ClassNode classNode; 62 private String [] tokenNames; 63 64 65 public Reduction parseCST(SourceUnit sourceUnit, Reader reader) throws CompilationFailedException { 66 ast = null; 67 68 setController(sourceUnit); 69 70 SourceBuffer sourceBuffer = new SourceBuffer(); 71 UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader,sourceBuffer); 72 GroovyLexer lexer = new GroovyLexer(unicodeReader); 73 unicodeReader.setLexer(lexer); 74 GroovyRecognizer parser = GroovyRecognizer.make(lexer); 75 parser.setSourceBuffer(sourceBuffer); 76 tokenNames = parser.getTokenNames(); 77 parser.setFilename(sourceUnit.getName()); 78 79 try { 81 parser.compilationUnit(); 82 } 83 catch (TokenStreamRecognitionException tsre) { 84 RecognitionException e = tsre.recog; 85 SyntaxException se = new SyntaxException(e.getMessage(),e,e.getLine(),e.getColumn()); 86 se.setFatal(true); 87 sourceUnit.addError(se); 88 } 89 catch (RecognitionException e) { 90 SyntaxException se = new SyntaxException(e.getMessage(),e,e.getLine(),e.getColumn()); 91 se.setFatal(true); 92 sourceUnit.addError(se); 93 } 94 catch (TokenStreamException e) { 95 sourceUnit.addException(e); 96 } 97 98 ast = parser.getAST(); 99 100 AntlrASTProcessor snippets = new AntlrASTProcessSnippets(sourceBuffer); 101 ast = snippets.process(ast); 102 103 if ("xml".equals(System.getProperty("antlr.ast"))) { 104 saveAsXML(sourceUnit.getName(), ast); 105 } 106 107 return null; } 109 110 private void saveAsXML(String name, AST ast) { 111 XStream xstream = new XStream(); 112 try { 113 xstream.toXML(ast, new FileWriter (name + ".antlr.xml")); 114 System.out.println("Written AST to " + name + ".antlr.xml"); 115 } 116 catch (Exception e) { 117 System.out.println("Couldn't write to " + name + ".antlr.xml"); 118 e.printStackTrace(); 119 } 120 } 121 122 public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException { 123 setClassLoader(classLoader); 124 makeModule(); 125 try { 126 convertGroovy(ast); 127 } 128 catch (ASTRuntimeException e) { 129 throw new ASTParserException(e.getMessage() + ". File: " + sourceUnit.getName(), e); 130 } 131 return output; 132 } 133 134 137 protected void convertGroovy(AST node) { 138 while (node != null) { 139 int type = node.getType(); 140 switch (type) { 141 case PACKAGE_DEF: 142 packageDef(node); 143 break; 144 145 case IMPORT: 146 importDef(node); 147 break; 148 149 case CLASS_DEF: 150 classDef(node); 151 break; 152 153 case INTERFACE_DEF: 154 interfaceDef(node); 155 break; 156 157 case METHOD_DEF: 158 methodDef(node); 159 break; 160 161 default: 162 { 163 Statement statement = statement(node); 164 output.addStatement(statement); 165 } 166 } 167 node = node.getNextSibling(); 168 } 169 } 170 171 174 protected void packageDef(AST packageDef) { 175 AST node = packageDef.getFirstChild(); 176 if (isType(ANNOTATIONS, node)) { 177 node = node.getNextSibling(); 178 } 179 String name = qualifiedName(node); 180 setPackageName(name); 181 } 182 183 protected void importDef(AST importNode) { 184 186 AST node = importNode.getFirstChild(); 187 188 String alias = null; 189 if (isType(LITERAL_as, node)) { 190 node = node.getFirstChild(); 192 AST aliasNode = node.getNextSibling(); 193 alias = identifier(aliasNode); 194 } 195 196 if (node.getNumberOfChildren()==0) { 197 String name = identifier(node); 199 importClass(null, name, alias); 200 return; 201 } 202 203 AST packageNode = node.getFirstChild(); 204 String packageName = qualifiedName(packageNode); 205 AST nameNode = packageNode.getNextSibling(); 206 if (isType(STAR, nameNode)) { 207 importPackageWithStar(packageName); 209 if (alias!=null) throw new GroovyBugError( 210 "imports like 'import foo.* as Bar' are not "+ 211 "supported and should be catched by the grammar"); 212 } else { 213 String name = identifier(nameNode); 215 importClass(packageName, name, alias); 216 } 217 } 218 219 protected void interfaceDef(AST classDef) { 220 List annotations = new ArrayList (); 221 AST node = classDef.getFirstChild(); 222 int modifiers = Opcodes.ACC_PUBLIC; 223 if (isType(MODIFIERS, node)) { 224 modifiers = modifiers(node, annotations, modifiers); 225 node = node.getNextSibling(); 226 } 227 modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE; 228 229 String name = identifier(node); 230 node = node.getNextSibling(); 231 String superClass = "java.lang.Object"; 232 233 String [] interfaces = {}; 234 if (isType(EXTENDS_CLAUSE, node)) { 235 interfaces = interfaces(node); 236 node = node.getNextSibling(); 237 } 238 239 addNewClassName(name); 240 String fullClassName = dot(getPackageName(), name); 241 classNode = new ClassNode(fullClassName, modifiers, superClass, interfaces, null); 242 classNode.addAnnotations(annotations); 243 configureAST(classNode, classDef); 244 245 assertNodeType(OBJBLOCK, node); 246 objectBlock(node); 247 output.addClass(classNode); 248 classNode = null; 249 } 250 251 protected void classDef(AST classDef) { 252 List annotations = new ArrayList (); 253 AST node = classDef.getFirstChild(); 254 int modifiers = Opcodes.ACC_PUBLIC; 255 if (isType(MODIFIERS, node)) { 256 modifiers = modifiers(node, annotations, modifiers); 257 node = node.getNextSibling(); 258 } 259 260 String name = identifier(node); 261 node = node.getNextSibling(); 262 263 String superClass = null; 264 if (isType(EXTENDS_CLAUSE, node)) { 265 superClass = typeName(node); 266 node = node.getNextSibling(); 267 } 268 if (superClass == null) { 269 superClass = "java.lang.Object"; 270 } 271 272 String [] interfaces = {}; 273 if (isType(IMPLEMENTS_CLAUSE, node)) { 274 interfaces = interfaces(node); 275 node = node.getNextSibling(); 276 } 277 278 MixinNode[] mixins = {}; 280 281 addNewClassName(name); 282 String fullClassName = dot(getPackageName(), name); 283 classNode = new ClassNode(fullClassName, modifiers, superClass, interfaces, mixins); 284 classNode.addAnnotations(annotations); 285 configureAST(classNode, classDef); 286 287 assertNodeType(OBJBLOCK, node); 288 objectBlock(node); 289 output.addClass(classNode); 290 classNode = null; 291 } 292 293 protected void objectBlock(AST objectBlock) { 294 for (AST node = objectBlock.getFirstChild(); node != null; node = node.getNextSibling()) { 295 int type = node.getType(); 296 switch (type) { 297 case OBJBLOCK: 298 objectBlock(node); 299 break; 300 301 case METHOD_DEF: 302 methodDef(node); 303 break; 304 305 case CTOR_IDENT: 306 constructorDef(node); 307 break; 308 309 case VARIABLE_DEF: 310 fieldDef(node); 311 break; 312 313 default: 314 unknownAST(node); 315 } 316 } 317 } 318 319 protected void methodDef(AST methodDef) { 320 List annotations = new ArrayList (); 321 AST node = methodDef.getFirstChild(); 322 int modifiers = Opcodes.ACC_PUBLIC; 323 if (isType(MODIFIERS, node)) { 324 modifiers = modifiers(node, annotations, modifiers); 325 node = node.getNextSibling(); 326 } 327 328 if (classNode!=null && (classNode.getModifiers() & Opcodes.ACC_INTERFACE) >0) { 329 modifiers |= Opcodes.ACC_ABSTRACT; 330 } 331 332 String returnType = null; 333 334 if (isType(TYPE, node)) { 335 returnType = typeName(node); 336 node = node.getNextSibling(); 337 } 338 339 String name = identifier(node); 340 if (classNode != null) { 341 if (classNode.getNameWithoutPackage().equals(name)) { 342 throw new ASTRuntimeException(methodDef, "Invalid constructor format. Try remove the 'def' expression?"); 343 } 344 } 345 node = node.getNextSibling(); 346 347 assertNodeType(PARAMETERS, node); 348 Parameter[] parameters = parameters(node); 349 node = node.getNextSibling(); 350 351 Statement code = null; 352 if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) { 353 if (node==null) { 354 throw new ASTRuntimeException(methodDef, "You defined a method without body. Try adding a body, or declare it abstract."); 355 } 356 assertNodeType(SLIST, node); 357 code = statementList(node); 358 } 359 360 MethodNode methodNode = new MethodNode(name, modifiers, returnType, parameters, code); 361 methodNode.addAnnotations(annotations); 362 configureAST(methodNode, methodDef); 363 if (classNode != null) { 364 classNode.addMethod(methodNode); 365 } 366 else { 367 output.addMethod(methodNode); 368 } 369 } 370 371 protected void constructorDef(AST constructorDef) { 372 List annotations = new ArrayList (); 373 AST node = constructorDef.getFirstChild(); 374 int modifiers = Opcodes.ACC_PUBLIC; 375 if (isType(MODIFIERS, node)) { 376 modifiers = modifiers(node, annotations, modifiers); 377 node = node.getNextSibling(); 378 } 379 380 assertNodeType(PARAMETERS, node); 381 Parameter[] parameters = parameters(node); 382 node = node.getNextSibling(); 383 384 assertNodeType(SLIST, node); 385 Statement code = statementList(node); 386 387 ConstructorNode constructorNode = classNode.addConstructor(modifiers, parameters, code); 388 constructorNode.addAnnotations(annotations); 389 configureAST(constructorNode, constructorDef); 390 } 391 392 protected void fieldDef(AST fieldDef) { 393 List annotations = new ArrayList (); 394 AST node = fieldDef.getFirstChild(); 395 396 int modifiers = 0; 397 if (isType(MODIFIERS, node)) { 398 modifiers = modifiers(node, annotations, modifiers); 399 node = node.getNextSibling(); 400 } 401 402 String type = null; 403 if (isType(TYPE, node)) { 404 type = typeName(node); 405 node = node.getNextSibling(); 406 } 407 408 String name = identifier(node); 409 node = node.getNextSibling(); 410 411 Expression initialValue = null; 412 if (node != null) { 413 assertNodeType(ASSIGN, node); 414 initialValue = expression(node); 415 } 416 417 418 FieldNode fieldNode = new FieldNode(name, modifiers, type, classNode, initialValue); 419 fieldNode.addAnnotations(annotations); 420 configureAST(fieldNode, fieldDef); 421 422 if (fieldNode.getAnnotations("Property") != null) { 424 int fieldModifiers = 0; 426 int flags = Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL; 427 428 fieldModifiers |= (modifiers & flags); 430 fieldNode.setModifiers(fieldModifiers); 431 432 if (!hasVisibility(modifiers)) { 433 modifiers |= Opcodes.ACC_PUBLIC; 434 } 435 PropertyNode propertyNode = new PropertyNode(fieldNode, modifiers, null, null); 436 configureAST(propertyNode, fieldDef); 437 classNode.addProperty(propertyNode); 438 } 439 else { 440 446 fieldNode.setModifiers(modifiers); 447 448 classNode.addField(fieldNode); 449 } 450 } 451 452 protected String [] interfaces(AST node) { 453 List interfaceList = new ArrayList (); 454 for (AST implementNode = node.getFirstChild(); implementNode != null; implementNode = implementNode.getNextSibling()) { 455 interfaceList.add(resolveTypeName(qualifiedName(implementNode))); 456 } 457 String [] interfaces = {}; 458 if (!interfaceList.isEmpty()) { 459 interfaces = new String [interfaceList.size()]; 460 interfaceList.toArray(interfaces); 461 462 } 463 return interfaces; 464 } 465 466 protected Parameter[] parameters(AST parametersNode) { 467 AST node = parametersNode.getFirstChild(); 468 if (node == null) { 469 return Parameter.EMPTY_ARRAY; 470 } 471 else { 472 List parameters = new ArrayList (); 473 do { 474 parameters.add(parameter(node)); 475 node = node.getNextSibling(); 476 } 477 while (node != null); 478 Parameter[] answer = new Parameter[parameters.size()]; 479 parameters.toArray(answer); 480 return answer; 481 } 482 } 483 484 protected Parameter parameter(AST paramNode) { 485 List annotations = new ArrayList (); 486 AST node = paramNode.getFirstChild(); 487 488 int modifiers = 0; 489 if (isType(MODIFIERS, node)) { 490 modifiers = modifiers(node, annotations, modifiers); 491 node = node.getNextSibling(); 492 } 493 494 String type = null; 495 if (isType(TYPE, node)) { 496 type = typeName(node); 497 node = node.getNextSibling(); 498 } 499 500 String name = identifier(node); 501 node = node.getNextSibling(); 502 VariableExpression leftExpression = new VariableExpression(name, type); 503 configureAST(leftExpression, paramNode); 504 505 Expression rightExpression = ConstantExpression.NULL; 506 if (node != null) { 507 assertNodeType(ASSIGN, node); 508 509 rightExpression = expression(node.getFirstChild()); 510 } 511 512 Parameter parameter = new Parameter(type, name, rightExpression); 513 return parameter; 517 } 518 519 protected int modifiers(AST modifierNode, List annotations, int defaultModifiers) { 520 assertNodeType(MODIFIERS, modifierNode); 521 522 boolean access = false; 523 int answer = 0; 524 525 for (AST node = modifierNode.getFirstChild(); node != null; node = node.getNextSibling()) { 526 int type = node.getType(); 527 switch (type) { 528 case ANNOTATION: 530 annotations.add(annotation(node)); 531 break; 532 533 534 case LITERAL_private: 536 answer = setModifierBit(node, answer, Opcodes.ACC_PRIVATE); 537 access = setAccessTrue(node, access); 538 break; 539 540 case LITERAL_protected: 541 answer = setModifierBit(node, answer, Opcodes.ACC_PROTECTED); 542 access = setAccessTrue(node, access); 543 break; 544 545 case LITERAL_public: 546 answer = setModifierBit(node, answer, Opcodes.ACC_PUBLIC); 547 access = setAccessTrue(node, access); 548 break; 549 550 case ABSTRACT: 552 answer = setModifierBit(node, answer, Opcodes.ACC_ABSTRACT); 553 break; 554 555 case FINAL: 556 answer = setModifierBit(node, answer, Opcodes.ACC_FINAL); 557 break; 558 559 case LITERAL_native: 560 answer = setModifierBit(node, answer, Opcodes.ACC_NATIVE); 561 break; 562 563 case LITERAL_static: 564 answer = setModifierBit(node, answer, Opcodes.ACC_STATIC); 565 break; 566 567 case STRICTFP: 568 answer = setModifierBit(node, answer, Opcodes.ACC_STRICT); 569 break; 570 571 case LITERAL_synchronized: 572 answer = setModifierBit(node, answer, Opcodes.ACC_SYNCHRONIZED); 573 break; 574 575 case LITERAL_transient: 576 answer = setModifierBit(node, answer, Opcodes.ACC_TRANSIENT); 577 break; 578 579 case LITERAL_volatile: 580 answer = setModifierBit(node, answer, Opcodes.ACC_VOLATILE); 581 break; 582 583 default: 584 unknownAST(node); 585 } 586 } 587 if (!access) { 588 answer |= defaultModifiers; 589 } 590 return answer; 591 } 592 593 protected boolean setAccessTrue(AST node, boolean access) { 594 if (!access) { 595 return true; 596 } 597 else { 598 throw new ASTRuntimeException(node, "Cannot specify modifier: " + node.getText() + " when access scope has already been defined"); 599 } 600 } 601 602 protected int setModifierBit(AST node, int answer, int bit) { 603 if ((answer & bit) != 0) { 604 throw new ASTRuntimeException(node, "Cannot repeat modifier: " + node.getText()); 605 } 606 return answer | bit; 607 } 608 609 protected AnnotationNode annotation(AST annotationNode) { 610 AST node = annotationNode.getFirstChild(); 611 String name = identifier(node); 612 AnnotationNode annotatedNode = new AnnotationNode(name); 613 configureAST(annotatedNode, node); 614 while (true) { 615 node = node.getNextSibling(); 616 if (isType(ANNOTATION_MEMBER_VALUE_PAIR, node)) { 617 AST memberNode = node.getFirstChild(); 618 String param = identifier(memberNode); 619 Expression expression = expression(memberNode.getNextSibling()); 620 annotatedNode.addMember(param, expression); 621 } 622 else { 623 break; 624 } 625 } 626 return annotatedNode; 627 } 628 629 630 631 634 protected Statement statement(AST node) { 635 Statement statement = null; 636 int type = node.getType(); 637 switch (type) { 638 case SLIST: 639 case LITERAL_finally: 640 statement = statementList(node); 641 break; 642 643 case METHOD_CALL: 644 statement = methodCall(node); 645 break; 646 647 case VARIABLE_DEF: 648 statement = variableDef(node); 649 break; 650 651 652 case LABELED_STAT: 653 statement = labelledStatement(node); 654 break; 655 656 case LITERAL_assert: 657 statement = assertStatement(node); 658 break; 659 660 case LITERAL_break: 661 statement = breakStatement(node); 662 break; 663 664 case LITERAL_continue: 665 statement = continueStatement(node); 666 break; 667 668 case LITERAL_if: 669 statement = ifStatement(node); 670 break; 671 672 case LITERAL_for: 673 statement = forStatement(node); 674 break; 675 676 case LITERAL_return: 677 statement = returnStatement(node); 678 break; 679 680 case LITERAL_synchronized: 681 statement = synchronizedStatement(node); 682 break; 683 684 case LITERAL_switch: 685 statement = switchStatement(node); 686 break; 687 688 case LITERAL_with: 689 statement = withStatement(node); 690 break; 691 692 case LITERAL_try: 693 statement = tryStatement(node); 694 break; 695 696 case LITERAL_throw: 697 statement = throwStatement(node); 698 break; 699 700 case LITERAL_while: 701 statement = whileStatement(node); 702 break; 703 704 default: 705 statement = new ExpressionStatement(expression(node)); 706 } 707 if (statement != null) { 708 configureAST(statement, node); 709 } 710 return statement; 711 } 712 713 protected Statement statementList(AST code) { 714 return statementListNoChild(code.getFirstChild()); 715 } 716 717 protected Statement statementListNoChild(AST node) { 718 BlockStatement block = new BlockStatement(); 719 for (; node != null; node = node.getNextSibling()) { 721 block.addStatement(statement(node)); 722 } 723 return block; 724 } 725 726 protected Statement assertStatement(AST assertNode) { 727 AST node = assertNode.getFirstChild(); 728 BooleanExpression booleanExpression = booleanExpression(node); 729 Expression messageExpression = null; 730 731 node = node.getNextSibling(); 732 if (node != null) { 733 messageExpression = expression(node); 734 } 735 else { 736 messageExpression = ConstantExpression.NULL; 737 } 738 AssertStatement assertStatement = new AssertStatement(booleanExpression, messageExpression); 739 configureAST(assertStatement, assertNode); 740 return assertStatement; 741 } 742 743 protected Statement breakStatement(AST node) { 744 BreakStatement breakStatement = new BreakStatement(label(node)); 745 configureAST(breakStatement, node); 746 return breakStatement; 747 } 748 749 protected Statement continueStatement(AST node) { 750 ContinueStatement continueStatement = new ContinueStatement(label(node)); 751 configureAST(continueStatement, node); 752 return continueStatement; 753 } 754 755 protected Statement forStatement(AST forNode) { 756 AST inNode = forNode.getFirstChild(); 757 AST variableNode = inNode.getFirstChild(); 758 AST collectionNode = variableNode.getNextSibling(); 759 760 Type type = OBJECT_TYPE; 761 if (isType(VARIABLE_DEF, variableNode)) { 762 AST typeNode = variableNode.getFirstChild(); 763 assertNodeType(TYPE, typeNode); 764 765 type = type(typeNode); 766 variableNode = typeNode.getNextSibling(); 767 } 768 String variable = identifier(variableNode); 769 770 Expression collectionExpression = expression(collectionNode); 771 Statement block = statement(inNode.getNextSibling()); 772 773 ForStatement forStatement = new ForStatement(variable, type, collectionExpression, block); 774 configureAST(forStatement, forNode); 775 return forStatement; 776 } 777 778 protected Statement ifStatement(AST ifNode) { 779 AST node = ifNode.getFirstChild(); 780 assertNodeType(EXPR, node); 781 BooleanExpression booleanExpression = booleanExpression(node); 782 783 node = node.getNextSibling(); 784 Statement ifBlock = statement(node); 785 786 Statement elseBlock = EmptyStatement.INSTANCE; 787 node = node.getNextSibling(); 788 if (node != null) { 789 elseBlock = statement(node); 790 } 791 IfStatement ifStatement = new IfStatement(booleanExpression, ifBlock, elseBlock); 792 configureAST(ifStatement, ifNode); 793 return ifStatement; 794 } 795 796 protected Statement labelledStatement(AST labelNode) { 797 AST node = labelNode.getFirstChild(); 798 String label = identifier(node); 799 Statement statement = statement(node.getNextSibling()); 800 statement.setStatementLabel(label); 801 return statement; 802 } 803 804 protected Statement methodCall(AST code) { 805 Expression expression = methodCallExpression(code); 806 ExpressionStatement expressionStatement = new ExpressionStatement(expression); 807 configureAST(expressionStatement, code); 808 return expressionStatement; 809 } 810 811 protected Statement variableDef(AST variableDef) { 812 AST node = variableDef.getFirstChild(); 813 String type = null; 814 if (isType(MODIFIERS, node)) { 815 node = node.getNextSibling(); 816 } 817 if (isType(TYPE, node)) { 818 type = typeName(node); 819 node = node.getNextSibling(); 820 } 821 822 String name = identifier(node); 823 node = node.getNextSibling(); 824 825 VariableExpression leftExpression = new VariableExpression(name, type); 826 configureAST(leftExpression, variableDef); 827 828 Expression rightExpression = ConstantExpression.NULL; 829 if (node != null) { 830 assertNodeType(ASSIGN, node); 831 832 rightExpression = expression(node.getFirstChild()); 833 } 834 Token token = makeToken(Types.ASSIGN, variableDef); 835 836 DeclarationExpression expression = new DeclarationExpression(leftExpression, token, rightExpression); 838 configureAST(expression, variableDef); 839 ExpressionStatement expressionStatement = new ExpressionStatement(expression); 840 configureAST(expressionStatement, variableDef); 841 return expressionStatement; 842 } 843 844 protected Statement returnStatement(AST node) { 845 AST exprNode = node.getFirstChild(); 846 847 if (exprNode != null) { 853 Expression expression = expression(exprNode); 854 if (expression instanceof ConstantExpression) { 855 ConstantExpression constantExpr = (ConstantExpression) expression; 856 if (constantExpr.getValue() == null) { 857 return ReturnStatement.RETURN_NULL_OR_VOID; 858 } 859 } 860 ReturnStatement returnStatement = new ReturnStatement(expression); 861 configureAST(returnStatement, node); 862 return returnStatement; 863 } 864 else { 865 return ReturnStatement.RETURN_NULL_OR_VOID; 866 } 867 } 868 869 protected Statement switchStatement(AST switchNode) { 870 AST node = switchNode.getFirstChild(); 871 Expression expression = expression(node); 872 Statement defaultStatement = EmptyStatement.INSTANCE; 873 874 List list = new ArrayList (); 875 for (node = node.getNextSibling(); isType(CASE_GROUP, node); node = node.getNextSibling()) { 876 AST child = node.getFirstChild(); 877 if (isType(LITERAL_case, child)) { 878 list.add(caseStatement(child)); 879 } 880 else { 881 defaultStatement = statement(child.getNextSibling()); 882 } 883 } 884 if (node != null) { 885 unknownAST(node); 886 } 887 SwitchStatement switchStatement = new SwitchStatement(expression, list, defaultStatement); 888 configureAST(switchStatement, switchNode); 889 return switchStatement; 890 } 891 892 protected CaseStatement caseStatement(AST node) { 893 Expression expression = expression(node.getFirstChild()); 894 AST nextSibling = node.getNextSibling(); 895 Statement statement = EmptyStatement.INSTANCE; 896 if (!isType(LITERAL_default, nextSibling)) { 897 statement = statement(nextSibling); 898 } 899 CaseStatement answer = new CaseStatement(expression, statement); 900 configureAST(answer, node); 901 return answer; 902 } 903 904 protected Statement synchronizedStatement(AST syncNode) { 905 AST node = syncNode.getFirstChild(); 906 Expression expression = expression(node); 907 Statement code = statement(node.getNextSibling()); 908 SynchronizedStatement synchronizedStatement = new SynchronizedStatement(expression, code); 909 configureAST(synchronizedStatement, syncNode); 910 return synchronizedStatement; 911 } 912 913 protected Statement throwStatement(AST node) { 914 AST expressionNode = node.getFirstChild(); 915 if (expressionNode == null) { 916 expressionNode = node.getNextSibling(); 917 } 918 if (expressionNode == null) { 919 throw new ASTRuntimeException(node, "No expression available"); 920 } 921 ThrowStatement throwStatement = new ThrowStatement(expression(expressionNode)); 922 configureAST(throwStatement, node); 923 return throwStatement; 924 } 925 926 protected Statement tryStatement(AST tryStatementNode) { 927 AST tryNode = tryStatementNode.getFirstChild(); 928 Statement tryStatement = statement(tryNode); 929 Statement finallyStatement = EmptyStatement.INSTANCE; 930 AST node = tryNode.getNextSibling(); 931 932 List catches = new ArrayList (); 934 for (; node != null && isType(LITERAL_catch, node); node = node.getNextSibling()) { 935 catches.add(catchStatement(node)); 936 } 937 938 if (isType(LITERAL_finally, node)) { 939 finallyStatement = statement(node); 940 node = node.getNextSibling(); 941 } 942 943 TryCatchStatement tryCatchStatement = new TryCatchStatement(tryStatement, finallyStatement); 944 configureAST(tryCatchStatement, tryStatementNode); 945 for (Iterator iter = catches.iterator(); iter.hasNext();) { 946 CatchStatement statement = (CatchStatement) iter.next(); 947 tryCatchStatement.addCatch(statement); 948 } 949 return tryCatchStatement; 950 } 951 952 protected CatchStatement catchStatement(AST catchNode) { 953 AST node = catchNode.getFirstChild(); 954 Parameter parameter = parameter(node); 955 String exceptionType = parameter.getType(); 956 String variable = parameter.getName(); 957 node = node.getNextSibling(); 958 Statement code = statement(node); 959 CatchStatement answer = new CatchStatement(exceptionType, variable, code); 960 configureAST(answer, catchNode); 961 return answer; 962 } 963 964 protected Statement whileStatement(AST whileNode) { 965 AST node = whileNode.getFirstChild(); 966 assertNodeType(EXPR, node); 967 BooleanExpression booleanExpression = booleanExpression(node); 968 969 node = node.getNextSibling(); 970 Statement block = statement(node); 971 WhileStatement whileStatement = new WhileStatement(booleanExpression, block); 972 configureAST(whileStatement, whileNode); 973 return whileStatement; 974 } 975 976 protected Statement withStatement(AST node) { 977 notImplementedYet(node); 978 return null; 979 } 980 981 982 983 986 protected Expression expression(AST node) { 987 Expression expression = expressionSwitch(node); 988 configureAST(expression, node); 989 return expression; 990 } 991 992 protected Expression expressionSwitch(AST node) { 993 int type = node.getType(); 994 switch (type) { 995 case EXPR: 996 return expression(node.getFirstChild()); 997 998 case ELIST: 999 return expressionList(node); 1000 1001 case SLIST: 1002 return blockExpression(node); 1003 1004 case CLOSED_BLOCK: 1005 return closureExpression(node); 1006 1007 case SUPER_CTOR_CALL: 1008 return superMethodCallExpression(node); 1009 1010 case METHOD_CALL: 1011 return methodCallExpression(node); 1012 1013 case LITERAL_new: 1014 return constructorCallExpression(node.getFirstChild()); 1015 1016 case CTOR_CALL: 1017 return constructorCallExpression(node); 1018 1019 case QUESTION: 1020 return ternaryExpression(node); 1021 1022 case OPTIONAL_DOT: 1023 case SPREAD_DOT: 1024 case DOT: 1025 return dotExpression(node); 1026 1027 case IDENT: 1028 case LITERAL_boolean: 1029 case LITERAL_byte: 1030 case LITERAL_char: 1031 case LITERAL_double: 1032 case LITERAL_float: 1033 case LITERAL_int: 1034 case LITERAL_long: 1035 case LITERAL_short: 1036 return variableExpression(node); 1037 1038 case LIST_CONSTRUCTOR: 1039 return listExpression(node); 1040 1041 case MAP_CONSTRUCTOR: 1042 return mapExpression(node); 1043 1044 case LABELED_ARG: 1045 return mapEntryExpression(node); 1046 1047 case SPREAD_ARG: 1048 return spreadExpression(node); 1049 1050 case SPREAD_MAP_ARG: 1051 return spreadMapExpression(node); 1052 1053 1057 case MEMBER_POINTER: 1058 return methodPointerExpression(node); 1059 1060 case INDEX_OP: 1061 return indexExpression(node); 1062 1063 case LITERAL_instanceof: 1064 return instanceofExpression(node); 1065 1066 case LITERAL_as: 1067 return asExpression(node); 1068 1069 case TYPECAST: 1070 return castExpression(node); 1071 1072 1074 case LITERAL_true: 1075 return ConstantExpression.TRUE; 1076 1077 case LITERAL_false: 1078 return ConstantExpression.FALSE; 1079 1080 case LITERAL_null: 1081 return ConstantExpression.NULL; 1082 1083 case STRING_LITERAL: 1084 ConstantExpression constantExpression = new ConstantExpression(node.getText()); 1085 configureAST(constantExpression, node); 1086 return constantExpression; 1087 1088 case STRING_CONSTRUCTOR: 1089 return gstring(node); 1090 1091 case NUM_DOUBLE: 1092 case NUM_FLOAT: 1093 case NUM_BIG_DECIMAL: 1094 return decimalExpression(node); 1095 1096 case NUM_BIG_INT: 1097 case NUM_INT: 1098 case NUM_LONG: 1099 return integerExpression(node); 1100 1101 case LITERAL_this: 1102 return VariableExpression.THIS_EXPRESSION; 1103 1104 case LITERAL_super: 1105 return VariableExpression.SUPER_EXPRESSION; 1106 1107 1108 case LNOT: 1110 NotExpression notExpression = new NotExpression(expression(node.getFirstChild())); 1111 configureAST(notExpression, node); 1112 return notExpression; 1113 1114 case UNARY_MINUS: 1115 return negateExpression(node); 1116 1117 case BNOT: 1118 BitwiseNegExpression bitwiseNegExpression = new BitwiseNegExpression(expression(node.getFirstChild())); 1119 configureAST(bitwiseNegExpression, node); 1120 return bitwiseNegExpression; 1121 1122 case UNARY_PLUS: 1123 return expression(node.getFirstChild()); 1124 1125 1126 case INC: 1128 return prefixExpression(node, Types.PLUS_PLUS); 1129 1130 case DEC: 1131 return prefixExpression(node, Types.MINUS_MINUS); 1132 1133 case POST_INC: 1135 return postfixExpression(node, Types.PLUS_PLUS); 1136 1137 case POST_DEC: 1138 return postfixExpression(node, Types.MINUS_MINUS); 1139 1140 1141 1143 case ASSIGN: 1144 return binaryExpression(Types.ASSIGN, node); 1145 1146 case EQUAL: 1147 return binaryExpression(Types.COMPARE_EQUAL, node); 1148 1149 case NOT_EQUAL: 1150 return binaryExpression(Types.COMPARE_NOT_EQUAL, node); 1151 1152 case COMPARE_TO: 1153 return binaryExpression(Types.COMPARE_TO, node); 1154 1155 case LE: 1156 return binaryExpression(Types.COMPARE_LESS_THAN_EQUAL, node); 1157 1158 case LT: 1159 return binaryExpression(Types.COMPARE_LESS_THAN, node); 1160 1161 case GT: 1162 return binaryExpression(Types.COMPARE_GREATER_THAN, node); 1163 1164 case GE: 1165 return binaryExpression(Types.COMPARE_GREATER_THAN_EQUAL, node); 1166 1167 1178 1179 case LAND: 1180 return binaryExpression(Types.LOGICAL_AND, node); 1181 1182 case LOR: 1183 return binaryExpression(Types.LOGICAL_OR, node); 1184 1185 case BAND: 1186 return binaryExpression(Types.BITWISE_AND, node); 1187 1188 case BAND_ASSIGN: 1189 return binaryExpression(Types.BITWISE_AND_EQUAL, node); 1190 1191 case BOR: 1192 return binaryExpression(Types.BITWISE_OR, node); 1193 1194 case BOR_ASSIGN: 1195 return binaryExpression(Types.BITWISE_OR_EQUAL, node); 1196 1197 case BXOR: 1198 return binaryExpression(Types.BITWISE_XOR, node); 1199 1200 case BXOR_ASSIGN: 1201 return binaryExpression(Types.BITWISE_XOR_EQUAL, node); 1202 1203 1204 case PLUS: 1205 return binaryExpression(Types.PLUS, node); 1206 1207 case PLUS_ASSIGN: 1208 return binaryExpression(Types.PLUS_EQUAL, node); 1209 1210 1211 case MINUS: 1212 return binaryExpression(Types.MINUS, node); 1213 1214 case MINUS_ASSIGN: 1215 return binaryExpression(Types.MINUS_EQUAL, node); 1216 1217 1218 case STAR: 1219 return binaryExpression(Types.MULTIPLY, node); 1220 1221 case STAR_ASSIGN: 1222 return binaryExpression(Types.MULTIPLY_EQUAL, node); 1223 1224 1225 case STAR_STAR: 1226 return binaryExpression(Types.POWER, node); 1227 1228 case STAR_STAR_ASSIGN: 1229 return binaryExpression(Types.POWER_EQUAL, node); 1230 1231 1232 case DIV: 1233 return binaryExpression(Types.DIVIDE, node); 1234 1235 case DIV_ASSIGN: 1236 return binaryExpression(Types.DIVIDE_EQUAL, node); 1237 1238 1239 case MOD: 1240 return binaryExpression(Types.MOD, node); 1241 1242 case MOD_ASSIGN: 1243 return binaryExpression(Types.MOD_EQUAL, node); 1244 1245 case SL: 1246 return binaryExpression(Types.LEFT_SHIFT, node); 1247 1248 case SL_ASSIGN: 1249 return binaryExpression(Types.LEFT_SHIFT_EQUAL, node); 1250 1251 case SR: 1252 return binaryExpression(Types.RIGHT_SHIFT, node); 1253 1254 case SR_ASSIGN: 1255 return binaryExpression(Types.RIGHT_SHIFT_EQUAL, node); 1256 1257 case BSR: 1258 return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED, node); 1259 1260 case BSR_ASSIGN: 1261 return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED_EQUAL, node); 1262 1263 case REGEX_FIND: 1265 return binaryExpression(Types.FIND_REGEX, node); 1266 1267 case REGEX_MATCH: 1268 return binaryExpression(Types.MATCH_REGEX, node); 1269 1270 1271 case RANGE_INCLUSIVE: 1273 return rangeExpression(node, true); 1274 1275 case RANGE_EXCLUSIVE: 1276 return rangeExpression(node, false); 1277 1278 default: 1279 unknownAST(node); 1280 } 1281 return null; 1282 } 1283 1284 protected Expression ternaryExpression(AST ternaryNode) { 1285 AST node = ternaryNode.getFirstChild(); 1286 BooleanExpression booleanExpression = booleanExpression(node); 1287 node = node.getNextSibling(); 1288 Expression left = expression(node); 1289 Expression right = expression(node.getNextSibling()); 1290 TernaryExpression ternaryExpression = new TernaryExpression(booleanExpression, left, right); 1291 configureAST(ternaryExpression, ternaryNode); 1292 return ternaryExpression; 1293 } 1294 1295 protected Expression variableExpression(AST node) { 1296 String text = node.getText(); 1297 1298 String newText = resolveTypeName(text, false); 1301 if (newText == null) { 1302 VariableExpression variableExpression = new VariableExpression(text); 1303 configureAST(variableExpression, node); 1304 return variableExpression; 1305 } 1306 else { 1307 ClassExpression classExpression = new ClassExpression(newText); 1308 configureAST(classExpression, node); 1309 return classExpression; 1310 } 1311 } 1312 1313 protected Expression rangeExpression(AST rangeNode, boolean inclusive) { 1314 AST node = rangeNode.getFirstChild(); 1315 Expression left = expression(node); 1316 Expression right = expression(node.getNextSibling()); 1317 RangeExpression rangeExpression = new RangeExpression(left, right, inclusive); 1318 configureAST(rangeExpression, rangeNode); 1319 return rangeExpression; 1320 } 1321 1322 protected Expression spreadExpression(AST node) { 1323 AST exprNode = node.getFirstChild(); 1324 AST listNode = exprNode.getFirstChild(); 1325 Expression right = expression(listNode); 1326 SpreadExpression spreadExpression = new SpreadExpression(right); 1327 configureAST(spreadExpression, node); 1328 return spreadExpression; 1329 } 1330 1331 protected Expression spreadMapExpression(AST node) { 1332 AST exprNode = node.getFirstChild(); 1333 Expression expr = expression(exprNode); 1334 SpreadMapExpression spreadMapExpression = new SpreadMapExpression(expr); 1335 configureAST(spreadMapExpression, node); 1336 return spreadMapExpression; 1337 } 1338 1339 protected Expression methodPointerExpression(AST node) { 1340 AST exprNode = node.getFirstChild(); 1341 String methodName = identifier(exprNode.getNextSibling()); 1342 Expression expression = expression(exprNode); 1343 MethodPointerExpression methodPointerExpression = new MethodPointerExpression(expression, methodName); 1344 configureAST(methodPointerExpression, node); 1345 return methodPointerExpression; 1346 } 1347 1348 1357 1358 protected Expression listExpression(AST listNode) { 1359 List expressions = new ArrayList (); 1360 AST elist = listNode.getFirstChild(); 1361 assertNodeType(ELIST, elist); 1362 1363 for (AST node = elist.getFirstChild(); node != null; node = node.getNextSibling()) { 1364 switch (node.getType()) { 1366 case LABELED_ARG: assertNodeType(COMMA, node); break; case SPREAD_MAP_ARG: assertNodeType(SPREAD_ARG, node); break; } 1369 expressions.add(expression(node)); 1370 } 1371 ListExpression listExpression = new ListExpression(expressions); 1372 configureAST(listExpression, listNode); 1373 return listExpression; 1374 } 1375 1376 1379 protected Expression mapExpression(AST mapNode) { 1380 List expressions = new ArrayList (); 1381 AST elist = mapNode.getFirstChild(); 1382 if (elist != null) { assertNodeType(ELIST, elist); 1384 for (AST node = elist.getFirstChild(); node != null; node = node.getNextSibling()) { 1385 switch (node.getType()) { 1386 case LABELED_ARG: 1387 case SPREAD_MAP_ARG: 1388 break; case SPREAD_ARG: 1390 assertNodeType(SPREAD_MAP_ARG, node); break; default: 1392 assertNodeType(LABELED_ARG, node); break; } 1394 expressions.add(mapEntryExpression(node)); 1395 } 1396 } 1397 MapExpression mapExpression = new MapExpression(expressions); 1398 configureAST(mapExpression, mapNode); 1399 return mapExpression; 1400 } 1401 1402 protected MapEntryExpression mapEntryExpression(AST node) { 1403 if (node.getType() == SPREAD_MAP_ARG) { 1404 AST rightNode = node.getFirstChild(); 1405 Expression keyExpression = spreadMapExpression(node); 1406 Expression rightExpression = expression(rightNode); 1407 MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, rightExpression); 1408 configureAST(mapEntryExpression, node); 1409 return mapEntryExpression; 1410 } 1411 else { 1412 AST keyNode = node.getFirstChild(); 1413 Expression keyExpression = expression(keyNode); 1414 AST valueNode = keyNode.getNextSibling(); 1415 Expression valueExpression = expression(valueNode); 1416 MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, valueExpression); 1417 configureAST(mapEntryExpression, node); 1418 return mapEntryExpression; 1419 } 1420 } 1421 1422 1423 protected Expression instanceofExpression(AST node) { 1424 AST leftNode = node.getFirstChild(); 1425 Expression leftExpression = expression(leftNode); 1426 1427 AST rightNode = leftNode.getNextSibling(); 1428 String typeName = resolvedName(rightNode); 1429 assertTypeNotNull(typeName, rightNode); 1430 1431 Expression rightExpression = new ClassExpression(typeName); 1432 configureAST(rightExpression, rightNode); 1433 BinaryExpression binaryExpression = new BinaryExpression(leftExpression, makeToken(Types.KEYWORD_INSTANCEOF, node), rightExpression); 1434 configureAST(binaryExpression, node); 1435 return binaryExpression; 1436 } 1437 1438 protected void assertTypeNotNull(String typeName, AST rightNode) { 1439 if (typeName == null) { 1440 throw new ASTRuntimeException(rightNode, "No type available for: " + qualifiedName(rightNode)); 1441 } 1442 } 1443 1444 protected Expression asExpression(AST node) { 1445 AST leftNode = node.getFirstChild(); 1446 Expression leftExpression = expression(leftNode); 1447 1448 AST rightNode = leftNode.getNextSibling(); 1449 String typeName = resolvedName(rightNode); 1450 1451 return CastExpression.asExpression(typeName, leftExpression); 1452 } 1453 1454 protected Expression castExpression(AST castNode) { 1455 AST node = castNode.getFirstChild(); 1456 String typeName = resolvedName(node); 1457 assertTypeNotNull(typeName, node); 1458 1459 AST expressionNode = node.getNextSibling(); 1460 Expression expression = expression(expressionNode); 1461 1462 CastExpression castExpression = new CastExpression(typeName, expression); 1463 configureAST(castExpression, castNode); 1464 return castExpression; 1465 } 1466 1467 1468 protected Expression indexExpression(AST indexNode) { 1469 AST leftNode = indexNode.getFirstChild(); 1470 Expression leftExpression = expression(leftNode); 1471 1472 AST rightNode = leftNode.getNextSibling(); 1473 Expression rightExpression = expression(rightNode); 1474 1475 BinaryExpression binaryExpression = new BinaryExpression(leftExpression, makeToken(Types.LEFT_SQUARE_BRACKET, indexNode), rightExpression); 1476 configureAST(binaryExpression, indexNode); 1477 return binaryExpression; 1478 } 1479 1480 protected Expression binaryExpression(int type, AST node) { 1481 Token token = makeToken(type, node); 1482 1483 AST leftNode = node.getFirstChild(); 1484 Expression leftExpression = expression(leftNode); 1485 1486 AST rightNode = leftNode.getNextSibling(); 1487 if (rightNode == null) { 1488 return leftExpression; 1489 } 1490 1491 if (Types.ofType(type, Types.ASSIGNMENT_OPERATOR)) { 1492 if (leftExpression instanceof VariableExpression || leftExpression instanceof PropertyExpression 1493 || leftExpression instanceof FieldExpression 1494 || leftExpression instanceof DeclarationExpression) { 1495 } 1497 else if (leftExpression instanceof ConstantExpression) { 1498 throw new ASTRuntimeException(node, "\n[" + ((ConstantExpression) leftExpression).getValue() + "] is a constant expression, but it should be a variable expression"); 1499 } 1500 else if (leftExpression instanceof BinaryExpression) { 1501 Expression leftexp = ((BinaryExpression) leftExpression).getLeftExpression(); 1502 int lefttype = ((BinaryExpression) leftExpression).getOperation().getType(); 1503 if (!Types.ofType(lefttype, Types.ASSIGNMENT_OPERATOR) && lefttype != Types.LEFT_SQUARE_BRACKET) { 1504 throw new ASTRuntimeException(node, "\n" + ((BinaryExpression) leftExpression).getText() + " is a binary expression, but it should be a variable expression"); 1505 } 1506 } 1507 else if (leftExpression instanceof GStringExpression) { 1508 throw new ASTRuntimeException(node, "\n\"" + ((GStringExpression) leftExpression).getText() + "\" is a GString expression, but it should be a variable expression"); 1509 } 1510 else if (leftExpression instanceof MethodCallExpression) { 1511 throw new ASTRuntimeException(node, "\n\"" + ((MethodCallExpression) leftExpression).getText() + "\" is a method call expression, but it should be a variable expression"); 1512 } 1513 else if (leftExpression instanceof MapExpression) { 1514 throw new ASTRuntimeException(node, "\n'" + ((MapExpression) leftExpression).getText() + "' is a map expression, but it should be a variable expression"); 1515 } 1516 else { 1517 throw new ASTRuntimeException(node, "\n" + leftExpression.getClass() + ", with its value '" + leftExpression.getText() + "', is a bad expression as the LSH of an assignment operator"); 1518 } 1519 } 1520 1523 Expression rightExpression = expression(rightNode); 1524 BinaryExpression binaryExpression = new BinaryExpression(leftExpression, token, rightExpression); 1525 configureAST(binaryExpression, node); 1526 return binaryExpression; 1527 } 1528 1529 protected Expression prefixExpression(AST node, int token) { 1530 Expression expression = expression(node.getFirstChild()); 1531 PrefixExpression prefixExpression = new PrefixExpression(makeToken(token, node), expression); 1532 configureAST(prefixExpression, node); 1533 return prefixExpression; 1534 } 1535 1536 protected Expression postfixExpression(AST node, int token) { 1537 Expression expression = expression(node.getFirstChild()); 1538 PostfixExpression postfixExpression = new PostfixExpression(expression, makeToken(token, node)); 1539 configureAST(postfixExpression, node); 1540 return postfixExpression; 1541 } 1542 1543 protected BooleanExpression booleanExpression(AST node) { 1544 BooleanExpression booleanExpression = new BooleanExpression(expression(node)); 1545 configureAST(booleanExpression, node); 1546 return booleanExpression; 1547 } 1548 1549 protected Expression dotExpression(AST node) { 1550 AST leftNode = node.getFirstChild(); 1552 if (leftNode != null) { 1553 AST identifierNode = leftNode.getNextSibling(); 1554 if (identifierNode != null) { 1555 Expression leftExpression = expression(leftNode); 1556 if (isType(SELECT_SLOT, identifierNode)) { 1557 String field = identifier(identifierNode.getFirstChild()); 1558 AttributeExpression attributeExpression = new AttributeExpression(leftExpression, field, node.getType() != DOT); 1559 if (node.getType() == SPREAD_DOT) { 1560 attributeExpression.setSpreadSafe(true); 1561 } 1562 configureAST(attributeExpression, node); 1563 return attributeExpression; 1564 } 1565 String property = identifier(identifierNode); 1566 PropertyExpression propertyExpression = new PropertyExpression(leftExpression, property, node.getType() != DOT); 1567 if (node.getType() == SPREAD_DOT) { 1568 propertyExpression.setSpreadSafe(true); 1569 } 1570 configureAST(propertyExpression, node); 1571 return propertyExpression; 1572 } 1573 } 1574 return methodCallExpression(node); 1575 } 1576 1577 protected Expression superMethodCallExpression(AST methodCallNode) { 1578 AST node = methodCallNode.getFirstChild(); 1579 1580 String name = "super"; 1581 Expression objectExpression = VariableExpression.SUPER_EXPRESSION; 1582 1583 Expression arguments = arguments(node); 1584 MethodCallExpression expression = new MethodCallExpression(objectExpression, name, arguments); 1585 configureAST(expression, methodCallNode); 1586 return expression; 1587 } 1588 1589 1590 protected Expression methodCallExpression(AST methodCallNode) { 1591 AST node = methodCallNode.getFirstChild(); 1592 1598 1599 Expression objectExpression; 1600 AST selector; 1601 AST elist = node.getNextSibling(); 1602 boolean safe = isType(OPTIONAL_DOT, node); 1603 boolean spreadSafe = isType(SPREAD_DOT, node); 1604 if (isType(DOT, node) || safe || spreadSafe) { 1605 AST objectNode = node.getFirstChild(); 1606 objectExpression = expression(objectNode); 1607 selector = objectNode.getNextSibling(); 1608 } else if (isType(IDENT, node)) { 1609 objectExpression = VariableExpression.THIS_EXPRESSION; 1610 selector = node; 1611 1612 } else { 1613 objectExpression = expression(node); 1614 selector = null; } 1616 1617 String name = null; 1618 if (selector == null) { 1619 name = "call"; 1620 } else if (isType(LITERAL_super, selector)) { 1621 name = "super"; 1622 if (objectExpression == VariableExpression.THIS_EXPRESSION) { 1623 objectExpression = VariableExpression.SUPER_EXPRESSION; 1624 } 1625 } 1626 else if (isPrimitiveTypeLiteral(selector)) { 1627 throw new ASTRuntimeException(selector, "Primitive type literal: " + selector.getText() 1628 + " cannot be used as a method name"); 1629 } 1630 else { 1631 name = identifier(selector); 1632 } 1633 1634 Expression arguments = arguments(elist); 1635 MethodCallExpression expression = new MethodCallExpression(objectExpression, name, arguments); 1636 boolean implicitThis = (objectExpression == VariableExpression.THIS_EXPRESSION); 1637 implicitThis = implicitThis || (objectExpression == VariableExpression.SUPER_EXPRESSION); 1638 expression.setSafe(safe); 1639 expression.setSpreadSafe(spreadSafe); 1640 expression.setImplicitThis(implicitThis); 1641 configureAST(expression, methodCallNode); 1642 return expression; 1643 } 1644 1645 protected Expression constructorCallExpression(AST node) { 1646 if (isType(CTOR_CALL, node) || isType(LITERAL_new, node)) { 1647 node = node.getFirstChild(); 1648 } 1649 AST constructorCallNode = node; 1650 1651 String name = resolvedName(node); 1652 AST elist = node.getNextSibling(); 1653 1654 if (isType(ARRAY_DECLARATOR, elist)) { 1655 AST expressionNode = elist.getFirstChild(); 1656 if (expressionNode == null) { 1657 throw new ASTRuntimeException(elist, "No expression for the array constructor call"); 1658 } 1659 Expression size = expression(expressionNode); 1660 ArrayExpression arrayExpression = new ArrayExpression(name, size); 1661 configureAST(arrayExpression, node); 1662 return arrayExpression; 1663 } 1664 Expression arguments = arguments(elist); 1665 ConstructorCallExpression expression = new ConstructorCallExpression(name, arguments); 1666 configureAST(expression, constructorCallNode); 1667 return expression; 1668 } 1669 1670 protected Expression arguments(AST elist) { 1671 List expressionList = new ArrayList (); 1672 boolean namedArguments = false; 1674 for (AST node = elist; node != null; node = node.getNextSibling()) { 1675 if (isType(ELIST, node)) { 1676 for (AST child = node.getFirstChild(); child != null; child = child.getNextSibling()) { 1677 namedArguments |= addArgumentExpression(child, expressionList); 1678 } 1679 } 1680 else { 1681 namedArguments |= addArgumentExpression(node, expressionList); 1682 } 1683 } 1684 if (namedArguments) { 1685 if (!expressionList.isEmpty()) { 1686 List argumentList = new ArrayList (); 1690 for (Iterator iter = expressionList.iterator(); iter.hasNext();) { 1691 Expression expression = (Expression) iter.next(); 1692 if (!(expression instanceof MapEntryExpression)) { 1693 argumentList.add(expression); 1694 } 1695 } 1696 if (!argumentList.isEmpty()) { 1697 expressionList.removeAll(argumentList); 1698 MapExpression mapExpression = new MapExpression(expressionList); 1699 configureAST(mapExpression, elist); 1700 argumentList.add(0, mapExpression); 1701 ArgumentListExpression argumentListExpression = new ArgumentListExpression(argumentList); 1702 configureAST(argumentListExpression, elist); 1703 return argumentListExpression; 1704 } 1705 } 1706 NamedArgumentListExpression namedArgumentListExpression = new NamedArgumentListExpression(expressionList); 1707 configureAST(namedArgumentListExpression, elist); 1708 return namedArgumentListExpression; 1709 } 1710 else { 1711 ArgumentListExpression argumentListExpression = new ArgumentListExpression(expressionList); 1712 configureAST(argumentListExpression, elist); 1713 return argumentListExpression; 1714 } 1715 } 1716 1717 protected boolean addArgumentExpression(AST node, List expressionList) { 1718 if (node.getType() == SPREAD_MAP_ARG) { 1719 AST rightNode = node.getFirstChild(); 1720 Expression keyExpression = spreadMapExpression(node); 1721 Expression rightExpression = expression(rightNode); 1722 MapEntryExpression mapEntryExpression = new MapEntryExpression(keyExpression, rightExpression); 1723 expressionList.add(mapEntryExpression); 1724 return true; 1725 } 1726 else { 1727 Expression expression = expression(node); 1728 expressionList.add(expression); 1729 return expression instanceof MapEntryExpression; 1730 } 1731 } 1732 1733 protected Expression expressionList(AST node) { 1734 List expressionList = new ArrayList (); 1735 for (AST child = node.getFirstChild(); child != null; child = child.getNextSibling()) { 1736 expressionList.add(expression(child)); 1737 } 1738 if (expressionList.size() == 1) { 1739 return (Expression) expressionList.get(0); 1740 } 1741 else { 1742 ListExpression listExpression = new ListExpression(expressionList); 1743 configureAST(listExpression, node); 1744 return listExpression; 1745 } 1746 } 1747 1748 protected ClosureExpression closureExpression(AST node) { 1749 AST paramNode = node.getFirstChild(); 1750 Parameter[] parameters = Parameter.EMPTY_ARRAY; 1751 AST codeNode = paramNode; 1752 if (isType(PARAMETERS, paramNode) || isType(IMPLICIT_PARAMETERS, paramNode)) { 1753 parameters = parameters(paramNode); 1754 codeNode = paramNode.getNextSibling(); 1755 } 1756 Statement code = statementListNoChild(codeNode); 1757 ClosureExpression closureExpression = new ClosureExpression(parameters, code); 1758 configureAST(closureExpression, node); 1759 return closureExpression; 1760 } 1761 1762 protected Expression blockExpression(AST node) { 1763 AST codeNode = node.getFirstChild(); 1764 if (codeNode == null) return ConstantExpression.NULL; 1765 if (codeNode.getType() == EXPR && codeNode.getNextSibling() == null) { 1766 return expression(codeNode); 1768 } 1769 Parameter[] parameters = Parameter.EMPTY_ARRAY; 1770 Statement code = statementListNoChild(codeNode); 1771 ClosureExpression closureExpression = new ClosureExpression(parameters, code); 1772 configureAST(closureExpression, node); 1773 String callName = "call"; 1775 Expression noArguments = new ArgumentListExpression(); 1776 MethodCallExpression call = new MethodCallExpression(closureExpression, callName, noArguments); 1777 configureAST(call, node); 1778 return call; 1779 } 1780 1781 protected Expression negateExpression(AST negateExpr) { 1782 AST node = negateExpr.getFirstChild(); 1783 1784 String text = node.getText(); 1787 switch (node.getType()) { 1788 case NUM_DOUBLE: 1789 case NUM_FLOAT: 1790 case NUM_BIG_DECIMAL: 1791 ConstantExpression constantExpression = new ConstantExpression(Numbers.parseDecimal("-" + text)); 1792 configureAST(constantExpression, negateExpr); 1793 return constantExpression; 1794 1795 case NUM_BIG_INT: 1796 case NUM_INT: 1797 case NUM_LONG: 1798 ConstantExpression constantLongExpression = new ConstantExpression(Numbers.parseInteger("-" + text)); 1799 configureAST(constantLongExpression, negateExpr); 1800 return constantLongExpression; 1801 1802 default: 1803 NegationExpression negationExpression = new NegationExpression(expression(node)); 1804 configureAST(negationExpression, negateExpr); 1805 return negationExpression; 1806 } 1807 } 1808 1809 protected ConstantExpression decimalExpression(AST node) { 1810 String text = node.getText(); 1811 ConstantExpression constantExpression = new ConstantExpression(Numbers.parseDecimal(text)); 1812 configureAST(constantExpression, node); 1813 return constantExpression; 1814 } 1815 1816 protected ConstantExpression integerExpression(AST node) { 1817 String text = node.getText(); 1818 ConstantExpression constantExpression = new ConstantExpression(Numbers.parseInteger(text)); 1819 configureAST(constantExpression, node); 1820 return constantExpression; 1821 } 1822 1823 protected Expression gstring(AST gstringNode) { 1824 List strings = new ArrayList (); 1825 List values = new ArrayList (); 1826 1827 StringBuffer buffer = new StringBuffer (); 1828 1829 boolean isPrevString = false; 1830 1831 for (AST node = gstringNode.getFirstChild(); node != null; node = node.getNextSibling()) { 1832 int type = node.getType(); 1833 String text = null; 1834 switch (type) { 1835 1836 case STRING_LITERAL: 1837 if (isPrevString) assertNodeType(IDENT, node); isPrevString = true; 1839 text = node.getText(); 1840 ConstantExpression constantExpression = new ConstantExpression(text); 1841 configureAST(constantExpression, node); 1842 strings.add(constantExpression); 1843 buffer.append(text); 1844 break; 1845 1846 default: 1847 { 1848 if (!isPrevString) assertNodeType(IDENT, node); isPrevString = false; 1850 Expression expression = expression(node); 1851 values.add(expression); 1852 buffer.append("$"); 1853 buffer.append(expression.getText()); 1854 } 1855 break; 1856 } 1857 } 1858 GStringExpression gStringExpression = new GStringExpression(buffer.toString(), strings, values); 1859 configureAST(gStringExpression, gstringNode); 1860 return gStringExpression; 1861 } 1862 1863 protected Type type(AST typeNode) { 1864 return new Type(resolvedName(typeNode.getFirstChild())); 1867 } 1868 1869 protected String qualifiedName(AST qualifiedNameNode) { 1870 if (isType(IDENT, qualifiedNameNode)) { 1871 return qualifiedNameNode.getText(); 1872 } 1873 if (isType(DOT, qualifiedNameNode)) { 1874 AST node = qualifiedNameNode.getFirstChild(); 1875 StringBuffer buffer = new StringBuffer (); 1876 boolean first = true; 1877 1878 for (; node != null; node = node.getNextSibling()) { 1879 if (first) { 1880 first = false; 1881 } 1882 else { 1883 buffer.append("."); 1884 } 1885 buffer.append(qualifiedName(node)); 1886 } 1887 return buffer.toString(); 1888 } 1889 else { 1890 return qualifiedNameNode.getText(); 1891 } 1892 } 1893 1894 protected String typeName(AST typeNode) { 1895 String answer = null; 1896 AST node = typeNode.getFirstChild(); 1897 if (node != null) { 1898 if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) { 1899 return resolveTypeName(qualifiedName(node.getFirstChild())) + "[]"; 1900 } 1901 answer = resolveTypeName(qualifiedName(node)); 1902 node = node.getNextSibling(); 1903 if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) { 1904 return answer + "[]"; 1905 } 1906 } 1907 return answer; 1908 } 1909 1910 1914 protected String resolveTypeName(String name, boolean safe) { 1915 if (name == null) { 1916 return null; 1917 } 1918 return resolveNewClassOrName(name, safe); 1919 } 1920 1921 1925 protected String resolveTypeName(String name) { 1926 return resolveTypeName(name, true); 1927 } 1928 1929 1933 protected String resolvedName(AST node) { 1934 if (isType(TYPE, node)) { 1935 node = node.getFirstChild(); 1936 } 1937 String answer = null; 1938 if (isType(DOT, node) || isType(OPTIONAL_DOT, node)) { 1939 answer = qualifiedName(node); 1940 } 1941 else if (isPrimitiveTypeLiteral(node)) { 1942 answer = node.getText(); 1943 } 1944 else if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) { 1945 AST child = node.getFirstChild(); 1946 String text = resolvedName(child); 1947 if (text.endsWith("[]")) { 1951 return text; 1952 } 1953 return text + "[]"; 1954 } 1955 else { 1956 String identifier = node.getText(); 1957 answer = resolveTypeName(identifier); 1958 1959 } 1960 AST nextSibling = node.getNextSibling(); 1961 if (isType(INDEX_OP, nextSibling) || isType(ARRAY_DECLARATOR, node)) { 1962 return answer + "[]"; 1963 } 1964 else { 1965 return answer; 1966 } 1967 } 1968 1969 protected boolean isPrimitiveTypeLiteral(AST node) { 1970 int type = node.getType(); 1971 switch (type) { 1972 case LITERAL_boolean: 1973 case LITERAL_byte: 1974 case LITERAL_char: 1975 case LITERAL_double: 1976 case LITERAL_float: 1977 case LITERAL_int: 1978 case LITERAL_long: 1979 case LITERAL_short: 1980 return true; 1981 1982 default: 1983 return false; 1984 } 1985 } 1986 1987 1990 protected String identifier(AST node) { 1991 assertNodeType(IDENT, node); 1992 return node.getText(); 1993 } 1994 1995 protected String label(AST labelNode) { 1996 AST node = labelNode.getFirstChild(); 1997 if (node == null) { 1998 return null; 1999 } 2000 return identifier(node); 2001 } 2002 2003 2004 2005 2008 2009 2012 protected boolean hasVisibility(int modifiers) { 2013 return (modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) != 0; 2014 } 2015 2016 protected void configureAST(ASTNode node, AST ast) { 2017 if (ast==null) throw new ASTRuntimeException(ast, "PARSER BUG: Tried to configure "+node.getClass().getName()+" with null Node"); 2018 node.setColumnNumber(ast.getColumn()); 2019 node.setLineNumber(ast.getLine()); 2020 2021 } 2024 2025 protected static Token makeToken(int typeCode, AST node) { 2026 return Token.newSymbol(typeCode, node.getLine(), node.getColumn()); 2027 } 2028 2029 protected String getFirstChildText(AST node) { 2030 AST child = node.getFirstChild(); 2031 return child != null ? child.getText() : null; 2032 } 2033 2034 2035 protected boolean isType(int typeCode, AST node) { 2036 return node != null && node.getType() == typeCode; 2037 } 2038 2039 private String getTokenName(int token) { 2040 if (tokenNames==null) return ""+token; 2041 return tokenNames[token]; 2042 } 2043 2044 private String getTokenName(AST node) { 2045 if (node==null) return "null"; 2046 return getTokenName(node.getType()); 2047 } 2048 2049 protected void assertNodeType(int type, AST node) { 2050 if (node == null) { 2051 throw new ASTRuntimeException(node, "No child node available in AST when expecting type: " + getTokenName(type)); 2052 } 2053 if (node.getType() != type) { 2054 throw new ASTRuntimeException(node, "Unexpected node type: " + getTokenName(node) + " found when expecting type: " + getTokenName(type)); 2055 } 2056 } 2057 2058 protected void notImplementedYet(AST node) { 2059 throw new ASTRuntimeException(node, "AST node not implemented yet for type: " + getTokenName(node)); 2060 } 2061 2062 protected void unknownAST(AST node) { 2063 throw new ASTRuntimeException(node, "Unknown type: " + getTokenName(node)); 2064 } 2065 2066 protected void dumpTree(AST ast) { 2067 for (AST node = ast.getFirstChild(); node != null; node = node.getNextSibling()) { 2068 dump(node); 2069 } 2070 } 2071 2072 protected void dump(AST node) { 2073 System.out.println("Type: " + getTokenName(node) + " text: " + node.getText()); 2074 } 2075} 2076 | Popular Tags |