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