groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject [15/17] groovy git commit: rename antlr4 parser to remove groovy- prefix since that is by convention for modules
Date Mon, 08 May 2017 00:27:15 GMT
http://git-wip-us.apache.org/repos/asf/groovy/blob/73acbcfe/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
deleted file mode 100644
index e0708f7..0000000
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ /dev/null
@@ -1,4317 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.groovy.parser.antlr4;
-
-import groovy.lang.IntRange;
-import org.antlr.v4.runtime.ANTLRErrorListener;
-import org.antlr.v4.runtime.ANTLRInputStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.RecognitionException;
-import org.antlr.v4.runtime.Recognizer;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.atn.PredictionMode;
-import org.antlr.v4.runtime.misc.ParseCancellationException;
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.antlr.v4.runtime.tree.TerminalNode;
-import org.apache.groovy.parser.antlr4.internal.AtnManager;
-import org.apache.groovy.parser.antlr4.internal.DescriptiveErrorStrategy;
-import org.apache.groovy.parser.antlr4.util.StringUtils;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.antlr.EnumHelper;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ConstructorNode;
-import org.codehaus.groovy.ast.EnumConstantClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.GenericsType;
-import org.codehaus.groovy.ast.ImportNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.ModuleNode;
-import org.codehaus.groovy.ast.PackageNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.ArrayExpression;
-import org.codehaus.groovy.ast.expr.AttributeExpression;
-import org.codehaus.groovy.ast.expr.BinaryExpression;
-import org.codehaus.groovy.ast.expr.BitwiseNegationExpression;
-import org.codehaus.groovy.ast.expr.BooleanExpression;
-import org.codehaus.groovy.ast.expr.CastExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ClosureListExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.DeclarationExpression;
-import org.codehaus.groovy.ast.expr.ElvisOperatorExpression;
-import org.codehaus.groovy.ast.expr.EmptyExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.GStringExpression;
-import org.codehaus.groovy.ast.expr.LambdaExpression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.codehaus.groovy.ast.expr.MapEntryExpression;
-import org.codehaus.groovy.ast.expr.MapExpression;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.MethodPointerExpression;
-import org.codehaus.groovy.ast.expr.MethodReferenceExpression;
-import org.codehaus.groovy.ast.expr.NamedArgumentListExpression;
-import org.codehaus.groovy.ast.expr.NotExpression;
-import org.codehaus.groovy.ast.expr.PostfixExpression;
-import org.codehaus.groovy.ast.expr.PrefixExpression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.RangeExpression;
-import org.codehaus.groovy.ast.expr.SpreadExpression;
-import org.codehaus.groovy.ast.expr.SpreadMapExpression;
-import org.codehaus.groovy.ast.expr.TernaryExpression;
-import org.codehaus.groovy.ast.expr.TupleExpression;
-import org.codehaus.groovy.ast.expr.UnaryMinusExpression;
-import org.codehaus.groovy.ast.expr.UnaryPlusExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.AssertStatement;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.BreakStatement;
-import org.codehaus.groovy.ast.stmt.CaseStatement;
-import org.codehaus.groovy.ast.stmt.CatchStatement;
-import org.codehaus.groovy.ast.stmt.ContinueStatement;
-import org.codehaus.groovy.ast.stmt.DoWhileStatement;
-import org.codehaus.groovy.ast.stmt.EmptyStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.ForStatement;
-import org.codehaus.groovy.ast.stmt.IfStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.stmt.SwitchStatement;
-import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
-import org.codehaus.groovy.ast.stmt.ThrowStatement;
-import org.codehaus.groovy.ast.stmt.TryCatchStatement;
-import org.codehaus.groovy.ast.stmt.WhileStatement;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.runtime.IOGroovyMethods;
-import org.codehaus.groovy.runtime.StringGroovyMethods;
-import org.codehaus.groovy.syntax.Numbers;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.syntax.Types;
-import org.objectweb.asm.Opcodes;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static org.apache.groovy.parser.antlr4.GroovyLangParser.*;
-import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
-import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;
-
-/**
- * Building the AST from the parse tree generated by Antlr4
- *
- * @author <a href="mailto:realbluesun@hotmail.com">Daniel.Sun</a>
- *         Created on 2016/08/14
- */
-public class AstBuilder extends GroovyParserBaseVisitor<Object> implements GroovyParserVisitor<Object> {
-
-    public AstBuilder(SourceUnit sourceUnit, ClassLoader classLoader) {
-        this.sourceUnit = sourceUnit;
-        this.moduleNode = new ModuleNode(sourceUnit);
-        this.classLoader = classLoader; // unused for the time being
-
-        this.lexer = new GroovyLangLexer(
-                new ANTLRInputStream(
-                        this.readSourceCode(sourceUnit)));
-        this.parser = new GroovyLangParser(
-                new CommonTokenStream(this.lexer));
-
-        this.parser.setErrorHandler(new DescriptiveErrorStrategy());
-
-        this.tryWithResourcesASTTransformation = new TryWithResourcesASTTransformation(this);
-        this.groovydocManager = new GroovydocManager(this);
-    }
-
-    private GroovyParserRuleContext buildCST() {
-        GroovyParserRuleContext result;
-
-        // parsing have to wait util clearing is complete.
-        AtnManager.RRWL.readLock().lock();
-        try {
-            result = buildCST(PredictionMode.SLL);
-        } catch (Throwable t) {
-            // if some syntax error occurred in the lexer, no need to retry the powerful LL mode
-            if (t instanceof GroovySyntaxError && GroovySyntaxError.LEXER == ((GroovySyntaxError) t).getSource()) {
-                throw t;
-            }
-
-            result = buildCST(PredictionMode.LL);
-        } finally {
-            AtnManager.RRWL.readLock().unlock();
-        }
-
-        return result;
-    }
-
-    private GroovyParserRuleContext buildCST(PredictionMode predictionMode) {
-        parser.getInterpreter().setPredictionMode(predictionMode);
-
-        if (PredictionMode.SLL.equals(predictionMode)) {
-            this.removeErrorListeners();
-        } else {
-            ((CommonTokenStream) parser.getInputStream()).reset();
-            this.addErrorListeners();
-        }
-
-        return parser.compilationUnit();
-    }
-
-    public ModuleNode buildAST() {
-        try {
-            return (ModuleNode) this.visit(this.buildCST());
-        } catch (Throwable t) {
-            CompilationFailedException cfe;
-
-            if (t instanceof CompilationFailedException) {
-                cfe = (CompilationFailedException) t;
-            } else if (t instanceof ParseCancellationException) {
-                cfe = createParsingFailedException(t.getCause());
-            } else {
-                cfe = createParsingFailedException(t);
-            }
-
-//            LOGGER.log(Level.SEVERE, "Failed to build AST", cfe);
-
-            throw cfe;
-        }
-    }
-
-    @Override
-    public ModuleNode visitCompilationUnit(CompilationUnitContext ctx) {
-        this.visit(ctx.packageDeclaration());
-
-        ctx.statement().stream()
-                .map(this::visit)
-//                .filter(e -> e instanceof Statement)
-                .forEach(e -> {
-                    if (e instanceof DeclarationListStatement) { // local variable declaration
-                        ((DeclarationListStatement) e).getDeclarationStatements().forEach(moduleNode::addStatement);
-                    } else if (e instanceof Statement) {
-                        moduleNode.addStatement((Statement) e);
-                    } else if (e instanceof MethodNode) { // script method
-                        moduleNode.addMethod((MethodNode) e);
-                    }
-                });
-
-        this.classNodeList.forEach(moduleNode::addClass);
-
-        if (this.isPackageInfoDeclaration()) {
-            this.addPackageInfoClassNode();
-        } else {
-            // if groovy source file only contains blank(including EOF), add "return null" to the AST
-            if (this.isBlankScript(ctx)) {
-                this.addEmptyReturnStatement();
-            }
-        }
-
-        this.configureScriptClassNode();
-
-        return moduleNode;
-    }
-
-    @Override
-    public PackageNode visitPackageDeclaration(PackageDeclarationContext ctx) {
-        String packageName = this.visitQualifiedName(ctx.qualifiedName());
-        moduleNode.setPackageName(packageName + DOT_STR);
-
-        PackageNode packageNode = moduleNode.getPackage();
-
-        this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(packageNode::addAnnotation);
-
-        return this.configureAST(packageNode, ctx);
-    }
-
-    @Override
-    public ImportNode visitImportDeclaration(ImportDeclarationContext ctx) {
-        ImportNode importNode;
-
-        boolean hasStatic = asBoolean(ctx.STATIC());
-        boolean hasStar = asBoolean(ctx.MUL());
-        boolean hasAlias = asBoolean(ctx.alias);
-
-        List<AnnotationNode> annotationNodeList = this.visitAnnotationsOpt(ctx.annotationsOpt());
-
-        if (hasStatic) {
-            if (hasStar) { // e.g. import static java.lang.Math.*
-                String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
-                ClassNode type = ClassHelper.make(qualifiedName);
-
-
-                moduleNode.addStaticStarImport(type.getText(), type, annotationNodeList);
-
-                importNode = last(moduleNode.getStaticStarImports().values());
-            } else { // e.g. import static java.lang.Math.pow
-                List<GroovyParserRuleContext> identifierList = new LinkedList<>(ctx.qualifiedName().qualifiedNameElement());
-                int identifierListSize = identifierList.size();
-                String name = identifierList.get(identifierListSize - 1).getText();
-                ClassNode classNode =
-                        ClassHelper.make(
-                                identifierList.stream()
-                                        .limit(identifierListSize - 1)
-                                        .map(ParseTree::getText)
-                                        .collect(Collectors.joining(DOT_STR)));
-                String alias = hasAlias
-                        ? ctx.alias.getText()
-                        : name;
-
-                moduleNode.addStaticImport(classNode, name, alias, annotationNodeList);
-
-                importNode = last(moduleNode.getStaticImports().values());
-            }
-        } else {
-            if (hasStar) { // e.g. import java.util.*
-                String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
-
-                moduleNode.addStarImport(qualifiedName + DOT_STR, annotationNodeList);
-
-                importNode = last(moduleNode.getStarImports());
-            } else { // e.g. import java.util.Map
-                String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
-                String name = last(ctx.qualifiedName().qualifiedNameElement()).getText();
-                ClassNode classNode = ClassHelper.make(qualifiedName);
-                String alias = hasAlias
-                        ? ctx.alias.getText()
-                        : name;
-
-                moduleNode.addImport(alias, classNode, annotationNodeList);
-
-                importNode = last(moduleNode.getImports());
-            }
-        }
-
-        return this.configureAST(importNode, ctx);
-    }
-
-    // statement {    --------------------------------------------------------------------
-    @Override
-    public AssertStatement visitAssertStatement(AssertStatementContext ctx) {
-        Expression conditionExpression = (Expression) this.visit(ctx.ce);
-        BooleanExpression booleanExpression =
-                this.configureAST(
-                        new BooleanExpression(conditionExpression), conditionExpression);
-
-        if (!asBoolean(ctx.me)) {
-            return this.configureAST(
-                    new AssertStatement(booleanExpression), ctx);
-        }
-
-        return this.configureAST(new AssertStatement(booleanExpression,
-                        (Expression) this.visit(ctx.me)),
-                ctx);
-    }
-
-    @Override
-    public AssertStatement visitAssertStmtAlt(AssertStmtAltContext ctx) {
-        return this.configureAST(this.visitAssertStatement(ctx.assertStatement()), ctx);
-    }
-
-    @Override
-    public IfStatement visitIfElseStmtAlt(IfElseStmtAltContext ctx) {
-        Expression conditionExpression = this.visitParExpression(ctx.parExpression());
-        BooleanExpression booleanExpression =
-                this.configureAST(
-                        new BooleanExpression(conditionExpression), conditionExpression);
-
-        Statement ifBlock =
-                this.unpackStatement(
-                        (Statement) this.visit(ctx.tb));
-        Statement elseBlock =
-                this.unpackStatement(
-                        asBoolean(ctx.ELSE())
-                                ? (Statement) this.visit(ctx.fb)
-                                : EmptyStatement.INSTANCE);
-
-        return this.configureAST(new IfStatement(booleanExpression, ifBlock, elseBlock), ctx);
-    }
-
-    @Override
-    public Statement visitLoopStmtAlt(LoopStmtAltContext ctx) {
-        return this.configureAST((Statement) this.visit(ctx.loopStatement()), ctx);
-    }
-
-    @Override
-    public ForStatement visitForStmtAlt(ForStmtAltContext ctx) {
-        Pair<Parameter, Expression> controlPair = this.visitForControl(ctx.forControl());
-
-        Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement()));
-
-        return this.configureAST(
-                new ForStatement(controlPair.getKey(), controlPair.getValue(), asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE),
-                ctx);
-    }
-
-    @Override
-    public Pair<Parameter, Expression> visitForControl(ForControlContext ctx) {
-        if (asBoolean(ctx.enhancedForControl())) { // e.g. for(int i in 0..<10) {}
-            return this.visitEnhancedForControl(ctx.enhancedForControl());
-        }
-
-        if (asBoolean(ctx.classicalForControl())) { // e.g. for(int i = 0; i < 10; i++) {}
-            return this.visitClassicalForControl(ctx.classicalForControl());
-        }
-
-        throw createParsingFailedException("Unsupported for control: " + ctx.getText(), ctx);
-    }
-
-    @Override
-    public Expression visitForInit(ForInitContext ctx) {
-        if (!asBoolean(ctx)) {
-            return EmptyExpression.INSTANCE;
-        }
-
-        if (asBoolean(ctx.localVariableDeclaration())) {
-            DeclarationListStatement declarationListStatement = this.visitLocalVariableDeclaration(ctx.localVariableDeclaration());
-            List<?> declarationExpressionList = declarationListStatement.getDeclarationExpressions();
-
-            if (declarationExpressionList.size() == 1) {
-                return this.configureAST((Expression) declarationExpressionList.get(0), ctx);
-            } else {
-                return this.configureAST(new ClosureListExpression((List<Expression>) declarationExpressionList), ctx);
-            }
-        }
-
-        if (asBoolean(ctx.expressionList())) {
-            return this.translateExpressionList(ctx.expressionList());
-        }
-
-        throw createParsingFailedException("Unsupported for init: " + ctx.getText(), ctx);
-    }
-
-    @Override
-    public Expression visitForUpdate(ForUpdateContext ctx) {
-        if (!asBoolean(ctx)) {
-            return EmptyExpression.INSTANCE;
-        }
-
-        return this.translateExpressionList(ctx.expressionList());
-    }
-
-    private Expression translateExpressionList(ExpressionListContext ctx) {
-        List<Expression> expressionList = this.visitExpressionList(ctx);
-
-        if (expressionList.size() == 1) {
-            return this.configureAST(expressionList.get(0), ctx);
-        } else {
-            return this.configureAST(new ClosureListExpression(expressionList), ctx);
-        }
-    }
-
-    @Override
-    public Pair<Parameter, Expression> visitEnhancedForControl(EnhancedForControlContext ctx) {
-        Parameter parameter = this.configureAST(
-                new Parameter(this.visitType(ctx.type()), this.visitVariableDeclaratorId(ctx.variableDeclaratorId()).getName()),
-                ctx.variableDeclaratorId());
-
-        // FIXME Groovy will ignore variableModifier of parameter in the for control
-        // In order to make the new parser behave same with the old one, we do not process variableModifier*
-
-        return new Pair<>(parameter, (Expression) this.visit(ctx.expression()));
-    }
-
-    @Override
-    public Pair<Parameter, Expression> visitClassicalForControl(ClassicalForControlContext ctx) {
-        ClosureListExpression closureListExpression = new ClosureListExpression();
-
-        closureListExpression.addExpression(this.visitForInit(ctx.forInit()));
-        closureListExpression.addExpression(asBoolean(ctx.expression()) ? (Expression) this.visit(ctx.expression()) : EmptyExpression.INSTANCE);
-        closureListExpression.addExpression(this.visitForUpdate(ctx.forUpdate()));
-
-        return new Pair<>(ForStatement.FOR_LOOP_DUMMY, closureListExpression);
-    }
-
-    @Override
-    public WhileStatement visitWhileStmtAlt(WhileStmtAltContext ctx) {
-        Expression conditionExpression = this.visitParExpression(ctx.parExpression());
-        BooleanExpression booleanExpression =
-                this.configureAST(
-                        new BooleanExpression(conditionExpression), conditionExpression);
-
-        Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement()));
-
-        return this.configureAST(
-                new WhileStatement(booleanExpression, asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE),
-                ctx);
-    }
-
-    @Override
-    public DoWhileStatement visitDoWhileStmtAlt(DoWhileStmtAltContext ctx) {
-        Expression conditionExpression = this.visitParExpression(ctx.parExpression());
-
-        BooleanExpression booleanExpression =
-                this.configureAST(
-                        new BooleanExpression(conditionExpression),
-                        conditionExpression
-                );
-
-        Statement loopBlock = this.unpackStatement((Statement) this.visit(ctx.statement()));
-
-        return this.configureAST(
-                new DoWhileStatement(booleanExpression, asBoolean(loopBlock) ? loopBlock : EmptyStatement.INSTANCE),
-                ctx);
-    }
-
-    @Override
-    public Statement visitTryCatchStmtAlt(TryCatchStmtAltContext ctx) {
-        return this.configureAST(this.visitTryCatchStatement(ctx.tryCatchStatement()), ctx);
-    }
-
-    @Override
-    public Statement visitTryCatchStatement(TryCatchStatementContext ctx) {
-        TryCatchStatement tryCatchStatement =
-                new TryCatchStatement((Statement) this.visit(ctx.block()),
-                        this.visitFinallyBlock(ctx.finallyBlock()));
-
-        if (asBoolean(ctx.resources())) {
-            this.visitResources(ctx.resources()).forEach(tryCatchStatement::addResource);
-        }
-
-        ctx.catchClause().stream().map(this::visitCatchClause)
-                .reduce(new LinkedList<CatchStatement>(), (r, e) -> {
-                    r.addAll(e); // merge several LinkedList<CatchStatement> instances into one LinkedList<CatchStatement> instance
-                    return r;
-                })
-                .forEach(tryCatchStatement::addCatch);
-
-        return this.configureAST(
-                tryWithResourcesASTTransformation.transform(
-                        this.configureAST(tryCatchStatement, ctx)),
-                ctx);
-    }
-
-
-    @Override
-    public List<ExpressionStatement> visitResources(ResourcesContext ctx) {
-        return this.visitResourceList(ctx.resourceList());
-    }
-
-    @Override
-    public List<ExpressionStatement> visitResourceList(ResourceListContext ctx) {
-        return ctx.resource().stream().map(this::visitResource).collect(Collectors.toList());
-    }
-
-    @Override
-    public ExpressionStatement visitResource(ResourceContext ctx) {
-        if (asBoolean(ctx.localVariableDeclaration())) {
-            List<ExpressionStatement> declarationStatements = this.visitLocalVariableDeclaration(ctx.localVariableDeclaration()).getDeclarationStatements();
-
-            if (declarationStatements.size() > 1) {
-                throw createParsingFailedException("Multi resources can not be declared in one statement", ctx);
-            }
-
-            return declarationStatements.get(0);
-        } else if (asBoolean(ctx.expression())) {
-            Expression expression = (Expression) this.visit(ctx.expression());
-            if (!(expression instanceof BinaryExpression
-                    && Types.ASSIGN == ((BinaryExpression) expression).getOperation().getType()
-                    && ((BinaryExpression) expression).getLeftExpression() instanceof VariableExpression)) {
-
-                throw createParsingFailedException("Only variable declarations are allowed to declare resource", ctx);
-            }
-
-            BinaryExpression assignmentExpression = (BinaryExpression) expression;
-
-            return this.configureAST(
-                    new ExpressionStatement(
-                            this.configureAST(
-                                    new DeclarationExpression(
-                                            this.configureAST(
-                                                    new VariableExpression(assignmentExpression.getLeftExpression().getText()),
-                                                    assignmentExpression.getLeftExpression()
-                                            ),
-                                            assignmentExpression.getOperation(),
-                                            assignmentExpression.getRightExpression()
-                                    ), ctx)
-                    ), ctx);
-        }
-
-        throw createParsingFailedException("Unsupported resource declaration: " + ctx.getText(), ctx);
-    }
-
-    /**
-     * Multi-catch(1..*) clause will be unpacked to several normal catch clauses, so the return type is List
-     *
-     * @param ctx the parse tree
-     * @return
-     */
-    @Override
-    public List<CatchStatement> visitCatchClause(CatchClauseContext ctx) {
-        // FIXME Groovy will ignore variableModifier of parameter in the catch clause
-        // In order to make the new parser behave same with the old one, we do not process variableModifier*
-
-        return this.visitCatchType(ctx.catchType()).stream()
-                .map(e -> this.configureAST(
-                        new CatchStatement(
-                                // FIXME The old parser does not set location info for the parameter of the catch clause.
-                                // we could make it better
-                                //this.configureAST(new Parameter(e, this.visitIdentifier(ctx.identifier())), ctx.Identifier()),
-
-                                new Parameter(e, this.visitIdentifier(ctx.identifier())),
-                                this.visitBlock(ctx.block())),
-                        ctx.block()))
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public List<ClassNode> visitCatchType(CatchTypeContext ctx) {
-        if (!asBoolean(ctx)) {
-            return Collections.singletonList(ClassHelper.OBJECT_TYPE);
-        }
-
-        return ctx.qualifiedClassName().stream()
-                .map(this::visitQualifiedClassName)
-                .collect(Collectors.toList());
-    }
-
-
-    @Override
-    public Statement visitFinallyBlock(FinallyBlockContext ctx) {
-        if (!asBoolean(ctx)) {
-            return EmptyStatement.INSTANCE;
-        }
-
-        return this.configureAST(
-                this.createBlockStatement((Statement) this.visit(ctx.block())),
-                ctx);
-    }
-
-    @Override
-    public SwitchStatement visitSwitchStmtAlt(SwitchStmtAltContext ctx) {
-        return this.configureAST(this.visitSwitchStatement(ctx.switchStatement()), ctx);
-    }
-
-    public SwitchStatement visitSwitchStatement(SwitchStatementContext ctx) {
-        List<Statement> statementList =
-                ctx.switchBlockStatementGroup().stream()
-                        .map(this::visitSwitchBlockStatementGroup)
-                        .reduce(new LinkedList<>(), (r, e) -> {
-                            r.addAll(e);
-                            return r;
-                        });
-
-        List<CaseStatement> caseStatementList = new LinkedList<>();
-        List<Statement> defaultStatementList = new LinkedList<>();
-
-        statementList.forEach(e -> {
-            if (e instanceof CaseStatement) {
-                caseStatementList.add((CaseStatement) e);
-            } else if (isTrue(e, IS_SWITCH_DEFAULT)) {
-                defaultStatementList.add(e);
-            }
-        });
-
-        int defaultStatementListSize = defaultStatementList.size();
-        if (defaultStatementListSize > 1) {
-            throw createParsingFailedException("switch statement should have only one default case, which should appear at last", defaultStatementList.get(0));
-        }
-
-        if (defaultStatementListSize > 0 && last(statementList) instanceof CaseStatement) {
-            throw createParsingFailedException("default case should appear at last", defaultStatementList.get(0));
-        }
-
-        return this.configureAST(
-                new SwitchStatement(
-                        this.visitParExpression(ctx.parExpression()),
-                        caseStatementList,
-                        defaultStatementListSize == 0 ? EmptyStatement.INSTANCE : defaultStatementList.get(0)
-                ),
-                ctx);
-
-    }
-
-
-    @Override
-    @SuppressWarnings({"unchecked"})
-    public List<Statement> visitSwitchBlockStatementGroup(SwitchBlockStatementGroupContext ctx) {
-        int labelCnt = ctx.switchLabel().size();
-        List<Token> firstLabelHolder = new ArrayList<>(1);
-
-        return (List<Statement>) ctx.switchLabel().stream()
-                .map(e -> (Object) this.visitSwitchLabel(e))
-                .reduce(new ArrayList<Statement>(4), (r, e) -> {
-                    List<Statement> statementList = (List<Statement>) r;
-                    Pair<Token, Expression> pair = (Pair<Token, Expression>) e;
-
-                    boolean isLast = labelCnt - 1 == statementList.size();
-
-                    switch (pair.getKey().getType()) {
-                        case CASE: {
-                            if (!asBoolean(statementList)) {
-                                firstLabelHolder.add(pair.getKey());
-                            }
-
-                            statementList.add(
-                                    this.configureAST(
-                                            new CaseStatement(
-                                                    pair.getValue(),
-
-                                                    // check whether processing the last label. if yes, block statement should be attached.
-                                                    isLast ? this.visitBlockStatements(ctx.blockStatements())
-                                                            : EmptyStatement.INSTANCE
-                                            ),
-                                            firstLabelHolder.get(0)));
-
-                            break;
-                        }
-                        case DEFAULT: {
-
-                            BlockStatement blockStatement = this.visitBlockStatements(ctx.blockStatements());
-                            blockStatement.putNodeMetaData(IS_SWITCH_DEFAULT, true);
-
-                            statementList.add(
-                                    // this.configureAST(blockStatement, pair.getKey())
-                                    blockStatement
-                            );
-
-                            break;
-                        }
-                    }
-
-                    return statementList;
-                });
-
-    }
-
-    @Override
-    public Pair<Token, Expression> visitSwitchLabel(SwitchLabelContext ctx) {
-        if (asBoolean(ctx.CASE())) {
-            return new Pair<>(ctx.CASE().getSymbol(), (Expression) this.visit(ctx.expression()));
-        } else if (asBoolean(ctx.DEFAULT())) {
-            return new Pair<>(ctx.DEFAULT().getSymbol(), EmptyExpression.INSTANCE);
-        }
-
-        throw createParsingFailedException("Unsupported switch label: " + ctx.getText(), ctx);
-    }
-
-
-    @Override
-    public SynchronizedStatement visitSynchronizedStmtAlt(SynchronizedStmtAltContext ctx) {
-        return this.configureAST(
-                new SynchronizedStatement(this.visitParExpression(ctx.parExpression()), this.visitBlock(ctx.block())),
-                ctx);
-    }
-
-
-    @Override
-    public ExpressionStatement visitExpressionStmtAlt(ExpressionStmtAltContext ctx) {
-        return (ExpressionStatement) this.visit(ctx.statementExpression());
-    }
-
-    @Override
-    public ReturnStatement visitReturnStmtAlt(ReturnStmtAltContext ctx) {
-        return this.configureAST(new ReturnStatement(asBoolean(ctx.expression())
-                        ? (Expression) this.visit(ctx.expression())
-                        : ConstantExpression.EMPTY_EXPRESSION),
-                ctx);
-    }
-
-    @Override
-    public ThrowStatement visitThrowStmtAlt(ThrowStmtAltContext ctx) {
-        return this.configureAST(
-                new ThrowStatement((Expression) this.visit(ctx.expression())),
-                ctx);
-    }
-
-    @Override
-    public Statement visitLabeledStmtAlt(LabeledStmtAltContext ctx) {
-        Statement statement = (Statement) this.visit(ctx.statement());
-
-        statement.addStatementLabel(this.visitIdentifier(ctx.identifier()));
-
-        return statement; // this.configureAST(statement, ctx);
-    }
-
-    @Override
-    public BreakStatement visitBreakStatement(BreakStatementContext ctx) {
-        String label = asBoolean(ctx.identifier())
-                ? this.visitIdentifier(ctx.identifier())
-                : null;
-
-        return this.configureAST(new BreakStatement(label), ctx);
-    }
-
-    @Override
-    public BreakStatement visitBreakStmtAlt(BreakStmtAltContext ctx) {
-        return this.configureAST(this.visitBreakStatement(ctx.breakStatement()), ctx);
-    }
-
-    @Override
-    public ContinueStatement visitContinueStatement(ContinueStatementContext ctx) {
-        String label = asBoolean(ctx.identifier())
-                ? this.visitIdentifier(ctx.identifier())
-                : null;
-
-        return this.configureAST(new ContinueStatement(label), ctx);
-
-    }
-
-    @Override
-    public ContinueStatement visitContinueStmtAlt(ContinueStmtAltContext ctx) {
-        return this.configureAST(this.visitContinueStatement(ctx.continueStatement()), ctx);
-    }
-
-    @Override
-    public ImportNode visitImportStmtAlt(ImportStmtAltContext ctx) {
-        return this.configureAST(this.visitImportDeclaration(ctx.importDeclaration()), ctx);
-    }
-
-    @Override
-    public ClassNode visitTypeDeclarationStmtAlt(TypeDeclarationStmtAltContext ctx) {
-        return this.configureAST(this.visitTypeDeclaration(ctx.typeDeclaration()), ctx);
-    }
-
-
-    @Override
-    public Statement visitLocalVariableDeclarationStmtAlt(LocalVariableDeclarationStmtAltContext ctx) {
-        return this.configureAST(this.visitLocalVariableDeclaration(ctx.localVariableDeclaration()), ctx);
-    }
-
-    @Override
-    public MethodNode visitMethodDeclarationStmtAlt(MethodDeclarationStmtAltContext ctx) {
-        return this.configureAST(this.visitMethodDeclaration(ctx.methodDeclaration()), ctx);
-    }
-
-    // } statement    --------------------------------------------------------------------
-
-    @Override
-    public ClassNode visitTypeDeclaration(TypeDeclarationContext ctx) {
-        if (asBoolean(ctx.classDeclaration())) { // e.g. class A {}
-            ctx.classDeclaration().putNodeMetaData(TYPE_DECLARATION_MODIFIERS, this.visitClassOrInterfaceModifiersOpt(ctx.classOrInterfaceModifiersOpt()));
-            return this.configureAST(this.visitClassDeclaration(ctx.classDeclaration()), ctx);
-        }
-
-        throw createParsingFailedException("Unsupported type declaration: " + ctx.getText(), ctx);
-    }
-
-    private void initUsingGenerics(ClassNode classNode) {
-        if (classNode.isUsingGenerics()) {
-            return;
-        }
-
-        if (!classNode.isEnum()) {
-            classNode.setUsingGenerics(classNode.getSuperClass().isUsingGenerics());
-        }
-
-        if (!classNode.isUsingGenerics() && asBoolean((Object) classNode.getInterfaces())) {
-            for (ClassNode anInterface : classNode.getInterfaces()) {
-                classNode.setUsingGenerics(classNode.isUsingGenerics() || anInterface.isUsingGenerics());
-
-                if (classNode.isUsingGenerics())
-                    break;
-            }
-        }
-    }
-
-    @Override
-    public ClassNode visitClassDeclaration(ClassDeclarationContext ctx) {
-        String packageName = moduleNode.getPackageName();
-        packageName = asBoolean((Object) packageName) ? packageName : "";
-
-        List<ModifierNode> modifierNodeList = ctx.getNodeMetaData(TYPE_DECLARATION_MODIFIERS);
-        Objects.requireNonNull(modifierNodeList, "modifierNodeList should not be null");
-
-        ModifierManager modifierManager = new ModifierManager(this, modifierNodeList);
-        int modifiers = modifierManager.getClassModifiersOpValue();
-
-        boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
-        modifiers &= ~Opcodes.ACC_SYNTHETIC;
-
-        final ClassNode outerClass = classNodeStack.peek();
-        ClassNode classNode;
-        String className = this.visitIdentifier(ctx.identifier());
-        if (asBoolean(ctx.ENUM())) {
-            classNode =
-                    EnumHelper.makeEnumNode(
-                            asBoolean(outerClass) ? className : packageName + className,
-                            modifiers, null, outerClass);
-        } else {
-            if (asBoolean(outerClass)) {
-                classNode =
-                        new InnerClassNode(
-                                outerClass,
-                                outerClass.getName() + "$" + className,
-                                modifiers | (outerClass.isInterface() ? Opcodes.ACC_STATIC : 0),
-                                ClassHelper.OBJECT_TYPE);
-            } else {
-                classNode =
-                        new ClassNode(
-                                packageName + className,
-                                modifiers,
-                                ClassHelper.OBJECT_TYPE);
-            }
-
-        }
-
-        this.configureAST(classNode, ctx);
-        classNode.putNodeMetaData(CLASS_NAME, className);
-        classNode.setSyntheticPublic(syntheticPublic);
-
-        if (asBoolean(ctx.TRAIT())) {
-            classNode.addAnnotation(new AnnotationNode(ClassHelper.make(GROOVY_TRANSFORM_TRAIT)));
-        }
-        classNode.addAnnotations(modifierManager.getAnnotations());
-        classNode.setGenericsTypes(this.visitTypeParameters(ctx.typeParameters()));
-
-        boolean isInterface = asBoolean(ctx.INTERFACE()) && !asBoolean(ctx.AT());
-        boolean isInterfaceWithDefaultMethods = false;
-
-        // declaring interface with default method
-        if (isInterface && this.containsDefaultMethods(ctx)) {
-            isInterfaceWithDefaultMethods = true;
-            classNode.addAnnotation(new AnnotationNode(ClassHelper.make(GROOVY_TRANSFORM_TRAIT)));
-            classNode.putNodeMetaData(IS_INTERFACE_WITH_DEFAULT_METHODS, true);
-        }
-
-        if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT()) || isInterfaceWithDefaultMethods) { // class OR trait OR interface with default methods
-            classNode.setSuperClass(this.visitType(ctx.sc));
-            classNode.setInterfaces(this.visitTypeList(ctx.is));
-
-            this.initUsingGenerics(classNode);
-        } else if (isInterface) { // interface(NOT annotation)
-            classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT);
-
-            classNode.setSuperClass(ClassHelper.OBJECT_TYPE);
-            classNode.setInterfaces(this.visitTypeList(ctx.scs));
-
-            this.initUsingGenerics(classNode);
-
-            this.hackMixins(classNode);
-        } else if (asBoolean(ctx.ENUM())) { // enum
-            classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_ENUM | Opcodes.ACC_FINAL);
-
-            classNode.setInterfaces(this.visitTypeList(ctx.is));
-
-            this.initUsingGenerics(classNode);
-        } else if (asBoolean(ctx.AT())) { // annotation
-            classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_ANNOTATION);
-
-            classNode.addInterface(ClassHelper.Annotation_TYPE);
-
-            this.hackMixins(classNode);
-        } else {
-            throw createParsingFailedException("Unsupported class declaration: " + ctx.getText(), ctx);
-        }
-
-        // we put the class already in output to avoid the most inner classes
-        // will be used as first class later in the loader. The first class
-        // there determines what GCL#parseClass for example will return, so we
-        // have here to ensure it won't be the inner class
-        if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT())) {
-            classNodeList.add(classNode);
-        }
-
-        int oldAnonymousInnerClassCounter = this.anonymousInnerClassCounter;
-        classNodeStack.push(classNode);
-        ctx.classBody().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-        this.visitClassBody(ctx.classBody());
-        classNodeStack.pop();
-        this.anonymousInnerClassCounter = oldAnonymousInnerClassCounter;
-
-        if (!(asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT()))) {
-            classNodeList.add(classNode);
-        }
-
-        groovydocManager.handle(classNode, ctx);
-
-        return classNode;
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private boolean containsDefaultMethods(ClassDeclarationContext ctx) {
-        List<MethodDeclarationContext> methodDeclarationContextList =
-                (List<MethodDeclarationContext>) ctx.classBody().classBodyDeclaration().stream()
-                .map(ClassBodyDeclarationContext::memberDeclaration)
-                .filter(Objects::nonNull)
-                .map(e -> (Object) e.methodDeclaration())
-                .filter(Objects::nonNull).reduce(new LinkedList<MethodDeclarationContext>(), (r, e) -> {
-                    MethodDeclarationContext methodDeclarationContext = (MethodDeclarationContext) e;
-
-                    if (createModifierManager(methodDeclarationContext).contains(DEFAULT)) {
-                        ((List) r).add(methodDeclarationContext);
-                    }
-
-                    return r;
-        });
-
-        return !methodDeclarationContextList.isEmpty();
-    }
-
-    @Override
-    public Void visitClassBody(ClassBodyContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        if (asBoolean(ctx.enumConstants())) {
-            ctx.enumConstants().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitEnumConstants(ctx.enumConstants());
-        }
-
-        ctx.classBodyDeclaration().forEach(e -> {
-            e.putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitClassBodyDeclaration(e);
-        });
-
-        return null;
-    }
-
-    @Override
-    public List<FieldNode> visitEnumConstants(EnumConstantsContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        return ctx.enumConstant().stream()
-                .map(e -> {
-                    e.putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-                    return this.visitEnumConstant(e);
-                })
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public FieldNode visitEnumConstant(EnumConstantContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        InnerClassNode anonymousInnerClassNode = null;
-        if (asBoolean(ctx.anonymousInnerClassDeclaration())) {
-            ctx.anonymousInnerClassDeclaration().putNodeMetaData(ANONYMOUS_INNER_CLASS_SUPER_CLASS, classNode);
-            anonymousInnerClassNode = this.visitAnonymousInnerClassDeclaration(ctx.anonymousInnerClassDeclaration());
-        }
-
-        FieldNode enumConstant =
-                EnumHelper.addEnumConstant(
-                        classNode,
-                        this.visitIdentifier(ctx.identifier()),
-                        createEnumConstantInitExpression(ctx.arguments(), anonymousInnerClassNode));
-
-        this.visitAnnotationsOpt(ctx.annotationsOpt()).forEach(enumConstant::addAnnotation);
-
-        groovydocManager.handle(enumConstant, ctx);
-
-        return this.configureAST(enumConstant, ctx);
-    }
-
-    private Expression createEnumConstantInitExpression(ArgumentsContext ctx, InnerClassNode anonymousInnerClassNode) {
-        if (!asBoolean(ctx) && !asBoolean(anonymousInnerClassNode)) {
-            return null;
-        }
-
-        TupleExpression argumentListExpression = (TupleExpression) this.visitArguments(ctx);
-        List<Expression> expressions = argumentListExpression.getExpressions();
-
-        if (expressions.size() == 1) {
-            Expression expression = expressions.get(0);
-
-            if (expression instanceof NamedArgumentListExpression) { // e.g. SOME_ENUM_CONSTANT(a: "1", b: "2")
-                List<MapEntryExpression> mapEntryExpressionList = ((NamedArgumentListExpression) expression).getMapEntryExpressions();
-                ListExpression listExpression =
-                        new ListExpression(
-                                mapEntryExpressionList.stream()
-                                        .map(e -> (Expression) e)
-                                        .collect(Collectors.toList()));
-
-                if (asBoolean(anonymousInnerClassNode)) {
-                    listExpression.addExpression(
-                            this.configureAST(
-                                    new ClassExpression(anonymousInnerClassNode),
-                                    anonymousInnerClassNode));
-                }
-
-                if (mapEntryExpressionList.size() > 1) {
-                    listExpression.setWrapped(true);
-                }
-
-                return this.configureAST(listExpression, ctx);
-            }
-
-            if (!asBoolean(anonymousInnerClassNode)) {
-                if (expression instanceof ListExpression) {
-                    ListExpression listExpression = new ListExpression();
-                    listExpression.addExpression(expression);
-
-                    return this.configureAST(listExpression, ctx);
-                }
-
-                return expression;
-            }
-
-            ListExpression listExpression = new ListExpression();
-
-            if (expression instanceof ListExpression) {
-                ((ListExpression) expression).getExpressions().forEach(listExpression::addExpression);
-            } else {
-                listExpression.addExpression(expression);
-            }
-
-            listExpression.addExpression(
-                    this.configureAST(
-                            new ClassExpression(anonymousInnerClassNode),
-                            anonymousInnerClassNode));
-
-            return this.configureAST(listExpression, ctx);
-        }
-
-        ListExpression listExpression = new ListExpression(expressions);
-        if (asBoolean(anonymousInnerClassNode)) {
-            listExpression.addExpression(
-                    this.configureAST(
-                            new ClassExpression(anonymousInnerClassNode),
-                            anonymousInnerClassNode));
-        }
-
-        if (asBoolean(ctx)) {
-            listExpression.setWrapped(true);
-        }
-
-        return asBoolean(ctx)
-                ? this.configureAST(listExpression, ctx)
-                : this.configureAST(listExpression, anonymousInnerClassNode);
-    }
-
-
-    @Override
-    public Void visitClassBodyDeclaration(ClassBodyDeclarationContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        if (asBoolean(ctx.memberDeclaration())) {
-            ctx.memberDeclaration().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitMemberDeclaration(ctx.memberDeclaration());
-        } else if (asBoolean(ctx.block())) {
-            Statement statement = this.visitBlock(ctx.block());
-
-            if (asBoolean(ctx.STATIC())) { // e.g. static { }
-                classNode.addStaticInitializerStatements(Collections.singletonList(statement), false);
-            } else { // e.g.  { }
-                classNode.addObjectInitializerStatements(
-                        this.configureAST(
-                                this.createBlockStatement(statement),
-                                statement));
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Void visitMemberDeclaration(MemberDeclarationContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        if (asBoolean(ctx.methodDeclaration())) {
-            ctx.methodDeclaration().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitMethodDeclaration(ctx.methodDeclaration());
-        } else if (asBoolean(ctx.fieldDeclaration())) {
-            ctx.fieldDeclaration().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitFieldDeclaration(ctx.fieldDeclaration());
-        } else if (asBoolean(ctx.classDeclaration())) {
-            ctx.classDeclaration().putNodeMetaData(TYPE_DECLARATION_MODIFIERS, this.visitModifiersOpt(ctx.modifiersOpt()));
-            ctx.classDeclaration().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-            this.visitClassDeclaration(ctx.classDeclaration());
-        }
-
-        return null;
-    }
-
-    @Override
-    public GenericsType[] visitTypeParameters(TypeParametersContext ctx) {
-        if (!asBoolean(ctx)) {
-            return null;
-        }
-
-        return ctx.typeParameter().stream()
-                .map(this::visitTypeParameter)
-                .toArray(GenericsType[]::new);
-    }
-
-    @Override
-    public GenericsType visitTypeParameter(TypeParameterContext ctx) {
-        return this.configureAST(
-                new GenericsType(
-                        ClassHelper.make(this.visitClassName(ctx.className())),
-                        this.visitTypeBound(ctx.typeBound()),
-                        null
-                ),
-                ctx);
-    }
-
-    @Override
-    public ClassNode[] visitTypeBound(TypeBoundContext ctx) {
-        if (!asBoolean(ctx)) {
-            return null;
-        }
-
-        return ctx.type().stream()
-                .map(this::visitType)
-                .toArray(ClassNode[]::new);
-    }
-
-    @Override
-    public Void visitFieldDeclaration(FieldDeclarationContext ctx) {
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        Objects.requireNonNull(classNode, "classNode should not be null");
-
-        ctx.variableDeclaration().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
-        this.visitVariableDeclaration(ctx.variableDeclaration());
-
-        return null;
-    }
-
-    private ConstructorCallExpression checkThisAndSuperConstructorCall(Statement statement) {
-        if (!(statement instanceof BlockStatement)) { // method code must be a BlockStatement
-            return null;
-        }
-
-        BlockStatement blockStatement = (BlockStatement) statement;
-        List<Statement> statementList = blockStatement.getStatements();
-
-        for (int i = 0, n = statementList.size(); i < n; i++) {
-            Statement s = statementList.get(i);
-            if (s instanceof ExpressionStatement) {
-                Expression expression = ((ExpressionStatement) s).getExpression();
-                if ((expression instanceof ConstructorCallExpression) && 0 != i) {
-                    return (ConstructorCallExpression) expression;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private ModifierManager createModifierManager(MethodDeclarationContext ctx) {
-        List<ModifierNode> modifierNodeList = Collections.emptyList();
-
-        if (asBoolean(ctx.modifiers())) {
-            modifierNodeList = this.visitModifiers(ctx.modifiers());
-        } else if (asBoolean(ctx.modifiersOpt())) {
-            modifierNodeList = this.visitModifiersOpt(ctx.modifiersOpt());
-        }
-
-        return new ModifierManager(this, modifierNodeList);
-    }
-
-    private void validateParametersOfMethodDeclaration(Parameter[] parameters, ClassNode classNode) {
-        if (!classNode.isInterface()) {
-            return;
-        }
-
-        Arrays.stream(parameters).forEach(e -> {
-            if (e.hasInitialExpression()) {
-                throw createParsingFailedException("Cannot specify default value for method parameter '" + e.getName() + " = " + e.getInitialExpression().getText() + "' inside an interface", e);
-            }
-        });
-    }
-
-    @Override
-    public MethodNode visitMethodDeclaration(MethodDeclarationContext ctx) {
-        ModifierManager modifierManager = createModifierManager(ctx);
-        String methodName = this.visitMethodName(ctx.methodName());
-        ClassNode returnType = this.visitReturnType(ctx.returnType());
-        Parameter[] parameters = this.visitFormalParameters(ctx.formalParameters());
-        ClassNode[] exceptions = this.visitQualifiedClassNameList(ctx.qualifiedClassNameList());
-
-        anonymousInnerClassesDefinedInMethodStack.push(new LinkedList<>());
-        Statement code = this.visitMethodBody(ctx.methodBody());
-        List<InnerClassNode> anonymousInnerClassList = anonymousInnerClassesDefinedInMethodStack.pop();
-
-        MethodNode methodNode;
-        // if classNode is not null, the method declaration is for class declaration
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-        if (asBoolean(classNode)) {
-            validateParametersOfMethodDeclaration(parameters, classNode);
-
-            methodNode = createConstructorOrMethodNodeForClass(ctx, modifierManager, methodName, returnType, parameters, exceptions, code, classNode);
-        } else { // script method declaration
-            methodNode = createScriptMethodNode(modifierManager, methodName, returnType, parameters, exceptions, code);
-        }
-        anonymousInnerClassList.forEach(e -> e.setEnclosingMethod(methodNode));
-
-        methodNode.setGenericsTypes(this.visitTypeParameters(ctx.typeParameters()));
-        methodNode.setSyntheticPublic(
-                this.isSyntheticPublic(
-                        this.isAnnotationDeclaration(classNode),
-                        classNode instanceof EnumConstantClassNode,
-                        asBoolean(ctx.returnType()),
-                        modifierManager));
-
-        if (modifierManager.contains(STATIC)) {
-            Arrays.stream(methodNode.getParameters()).forEach(e -> e.setInStaticContext(true));
-            methodNode.getVariableScope().setInStaticContext(true);
-        }
-
-        this.configureAST(methodNode, ctx);
-
-        validateMethodDeclaration(ctx, methodNode, modifierManager, classNode);
-
-        groovydocManager.handle(methodNode, ctx);
-
-        return methodNode;
-    }
-
-    private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode methodNode, ModifierManager modifierManager, ClassNode classNode) {
-        boolean isAbstractMethod = methodNode.isAbstract();
-        boolean hasMethodBody = asBoolean(methodNode.getCode());
-
-        if (9 == ctx.ct) { // script
-            if (isAbstractMethod || !hasMethodBody) { // method should not be declared abstract in the script
-                throw createParsingFailedException("You can not define a " + (isAbstractMethod ? "abstract" : "") + " method[" + methodNode.getName() + "] " + (!hasMethodBody ? "without method body" : "") + " in the script. Try " + (isAbstractMethod ? "removing the 'abstract'" : "") + (isAbstractMethod && !hasMethodBody ? " and" : "") + (!hasMethodBody ? " adding a method body" : ""), methodNode);
-            }
-        } else {
-            if (!isAbstractMethod && !hasMethodBody) { // non-abstract method without body in the non-script(e.g. class, enum, trait) is not allowed!
-                throw createParsingFailedException("You defined a method[" + methodNode.getName() + "] without body. Try adding a method body, or declare it abstract", methodNode);
-            }
-
-            boolean isInterfaceOrAbstractClass = asBoolean(classNode) && classNode.isAbstract() && !classNode.isAnnotationDefinition();
-            if (isInterfaceOrAbstractClass && !modifierManager.contains(DEFAULT) && isAbstractMethod && hasMethodBody) {
-                throw createParsingFailedException("You defined an abstract method[" + methodNode.getName() + "] with body. Try removing the method body" + (classNode.isInterface() ? ", or declare it default" : ""), methodNode);
-            }
-        }
-
-        modifierManager.validate(methodNode);
-
-        if (methodNode instanceof ConstructorNode) {
-            modifierManager.validate((ConstructorNode) methodNode);
-        }
-    }
-
-    private MethodNode createScriptMethodNode(ModifierManager modifierManager, String methodName, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
-        MethodNode methodNode;
-        methodNode =
-                new MethodNode(
-                        methodName,
-                        modifierManager.contains(PRIVATE) ? Opcodes.ACC_PRIVATE : Opcodes.ACC_PUBLIC,
-                        returnType,
-                        parameters,
-                        exceptions,
-                        code);
-
-        modifierManager.processMethodNode(methodNode);
-        return methodNode;
-    }
-
-    private MethodNode createConstructorOrMethodNodeForClass(MethodDeclarationContext ctx, ModifierManager modifierManager, String methodName, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code, ClassNode classNode) {
-        MethodNode methodNode;
-        String className = classNode.getNodeMetaData(CLASS_NAME);
-        int modifiers = modifierManager.getClassMemberModifiersOpValue();
-
-        if (!asBoolean(ctx.returnType())
-                && asBoolean(ctx.methodBody())
-                && methodName.equals(className)) { // constructor declaration
-
-            methodNode = createConstructorNodeForClass(methodName, parameters, exceptions, code, classNode, modifiers);
-        } else { // class memeber method declaration
-            methodNode = createMethodNodeForClass(ctx, modifierManager, methodName, returnType, parameters, exceptions, code, classNode, modifiers);
-        }
-
-        modifierManager.attachAnnotations(methodNode);
-        return methodNode;
-    }
-
-    private MethodNode createMethodNodeForClass(MethodDeclarationContext ctx, ModifierManager modifierManager, String methodName, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code, ClassNode classNode, int modifiers) {
-        MethodNode methodNode;
-        if (asBoolean(ctx.elementValue())) { // the code of annotation method
-            code = this.configureAST(
-                    new ExpressionStatement(
-                            this.visitElementValue(ctx.elementValue())),
-                    ctx.elementValue());
-
-        }
-
-        modifiers |= !modifierManager.contains(STATIC) && (classNode.isInterface() || (isTrue(classNode, IS_INTERFACE_WITH_DEFAULT_METHODS) && !modifierManager.contains(DEFAULT))) ? Opcodes.ACC_ABSTRACT : 0;
-
-        checkWhetherMethodNodeWithSameSignatureExists(classNode, methodName, parameters, ctx);
-
-        methodNode = classNode.addMethod(methodName, modifiers, returnType, parameters, exceptions, code);
-
-        methodNode.setAnnotationDefault(asBoolean(ctx.elementValue()));
-        return methodNode;
-    }
-
-    private void checkWhetherMethodNodeWithSameSignatureExists(ClassNode classNode, String methodName, Parameter[] parameters, MethodDeclarationContext ctx) {
-        MethodNode sameSigMethodNode = classNode.getDeclaredMethod(methodName, parameters);
-
-        if (null == sameSigMethodNode) {
-            return;
-        }
-
-        throw createParsingFailedException("The method " +  sameSigMethodNode.getText() + " duplicates another method of the same signature", ctx);
-    }
-
-    private ConstructorNode createConstructorNodeForClass(String methodName, Parameter[] parameters, ClassNode[] exceptions, Statement code, ClassNode classNode, int modifiers) {
-        ConstructorCallExpression thisOrSuperConstructorCallExpression = this.checkThisAndSuperConstructorCall(code);
-        if (asBoolean(thisOrSuperConstructorCallExpression)) {
-            throw createParsingFailedException(thisOrSuperConstructorCallExpression.getText() + " should be the first statement in the constructor[" + methodName + "]", thisOrSuperConstructorCallExpression);
-        }
-
-        return classNode.addConstructor(
-                modifiers,
-                parameters,
-                exceptions,
-                code);
-    }
-
-    @Override
-    public String visitMethodName(MethodNameContext ctx) {
-        if (asBoolean(ctx.identifier())) {
-            return this.visitIdentifier(ctx.identifier());
-        }
-
-        if (asBoolean(ctx.stringLiteral())) {
-            return this.visitStringLiteral(ctx.stringLiteral()).getText();
-        }
-
-        throw createParsingFailedException("Unsupported method name: " + ctx.getText(), ctx);
-    }
-
-    @Override
-    public ClassNode visitReturnType(ReturnTypeContext ctx) {
-        if (!asBoolean(ctx)) {
-            return ClassHelper.OBJECT_TYPE;
-        }
-
-        if (asBoolean(ctx.type())) {
-            return this.visitType(ctx.type());
-        }
-
-        if (asBoolean(ctx.VOID())) {
-            return ClassHelper.VOID_TYPE;
-        }
-
-        throw createParsingFailedException("Unsupported return type: " + ctx.getText(), ctx);
-    }
-
-    @Override
-    public Statement visitMethodBody(MethodBodyContext ctx) {
-        if (!asBoolean(ctx)) {
-            return null;
-        }
-
-        return this.configureAST(this.visitBlock(ctx.block()), ctx);
-    }
-
-    @Override
-    public DeclarationListStatement visitLocalVariableDeclaration(LocalVariableDeclarationContext ctx) {
-        return this.configureAST(this.visitVariableDeclaration(ctx.variableDeclaration()), ctx);
-    }
-
-    private ModifierManager createModifierManager(VariableDeclarationContext ctx) {
-        List<ModifierNode> modifierNodeList = Collections.emptyList();
-
-        if (asBoolean(ctx.variableModifiers())) {
-            modifierNodeList = this.visitVariableModifiers(ctx.variableModifiers());
-        } else if (asBoolean(ctx.variableModifiersOpt())) {
-            modifierNodeList = this.visitVariableModifiersOpt(ctx.variableModifiersOpt());
-        } else if (asBoolean(ctx.modifiers())) {
-            modifierNodeList = this.visitModifiers(ctx.modifiers());
-        } else if (asBoolean(ctx.modifiersOpt())) {
-            modifierNodeList = this.visitModifiersOpt(ctx.modifiersOpt());
-        }
-
-        return new ModifierManager(this, modifierNodeList);
-    }
-
-    private DeclarationListStatement createMultiAssignmentDeclarationListStatement(VariableDeclarationContext ctx, ModifierManager modifierManager) {
-        if (!modifierManager.contains(DEF)) {
-            throw createParsingFailedException("keyword def is required to declare tuple, e.g. def (int a, int b) = [1, 2]", ctx);
-        }
-
-        return this.configureAST(
-                new DeclarationListStatement(
-                        this.configureAST(
-                                modifierManager.attachAnnotations(
-                                        new DeclarationExpression(
-                                                new ArgumentListExpression(
-                                                        this.visitTypeNamePairs(ctx.typeNamePairs()).stream()
-                                                                .peek(e -> modifierManager.processVariableExpression((VariableExpression) e))
-                                                                .collect(Collectors.toList())
-                                                ),
-                                                this.createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN),
-                                                this.visitVariableInitializer(ctx.variableInitializer())
-                                        )
-                                ),
-                                ctx
-                        )
-                ),
-                ctx
-        );
-    }
-
-    @Override
-    public DeclarationListStatement visitVariableDeclaration(VariableDeclarationContext ctx) {
-        ModifierManager modifierManager = this.createModifierManager(ctx);
-
-        if (asBoolean(ctx.typeNamePairs())) { // e.g. def (int a, int b) = [1, 2]
-            return this.createMultiAssignmentDeclarationListStatement(ctx, modifierManager);
-        }
-
-        ClassNode variableType = this.visitType(ctx.type());
-        ctx.variableDeclarators().putNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE, variableType);
-        List<DeclarationExpression> declarationExpressionList = this.visitVariableDeclarators(ctx.variableDeclarators());
-
-        // if classNode is not null, the variable declaration is for class declaration. In other words, it is a field declaration
-        ClassNode classNode = ctx.getNodeMetaData(CLASS_DECLARATION_CLASS_NODE);
-
-        if (asBoolean(classNode)) {
-            return createFieldDeclarationListStatement(ctx, modifierManager, variableType, declarationExpressionList, classNode);
-        }
-
-        declarationExpressionList.forEach(e -> {
-            VariableExpression variableExpression = (VariableExpression) e.getLeftExpression();
-
-            modifierManager.processVariableExpression(variableExpression);
-            modifierManager.attachAnnotations(e);
-        });
-
-        int size = declarationExpressionList.size();
-        if (size > 0) {
-            DeclarationExpression declarationExpression = declarationExpressionList.get(0);
-
-            if (1 == size) {
-                this.configureAST(declarationExpression, ctx);
-            } else {
-                // Tweak start of first declaration
-                declarationExpression.setLineNumber(ctx.getStart().getLine());
-                declarationExpression.setColumnNumber(ctx.getStart().getCharPositionInLine() + 1);
-            }
-        }
-
-        return this.configureAST(new DeclarationListStatement(declarationExpressionList), ctx);
-    }
-
-    private DeclarationListStatement createFieldDeclarationListStatement(VariableDeclarationContext ctx, ModifierManager modifierManager, ClassNode variableType, List<DeclarationExpression> declarationExpressionList, ClassNode classNode) {
-        declarationExpressionList.forEach(e -> {
-            VariableExpression variableExpression = (VariableExpression) e.getLeftExpression();
-
-            int modifiers = modifierManager.getClassMemberModifiersOpValue();
-
-            Expression initialValue = EmptyExpression.INSTANCE.equals(e.getRightExpression()) ? null : e.getRightExpression();
-            Object defaultValue = findDefaultValueByType(variableType);
-
-            if (classNode.isInterface()) {
-                if (!asBoolean(initialValue)) {
-                    initialValue = !asBoolean(defaultValue) ? null : new ConstantExpression(defaultValue);
-                }
-
-                modifiers |= Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
-            }
-
-            if (classNode.isInterface() || modifierManager.containsVisibilityModifier()) {
-                FieldNode fieldNode =
-                        classNode.addField(
-                                variableExpression.getName(),
-                                modifiers,
-                                variableType,
-                                initialValue);
-                modifierManager.attachAnnotations(fieldNode);
-
-                groovydocManager.handle(fieldNode, ctx);
-
-                this.configureAST(fieldNode, ctx);
-            } else {
-                PropertyNode propertyNode =
-                        classNode.addProperty(
-                                variableExpression.getName(),
-                                modifiers | Opcodes.ACC_PUBLIC,
-                                variableType,
-                                initialValue,
-                                null,
-                                null);
-
-                FieldNode fieldNode = propertyNode.getField();
-                fieldNode.setModifiers(modifiers & ~Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE);
-                fieldNode.setSynthetic(!classNode.isInterface());
-                modifierManager.attachAnnotations(fieldNode);
-
-                groovydocManager.handle(fieldNode, ctx);
-                groovydocManager.handle(propertyNode, ctx);
-
-                this.configureAST(fieldNode, ctx);
-                this.configureAST(propertyNode, ctx);
-            }
-
-        });
-
-        return null;
-    }
-
-    @Override
-    public List<Expression> visitTypeNamePairs(TypeNamePairsContext ctx) {
-        return ctx.typeNamePair().stream().map(this::visitTypeNamePair).collect(Collectors.toList());
-    }
-
-    @Override
-    public VariableExpression visitTypeNamePair(TypeNamePairContext ctx) {
-        return this.configureAST(
-                new VariableExpression(
-                        this.visitVariableDeclaratorId(ctx.variableDeclaratorId()).getName(),
-                        this.visitType(ctx.type())),
-                ctx);
-    }
-
-    @Override
-    public List<DeclarationExpression> visitVariableDeclarators(VariableDeclaratorsContext ctx) {
-        ClassNode variableType = ctx.getNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE);
-        Objects.requireNonNull(variableType, "variableType should not be null");
-
-        return ctx.variableDeclarator().stream()
-                .map(e -> {
-                    e.putNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE, variableType);
-                    return this.visitVariableDeclarator(e);
-//                    return this.configureAST(this.visitVariableDeclarator(e), ctx);
-                })
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public DeclarationExpression visitVariableDeclarator(VariableDeclaratorContext ctx) {
-        ClassNode variableType = ctx.getNodeMetaData(VARIABLE_DECLARATION_VARIABLE_TYPE);
-        Objects.requireNonNull(variableType, "variableType should not be null");
-
-        org.codehaus.groovy.syntax.Token token;
-        if (asBoolean(ctx.ASSIGN())) {
-            token = createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN);
-        } else {
-            token = new org.codehaus.groovy.syntax.Token(Types.ASSIGN, ASSIGN_STR, ctx.start.getLine(), 1);
-        }
-
-        return this.configureAST(
-                new DeclarationExpression(
-                        this.configureAST(
-                                new VariableExpression(
-                                        this.visitVariableDeclaratorId(ctx.variableDeclaratorId()).getName(),
-                                        variableType
-                                ),
-                                ctx.variableDeclaratorId()),
-                        token,
-                        this.visitVariableInitializer(ctx.variableInitializer())),
-                ctx);
-    }
-
-    @Override
-    public Expression visitVariableInitializer(VariableInitializerContext ctx) {
-        if (!asBoolean(ctx)) {
-            return EmptyExpression.INSTANCE;
-        }
-
-        if (asBoolean(ctx.statementExpression())) {
-            return this.configureAST(
-                    ((ExpressionStatement) this.visit(ctx.statementExpression())).getExpression(),
-                    ctx);
-        }
-
-        if (asBoolean(ctx.standardLambda())) {
-            return this.configureAST(this.visitStandardLambda(ctx.standardLambda()), ctx);
-        }
-
-        throw createParsingFailedException("Unsupported variable initializer: " + ctx.getText(), ctx);
-    }
-
-    @Override
-    public List<Expression> visitVariableInitializers(VariableInitializersContext ctx) {
-        if (!asBoolean(ctx)) {
-            return Collections.emptyList();
-        }
-
-        return ctx.variableInitializer().stream()
-                        .map(this::visitVariableInitializer)
-                        .collect(Collectors.toList());
-    }
-
-    @Override
-    public List<Expression> visitArrayInitializer(ArrayInitializerContext ctx) {
-        if (!asBoolean(ctx)) {
-            return Collections.emptyList();
-        }
-
-        return this.visitVariableInitializers(ctx.variableInitializers());
-    }
-
-    @Override
-    public Statement visitBlock(BlockContext ctx) {
-        if (!asBoolean(ctx)) {
-            return this.createBlockStatement();
-        }
-
-        return this.configureAST(
-                this.visitBlockStatementsOpt(ctx.blockStatementsOpt()),
-                ctx);
-    }
-
-
-    @Override
-    public ExpressionStatement visitNormalExprAlt(NormalExprAltContext ctx) {
-        return this.configureAST(new ExpressionStatement((Expression) this.visit(ctx.expression())), ctx);
-    }
-
-    @Override
-    public ExpressionStatement visitCommandExprAlt(CommandExprAltContext ctx) {
-        return this.configureAST(new ExpressionStatement(this.visitCommandExpression(ctx.commandExpression())), ctx);
-    }
-
-    @Override
-    public Expression visitCommandExpression(CommandExpressionContext ctx) {
-        Expression baseExpr = this.visitPathExpression(ctx.pathExpression());
-        Expression arguments = this.visitEnhancedArgumentList(ctx.enhancedArgumentList());
-
-        MethodCallExpression methodCallExpression;
-        if (baseExpr instanceof PropertyExpression) { // e.g. obj.a 1, 2
-            methodCallExpression =
-                    this.configureAST(
-                            this.createMethodCallExpression(
-                                    (PropertyExpression) baseExpr, arguments),
-                            arguments);
-
-        } else if (baseExpr instanceof MethodCallExpression && !isTrue(baseExpr, IS_INSIDE_PARENTHESES)) { // e.g. m {} a, b  OR  m(...) a, b
-            if (asBoolean(arguments)) {
-                // The error should never be thrown.
-                throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList");
-            }
-
-            methodCallExpression = (MethodCallExpression) baseExpr;
-        } else if (
-                !isTrue(baseExpr, IS_INSIDE_PARENTHESES)
-                        && (baseExpr instanceof VariableExpression /* e.g. m 1, 2 */
-                        || baseExpr instanceof GStringExpression /* e.g. "$m" 1, 2 */
-                        || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)) /* e.g. "m" 1, 2 */)
-                ) {
-            methodCallExpression =
-                    this.configureAST(
-                            this.createMethodCallExpression(baseExpr, arguments),
-                            arguments);
-        } else { // e.g. a[x] b, new A() b, etc.
-            methodCallExpression =
-                    this.configureAST(
-                            new MethodCallExpression(
-                                    baseExpr,
-                                    CALL_STR,
-                                    arguments
-                            ),
-                            arguments
-                    );
-
-            methodCallExpression.setImplicitThis(false);
-        }
-
-        if (!asBoolean(ctx.commandArgument())) {
-            return this.configureAST(methodCallExpression, ctx);
-        }
-
-        return this.configureAST(
-                (Expression) ctx.commandArgument().stream()
-                        .map(e -> (Object) e)
-                        .reduce(methodCallExpression,
-                                (r, e) -> {
-                                    CommandArgumentContext commandArgumentContext = (CommandArgumentContext) e;
-                                    commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r);
-
-                                    return this.visitCommandArgument(commandArgumentContext);
-                                }
-                        ),
-                ctx);
-    }
-
-    @Override
-    public Expression visitCommandArgument(CommandArgumentContext ctx) {
-        // e.g. x y a b     we call "x y" as the base expression
-        Expression baseExpr = ctx.getNodeMetaData(CMD_EXPRESSION_BASE_EXPR);
-
-        Expression primaryExpr = (Expression) this.visit(ctx.primary());
-
-        if (asBoolean(ctx.enhancedArgumentList())) { // e.g. x y a b
-            if (baseExpr instanceof PropertyExpression) { // the branch should never reach, because a.b.c will be parsed as a path expression, not a method call
-                throw createParsingFailedException("Unsupported command argument: " + ctx.getText(), ctx);
-            }
-
-            // the following code will process "a b" of "x y a b"
-            MethodCallExpression methodCallExpression =
-                    new MethodCallExpression(
-                            baseExpr,
-                            this.createConstantExpression(primaryExpr),
-                            this.visitEnhancedArgumentList(ctx.enhancedArgumentList())
-                    );
-            methodCallExpression.setImplicitThis(false);
-
-            return this.configureAST(methodCallExpression, ctx);
-        } else if (asBoolean(ctx.pathElement())) { // e.g. x y a.b
-            Expression pathExpression =
-                    this.createPathExpression(
-                            this.configureAST(
-                                    new PropertyExpression(baseExpr, this.createConstantExpression(primaryExpr)),
-                                    primaryExpr
-                            ),
-                            ctx.pathElement()
-                    );
-
-            return this.configureAST(pathExpression, ctx);
-        }
-
-        // e.g. x y a
-        return this.configureAST(
-                new PropertyExpression(
-                        baseExpr,
-                        primaryExpr instanceof VariableExpression
-                                ? this.createConstantExpression(primaryExpr)
-                                : primaryExpr
-                ),
-                primaryExpr
-        );
-    }
-
-
-    // expression {    --------------------------------------------------------------------
-
-    @Override
-    public ClassNode visitCastParExpression(CastParExpressionContext ctx) {
-        return this.visitType(ctx.type());
-    }
-
-    @Override
-    public Expression visitParExpression(ParExpressionContext ctx) {
-        Expression expression;
-
-        if (asBoolean(ctx.statementExpression())) {
-            expression = ((ExpressionStatement) this.visit(ctx.statementExpression())).getExpression();
-        } else if (asBoolean(ctx.standardLambda())) {
-            expression = this.visitStandardLambda(ctx.standardLambda());
-        } else {
-            throw createParsingFailedException("Unsupported parentheses expression: " + ctx.getText(), ctx);
-        }
-
-        expression.putNodeMetaData(IS_INSIDE_PARENTHESES, true);
-
-        Integer insideParenLevel = expression.getNodeMetaData(INSIDE_PARENTHESES_LEVEL);
-        if (asBoolean((Object) insideParenLevel)) {
-            insideParenLevel++;
-        } else {
-            insideParenLevel = 1;
-        }
-        expression.putNodeMetaData(INSIDE_PARENTHESES_LEVEL, insideParenLevel);
-
-        return this.configureAST(expression, ctx);
-    }
-
-    @Override
-    public Expression visitPathExpression(PathExpressionContext ctx) {
-        return this.configureAST(
-                this.createPathExpression((Expression) this.visit(ctx.primary()), ctx.pathElement()),
-                ctx);
-    }
-
-    @Override
-    public Expression visitPathElement(PathElementContext ctx) {
-        Expression baseExpr = ctx.getNodeMetaData(PATH_EXPRESSION_BASE_EXPR);
-        Objects.requireNonNull(baseExpr, "baseExpr is required!");
-
-        if (asBoolean(ctx.namePart())) {
-            Expression namePartExpr = this.visitNamePart(ctx.namePart());
-            GenericsType[] genericsTypes = this.visitNonWildcardTypeArguments(ctx.nonWildcardTypeArguments());
-
-
-            if (asBoolean(ctx.DOT())) {
-                if (asBoolean(ctx.AT())) { // e.g. obj.@a
-                    return this.configureAST(new AttributeExpression(baseExpr, namePartExpr), ctx);
-                } else { // e.g. obj.p
-                    PropertyExpression propertyExpression = new PropertyExpression(baseExpr, namePartExpr);
-                    propertyExpression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES, genericsTypes);
-
-                    return this.configureAST(propertyExpression, ctx);
-                }
-            } else if (asBoolean(ctx.SAFE_DOT())) {
-                if (asBoolean(ctx.AT())) { // e.g. obj?.@a
-                    return this.configureAST(new AttributeExpression(baseExpr, namePartExpr, true), ctx);
-                } else { // e.g. obj?.p
-                    PropertyExpression propertyExpression = new PropertyExpression(baseExpr, namePartExpr, true);
-                    propertyExpression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES, genericsTypes);
-
-                    return this.configureAST(propertyExpression, ctx);
-                }
-            } else if (asBoolean(ctx.METHOD_POINTER())) { // e.g. obj.&m
-                return this.configureAST(new MethodPointerExpression(baseExpr, namePartExpr), ctx);
-            } else if (asBoolean(ctx.METHOD_REFERENCE())) { // e.g. obj::m
-                return this.configureAST(new MethodReferenceExpression(baseExpr, namePartExpr), ctx);
-            } else if (asBoolean(ctx.SPREAD_DOT())) {
-                if (asBoolean(ctx.AT())) { // e.g. obj*.@a
-                    AttributeExpression attributeExpression = new AttributeExpression(baseExpr, namePartExpr, true);
-
-                    attributeExpression.setSpreadSafe(true);
-
-                    return this.configureAST(attributeExpression, ctx);
-                } else { // e.g. obj*.p
-                    PropertyExpression propertyExpression = new PropertyExpression(baseExpr, namePartExpr, true);
-                    propertyExpression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES, genericsTypes);
-
-                    propertyExpression.setSpreadSafe(true);
-
-                    return this.configureAST(propertyExpression, ctx);
-                }
-            }
-        }
-
-        if (asBoolean(ctx.indexPropertyArgs())) { // e.g. list[1, 3, 5]
-            Pair<Token, Expression> pair = this.visitIndexPropertyArgs(ctx.indexPropertyArgs());
-
-            return this.configureAST(
-                    new BinaryExpression(baseExpr, createGroovyToken(pair.getKey()), pair.getValue(), asBoolean(ctx.indexPropertyArgs().QUESTION())),
-                    ctx);
-        }
-
-        if (asBoolean(ctx.namedPropertyArgs())) { // this is a special way to new instance, e.g. Person(name: 'Daniel.Sun', location: 'Shanghai')
-            List<MapEntryExpression> mapEntryExpressionList =
-                    this.visitNamedPropertyArgs(ctx.namedPropertyArgs());
-
-            Expression right;
-            if (mapEntryExpressionList.size() == 1) {
-                MapEntryExpression mapEntryExpression = mapEntryExpressionList.get(0);
-
-                if (mapEntryExpression.getKeyExpression() instanceof SpreadMapExpression) {
-                    right = mapEntryExpression.getKeyExpression();
-                } else {
-                    right = mapEntryExpression;
-                }
-            } else {
-                ListExpression listExpression =
-                        this.configureAST(
-                                new ListExpression(
-                                        mapEntryExpressionList.stream()
-                                                .map(
-                                                        e -> {
-                                                            if (e.getKeyExpression() instanceof SpreadMapExpression) {
-                                                                return e.getKeyExpression();
-                                                            }
-
-                                                            return e;
-                                                        }
-                                                )
-                                                .collect(Collectors.toList())),
-                                ctx.namedPropertyArgs()
-                        );
-                listExpression.setWrapped(true);
-                right = listExpression;
-            }
-
-            return this.configureAST(
-                    new BinaryExpression(baseExpr, createGroovyToken(ctx.namedPropertyArgs().LBRACK().getSymbol()), right),
-                    ctx);
-        }
-
-        if (asBoolean(ctx.arguments())) {
-            Expression argumentsExpr = this.visitArguments(ctx.arguments());
-
-            if (isTrue(baseExpr, IS_INSIDE_PARENTHESES)) { // e.g. (obj.x)(), (obj.@x)()
-                MethodCallExpression methodCallExpression =
-                        new MethodCallExpression(
-                                baseExpr,
-                                CALL_STR,
-                                argumentsExpr
-                        );
-
-                methodCallExpression.setImplicitThis(false);
-
-                return this.configureAST(methodCallExpression, ctx);
-            }
-
-            if (baseExpr instanceof AttributeExpression) { // e.g. obj.@a(1, 2)
-                AttributeExpression attributeExpression = (AttributeExpression) baseExpr;
-                attributeExpression.setSpreadSafe(false); // whether attributeExpression is spread safe or not, we must reset it as false
-
-                MethodCallExpression methodCallExpression =
-                        new MethodCallExpression(
-                                attributeExpression,
-                                CALL_STR,
-                                argumentsExpr
-                        );
-
-                return this.configureAST(methodCallExpression, ctx);
-            }
-
-            if (baseExpr instanceof PropertyExpression) { // e.g. obj.a(1, 2)
-                MethodCallExpression methodCallExpression =
-                        this.createMethodCallExpression((PropertyExpression) baseExpr, argumentsExpr);
-
-                return this.configureAST(methodCallExpression, ctx);
-            }
-
-            if (baseExpr instanceof VariableExpression) { // void and primitive type AST node must be an instance of VariableExpression
-                String baseExprText = baseExpr.getText();
-                if (VOID_STR.equals(baseExprText)) { // e.g. void()
-                    MethodCallExpression methodCallExpression =
-                            new MethodCallExpression(
-                                    this.createConstantExpression(baseExpr),
-                                    CALL_STR,
-                                    argumentsExpr
-                            );
-
-                    methodCallExpression.setImplicitThis(false);
-
-                    return this.configureAST(methodCallExpression, ctx);
-                } else if (PRIMITIVE_TYPE_SET.contains(baseExprText)) { // e.g. int(), long(), float(), etc.
-                    throw createParsingFailedException("Primitive type literal: " + baseExprText + " cannot be used as a method name", ctx);
-                }
-            }
-
-            if (baseExpr instanceof VariableExpression
-                    || baseExpr instanceof GStringExpression
-                    || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING))) { // e.g. m(), "$m"(), "m"()
-
-          

<TRUNCATED>

Mime
View raw message