Source Code Cross Referenced for AntlrParserPlugin.java in  » Scripting » groovy-1.0 » org » codehaus » groovy » antlr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » groovy 1.0 » org.codehaus.groovy.antlr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         *
0003:         * Copyright 2004 James Strachan
0004:         *
0005:         * Licensed under the Apache License, Version 2.0 (the "License");
0006:         * you may not use this file except in compliance with the License.
0007:         * You may obtain a copy of the License at
0008:         *
0009:         * http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         *
0017:         **/package org.codehaus.groovy.antlr;
0018:
0019:        import antlr.RecognitionException;
0020:        import antlr.TokenStreamException;
0021:        import antlr.TokenStreamRecognitionException;
0022:        import antlr.collections.AST;
0023:        import com.thoughtworks.xstream.XStream;
0024:
0025:        import org.codehaus.groovy.GroovyBugError;
0026:        import org.codehaus.groovy.antlr.parser.GroovyLexer;
0027:        import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
0028:        import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
0029:        import org.codehaus.groovy.antlr.treewalker.*;
0030:        import org.codehaus.groovy.ast.*;
0031:        import org.codehaus.groovy.ast.expr.*;
0032:        import org.codehaus.groovy.ast.stmt.*;
0033:        import org.codehaus.groovy.control.CompilationFailedException;
0034:        import org.codehaus.groovy.control.ParserPlugin;
0035:        import org.codehaus.groovy.control.SourceUnit;
0036:        import org.codehaus.groovy.syntax.*;
0037:        import org.objectweb.asm.Opcodes;
0038:
0039:        import java.io.*;
0040:        import java.security.AccessController;
0041:        import java.security.PrivilegedAction;
0042:        import java.util.ArrayList;
0043:        import java.util.Iterator;
0044:        import java.util.List;
0045:
0046:        /**
0047:         * A parser plugin which adapts the JSR Antlr Parser to the Groovy runtime
0048:         *
0049:         * @author <a href="mailto:jstrachan@protique.com">James Strachan</a>
0050:         * @version $Revision: 4526 $
0051:         */
0052:        public class AntlrParserPlugin extends ASTHelper implements 
0053:                ParserPlugin, GroovyTokenTypes {
0054:
0055:            private AST ast;
0056:            private ClassNode classNode;
0057:            private String[] tokenNames;
0058:
0059:            public Reduction parseCST(final SourceUnit sourceUnit, Reader reader)
0060:                    throws CompilationFailedException {
0061:                ast = null;
0062:
0063:                setController(sourceUnit);
0064:
0065:                SourceBuffer sourceBuffer = new SourceBuffer();
0066:                UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(
0067:                        reader, sourceBuffer);
0068:                GroovyLexer lexer = new GroovyLexer(unicodeReader);
0069:                unicodeReader.setLexer(lexer);
0070:                GroovyRecognizer parser = GroovyRecognizer.make(lexer);
0071:                parser.setSourceBuffer(sourceBuffer);
0072:                tokenNames = parser.getTokenNames();
0073:                parser.setFilename(sourceUnit.getName());
0074:
0075:                // start parsing at the compilationUnit rule
0076:                try {
0077:                    parser.compilationUnit();
0078:                } catch (TokenStreamRecognitionException tsre) {
0079:                    RecognitionException e = tsre.recog;
0080:                    SyntaxException se = new SyntaxException(e.getMessage(), e,
0081:                            e.getLine(), e.getColumn());
0082:                    se.setFatal(true);
0083:                    sourceUnit.addError(se);
0084:                } catch (RecognitionException e) {
0085:                    SyntaxException se = new SyntaxException(e.getMessage(), e,
0086:                            e.getLine(), e.getColumn());
0087:                    se.setFatal(true);
0088:                    sourceUnit.addError(se);
0089:                } catch (TokenStreamException e) {
0090:                    sourceUnit.addException(e);
0091:                }
0092:
0093:                ast = parser.getAST();
0094:
0095:                AntlrASTProcessor snippets = new AntlrASTProcessSnippets(
0096:                        sourceBuffer);
0097:                ast = snippets.process(ast);
0098:
0099:                AccessController.doPrivileged(new PrivilegedAction() {
0100:                    public Object run() {
0101:                        outputASTInVariousFormsIfNeeded(sourceUnit);
0102:                        return null;
0103:                    }
0104:                });
0105:
0106:                return null; //new Reduction(Tpken.EOF);
0107:            }
0108:
0109:            public SourceSummary getSummary() {
0110:                SummaryCollector summaryCollector = new SummaryCollector();
0111:                AntlrASTProcessor treewalker = new PreOrderTraversal(
0112:                        summaryCollector);
0113:                treewalker.process(ast);
0114:                return summaryCollector.getSourceSummary();
0115:            }
0116:
0117:            private void outputASTInVariousFormsIfNeeded(SourceUnit sourceUnit) {
0118:                // straight xstream output of AST
0119:                if ("xml".equals(System.getProperty("antlr.ast"))) {
0120:                    saveAsXML(sourceUnit.getName(), ast);
0121:                }
0122:
0123:                // 'pretty printer' output of AST
0124:                if ("groovy".equals(System.getProperty("antlr.ast"))) {
0125:                    try {
0126:                        PrintStream out = new PrintStream(new FileOutputStream(
0127:                                sourceUnit.getName() + ".pretty.groovy"));
0128:                        Visitor visitor = new SourcePrinter(out, tokenNames);
0129:                        AntlrASTProcessor treewalker = new SourceCodeTraversal(
0130:                                visitor);
0131:                        treewalker.process(ast);
0132:                    } catch (FileNotFoundException e) {
0133:                        System.out.println("Cannot create "
0134:                                + sourceUnit.getName() + ".pretty.groovy");
0135:                    }
0136:                }
0137:
0138:                // output AST in format suitable for opening in http://freemind.sourceforge.net
0139:                // which is a really nice way of seeing the AST, folding nodes etc
0140:                if ("mindmap".equals(System.getProperty("antlr.ast"))) {
0141:                    try {
0142:                        PrintStream out = new PrintStream(new FileOutputStream(
0143:                                sourceUnit.getName() + ".mm"));
0144:                        Visitor visitor = new MindMapPrinter(out, tokenNames);
0145:                        AntlrASTProcessor treewalker = new PreOrderTraversal(
0146:                                visitor);
0147:                        treewalker.process(ast);
0148:                    } catch (FileNotFoundException e) {
0149:                        System.out.println("Cannot create "
0150:                                + sourceUnit.getName() + ".mm");
0151:                    }
0152:                }
0153:
0154:                // html output of AST
0155:                if ("html".equals(System.getProperty("antlr.ast"))) {
0156:                    try {
0157:                        PrintStream out = new PrintStream(new FileOutputStream(
0158:                                sourceUnit.getName() + ".html"));
0159:                        List v = new ArrayList();
0160:                        v.add(new NodeAsHTMLPrinter(out, tokenNames));
0161:                        v.add(new SourcePrinter(out, tokenNames));
0162:                        Visitor visitors = new CompositeVisitor(v);
0163:                        AntlrASTProcessor treewalker = new SourceCodeTraversal(
0164:                                visitors);
0165:                        treewalker.process(ast);
0166:                    } catch (FileNotFoundException e) {
0167:                        System.out.println("Cannot create "
0168:                                + sourceUnit.getName() + ".html");
0169:                    }
0170:                }
0171:
0172:            }
0173:
0174:            private void saveAsXML(String name, AST ast) {
0175:                XStream xstream = new XStream();
0176:                try {
0177:                    xstream.toXML(ast, new FileWriter(name + ".antlr.xml"));
0178:                    System.out.println("Written AST to " + name + ".antlr.xml");
0179:                } catch (Exception e) {
0180:                    System.out.println("Couldn't write to " + name
0181:                            + ".antlr.xml");
0182:                    e.printStackTrace();
0183:                }
0184:            }
0185:
0186:            public ModuleNode buildAST(SourceUnit sourceUnit,
0187:                    ClassLoader classLoader, Reduction cst)
0188:                    throws ParserException {
0189:                setClassLoader(classLoader);
0190:                makeModule();
0191:                try {
0192:                    convertGroovy(ast);
0193:                } catch (ASTRuntimeException e) {
0194:                    throw new ASTParserException(e.getMessage() + ". File: "
0195:                            + sourceUnit.getName(), e);
0196:                }
0197:                return output;
0198:            }
0199:
0200:            /**
0201:             * Converts the Antlr AST to the Groovy AST
0202:             */
0203:            protected void convertGroovy(AST node) {
0204:                while (node != null) {
0205:                    int type = node.getType();
0206:                    switch (type) {
0207:                    case PACKAGE_DEF:
0208:                        packageDef(node);
0209:                        break;
0210:
0211:                    case IMPORT:
0212:                        importDef(node);
0213:                        break;
0214:
0215:                    case CLASS_DEF:
0216:                        classDef(node);
0217:                        break;
0218:
0219:                    case INTERFACE_DEF:
0220:                        interfaceDef(node);
0221:                        break;
0222:
0223:                    case METHOD_DEF:
0224:                        methodDef(node);
0225:                        break;
0226:
0227:                    default: {
0228:                        Statement statement = statement(node);
0229:                        output.addStatement(statement);
0230:                    }
0231:                    }
0232:                    node = node.getNextSibling();
0233:                }
0234:            }
0235:
0236:            // Top level control structures
0237:            //-------------------------------------------------------------------------
0238:
0239:            protected void packageDef(AST packageDef) {
0240:                AST node = packageDef.getFirstChild();
0241:                if (isType(ANNOTATIONS, node)) {
0242:                    node = node.getNextSibling();
0243:                }
0244:                String name = qualifiedName(node);
0245:                setPackageName(name);
0246:            }
0247:
0248:            protected void importDef(AST importNode) {
0249:                // TODO handle static imports
0250:
0251:                AST node = importNode.getFirstChild();
0252:
0253:                String alias = null;
0254:                if (isType(LITERAL_as, node)) {
0255:                    //import is like "import Foo as Bar"
0256:                    node = node.getFirstChild();
0257:                    AST aliasNode = node.getNextSibling();
0258:                    alias = identifier(aliasNode);
0259:                }
0260:
0261:                if (node.getNumberOfChildren() == 0) {
0262:                    // import is like  "import Foo"
0263:                    String name = identifier(node);
0264:                    ClassNode type = ClassHelper.make(name);
0265:                    configureAST(type, importNode);
0266:                    importClass(type, name, alias);
0267:                    return;
0268:                }
0269:
0270:                AST packageNode = node.getFirstChild();
0271:                String packageName = qualifiedName(packageNode);
0272:                AST nameNode = packageNode.getNextSibling();
0273:                if (isType(STAR, nameNode)) {
0274:                    // import is like "import foo.*"
0275:                    importPackageWithStar(packageName);
0276:                    if (alias != null)
0277:                        throw new GroovyBugError(
0278:                                "imports like 'import foo.* as Bar' are not "
0279:                                        + "supported and should be caught by the grammar");
0280:                } else {
0281:                    // import is like "import foo.Bar"
0282:                    String name = identifier(nameNode);
0283:                    ClassNode type = ClassHelper.make(packageName + "." + name);
0284:                    configureAST(type, importNode);
0285:                    importClass(type, name, alias);
0286:                }
0287:            }
0288:
0289:            protected void interfaceDef(AST classDef) {
0290:                List annotations = new ArrayList();
0291:                AST node = classDef.getFirstChild();
0292:                int modifiers = Opcodes.ACC_PUBLIC;
0293:                if (isType(MODIFIERS, node)) {
0294:                    modifiers = modifiers(node, annotations, modifiers);
0295:                    node = node.getNextSibling();
0296:                }
0297:                modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE;
0298:
0299:                String name = identifier(node);
0300:                node = node.getNextSibling();
0301:                ClassNode super Class = ClassHelper.OBJECT_TYPE;
0302:
0303:                ClassNode[] interfaces = {};
0304:                if (isType(EXTENDS_CLAUSE, node)) {
0305:                    interfaces = interfaces(node);
0306:                    node = node.getNextSibling();
0307:                }
0308:
0309:                addNewClassName(name);
0310:                classNode = new ClassNode(dot(getPackageName(), name),
0311:                        modifiers, super Class, interfaces, null);
0312:                classNode.addAnnotations(annotations);
0313:                configureAST(classNode, classDef);
0314:
0315:                assertNodeType(OBJBLOCK, node);
0316:                objectBlock(node);
0317:                output.addClass(classNode);
0318:                classNode = null;
0319:            }
0320:
0321:            protected void classDef(AST classDef) {
0322:                List annotations = new ArrayList();
0323:                AST node = classDef.getFirstChild();
0324:                int modifiers = Opcodes.ACC_PUBLIC;
0325:                if (isType(MODIFIERS, node)) {
0326:                    modifiers = modifiers(node, annotations, modifiers);
0327:                    node = node.getNextSibling();
0328:                }
0329:
0330:                String name = identifier(node);
0331:                node = node.getNextSibling();
0332:
0333:                ClassNode super Class = null;
0334:                if (isType(EXTENDS_CLAUSE, node)) {
0335:                    super Class = makeType(node);
0336:                    node = node.getNextSibling();
0337:                }
0338:
0339:                ClassNode[] interfaces = {};
0340:                if (isType(IMPLEMENTS_CLAUSE, node)) {
0341:                    interfaces = interfaces(node);
0342:                    node = node.getNextSibling();
0343:                }
0344:
0345:                // TODO read mixins
0346:                MixinNode[] mixins = {};
0347:
0348:                addNewClassName(name);
0349:                classNode = new ClassNode(dot(getPackageName(), name),
0350:                        modifiers, super Class, interfaces, mixins);
0351:                classNode.addAnnotations(annotations);
0352:                configureAST(classNode, classDef);
0353:
0354:                assertNodeType(OBJBLOCK, node);
0355:                objectBlock(node);
0356:                output.addClass(classNode);
0357:                classNode = null;
0358:            }
0359:
0360:            protected void objectBlock(AST objectBlock) {
0361:                for (AST node = objectBlock.getFirstChild(); node != null; node = node
0362:                        .getNextSibling()) {
0363:                    int type = node.getType();
0364:                    switch (type) {
0365:                    case OBJBLOCK:
0366:                        objectBlock(node);
0367:                        break;
0368:
0369:                    case METHOD_DEF:
0370:                        methodDef(node);
0371:                        break;
0372:
0373:                    case CTOR_IDENT:
0374:                        constructorDef(node);
0375:                        break;
0376:
0377:                    case VARIABLE_DEF:
0378:                        fieldDef(node);
0379:                        break;
0380:
0381:                    case STATIC_INIT:
0382:                        staticInit(node);
0383:                        break;
0384:
0385:                    case INSTANCE_INIT:
0386:                        objectInit(node);
0387:                        break;
0388:
0389:                    default:
0390:                        unknownAST(node);
0391:                    }
0392:                }
0393:            }
0394:
0395:            protected void throwsList(AST node, List list) {
0396:                String clazz = identifier(node);
0397:                ClassNode exception = ClassHelper.make(clazz);
0398:                list.add(exception);
0399:                AST next = node.getNextSibling();
0400:                if (next != null)
0401:                    throwsList(next, list);
0402:                next = node.getFirstChild();
0403:                if (next != null)
0404:                    throwsList(next, list);
0405:            }
0406:
0407:            protected void methodDef(AST methodDef) {
0408:                List annotations = new ArrayList();
0409:                AST node = methodDef.getFirstChild();
0410:                int modifiers = Opcodes.ACC_PUBLIC;
0411:                if (isType(MODIFIERS, node)) {
0412:                    modifiers = modifiers(node, annotations, modifiers);
0413:                    node = node.getNextSibling();
0414:                }
0415:
0416:                if (classNode != null
0417:                        && (classNode.getModifiers() & Opcodes.ACC_INTERFACE) > 0) {
0418:                    modifiers |= Opcodes.ACC_ABSTRACT;
0419:                }
0420:
0421:                ClassNode returnType = null;
0422:                if (isType(TYPE, node)) {
0423:                    returnType = makeType(node);
0424:                    node = node.getNextSibling();
0425:                }
0426:
0427:                String name = identifier(node);
0428:                if (classNode != null) {
0429:                    if (classNode.getNameWithoutPackage().equals(name)) {
0430:                        throw new ASTRuntimeException(methodDef,
0431:                                "Invalid constructor format. Try remove the 'def' expression?");
0432:                    }
0433:                }
0434:                node = node.getNextSibling();
0435:
0436:                assertNodeType(PARAMETERS, node);
0437:                Parameter[] parameters = parameters(node);
0438:                if (parameters == null)
0439:                    parameters = Parameter.EMPTY_ARRAY;
0440:                node = node.getNextSibling();
0441:
0442:                ClassNode[] exceptions = new ClassNode[0];
0443:                if (isType(LITERAL_throws, node)) {
0444:                    AST throwsNode = node.getFirstChild();
0445:                    List exceptionList = new ArrayList();
0446:                    throwsList(throwsNode, exceptionList);
0447:                    exceptions = (ClassNode[]) exceptionList
0448:                            .toArray(exceptions);
0449:                    node = node.getNextSibling();
0450:                }
0451:
0452:                Statement code = null;
0453:                if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) {
0454:                    if (node == null) {
0455:                        throw new ASTRuntimeException(methodDef,
0456:                                "You defined a method without body. Try adding a body, or declare it abstract.");
0457:                    }
0458:                    assertNodeType(SLIST, node);
0459:                    code = statementList(node);
0460:                }
0461:
0462:                MethodNode methodNode = new MethodNode(name, modifiers,
0463:                        returnType, parameters, exceptions, code);
0464:                methodNode.addAnnotations(annotations);
0465:                configureAST(methodNode, methodDef);
0466:                if (classNode != null) {
0467:                    classNode.addMethod(methodNode);
0468:                } else {
0469:                    output.addMethod(methodNode);
0470:                }
0471:            }
0472:
0473:            protected void staticInit(AST staticInit) {
0474:                BlockStatement code = (BlockStatement) statementList(staticInit);
0475:                classNode.addStaticInitializerStatements(code.getStatements(),
0476:                        false);
0477:            }
0478:
0479:            protected void objectInit(AST init) {
0480:                BlockStatement code = (BlockStatement) statementList(init);
0481:                classNode.addObjectInitializerStatements(code);
0482:            }
0483:
0484:            protected void constructorDef(AST constructorDef) {
0485:                List annotations = new ArrayList();
0486:                AST node = constructorDef.getFirstChild();
0487:                int modifiers = Opcodes.ACC_PUBLIC;
0488:                if (isType(MODIFIERS, node)) {
0489:                    modifiers = modifiers(node, annotations, modifiers);
0490:                    node = node.getNextSibling();
0491:                }
0492:
0493:                assertNodeType(PARAMETERS, node);
0494:                Parameter[] parameters = parameters(node);
0495:                if (parameters == null)
0496:                    parameters = Parameter.EMPTY_ARRAY;
0497:                node = node.getNextSibling();
0498:
0499:                ClassNode[] exceptions = new ClassNode[0];
0500:                if (isType(LITERAL_throws, node)) {
0501:                    AST throwsNode = node.getFirstChild();
0502:                    List exceptionList = new ArrayList();
0503:                    throwsList(throwsNode, exceptionList);
0504:                    exceptions = (ClassNode[]) exceptionList
0505:                            .toArray(exceptions);
0506:                    node = node.getNextSibling();
0507:                }
0508:
0509:                assertNodeType(SLIST, node);
0510:                Statement code = statementList(node);
0511:
0512:                ConstructorNode constructorNode = classNode.addConstructor(
0513:                        modifiers, parameters, exceptions, code);
0514:                constructorNode.addAnnotations(annotations);
0515:                configureAST(constructorNode, constructorDef);
0516:            }
0517:
0518:            protected void fieldDef(AST fieldDef) {
0519:                List annotations = new ArrayList();
0520:                AST node = fieldDef.getFirstChild();
0521:
0522:                int modifiers = 0;
0523:                if (isType(MODIFIERS, node)) {
0524:                    modifiers = modifiers(node, annotations, modifiers);
0525:                    node = node.getNextSibling();
0526:                }
0527:
0528:                if (classNode.isInterface()) {
0529:                    modifiers |= Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
0530:                    if ((modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) == 0) {
0531:                        modifiers |= Opcodes.ACC_PUBLIC;
0532:                    }
0533:                }
0534:
0535:                ClassNode type = null;
0536:                if (isType(TYPE, node)) {
0537:                    type = makeType(node);
0538:                    node = node.getNextSibling();
0539:                }
0540:
0541:                String name = identifier(node);
0542:                node = node.getNextSibling();
0543:
0544:                Expression initialValue = null;
0545:                if (node != null) {
0546:                    assertNodeType(ASSIGN, node);
0547:                    initialValue = expression(node);
0548:                }
0549:
0550:                if (initialValue == null && type != null) {
0551:                    if (type == ClassHelper.int_TYPE) {
0552:                        initialValue = new ConstantExpression(new Integer(0));
0553:                    } else if (type == ClassHelper.long_TYPE) {
0554:                        initialValue = new ConstantExpression(new Long(0L));
0555:                    } else if (type == ClassHelper.double_TYPE) {
0556:                        initialValue = new ConstantExpression(new Double(0.0));
0557:                    } else if (type == ClassHelper.float_TYPE) {
0558:                        initialValue = new ConstantExpression(new Float(0.0F));
0559:                    } else if (type == ClassHelper.boolean_TYPE) {
0560:                        initialValue = ConstantExpression.FALSE;
0561:                    } else if (type == ClassHelper.short_TYPE) {
0562:                        initialValue = new ConstantExpression(new Short(
0563:                                (short) 0));
0564:                    } else if (type == ClassHelper.byte_TYPE) {
0565:                        initialValue = new ConstantExpression(
0566:                                new Byte((byte) 0));
0567:                    } else if (type == ClassHelper.char_TYPE) {
0568:                        initialValue = new ConstantExpression(new Character(
0569:                                (char) 0));
0570:                    }
0571:                }
0572:
0573:                FieldNode fieldNode = new FieldNode(name, modifiers, type,
0574:                        classNode, initialValue);
0575:                fieldNode.addAnnotations(annotations);
0576:                configureAST(fieldNode, fieldDef);
0577:
0578:                if (!hasVisibility(modifiers)) {
0579:                    // lets set the modifiers on the field
0580:                    int fieldModifiers = 0;
0581:                    int flags = Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT
0582:                            | Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL;
0583:
0584:                    if (!hasVisibility(modifiers)) {
0585:                        modifiers |= Opcodes.ACC_PUBLIC;
0586:                        fieldModifiers |= Opcodes.ACC_PRIVATE;
0587:                    }
0588:
0589:                    // lets pass along any other modifiers we need
0590:                    fieldModifiers |= (modifiers & flags);
0591:                    fieldNode.setModifiers(fieldModifiers);
0592:
0593:                    PropertyNode propertyNode = new PropertyNode(fieldNode,
0594:                            modifiers, null, null);
0595:                    configureAST(propertyNode, fieldDef);
0596:                    classNode.addProperty(propertyNode);
0597:                } else {
0598:                    fieldNode.setModifiers(modifiers);
0599:                    classNode.addField(fieldNode);
0600:                }
0601:            }
0602:
0603:            protected ClassNode[] interfaces(AST node) {
0604:                List interfaceList = new ArrayList();
0605:                for (AST implementNode = node.getFirstChild(); implementNode != null; implementNode = implementNode
0606:                        .getNextSibling()) {
0607:                    interfaceList.add(ClassHelper
0608:                            .make(qualifiedName(implementNode)));
0609:                }
0610:                ClassNode[] interfaces = {};
0611:                if (!interfaceList.isEmpty()) {
0612:                    interfaces = new ClassNode[interfaceList.size()];
0613:                    interfaceList.toArray(interfaces);
0614:
0615:                }
0616:                return interfaces;
0617:            }
0618:
0619:            protected Parameter[] parameters(AST parametersNode) {
0620:                AST node = parametersNode.getFirstChild();
0621:                if (node == null) {
0622:                    if (isType(IMPLICIT_PARAMETERS, parametersNode))
0623:                        return Parameter.EMPTY_ARRAY;
0624:                    return null;
0625:                } else {
0626:                    List parameters = new ArrayList();
0627:                    do {
0628:                        parameters.add(parameter(node));
0629:                        node = node.getNextSibling();
0630:                    } while (node != null);
0631:                    Parameter[] answer = new Parameter[parameters.size()];
0632:                    parameters.toArray(answer);
0633:                    return answer;
0634:                }
0635:            }
0636:
0637:            protected Parameter parameter(AST paramNode) {
0638:                List annotations = new ArrayList();
0639:                AST node = paramNode.getFirstChild();
0640:
0641:                int modifiers = 0;
0642:                if (isType(MODIFIERS, node)) {
0643:                    modifiers = modifiers(node, annotations, modifiers);
0644:                    node = node.getNextSibling();
0645:                }
0646:
0647:                ClassNode type = ClassHelper.DYNAMIC_TYPE;
0648:                if (isType(TYPE, node)) {
0649:                    type = makeType(node);
0650:                    node = node.getNextSibling();
0651:                }
0652:
0653:                String name = identifier(node);
0654:                node = node.getNextSibling();
0655:                VariableExpression leftExpression = new VariableExpression(
0656:                        name, type);
0657:                configureAST(leftExpression, paramNode);
0658:
0659:                Parameter parameter = null;
0660:                if (node != null) {
0661:                    assertNodeType(ASSIGN, node);
0662:                    Expression rightExpression = expression(node
0663:                            .getFirstChild());
0664:                    parameter = new Parameter(type, name, rightExpression);
0665:                } else
0666:                    parameter = new Parameter(type, name);
0667:
0668:                // TODO
0669:                //configureAST(parameter,paramNode);
0670:                //parameter.addAnnotations(annotations);
0671:                return parameter;
0672:            }
0673:
0674:            protected int modifiers(AST modifierNode, List annotations,
0675:                    int defaultModifiers) {
0676:                assertNodeType(MODIFIERS, modifierNode);
0677:
0678:                boolean access = false;
0679:                int answer = 0;
0680:
0681:                for (AST node = modifierNode.getFirstChild(); node != null; node = node
0682:                        .getNextSibling()) {
0683:                    int type = node.getType();
0684:                    switch (type) {
0685:                    // annotations
0686:                    case ANNOTATION:
0687:                        annotations.add(annotation(node));
0688:                        break;
0689:
0690:                    // core access scope modifiers
0691:                    case LITERAL_private:
0692:                        answer = setModifierBit(node, answer,
0693:                                Opcodes.ACC_PRIVATE);
0694:                        access = setAccessTrue(node, access);
0695:                        break;
0696:
0697:                    case LITERAL_protected:
0698:                        answer = setModifierBit(node, answer,
0699:                                Opcodes.ACC_PROTECTED);
0700:                        access = setAccessTrue(node, access);
0701:                        break;
0702:
0703:                    case LITERAL_public:
0704:                        answer = setModifierBit(node, answer,
0705:                                Opcodes.ACC_PUBLIC);
0706:                        access = setAccessTrue(node, access);
0707:                        break;
0708:
0709:                    // other modifiers
0710:                    case ABSTRACT:
0711:                        answer = setModifierBit(node, answer,
0712:                                Opcodes.ACC_ABSTRACT);
0713:                        break;
0714:
0715:                    case FINAL:
0716:                        answer = setModifierBit(node, answer, Opcodes.ACC_FINAL);
0717:                        break;
0718:
0719:                    case LITERAL_native:
0720:                        answer = setModifierBit(node, answer,
0721:                                Opcodes.ACC_NATIVE);
0722:                        break;
0723:
0724:                    case LITERAL_static:
0725:                        answer = setModifierBit(node, answer,
0726:                                Opcodes.ACC_STATIC);
0727:                        break;
0728:
0729:                    case STRICTFP:
0730:                        answer = setModifierBit(node, answer,
0731:                                Opcodes.ACC_STRICT);
0732:                        break;
0733:
0734:                    case LITERAL_synchronized:
0735:                        answer = setModifierBit(node, answer,
0736:                                Opcodes.ACC_SYNCHRONIZED);
0737:                        break;
0738:
0739:                    case LITERAL_transient:
0740:                        answer = setModifierBit(node, answer,
0741:                                Opcodes.ACC_TRANSIENT);
0742:                        break;
0743:
0744:                    case LITERAL_volatile:
0745:                        answer = setModifierBit(node, answer,
0746:                                Opcodes.ACC_VOLATILE);
0747:                        break;
0748:
0749:                    default:
0750:                        unknownAST(node);
0751:                    }
0752:                }
0753:                if (!access) {
0754:                    answer |= defaultModifiers;
0755:                }
0756:                return answer;
0757:            }
0758:
0759:            protected boolean setAccessTrue(AST node, boolean access) {
0760:                if (!access) {
0761:                    return true;
0762:                } else {
0763:                    throw new ASTRuntimeException(
0764:                            node,
0765:                            "Cannot specify modifier: "
0766:                                    + node.getText()
0767:                                    + " when access scope has already been defined");
0768:                }
0769:            }
0770:
0771:            protected int setModifierBit(AST node, int answer, int bit) {
0772:                if ((answer & bit) != 0) {
0773:                    throw new ASTRuntimeException(node,
0774:                            "Cannot repeat modifier: " + node.getText());
0775:                }
0776:                return answer | bit;
0777:            }
0778:
0779:            protected AnnotationNode annotation(AST annotationNode) {
0780:                AST node = annotationNode.getFirstChild();
0781:                String name = identifier(node);
0782:                AnnotationNode annotatedNode = new AnnotationNode(ClassHelper
0783:                        .make(name));
0784:                configureAST(annotatedNode, node);
0785:                while (true) {
0786:                    node = node.getNextSibling();
0787:                    if (isType(ANNOTATION_MEMBER_VALUE_PAIR, node)) {
0788:                        AST memberNode = node.getFirstChild();
0789:                        String param = identifier(memberNode);
0790:                        Expression expression = expression(memberNode
0791:                                .getNextSibling());
0792:                        annotatedNode.addMember(param, expression);
0793:                    } else {
0794:                        break;
0795:                    }
0796:                }
0797:                return annotatedNode;
0798:            }
0799:
0800:            // Statements
0801:            //-------------------------------------------------------------------------
0802:
0803:            protected Statement statement(AST node) {
0804:                Statement statement = null;
0805:                int type = node.getType();
0806:                switch (type) {
0807:                case SLIST:
0808:                case LITERAL_finally:
0809:                    statement = statementList(node);
0810:                    break;
0811:
0812:                case METHOD_CALL:
0813:                    statement = methodCall(node);
0814:                    break;
0815:
0816:                case VARIABLE_DEF:
0817:                    statement = variableDef(node);
0818:                    break;
0819:
0820:                case LABELED_STAT:
0821:                    statement = labelledStatement(node);
0822:                    break;
0823:
0824:                case LITERAL_assert:
0825:                    statement = assertStatement(node);
0826:                    break;
0827:
0828:                case LITERAL_break:
0829:                    statement = breakStatement(node);
0830:                    break;
0831:
0832:                case LITERAL_continue:
0833:                    statement = continueStatement(node);
0834:                    break;
0835:
0836:                case LITERAL_if:
0837:                    statement = ifStatement(node);
0838:                    break;
0839:
0840:                case LITERAL_for:
0841:                    statement = forStatement(node);
0842:                    break;
0843:
0844:                case LITERAL_return:
0845:                    statement = returnStatement(node);
0846:                    break;
0847:
0848:                case LITERAL_synchronized:
0849:                    statement = synchronizedStatement(node);
0850:                    break;
0851:
0852:                case LITERAL_switch:
0853:                    statement = switchStatement(node);
0854:                    break;
0855:
0856:                case LITERAL_with:
0857:                    statement = withStatement(node);
0858:                    break;
0859:
0860:                case LITERAL_try:
0861:                    statement = tryStatement(node);
0862:                    break;
0863:
0864:                case LITERAL_throw:
0865:                    statement = throwStatement(node);
0866:                    break;
0867:
0868:                case LITERAL_while:
0869:                    statement = whileStatement(node);
0870:                    break;
0871:
0872:                default:
0873:                    statement = new ExpressionStatement(expression(node));
0874:                }
0875:                if (statement != null) {
0876:                    configureAST(statement, node);
0877:                }
0878:                return statement;
0879:            }
0880:
0881:            protected Statement statementList(AST code) {
0882:                return statementListNoChild(code.getFirstChild());
0883:            }
0884:
0885:            protected Statement statementListNoChild(AST node) {
0886:                BlockStatement block = new BlockStatement();
0887:                // no need to configureAST(block,node); as node is probably null
0888:                for (; node != null; node = node.getNextSibling()) {
0889:                    block.addStatement(statement(node));
0890:                }
0891:                return block;
0892:            }
0893:
0894:            protected Statement assertStatement(AST assertNode) {
0895:                AST node = assertNode.getFirstChild();
0896:                BooleanExpression booleanExpression = booleanExpression(node);
0897:                Expression messageExpression = null;
0898:
0899:                node = node.getNextSibling();
0900:                if (node != null) {
0901:                    messageExpression = expression(node);
0902:                } else {
0903:                    messageExpression = ConstantExpression.NULL;
0904:                }
0905:                AssertStatement assertStatement = new AssertStatement(
0906:                        booleanExpression, messageExpression);
0907:                configureAST(assertStatement, assertNode);
0908:                return assertStatement;
0909:            }
0910:
0911:            protected Statement breakStatement(AST node) {
0912:                BreakStatement breakStatement = new BreakStatement(label(node));
0913:                configureAST(breakStatement, node);
0914:                return breakStatement;
0915:            }
0916:
0917:            protected Statement continueStatement(AST node) {
0918:                ContinueStatement continueStatement = new ContinueStatement(
0919:                        label(node));
0920:                configureAST(continueStatement, node);
0921:                return continueStatement;
0922:            }
0923:
0924:            protected Statement forStatement(AST forNode) {
0925:                assertNotLegacyFor(forNode);
0926:                AST inNode = forNode.getFirstChild();
0927:                AST variableNode = inNode.getFirstChild();
0928:                AST collectionNode = variableNode.getNextSibling();
0929:
0930:                ClassNode type = ClassHelper.OBJECT_TYPE;
0931:                if (isType(VARIABLE_DEF, variableNode)) {
0932:                    AST typeNode = variableNode.getFirstChild();
0933:                    assertNodeType(TYPE, typeNode);
0934:
0935:                    type = type(typeNode);
0936:                    variableNode = typeNode.getNextSibling();
0937:                }
0938:                String variable = identifier(variableNode);
0939:
0940:                Expression collectionExpression = expression(collectionNode);
0941:                Statement block = statement(inNode.getNextSibling());
0942:                Parameter forParameter = new Parameter(type, variable);
0943:
0944:                ForStatement forStatement = new ForStatement(forParameter,
0945:                        collectionExpression, block);
0946:                configureAST(forStatement, forNode);
0947:                return forStatement;
0948:            }
0949:
0950:            private void assertNotLegacyFor(AST forNode) {
0951:                AST childNode = forNode.getFirstChild();
0952:                boolean legacy = false;
0953:                while (childNode != null) {
0954:                    int type = childNode.getType();
0955:                    if (type == FOR_INIT || type == FOR_CONDITION
0956:                            || type == FOR_ITERATOR) {
0957:                        legacy = true;
0958:                        break;
0959:                    }
0960:                    childNode = childNode.getNextSibling();
0961:                }
0962:                if (legacy) {
0963:                    throw new ASTRuntimeException(
0964:                            forNode,
0965:                            "For statement contains unexpected tokens. Possible attempt to use unsupported Java-style for loop.");
0966:                }
0967:            }
0968:
0969:            protected Statement ifStatement(AST ifNode) {
0970:                AST node = ifNode.getFirstChild();
0971:                assertNodeType(EXPR, node);
0972:                BooleanExpression booleanExpression = booleanExpression(node);
0973:
0974:                node = node.getNextSibling();
0975:                Statement ifBlock = statement(node);
0976:
0977:                Statement elseBlock = EmptyStatement.INSTANCE;
0978:                node = node.getNextSibling();
0979:                if (node != null) {
0980:                    elseBlock = statement(node);
0981:                }
0982:                IfStatement ifStatement = new IfStatement(booleanExpression,
0983:                        ifBlock, elseBlock);
0984:                configureAST(ifStatement, ifNode);
0985:                return ifStatement;
0986:            }
0987:
0988:            protected Statement labelledStatement(AST labelNode) {
0989:                AST node = labelNode.getFirstChild();
0990:                String label = identifier(node);
0991:                Statement statement = statement(node.getNextSibling());
0992:                statement.setStatementLabel(label);
0993:                return statement;
0994:            }
0995:
0996:            protected Statement methodCall(AST code) {
0997:                Expression expression = methodCallExpression(code);
0998:                ExpressionStatement expressionStatement = new ExpressionStatement(
0999:                        expression);
1000:                configureAST(expressionStatement, code);
1001:                return expressionStatement;
1002:            }
1003:
1004:            protected Statement variableDef(AST variableDef) {
1005:                AST node = variableDef.getFirstChild();
1006:                ClassNode type = null;
1007:                if (isType(MODIFIERS, node)) {
1008:                    node = node.getNextSibling();
1009:                }
1010:                if (isType(TYPE, node)) {
1011:                    type = makeType(node);
1012:                    node = node.getNextSibling();
1013:                }
1014:
1015:                String name = identifier(node);
1016:                node = node.getNextSibling();
1017:
1018:                VariableExpression leftExpression = new VariableExpression(
1019:                        name, type);
1020:                configureAST(leftExpression, variableDef);
1021:
1022:                Expression rightExpression = ConstantExpression.NULL;
1023:                if (node != null) {
1024:                    assertNodeType(ASSIGN, node);
1025:
1026:                    rightExpression = expression(node.getFirstChild());
1027:                }
1028:                Token token = makeToken(Types.ASSIGN, variableDef);
1029:
1030:                // TODO should we have a variable declaration statement?
1031:                DeclarationExpression expression = new DeclarationExpression(
1032:                        leftExpression, token, rightExpression);
1033:                configureAST(expression, variableDef);
1034:                ExpressionStatement expressionStatement = new ExpressionStatement(
1035:                        expression);
1036:                configureAST(expressionStatement, variableDef);
1037:                return expressionStatement;
1038:            }
1039:
1040:            protected Statement returnStatement(AST node) {
1041:                AST exprNode = node.getFirstChild();
1042:
1043:                // This will pick up incorrect sibling node if 'node' is a plain 'return'
1044:                //
1045:                //if (exprNode == null) {
1046:                //    exprNode = node.getNextSibling();
1047:                //}
1048:                if (exprNode != null) {
1049:                    Expression expression = expression(exprNode);
1050:                    if (expression instanceof  ConstantExpression) {
1051:                        ConstantExpression constantExpr = (ConstantExpression) expression;
1052:                        if (constantExpr.getValue() == null) {
1053:                            return ReturnStatement.RETURN_NULL_OR_VOID;
1054:                        }
1055:                    }
1056:                    ReturnStatement returnStatement = new ReturnStatement(
1057:                            expression);
1058:                    configureAST(returnStatement, node);
1059:                    return returnStatement;
1060:                } else {
1061:                    return ReturnStatement.RETURN_NULL_OR_VOID;
1062:                }
1063:            }
1064:
1065:            protected Statement switchStatement(AST switchNode) {
1066:                AST node = switchNode.getFirstChild();
1067:                Expression expression = expression(node);
1068:                Statement defaultStatement = EmptyStatement.INSTANCE;
1069:
1070:                List list = new ArrayList();
1071:                for (node = node.getNextSibling(); isType(CASE_GROUP, node); node = node
1072:                        .getNextSibling()) {
1073:                    AST child = node.getFirstChild();
1074:                    if (isType(LITERAL_case, child)) {
1075:                        list.add(caseStatement(child));
1076:                    } else {
1077:                        defaultStatement = statement(child.getNextSibling());
1078:                    }
1079:                }
1080:                if (node != null) {
1081:                    unknownAST(node);
1082:                }
1083:                SwitchStatement switchStatement = new SwitchStatement(
1084:                        expression, list, defaultStatement);
1085:                configureAST(switchStatement, switchNode);
1086:                return switchStatement;
1087:            }
1088:
1089:            protected CaseStatement caseStatement(AST node) {
1090:                List expressions = new ArrayList();
1091:                Statement statement = EmptyStatement.INSTANCE;
1092:                AST nextSibling = node;
1093:                do {
1094:                    Expression expression = expression(nextSibling
1095:                            .getFirstChild());
1096:                    expressions.add(expression);
1097:                    nextSibling = nextSibling.getNextSibling();
1098:                } while (isType(LITERAL_case, nextSibling));
1099:                if (!isType(LITERAL_default, nextSibling)
1100:                        && nextSibling != null) {
1101:                    statement = statement(nextSibling);
1102:                }
1103:                CaseStatement answer;
1104:                if (expressions.size() == 1) {
1105:                    // single case uses original code for effiiency
1106:                    answer = new CaseStatement((Expression) expressions.get(0),
1107:                            statement);
1108:                } else {
1109:                    // multiple cases in casegroup are grouped as an expression
1110:                    // doesn't seem to mix well with certain case expressions, e.g. regex
1111:                    ListExpression listExpression = new ListExpression(
1112:                            expressions);
1113:                    answer = new CaseStatement(listExpression, statement);
1114:                }
1115:                configureAST(answer, node);
1116:                return answer;
1117:            }
1118:
1119:            protected Statement synchronizedStatement(AST syncNode) {
1120:                AST node = syncNode.getFirstChild();
1121:                Expression expression = expression(node);
1122:                Statement code = statement(node.getNextSibling());
1123:                SynchronizedStatement synchronizedStatement = new SynchronizedStatement(
1124:                        expression, code);
1125:                configureAST(synchronizedStatement, syncNode);
1126:                return synchronizedStatement;
1127:            }
1128:
1129:            protected Statement throwStatement(AST node) {
1130:                AST expressionNode = node.getFirstChild();
1131:                if (expressionNode == null) {
1132:                    expressionNode = node.getNextSibling();
1133:                }
1134:                if (expressionNode == null) {
1135:                    throw new ASTRuntimeException(node,
1136:                            "No expression available");
1137:                }
1138:                ThrowStatement throwStatement = new ThrowStatement(
1139:                        expression(expressionNode));
1140:                configureAST(throwStatement, node);
1141:                return throwStatement;
1142:            }
1143:
1144:            protected Statement tryStatement(AST tryStatementNode) {
1145:                AST tryNode = tryStatementNode.getFirstChild();
1146:                Statement tryStatement = statement(tryNode);
1147:                Statement finallyStatement = EmptyStatement.INSTANCE;
1148:                AST node = tryNode.getNextSibling();
1149:
1150:                // lets do the catch nodes
1151:                List catches = new ArrayList();
1152:                for (; node != null && isType(LITERAL_catch, node); node = node
1153:                        .getNextSibling()) {
1154:                    catches.add(catchStatement(node));
1155:                }
1156:
1157:                if (isType(LITERAL_finally, node)) {
1158:                    finallyStatement = statement(node);
1159:                    node = node.getNextSibling();
1160:                }
1161:
1162:                TryCatchStatement tryCatchStatement = new TryCatchStatement(
1163:                        tryStatement, finallyStatement);
1164:                configureAST(tryCatchStatement, tryStatementNode);
1165:                for (Iterator iter = catches.iterator(); iter.hasNext();) {
1166:                    CatchStatement statement = (CatchStatement) iter.next();
1167:                    tryCatchStatement.addCatch(statement);
1168:                }
1169:                return tryCatchStatement;
1170:            }
1171:
1172:            protected CatchStatement catchStatement(AST catchNode) {
1173:                AST node = catchNode.getFirstChild();
1174:                Parameter parameter = parameter(node);
1175:                ClassNode exceptionType = parameter.getType();
1176:                String variable = parameter.getName();
1177:                node = node.getNextSibling();
1178:                Statement code = statement(node);
1179:                Parameter catchParameter = new Parameter(exceptionType,
1180:                        variable);
1181:                CatchStatement answer = new CatchStatement(catchParameter, code);
1182:                configureAST(answer, catchNode);
1183:                return answer;
1184:            }
1185:
1186:            protected Statement whileStatement(AST whileNode) {
1187:                AST node = whileNode.getFirstChild();
1188:                assertNodeType(EXPR, node);
1189:                BooleanExpression booleanExpression = booleanExpression(node);
1190:
1191:                node = node.getNextSibling();
1192:                Statement block = statement(node);
1193:                WhileStatement whileStatement = new WhileStatement(
1194:                        booleanExpression, block);
1195:                configureAST(whileStatement, whileNode);
1196:                return whileStatement;
1197:            }
1198:
1199:            protected Statement withStatement(AST node) {
1200:                notImplementedYet(node);
1201:                return null;
1202:                /** TODO */
1203:            }
1204:
1205:            // Expressions
1206:            //-------------------------------------------------------------------------
1207:
1208:            protected Expression expression(AST node) {
1209:                return expression(node, false);
1210:            }
1211:
1212:            protected Expression expression(AST node, boolean convertToConstant) {
1213:                Expression expression = expressionSwitch(node);
1214:                if (convertToConstant) {
1215:                    // a method name can never be a VariableExprssion, so it must converted
1216:                    // to a ConstantExpression then. This is needed as the expression
1217:                    // method doesn't know we want a ConstantExpression instead of a
1218:                    // VariableExpression
1219:                    if (expression != VariableExpression.THIS_EXPRESSION
1220:                            && expression != VariableExpression.SUPER_EXPRESSION
1221:                            && expression instanceof  VariableExpression) {
1222:                        VariableExpression ve = (VariableExpression) expression;
1223:                        expression = new ConstantExpression(ve.getName());
1224:                    }
1225:                }
1226:                configureAST(expression, node);
1227:                return expression;
1228:            }
1229:
1230:            protected Expression expressionSwitch(AST node) {
1231:                int type = node.getType();
1232:                switch (type) {
1233:                case EXPR:
1234:                    return expression(node.getFirstChild());
1235:
1236:                case ELIST:
1237:                    return expressionList(node);
1238:
1239:                case SLIST:
1240:                    return blockExpression(node);
1241:
1242:                case CLOSABLE_BLOCK:
1243:                    return closureExpression(node);
1244:
1245:                case SUPER_CTOR_CALL:
1246:                    return specialConstructorCallExpression(node,
1247:                            ClassNode.SUPER);
1248:
1249:                case METHOD_CALL:
1250:                    return methodCallExpression(node);
1251:
1252:                case LITERAL_new:
1253:                    return constructorCallExpression(node.getFirstChild());
1254:
1255:                case CTOR_CALL:
1256:                    return specialConstructorCallExpression(node,
1257:                            ClassNode.THIS);
1258:
1259:                case QUESTION:
1260:                    return ternaryExpression(node);
1261:
1262:                case OPTIONAL_DOT:
1263:                case SPREAD_DOT:
1264:                case DOT:
1265:                    return dotExpression(node);
1266:
1267:                case IDENT:
1268:                case LITERAL_boolean:
1269:                case LITERAL_byte:
1270:                case LITERAL_char:
1271:                case LITERAL_double:
1272:                case LITERAL_float:
1273:                case LITERAL_int:
1274:                case LITERAL_long:
1275:                case LITERAL_short:
1276:                case LITERAL_void:
1277:                    return variableExpression(node);
1278:
1279:                case LIST_CONSTRUCTOR:
1280:                    return listExpression(node);
1281:
1282:                case MAP_CONSTRUCTOR:
1283:                    return mapExpression(node);
1284:
1285:                case LABELED_ARG:
1286:                    return mapEntryExpression(node);
1287:
1288:                case SPREAD_ARG:
1289:                    return spreadExpression(node);
1290:
1291:                case SPREAD_MAP_ARG:
1292:                    return spreadMapExpression(node);
1293:
1294:                    // commented out of groovy.g due to non determinisms
1295:                    //case MEMBER_POINTER_DEFAULT:
1296:                    //    return defaultMethodPointerExpression(node);
1297:
1298:                case MEMBER_POINTER:
1299:                    return methodPointerExpression(node);
1300:
1301:                case INDEX_OP:
1302:                    return indexExpression(node);
1303:
1304:                case LITERAL_instanceof :
1305:                    return instanceof Expression(node);
1306:
1307:                case LITERAL_as:
1308:                    return asExpression(node);
1309:
1310:                case TYPECAST:
1311:                    return castExpression(node);
1312:
1313:                    // literals
1314:
1315:                case LITERAL_true:
1316:                    return ConstantExpression.TRUE;
1317:
1318:                case LITERAL_false:
1319:                    return ConstantExpression.FALSE;
1320:
1321:                case LITERAL_null:
1322:                    return ConstantExpression.NULL;
1323:
1324:                case STRING_LITERAL:
1325:                    ConstantExpression constantExpression = new ConstantExpression(
1326:                            node.getText());
1327:                    configureAST(constantExpression, node);
1328:                    return constantExpression;
1329:
1330:                case STRING_CONSTRUCTOR:
1331:                    return gstring(node);
1332:
1333:                case NUM_DOUBLE:
1334:                case NUM_FLOAT:
1335:                case NUM_BIG_DECIMAL:
1336:                    return decimalExpression(node);
1337:
1338:                case NUM_BIG_INT:
1339:                case NUM_INT:
1340:                case NUM_LONG:
1341:                    return integerExpression(node);
1342:
1343:                case LITERAL_this :
1344:                    return VariableExpression.THIS_EXPRESSION;
1345:
1346:                case LITERAL_super :
1347:                    return VariableExpression.SUPER_EXPRESSION;
1348:
1349:                    // Unary expressions
1350:                case LNOT:
1351:                    NotExpression notExpression = new NotExpression(
1352:                            expression(node.getFirstChild()));
1353:                    configureAST(notExpression, node);
1354:                    return notExpression;
1355:
1356:                case UNARY_MINUS:
1357:                    return negateExpression(node);
1358:
1359:                case BNOT:
1360:                    BitwiseNegExpression bitwiseNegExpression = new BitwiseNegExpression(
1361:                            expression(node.getFirstChild()));
1362:                    configureAST(bitwiseNegExpression, node);
1363:                    return bitwiseNegExpression;
1364:
1365:                case UNARY_PLUS:
1366:                    return expression(node.getFirstChild());
1367:
1368:                    // Prefix expressions
1369:                case INC:
1370:                    return prefixExpression(node, Types.PLUS_PLUS);
1371:
1372:                case DEC:
1373:                    return prefixExpression(node, Types.MINUS_MINUS);
1374:
1375:                    // Postfix expressions
1376:                case POST_INC:
1377:                    return postfixExpression(node, Types.PLUS_PLUS);
1378:
1379:                case POST_DEC:
1380:                    return postfixExpression(node, Types.MINUS_MINUS);
1381:
1382:                    // Binary expressions
1383:
1384:                case ASSIGN:
1385:                    return binaryExpression(Types.ASSIGN, node);
1386:
1387:                case EQUAL:
1388:                    return binaryExpression(Types.COMPARE_EQUAL, node);
1389:
1390:                case NOT_EQUAL:
1391:                    return binaryExpression(Types.COMPARE_NOT_EQUAL, node);
1392:
1393:                case COMPARE_TO:
1394:                    return binaryExpression(Types.COMPARE_TO, node);
1395:
1396:                case LE:
1397:                    return binaryExpression(Types.COMPARE_LESS_THAN_EQUAL, node);
1398:
1399:                case LT:
1400:                    return binaryExpression(Types.COMPARE_LESS_THAN, node);
1401:
1402:                case GT:
1403:                    return binaryExpression(Types.COMPARE_GREATER_THAN, node);
1404:
1405:                case GE:
1406:                    return binaryExpression(Types.COMPARE_GREATER_THAN_EQUAL,
1407:                            node);
1408:
1409:                    /**
1410:                     * TODO treble equal?
1411:                     return binaryExpression(Types.COMPARE_IDENTICAL, node);
1412:
1413:                     case ???:
1414:                     return binaryExpression(Types.LOGICAL_AND_EQUAL, node);
1415:
1416:                     case ???:
1417:                     return binaryExpression(Types.LOGICAL_OR_EQUAL, node);
1418:
1419:                     */
1420:
1421:                case LAND:
1422:                    return binaryExpression(Types.LOGICAL_AND, node);
1423:
1424:                case LOR:
1425:                    return binaryExpression(Types.LOGICAL_OR, node);
1426:
1427:                case BAND:
1428:                    return binaryExpression(Types.BITWISE_AND, node);
1429:
1430:                case BAND_ASSIGN:
1431:                    return binaryExpression(Types.BITWISE_AND_EQUAL, node);
1432:
1433:                case BOR:
1434:                    return binaryExpression(Types.BITWISE_OR, node);
1435:
1436:                case BOR_ASSIGN:
1437:                    return binaryExpression(Types.BITWISE_OR_EQUAL, node);
1438:
1439:                case BXOR:
1440:                    return binaryExpression(Types.BITWISE_XOR, node);
1441:
1442:                case BXOR_ASSIGN:
1443:                    return binaryExpression(Types.BITWISE_XOR_EQUAL, node);
1444:
1445:                case PLUS:
1446:                    return binaryExpression(Types.PLUS, node);
1447:
1448:                case PLUS_ASSIGN:
1449:                    return binaryExpression(Types.PLUS_EQUAL, node);
1450:
1451:                case MINUS:
1452:                    return binaryExpression(Types.MINUS, node);
1453:
1454:                case MINUS_ASSIGN:
1455:                    return binaryExpression(Types.MINUS_EQUAL, node);
1456:
1457:                case STAR:
1458:                    return binaryExpression(Types.MULTIPLY, node);
1459:
1460:                case STAR_ASSIGN:
1461:                    return binaryExpression(Types.MULTIPLY_EQUAL, node);
1462:
1463:                case STAR_STAR:
1464:                    return binaryExpression(Types.POWER, node);
1465:
1466:                case STAR_STAR_ASSIGN:
1467:                    return binaryExpression(Types.POWER_EQUAL, node);
1468:
1469:                case DIV:
1470:                    return binaryExpression(Types.DIVIDE, node);
1471:
1472:                case DIV_ASSIGN:
1473:                    return binaryExpression(Types.DIVIDE_EQUAL, node);
1474:
1475:                case MOD:
1476:                    return binaryExpression(Types.MOD, node);
1477:
1478:                case MOD_ASSIGN:
1479:                    return binaryExpression(Types.MOD_EQUAL, node);
1480:
1481:                case SL:
1482:                    return binaryExpression(Types.LEFT_SHIFT, node);
1483:
1484:                case SL_ASSIGN:
1485:                    return binaryExpression(Types.LEFT_SHIFT_EQUAL, node);
1486:
1487:                case SR:
1488:                    return binaryExpression(Types.RIGHT_SHIFT, node);
1489:
1490:                case SR_ASSIGN:
1491:                    return binaryExpression(Types.RIGHT_SHIFT_EQUAL, node);
1492:
1493:                case BSR:
1494:                    return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED, node);
1495:
1496:                case BSR_ASSIGN:
1497:                    return binaryExpression(Types.RIGHT_SHIFT_UNSIGNED_EQUAL,
1498:                            node);
1499:
1500:                    // Regex
1501:                case REGEX_FIND:
1502:                    return binaryExpression(Types.FIND_REGEX, node);
1503:
1504:                case REGEX_MATCH:
1505:                    return binaryExpression(Types.MATCH_REGEX, node);
1506:
1507:                    // Ranges
1508:                case RANGE_INCLUSIVE:
1509:                    return rangeExpression(node, true);
1510:
1511:                case RANGE_EXCLUSIVE:
1512:                    return rangeExpression(node, false);
1513:
1514:                case DYNAMIC_MEMBER:
1515:                    return dynamicMemberExpression(node);
1516:
1517:                case LITERAL_in:
1518:                    return binaryExpression(Types.KEYWORD_IN, node);
1519:
1520:                default:
1521:                    unknownAST(node);
1522:                }
1523:                return null;
1524:            }
1525:
1526:            protected Expression dynamicMemberExpression(AST dynamicMemberNode) {
1527:                AST node = dynamicMemberNode.getFirstChild();
1528:                return expression(node);
1529:            }
1530:
1531:            protected Expression ternaryExpression(AST ternaryNode) {
1532:                AST node = ternaryNode.getFirstChild();
1533:                BooleanExpression booleanExpression = booleanExpression(node);
1534:                node = node.getNextSibling();
1535:                Expression left = expression(node);
1536:                Expression right = expression(node.getNextSibling());
1537:                TernaryExpression ternaryExpression = new TernaryExpression(
1538:                        booleanExpression, left, right);
1539:                configureAST(ternaryExpression, ternaryNode);
1540:                return ternaryExpression;
1541:            }
1542:
1543:            protected Expression variableExpression(AST node) {
1544:                String text = node.getText();
1545:
1546:                // TODO we might wanna only try to resolve the name if we are
1547:                // on the left hand side of an expression or before a dot?
1548:                VariableExpression variableExpression = new VariableExpression(
1549:                        text);
1550:                configureAST(variableExpression, node);
1551:                return variableExpression;
1552:            }
1553:
1554:            protected Expression rangeExpression(AST rangeNode,
1555:                    boolean inclusive) {
1556:                AST node = rangeNode.getFirstChild();
1557:                Expression left = expression(node);
1558:                Expression right = expression(node.getNextSibling());
1559:                RangeExpression rangeExpression = new RangeExpression(left,
1560:                        right, inclusive);
1561:                configureAST(rangeExpression, rangeNode);
1562:                return rangeExpression;
1563:            }
1564:
1565:            protected Expression spreadExpression(AST node) {
1566:                AST exprNode = node.getFirstChild();
1567:                AST listNode = exprNode.getFirstChild();
1568:                Expression right = expression(listNode);
1569:                SpreadExpression spreadExpression = new SpreadExpression(right);
1570:                configureAST(spreadExpression, node);
1571:                return spreadExpression;
1572:            }
1573:
1574:            protected Expression spreadMapExpression(AST node) {
1575:                AST exprNode = node.getFirstChild();
1576:                Expression expr = expression(exprNode);
1577:                SpreadMapExpression spreadMapExpression = new SpreadMapExpression(
1578:                        expr);
1579:                configureAST(spreadMapExpression, node);
1580:                return spreadMapExpression;
1581:            }
1582:
1583:            protected Expression methodPointerExpression(AST node) {
1584:                AST exprNode = node.getFirstChild();
1585:                String methodName = identifier(exprNode.getNextSibling());
1586:                Expression expression = expression(exprNode);
1587:                MethodPointerExpression methodPointerExpression = new MethodPointerExpression(
1588:                        expression, methodName);
1589:                configureAST(methodPointerExpression, node);
1590:                return methodPointerExpression;
1591:            }
1592:
1593:            /*  commented out due to groovy.g non-determinisms
1594:             protected Expression defaultMethodPointerExpression(AST node) {
1595:             AST exprNode = node.getFirstChild();
1596:             String methodName = exprNode.toString();
1597:             MethodPointerExpression methodPointerExpression = new MethodPointerExpression(null, methodName);
1598:             configureAST(methodPointerExpression, node);
1599:             return methodPointerExpression;
1600:             }
1601:             */
1602:
1603:            protected Expression listExpression(AST listNode) {
1604:                List expressions = new ArrayList();
1605:                AST elist = listNode.getFirstChild();
1606:                assertNodeType(ELIST, elist);
1607:
1608:                for (AST node = elist.getFirstChild(); node != null; node = node
1609:                        .getNextSibling()) {
1610:                    // check for stray labeled arguments:
1611:                    switch (node.getType()) {
1612:                    case LABELED_ARG:
1613:                        assertNodeType(COMMA, node);
1614:                        break; // helpful error?
1615:                    case SPREAD_MAP_ARG:
1616:                        assertNodeType(SPREAD_ARG, node);
1617:                        break; // helpful error
1618:                    }
1619:                    expressions.add(expression(node));
1620:                }
1621:                ListExpression listExpression = new ListExpression(expressions);
1622:                configureAST(listExpression, listNode);
1623:                return listExpression;
1624:            }
1625:
1626:            /**
1627:             * Typically only used for map constructors I think?
1628:             */
1629:            protected Expression mapExpression(AST mapNode) {
1630:                List expressions = new ArrayList();
1631:                AST elist = mapNode.getFirstChild();
1632:                if (elist != null) { // totally empty in the case of [:]
1633:                    assertNodeType(ELIST, elist);
1634:                    for (AST node = elist.getFirstChild(); node != null; node = node
1635:                            .getNextSibling()) {
1636:                        switch (node.getType()) {
1637:                        case LABELED_ARG:
1638:                        case SPREAD_MAP_ARG:
1639:                            break; // legal cases
1640:                        case SPREAD_ARG:
1641:                            assertNodeType(SPREAD_MAP_ARG, node);
1642:                            break; // helpful error
1643:                        default:
1644:                            assertNodeType(LABELED_ARG, node);
1645:                            break; // helpful error
1646:                        }
1647:                        expressions.add(mapEntryExpression(node));
1648:                    }
1649:                }
1650:                MapExpression mapExpression = new MapExpression(expressions);
1651:                configureAST(mapExpression, mapNode);
1652:                return mapExpression;
1653:            }
1654:
1655:            protected MapEntryExpression mapEntryExpression(AST node) {
1656:                if (node.getType() == SPREAD_MAP_ARG) {
1657:                    AST rightNode = node.getFirstChild();
1658:                    Expression keyExpression = spreadMapExpression(node);
1659:                    Expression rightExpression = expression(rightNode);
1660:                    MapEntryExpression mapEntryExpression = new MapEntryExpression(
1661:                            keyExpression, rightExpression);
1662:                    configureAST(mapEntryExpression, node);
1663:                    return mapEntryExpression;
1664:                } else {
1665:                    AST keyNode = node.getFirstChild();
1666:                    Expression keyExpression = expression(keyNode);
1667:                    AST valueNode = keyNode.getNextSibling();
1668:                    Expression valueExpression = expression(valueNode);
1669:                    MapEntryExpression mapEntryExpression = new MapEntryExpression(
1670:                            keyExpression, valueExpression);
1671:                    configureAST(mapEntryExpression, node);
1672:                    return mapEntryExpression;
1673:                }
1674:            }
1675:
1676:            protected Expression instanceof Expression(AST node) {
1677:                AST leftNode = node.getFirstChild();
1678:                Expression leftExpression = expression(leftNode);
1679:
1680:                AST rightNode = leftNode.getNextSibling();
1681:                ClassNode type = buildName(rightNode);
1682:                assertTypeNotNull(type, rightNode);
1683:
1684:                Expression rightExpression = new ClassExpression(type);
1685:                configureAST(rightExpression, rightNode);
1686:                BinaryExpression binaryExpression = new BinaryExpression(
1687:                        leftExpression, makeToken(Types.KEYWORD_INSTANCEOF,
1688:                                node), rightExpression);
1689:                configureAST(binaryExpression, node);
1690:                return binaryExpression;
1691:            }
1692:
1693:            protected void assertTypeNotNull(ClassNode type, AST rightNode) {
1694:                if (type == null) {
1695:                    throw new ASTRuntimeException(rightNode,
1696:                            "No type available for: "
1697:                                    + qualifiedName(rightNode));
1698:                }
1699:            }
1700:
1701:            protected Expression asExpression(AST node) {
1702:                AST leftNode = node.getFirstChild();
1703:                Expression leftExpression = expression(leftNode);
1704:
1705:                AST rightNode = leftNode.getNextSibling();
1706:                ClassNode type = buildName(rightNode);
1707:
1708:                return CastExpression.asExpression(type, leftExpression);
1709:            }
1710:
1711:            protected Expression castExpression(AST castNode) {
1712:                AST node = castNode.getFirstChild();
1713:                ClassNode type = buildName(node);
1714:                assertTypeNotNull(type, node);
1715:
1716:                AST expressionNode = node.getNextSibling();
1717:                Expression expression = expression(expressionNode);
1718:
1719:                CastExpression castExpression = new CastExpression(type,
1720:                        expression);
1721:                configureAST(castExpression, castNode);
1722:                return castExpression;
1723:            }
1724:
1725:            protected Expression indexExpression(AST indexNode) {
1726:                AST leftNode = indexNode.getFirstChild();
1727:                Expression leftExpression = expression(leftNode);
1728:
1729:                AST rightNode = leftNode.getNextSibling();
1730:                Expression rightExpression = expression(rightNode);
1731:
1732:                BinaryExpression binaryExpression = new BinaryExpression(
1733:                        leftExpression, makeToken(Types.LEFT_SQUARE_BRACKET,
1734:                                indexNode), rightExpression);
1735:                configureAST(binaryExpression, indexNode);
1736:                return binaryExpression;
1737:            }
1738:
1739:            protected Expression binaryExpression(int type, AST node) {
1740:                Token token = makeToken(type, node);
1741:
1742:                AST leftNode = node.getFirstChild();
1743:                Expression leftExpression = expression(leftNode);
1744:
1745:                AST rightNode = leftNode.getNextSibling();
1746:                if (rightNode == null) {
1747:                    return leftExpression;
1748:                }
1749:
1750:                if (Types.ofType(type, Types.ASSIGNMENT_OPERATOR)) {
1751:                    if (leftExpression instanceof  VariableExpression
1752:                            || leftExpression.getClass() == PropertyExpression.class
1753:                            || leftExpression instanceof  FieldExpression
1754:                            || leftExpression instanceof  AttributeExpression
1755:                            || leftExpression instanceof  DeclarationExpression) {
1756:                        // Do nothing.
1757:                    } else if (leftExpression instanceof  ConstantExpression) {
1758:                        throw new ASTRuntimeException(
1759:                                node,
1760:                                "\n["
1761:                                        + ((ConstantExpression) leftExpression)
1762:                                                .getValue()
1763:                                        + "] is a constant expression, but it should be a variable expression");
1764:                    } else if (leftExpression instanceof  BinaryExpression) {
1765:                        Expression leftexp = ((BinaryExpression) leftExpression)
1766:                                .getLeftExpression();
1767:                        int lefttype = ((BinaryExpression) leftExpression)
1768:                                .getOperation().getType();
1769:                        if (!Types.ofType(lefttype, Types.ASSIGNMENT_OPERATOR)
1770:                                && lefttype != Types.LEFT_SQUARE_BRACKET) {
1771:                            throw new ASTRuntimeException(
1772:                                    node,
1773:                                    "\n"
1774:                                            + ((BinaryExpression) leftExpression)
1775:                                                    .getText()
1776:                                            + " is a binary expression, but it should be a variable expression");
1777:                        }
1778:                    } else if (leftExpression instanceof  GStringExpression) {
1779:                        throw new ASTRuntimeException(
1780:                                node,
1781:                                "\n\""
1782:                                        + ((GStringExpression) leftExpression)
1783:                                                .getText()
1784:                                        + "\" is a GString expression, but it should be a variable expression");
1785:                    } else if (leftExpression instanceof  MethodCallExpression) {
1786:                        throw new ASTRuntimeException(
1787:                                node,
1788:                                "\n\""
1789:                                        + ((MethodCallExpression) leftExpression)
1790:                                                .getText()
1791:                                        + "\" is a method call expression, but it should be a variable expression");
1792:                    } else if (leftExpression instanceof  MapExpression) {
1793:                        throw new ASTRuntimeException(
1794:                                node,
1795:                                "\n'"
1796:                                        + ((MapExpression) leftExpression)
1797:                                                .getText()
1798:                                        + "' is a map expression, but it should be a variable expression");
1799:                    } else {
1800:                        throw new ASTRuntimeException(
1801:                                node,
1802:                                "\n"
1803:                                        + leftExpression.getClass()
1804:                                        + ", with its value '"
1805:                                        + leftExpression.getText()
1806:                                        + "', is a bad expression as the LSH of an assignment operator");
1807:                    }
1808:                }
1809:                /*if (rightNode == null) {
1810:                    throw new NullPointerException("No rightNode associated with binary expression");
1811:                }*/
1812:                Expression rightExpression = expression(rightNode);
1813:                BinaryExpression binaryExpression = new BinaryExpression(
1814:                        leftExpression, token, rightExpression);
1815:                configureAST(binaryExpression, node);
1816:                return binaryExpression;
1817:            }
1818:
1819:            protected Expression prefixExpression(AST node, int token) {
1820:                Expression expression = expression(node.getFirstChild());
1821:                PrefixExpression prefixExpression = new PrefixExpression(
1822:                        makeToken(token, node), expression);
1823:                configureAST(prefixExpression, node);
1824:                return prefixExpression;
1825:            }
1826:
1827:            protected Expression postfixExpression(AST node, int token) {
1828:                Expression expression = expression(node.getFirstChild());
1829:                PostfixExpression postfixExpression = new PostfixExpression(
1830:                        expression, makeToken(token, node));
1831:                configureAST(postfixExpression, node);
1832:                return postfixExpression;
1833:            }
1834:
1835:            protected BooleanExpression booleanExpression(AST node) {
1836:                BooleanExpression booleanExpression = new BooleanExpression(
1837:                        expression(node));
1838:                configureAST(booleanExpression, node);
1839:                return booleanExpression;
1840:            }
1841:
1842:            protected Expression dotExpression(AST node) {
1843:                // lets decide if this is a propery invocation or a method call
1844:                AST leftNode = node.getFirstChild();
1845:                if (leftNode != null) {
1846:                    AST identifierNode = leftNode.getNextSibling();
1847:                    if (identifierNode != null) {
1848:                        Expression leftExpression = expression(leftNode);
1849:                        if (isType(SELECT_SLOT, identifierNode)) {
1850:                            Expression field = expression(identifierNode
1851:                                    .getFirstChild(), true);
1852:                            AttributeExpression attributeExpression = new AttributeExpression(
1853:                                    leftExpression, field,
1854:                                    node.getType() != DOT);
1855:                            if (node.getType() == SPREAD_DOT) {
1856:                                attributeExpression.setSpreadSafe(true);
1857:                            }
1858:                            configureAST(attributeExpression, node);
1859:                            return attributeExpression;
1860:                        }
1861:                        Expression property = expression(identifierNode, true);
1862:
1863:                        PropertyExpression propertyExpression = new PropertyExpression(
1864:                                leftExpression, property, node.getType() != DOT);
1865:                        if (node.getType() == SPREAD_DOT) {
1866:                            propertyExpression.setSpreadSafe(true);
1867:                        }
1868:                        configureAST(propertyExpression, node);
1869:                        return propertyExpression;
1870:                    }
1871:                }
1872:                return methodCallExpression(node);
1873:            }
1874:
1875:            protected Expression specialConstructorCallExpression(
1876:                    AST methodCallNode, ClassNode special) {
1877:                AST node = methodCallNode.getFirstChild();
1878:                Expression arguments = arguments(node);
1879:
1880:                ConstructorCallExpression expression = new ConstructorCallExpression(
1881:                        special, arguments);
1882:                configureAST(expression, methodCallNode);
1883:                return expression;
1884:            }
1885:
1886:            private int getTypeInParenthesis(AST node) {
1887:                if (!isType(EXPR, node))
1888:                    node = node.getFirstChild();
1889:                while (node != null && isType(EXPR, node)
1890:                        && node.getNextSibling() == null) {
1891:                    node = node.getFirstChild();
1892:                }
1893:                if (node == null)
1894:                    return -1;
1895:                return node.getType();
1896:            }
1897:
1898:            protected Expression methodCallExpression(AST methodCallNode) {
1899:                AST node = methodCallNode.getFirstChild();
1900:                /* // Bad idea, since foo(1)(2) is valid Groovy for foo(1).call(2).
1901:                if (isType(METHOD_CALL, node)) {
1902:                    // sometimes method calls get wrapped in method calls for some wierd reason
1903:                    return methodCallExpression(node);
1904:                }
1905:                 */
1906:
1907:                Expression objectExpression;
1908:                AST selector;
1909:                AST elist = node.getNextSibling();
1910:
1911:                boolean implicitThis = false;
1912:                boolean safe = isType(OPTIONAL_DOT, node);
1913:                boolean spreadSafe = isType(SPREAD_DOT, node);
1914:                if (isType(DOT, node) || safe || spreadSafe) {
1915:                    AST objectNode = node.getFirstChild();
1916:                    objectExpression = expression(objectNode);
1917:                    selector = objectNode.getNextSibling();
1918:                } else {
1919:                    implicitThis = true;
1920:                    objectExpression = VariableExpression.THIS_EXPRESSION;
1921:                    selector = node;
1922:                }
1923:
1924:                Expression name = null;
1925:                if (isType(LITERAL_super , selector)) {
1926:                    implicitThis = true;
1927:                    name = new ConstantExpression("super");
1928:                    if (objectExpression == VariableExpression.THIS_EXPRESSION) {
1929:                        objectExpression = VariableExpression.SUPER_EXPRESSION;
1930:                    }
1931:                } else if (isPrimitiveTypeLiteral(selector)) {
1932:                    throw new ASTRuntimeException(selector,
1933:                            "Primitive type literal: " + selector.getText()
1934:                                    + " cannot be used as a method name");
1935:                } else if (isType(SELECT_SLOT, selector)) {
1936:                    Expression field = expression(selector.getFirstChild(),
1937:                            true);
1938:                    AttributeExpression attributeExpression = new AttributeExpression(
1939:                            objectExpression, field, node.getType() != DOT);
1940:                    configureAST(attributeExpression, node);
1941:                    Expression arguments = arguments(elist);
1942:                    MethodCallExpression expression = new MethodCallExpression(
1943:                            attributeExpression, "call", arguments);
1944:                    configureAST(expression, methodCallNode);
1945:                    return expression;
1946:                } else if (isType(DYNAMIC_MEMBER, selector)
1947:                        || isType(IDENT, selector)
1948:                        || isType(STRING_CONSTRUCTOR, selector)
1949:                        || isType(STRING_LITERAL, selector)) {
1950:                    name = expression(selector, true);
1951:                } else {
1952:                    implicitThis = false;
1953:                    name = new ConstantExpression("call");
1954:                    objectExpression = expression(selector, true);
1955:                }
1956:
1957:                Expression arguments = arguments(elist);
1958:                MethodCallExpression expression = new MethodCallExpression(
1959:                        objectExpression, name, arguments);
1960:                expression.setSafe(safe);
1961:                expression.setSpreadSafe(spreadSafe);
1962:                expression.setImplicitThis(implicitThis);
1963:                Expression ret = expression;
1964:                //FIXME: do we really want this() to create a new object regardless
1965:                // the position.. for example not as first statement in a constructor
1966:                // this=first statement in contructor is handled by specialConstructorCallExpression
1967:                // we may have to add a check and remove this part of the code
1968:                if (implicitThis
1969:                        && "this".equals(expression.getMethodAsString())) {
1970:                    ret = new ConstructorCallExpression(this .classNode,
1971:                            arguments);
1972:                }
1973:                configureAST(ret, methodCallNode);
1974:                return ret;
1975:            }
1976:
1977:            protected Expression constructorCallExpression(AST node) {
1978:                AST constructorCallNode = node;
1979:                ClassNode type = buildName(constructorCallNode);
1980:
1981:                if (isType(CTOR_CALL, node) || isType(LITERAL_new, node)) {
1982:                    node = node.getFirstChild();
1983:                }
1984:
1985:                AST elist = node.getNextSibling();
1986:
1987:                if (elist == null && isType(ELIST, node)) {
1988:                    elist = node;
1989:                    if ("(".equals(type.getName())) {
1990:                        type = classNode;
1991:                    }
1992:                }
1993:
1994:                if (isType(ARRAY_DECLARATOR, elist)) {
1995:                    AST expressionNode = elist.getFirstChild();
1996:                    if (expressionNode == null) {
1997:                        throw new ASTRuntimeException(elist,
1998:                                "No expression for the array constructor call");
1999:                    }
2000:                    List size = arraySizeExpression(expressionNode);
2001:                    ArrayExpression arrayExpression = new ArrayExpression(type,
2002:                            null, size);
2003:                    configureAST(arrayExpression, constructorCallNode);
2004:                    return arrayExpression;
2005:                }
2006:                Expression arguments = arguments(elist);
2007:                ConstructorCallExpression expression = new ConstructorCallExpression(
2008:                        type, arguments);
2009:                configureAST(expression, constructorCallNode);
2010:                return expression;
2011:            }
2012:
2013:            protected List arraySizeExpression(AST node) {
2014:                List list;
2015:                Expression size = null;
2016:                if (isType(ARRAY_DECLARATOR, node)) {
2017:                    AST right = node.getNextSibling();
2018:                    if (right != null) {
2019:                        size = expression(right);
2020:                    } else {
2021:                        size = ConstantExpression.EMTPY_EXPRESSION;
2022:                    }
2023:                    list = arraySizeExpression(node.getFirstChild());
2024:                } else {
2025:                    size = expression(node);
2026:                    list = new ArrayList();
2027:                }
2028:                list.add(size);
2029:                return list;
2030:            }
2031:
2032:            protected Expression arguments(AST elist) {
2033:                List expressionList = new ArrayList();
2034:                // FIXME: all labeled arguments should follow any unlabeled arguments
2035:                boolean namedArguments = false;
2036:                for (AST node = elist; node != null; node = node
2037:                        .getNextSibling()) {
2038:                    if (isType(ELIST, node)) {
2039:                        for (AST child = node.getFirstChild(); child != null; child = child
2040:                                .getNextSibling()) {
2041:                            namedArguments |= addArgumentExpression(child,
2042:                                    expressionList);
2043:                        }
2044:                    } else {
2045:                        namedArguments |= addArgumentExpression(node,
2046:                                expressionList);
2047:                    }
2048:                }
2049:                if (namedArguments) {
2050:                    if (!expressionList.isEmpty()) {
2051:                        // lets remove any non-MapEntryExpression instances
2052:                        // such as if the last expression is a ClosureExpression
2053:                        // so lets wrap the named method calls in a Map expression
2054:                        List argumentList = new ArrayList();
2055:                        for (Iterator iter = expressionList.iterator(); iter
2056:                                .hasNext();) {
2057:                            Expression expression = (Expression) iter.next();
2058:                            if (!(expression instanceof  MapEntryExpression)) {
2059:                                argumentList.add(expression);
2060:                            }
2061:                        }
2062:                        if (!argumentList.isEmpty()) {
2063:                            expressionList.removeAll(argumentList);
2064:                            MapExpression mapExpression = new MapExpression(
2065:                                    expressionList);
2066:                            configureAST(mapExpression, elist);
2067:                            argumentList.add(0, mapExpression);
2068:                            ArgumentListExpression argumentListExpression = new ArgumentListExpression(
2069:                                    argumentList);
2070:                            configureAST(argumentListExpression, elist);
2071:                            return argumentListExpression;
2072:                        }
2073:                    }
2074:                    NamedArgumentListExpression namedArgumentListExpression = new NamedArgumentListExpression(
2075:                            expressionList);
2076:                    configureAST(namedArgumentListExpression, elist);
2077:                    return namedArgumentListExpression;
2078:                } else {
2079:                    ArgumentListExpression argumentListExpression = new ArgumentListExpression(
2080:                            expressionList);
2081:                    configureAST(argumentListExpression, elist);
2082:                    return argumentListExpression;
2083:                }
2084:            }
2085:
2086:            protected boolean addArgumentExpression(AST node,
2087:                    List expressionList) {
2088:                if (node.getType() == SPREAD_MAP_ARG) {
2089:                    AST rightNode = node.getFirstChild();
2090:                    Expression keyExpression = spreadMapExpression(node);
2091:                    Expression rightExpression = expression(rightNode);
2092:                    MapEntryExpression mapEntryExpression = new MapEntryExpression(
2093:                            keyExpression, rightExpression);
2094:                    expressionList.add(mapEntryExpression);
2095:                    return true;
2096:                } else {
2097:                    Expression expression = expression(node);
2098:                    expressionList.add(expression);
2099:                    return expression instanceof  MapEntryExpression;
2100:                }
2101:            }
2102:
2103:            protected Expression expressionList(AST node) {
2104:                List expressionList = new ArrayList();
2105:                for (AST child = node.getFirstChild(); child != null; child = child
2106:                        .getNextSibling()) {
2107:                    expressionList.add(expression(child));
2108:                }
2109:                if (expressionList.size() == 1) {
2110:                    return (Expression) expressionList.get(0);
2111:                } else {
2112:                    ListExpression listExpression = new ListExpression(
2113:                            expressionList);
2114:                    configureAST(listExpression, node);
2115:                    return listExpression;
2116:                }
2117:            }
2118:
2119:            protected ClosureExpression closureExpression(AST node) {
2120:                AST paramNode = node.getFirstChild();
2121:                Parameter[] parameters = null;
2122:                AST codeNode = paramNode;
2123:                if (isType(PARAMETERS, paramNode)
2124:                        || isType(IMPLICIT_PARAMETERS, paramNode)) {
2125:                    parameters = parameters(paramNode);
2126:                    codeNode = paramNode.getNextSibling();
2127:                }
2128:                Statement code = statementListNoChild(codeNode);
2129:                ClosureExpression closureExpression = new ClosureExpression(
2130:                        parameters, code);
2131:                configureAST(closureExpression, node);
2132:                return closureExpression;
2133:            }
2134:
2135:            protected Expression blockExpression(AST node) {
2136:                AST codeNode = node.getFirstChild();
2137:                if (codeNode == null)
2138:                    return ConstantExpression.NULL;
2139:                if (codeNode.getType() == EXPR
2140:                        && codeNode.getNextSibling() == null) {
2141:                    // Simplify common case of {expr} to expr.
2142:                    return expression(codeNode);
2143:                }
2144:                Parameter[] parameters = Parameter.EMPTY_ARRAY;
2145:                Statement code = statementListNoChild(codeNode);
2146:                ClosureExpression closureExpression = new ClosureExpression(
2147:                        parameters, code);
2148:                configureAST(closureExpression, node);
2149:                // Call it immediately.
2150:                String callName = "call";
2151:                Expression noArguments = new ArgumentListExpression();
2152:                MethodCallExpression call = new MethodCallExpression(
2153:                        closureExpression, callName, noArguments);
2154:                configureAST(call, node);
2155:                return call;
2156:            }
2157:
2158:            protected Expression negateExpression(AST negateExpr) {
2159:                AST node = negateExpr.getFirstChild();
2160:
2161:                // if we are a number literal then lets just parse it
2162:                // as the negation operator on MIN_INT causes rounding to a long
2163:                String text = node.getText();
2164:                switch (node.getType()) {
2165:                case NUM_DOUBLE:
2166:                case NUM_FLOAT:
2167:                case NUM_BIG_DECIMAL:
2168:                    ConstantExpression constantExpression = new ConstantExpression(
2169:                            Numbers.parseDecimal("-" + text));
2170:                    configureAST(constantExpression, negateExpr);
2171:                    return constantExpression;
2172:
2173:                case NUM_BIG_INT:
2174:                case NUM_INT:
2175:                case NUM_LONG:
2176:                    ConstantExpression constantLongExpression = new ConstantExpression(
2177:                            Numbers.parseInteger("-" + text));
2178:                    configureAST(constantLongExpression, negateExpr);
2179:                    return constantLongExpression;
2180:
2181:                default:
2182:                    NegationExpression negationExpression = new NegationExpression(
2183:                            expression(node));
2184:                    configureAST(negationExpression, negateExpr);
2185:                    return negationExpression;
2186:                }
2187:            }
2188:
2189:            protected ConstantExpression decimalExpression(AST node) {
2190:                String text = node.getText();
2191:                ConstantExpression constantExpression = new ConstantExpression(
2192:                        Numbers.parseDecimal(text));
2193:                configureAST(constantExpression, node);
2194:                return constantExpression;
2195:            }
2196:
2197:            protected ConstantExpression integerExpression(AST node) {
2198:                String text = node.getText();
2199:                ConstantExpression constantExpression = new ConstantExpression(
2200:                        Numbers.parseInteger(text));
2201:                configureAST(constantExpression, node);
2202:                return constantExpression;
2203:            }
2204:
2205:            protected Expression gstring(AST gstringNode) {
2206:                List strings = new ArrayList();
2207:                List values = new ArrayList();
2208:
2209:                StringBuffer buffer = new StringBuffer();
2210:
2211:                boolean isPrevString = false;
2212:
2213:                for (AST node = gstringNode.getFirstChild(); node != null; node = node
2214:                        .getNextSibling()) {
2215:                    int type = node.getType();
2216:                    String text = null;
2217:                    switch (type) {
2218:
2219:                    case STRING_LITERAL:
2220:                        if (isPrevString)
2221:                            assertNodeType(IDENT, node); // parser bug
2222:                        isPrevString = true;
2223:                        text = node.getText();
2224:                        ConstantExpression constantExpression = new ConstantExpression(
2225:                                text);
2226:                        configureAST(constantExpression, node);
2227:                        strings.add(constantExpression);
2228:                        buffer.append(text);
2229:                        break;
2230:
2231:                    default: {
2232:                        if (!isPrevString)
2233:                            assertNodeType(IDENT, node); // parser bug
2234:                        isPrevString = false;
2235:                        Expression expression = expression(node);
2236:                        values.add(expression);
2237:                        buffer.append("$");
2238:                        buffer.append(expression.getText());
2239:                    }
2240:                        break;
2241:                    }
2242:                }
2243:                GStringExpression gStringExpression = new GStringExpression(
2244:                        buffer.toString(), strings, values);
2245:                configureAST(gStringExpression, gstringNode);
2246:                return gStringExpression;
2247:            }
2248:
2249:            protected ClassNode type(AST typeNode) {
2250:                // TODO intern types?
2251:                // TODO configureAST(...)
2252:                return buildName(typeNode.getFirstChild());
2253:            }
2254:
2255:            public static String qualifiedName(AST qualifiedNameNode) {
2256:                if (isType(IDENT, qualifiedNameNode)) {
2257:                    return qualifiedNameNode.getText();
2258:                }
2259:                if (isType(DOT, qualifiedNameNode)) {
2260:                    AST node = qualifiedNameNode.getFirstChild();
2261:                    StringBuffer buffer = new StringBuffer();
2262:                    boolean first = true;
2263:
2264:                    for (; node != null; node = node.getNextSibling()) {
2265:                        if (first) {
2266:                            first = false;
2267:                        } else {
2268:                            buffer.append(".");
2269:                        }
2270:                        buffer.append(qualifiedName(node));
2271:                    }
2272:                    return buffer.toString();
2273:                } else {
2274:                    return qualifiedNameNode.getText();
2275:                }
2276:            }
2277:
2278:            protected ClassNode makeType(AST typeNode) {
2279:                ClassNode answer = ClassHelper.DYNAMIC_TYPE;
2280:                AST node = typeNode.getFirstChild();
2281:                if (node != null) {
2282:                    if (isType(INDEX_OP, node)
2283:                            || isType(ARRAY_DECLARATOR, node)) {
2284:                        return makeType(node).makeArray();
2285:                    }
2286:                    return ClassHelper.make(qualifiedName(node));
2287:                }
2288:                return answer;
2289:            }
2290:
2291:            /**
2292:             * Performs a name resolution to see if the given name is a type from imports,
2293:             * aliases or newly created classes
2294:             */
2295:            /*protected String resolveTypeName(String name, boolean safe) {
2296:                if (name == null) {
2297:                    return null;
2298:                }
2299:                return resolveNewClassOrName(name, safe);
2300:            }*/
2301:
2302:            /**
2303:             * Extracts an identifier from the Antlr AST and then performs a name resolution
2304:             * to see if the given name is a type from imports, aliases or newly created classes
2305:             */
2306:            protected ClassNode buildName(AST node) {
2307:                if (isType(TYPE, node)) {
2308:                    node = node.getFirstChild();
2309:                }
2310:                ClassNode answer = null;
2311:                if (isType(DOT, node) || isType(OPTIONAL_DOT, node)) {
2312:                    answer = ClassHelper.make(qualifiedName(node));
2313:                } else if (isPrimitiveTypeLiteral(node)) {
2314:                    answer = ClassHelper.make(node.getText());
2315:                } else if (isType(INDEX_OP, node)
2316:                        || isType(ARRAY_DECLARATOR, node)) {
2317:                    AST child = node.getFirstChild();
2318:                    return buildName(child).makeArray();
2319:                } else {
2320:                    String identifier = node.getText();
2321:                    answer = ClassHelper.make(identifier);
2322:                }
2323:                AST nextSibling = node.getNextSibling();
2324:                if (isType(INDEX_OP, nextSibling)
2325:                        || isType(ARRAY_DECLARATOR, node)) {
2326:                    return answer.makeArray();
2327:                } else {
2328:                    return answer;
2329:                }
2330:            }
2331:
2332:            protected boolean isPrimitiveTypeLiteral(AST node) {
2333:                int type = node.getType();
2334:                switch (type) {
2335:                case LITERAL_boolean:
2336:                case LITERAL_byte:
2337:                case LITERAL_char:
2338:                case LITERAL_double:
2339:                case LITERAL_float:
2340:                case LITERAL_int:
2341:                case LITERAL_long:
2342:                case LITERAL_short:
2343:                    return true;
2344:
2345:                default:
2346:                    return false;
2347:                }
2348:            }
2349:
2350:            /**
2351:             * Extracts an identifier from the Antlr AST
2352:             */
2353:            protected String identifier(AST node) {
2354:                assertNodeType(IDENT, node);
2355:                return node.getText();
2356:            }
2357:
2358:            protected String label(AST labelNode) {
2359:                AST node = labelNode.getFirstChild();
2360:                if (node == null) {
2361:                    return null;
2362:                }
2363:                return identifier(node);
2364:            }
2365:
2366:            // Helper methods
2367:            //-------------------------------------------------------------------------
2368:
2369:            /**
2370:             * Returns true if the modifiers flags contain a visibility modifier
2371:             */
2372:            protected boolean hasVisibility(int modifiers) {
2373:                return (modifiers & (Opcodes.ACC_PRIVATE
2374:                        | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) != 0;
2375:            }
2376:
2377:            protected void configureAST(ASTNode node, AST ast) {
2378:                if (ast == null)
2379:                    throw new ASTRuntimeException(ast,
2380:                            "PARSER BUG: Tried to configure "
2381:                                    + node.getClass().getName()
2382:                                    + " with null Node");
2383:                node.setColumnNumber(ast.getColumn());
2384:                node.setLineNumber(ast.getLine());
2385:                if (ast instanceof  GroovySourceAST) {
2386:                    node.setLastColumnNumber(((GroovySourceAST) ast)
2387:                            .getColumnLast());
2388:                    node.setLastLineNumber(((GroovySourceAST) ast)
2389:                            .getLineLast());
2390:                }
2391:
2392:                // TODO we could one day store the Antlr AST on the Groovy AST
2393:                // node.setCSTNode(ast);
2394:            }
2395:
2396:            protected static Token makeToken(int typeCode, AST node) {
2397:                return Token.newSymbol(typeCode, node.getLine(), node
2398:                        .getColumn());
2399:            }
2400:
2401:            protected String getFirstChildText(AST node) {
2402:                AST child = node.getFirstChild();
2403:                return child != null ? child.getText() : null;
2404:            }
2405:
2406:            public static boolean isType(int typeCode, AST node) {
2407:                return node != null && node.getType() == typeCode;
2408:            }
2409:
2410:            private String getTokenName(int token) {
2411:                if (tokenNames == null)
2412:                    return "" + token;
2413:                return tokenNames[token];
2414:            }
2415:
2416:            private String getTokenName(AST node) {
2417:                if (node == null)
2418:                    return "null";
2419:                return getTokenName(node.getType());
2420:            }
2421:
2422:            protected void assertNodeType(int type, AST node) {
2423:                if (node == null) {
2424:                    throw new ASTRuntimeException(node,
2425:                            "No child node available in AST when expecting type: "
2426:                                    + getTokenName(type));
2427:                }
2428:                if (node.getType() != type) {
2429:                    throw new ASTRuntimeException(node,
2430:                            "Unexpected node type: " + getTokenName(node)
2431:                                    + " found when expecting type: "
2432:                                    + getTokenName(type));
2433:                }
2434:            }
2435:
2436:            protected void notImplementedYet(AST node) {
2437:                throw new ASTRuntimeException(node,
2438:                        "AST node not implemented yet for type: "
2439:                                + getTokenName(node));
2440:            }
2441:
2442:            protected void unknownAST(AST node) {
2443:                if (node.getType() == CLASS_DEF) {
2444:                    throw new ASTRuntimeException(
2445:                            node,
2446:                            "Class definition not expected here. Possible attempt to use inner class. "
2447:                                    + "Inner classes not supported, perhaps try using a closure instead.");
2448:                }
2449:                throw new ASTRuntimeException(node, "Unknown type: "
2450:                        + getTokenName(node));
2451:            }
2452:
2453:            protected void dumpTree(AST ast) {
2454:                for (AST node = ast.getFirstChild(); node != null; node = node
2455:                        .getNextSibling()) {
2456:                    dump(node);
2457:                }
2458:            }
2459:
2460:            protected void dump(AST node) {
2461:                System.out.println("Type: " + getTokenName(node) + " text: "
2462:                        + node.getText());
2463:            }
2464:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.