groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject [2/2] groovy git commit: Fix some tests which have not been covered by Parrot before
Date Fri, 05 May 2017 12:28:06 GMT
Fix some tests which have not been covered by Parrot before


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/6f41416f
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/6f41416f
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/6f41416f

Branch: refs/heads/master
Commit: 6f41416f24d322a7d169a771f817b1700d2937d2
Parents: e817651
Author: sunlan <sunlan@apache.org>
Authored: Fri May 5 20:26:01 2017 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Fri May 5 20:27:52 2017 +0800

----------------------------------------------------------------------
 src/test/groovy/bugs/Groovy4252Bug.groovy       |  12 +-
 src/test/groovy/bugs/Groovy8046Bug.groovy       |   9 +-
 .../codehaus/groovy/antlr/GStringEndTest.groovy |  12 +-
 .../apache/groovy/parser/antlr4/GroovyLexer.g4  |  25 +-
 .../apache/groovy/parser/antlr4/GroovyParser.g4 |  45 ++-
 .../parser/antlr4/util/GroovyTestRig.groovy     |   4 +-
 .../apache/groovy/parser/antlr4/AstBuilder.java | 375 +++++--------------
 .../groovy/parser/antlr4/GroovySyntaxError.java |  13 +-
 .../groovy/parser/antlr4/ModifierManager.java   | 198 ++++++++++
 .../groovy/parser/antlr4/ModifierNode.java      | 164 ++++++++
 .../groovy/parser/antlr4/PositionInfo.java      |  73 ++++
 .../parser/antlr4/SemanticPredicates.java       |   6 +-
 .../parser/antlr4/SyntaxErrorReportable.java    |  30 +-
 .../parser/antlr4/GroovyParserTest.groovy       | 308 +++++++--------
 .../groovy/parser/antlr4/SyntaxErrorTest.groovy |  35 +-
 .../resources/core/EnumDeclaration_04.groovy    |   4 +
 .../resources/core/EnumDeclaration_05.groovy    |   4 +
 .../src/test/resources/core/GString_04.groovy   |   1 +
 .../src/test/resources/core/GString_05.groovy   |   1 +
 .../src/test/resources/core/GString_06.groovy   |   1 +
 .../src/test/resources/core/Script_01x.groovy   |   5 +
 .../resources/fail/ClassDeclaration_01x.groovy  |   7 +
 .../fail/ClosureListExpression_01.groovy        |   1 +
 .../fail/ClosureListExpression_02.groovy        |   1 +
 .../fail/ClosureListExpression_03.groovy        |   1 +
 .../fail/ClosureListExpression_04.groovy        |  10 +
 .../fail/ConstructorDeclaration_01.groovy       |   1 +
 .../fail/InterfaceDeclaration_01.groovy         |   3 +
 .../resources/fail/MethodDeclaration_01.groovy  |   5 +
 .../src/test/resources/fail/Modifier_07.groovy  |   1 +
 .../src/test/resources/fail/Void_01x.groovy     |   3 +
 .../src/test/resources/fail/Void_02x.groovy     |   5 +
 32 files changed, 873 insertions(+), 490 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/src/test/groovy/bugs/Groovy4252Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy4252Bug.groovy b/src/test/groovy/bugs/Groovy4252Bug.groovy
index 20b2693..1641286 100644
--- a/src/test/groovy/bugs/Groovy4252Bug.groovy
+++ b/src/test/groovy/bugs/Groovy4252Bug.groovy
@@ -29,7 +29,8 @@ class Groovy4252Bug extends GroovyShellTestCase {
             fail("The compilation should have failed as expression list of form (a;b;c) is not supported in this context")
         } catch (MultipleCompilationErrorsException e) {
             def syntaxError = e.errorCollector.getSyntaxError(0)
-            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context")
+            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context") ||
+                    syntaxError.message.contains("Missing ')'")
         }
     }
 
@@ -41,7 +42,8 @@ class Groovy4252Bug extends GroovyShellTestCase {
             fail("The compilation should have failed as expression list of form (a;b;c) is not supported in this context")
         } catch (MultipleCompilationErrorsException e) {
             def syntaxError = e.errorCollector.getSyntaxError(0)
-            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context")
+            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context") ||
+                    syntaxError.message.contains("Missing ')'")
         }
     }
 
@@ -53,7 +55,8 @@ class Groovy4252Bug extends GroovyShellTestCase {
             fail("The compilation should have failed as expression list of form (a;b;c) is not supported in this context")
         } catch (MultipleCompilationErrorsException e) {
             def syntaxError = e.errorCollector.getSyntaxError(0)
-            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context")
+            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context") ||
+                    syntaxError.message.contains("Missing ')'")
         }
     }
 
@@ -74,7 +77,8 @@ class Groovy4252Bug extends GroovyShellTestCase {
             fail("The compilation should have failed as expression list of form (a;b;c) is not supported in this context")
         } catch (MultipleCompilationErrorsException e) {
             def syntaxError = e.errorCollector.getSyntaxError(0)
-            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context")
+            assert syntaxError.message.contains("Expression list of the form (a; b; c) is not supported in this context") ||
+                    syntaxError.message.contains("Missing ')'")
         }
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/src/test/groovy/bugs/Groovy8046Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8046Bug.groovy b/src/test/groovy/bugs/Groovy8046Bug.groovy
index c8bf633..3b81814 100644
--- a/src/test/groovy/bugs/Groovy8046Bug.groovy
+++ b/src/test/groovy/bugs/Groovy8046Bug.groovy
@@ -27,7 +27,8 @@ class Groovy8046Bug extends CompilableTestSupport {
                 void field
             }
         """
-        assert message.contains("The field 'field' has invalid type void")
+        assert message.contains("The field 'field' has invalid type void") ||
+                message.contains("void is not allowed here")
     }
 
     void testParameterShouldNotHavePrimitiveVoidType() {
@@ -36,7 +37,8 @@ class Groovy8046Bug extends CompilableTestSupport {
                 int foo(void param) {}
             }
         """
-        assert message.contains("The parameter 'param' in method 'int foo(void)' has invalid type void")
+        assert message.contains("The parameter 'param' in method 'int foo(void)' has invalid type void") ||
+                message.contains("void is not allowed here")
     }
 
     void testLocalVariableShouldNotHavePrimitiveVoidType() {
@@ -47,6 +49,7 @@ class Groovy8046Bug extends CompilableTestSupport {
                 }
             }
         """
-        assert message.contains("The variable 'bar' has invalid type void")
+        assert message.contains("The variable 'bar' has invalid type void") ||
+                message.contains("void is not allowed here")
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/src/test/org/codehaus/groovy/antlr/GStringEndTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/antlr/GStringEndTest.groovy b/src/test/org/codehaus/groovy/antlr/GStringEndTest.groovy
index b8f380f..fc7f98e 100644
--- a/src/test/org/codehaus/groovy/antlr/GStringEndTest.groovy
+++ b/src/test/org/codehaus/groovy/antlr/GStringEndTest.groovy
@@ -1,3 +1,7 @@
+package org.codehaus.groovy.antlr
+
+import org.codehaus.groovy.antlr.parser.GroovyLexer
+
 /*
  *  Licensed to the Apache Software Foundation (ASF) under one
  *  or more contributor license agreements.  See the NOTICE file
@@ -16,10 +20,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-import org.codehaus.groovy.control.*
-import org.codehaus.groovy.antlr.parser.GroovyLexer
-
-import antlr.TokenStreamRecognitionException;
+import org.codehaus.groovy.control.MultipleCompilationErrorsException;
 
 class GStringEndTest extends GroovyTestCase {
     void testInvalidEndContainsLineNumber(){
@@ -29,7 +30,8 @@ class GStringEndTest extends GroovyTestCase {
             '''
         } catch (MultipleCompilationErrorsException mcee) {
             def text = mcee.toString();
-            assert text.contains("line 2, column 41")
+            assert text.contains("line 2, column 41") ||  // the old parser
+                        text.contains("line 2, column 40") // parrot: column 40 is more accurate than the original 41
         }
     }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4 b/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
index ec7a08d..cdcfeea 100644
--- a/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
+++ b/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyLexer.g4
@@ -153,8 +153,7 @@ options {
 
         require(null != paren, "Too many '" + text + "'");
         require(text.equals(PAREN_MAP.get(paren.getText())),
-                "'" + text + "' " + genPositionInfo() + " can not match '" + paren.getText() + "' " + formatPositionInfo(paren.getLine(), paren.getColumn()),
-                false);
+                "'" + paren.getText() + "'" + new PositionInfo(paren.getLine(), paren.getColumn()) + " can not match '" + text + "'");
 
         parenStack.pop();
     }
@@ -190,8 +189,13 @@ options {
     }
 
     @Override
-    public String genPositionInfo() {
-        return formatPositionInfo(getLine(), getCharPositionInLine() + 1);
+    public int getErrorLine() {
+        return getLine();
+    }
+
+    @Override
+    public int getErrorColumn() {
+        return getCharPositionInLine() + 1;
     }
 }
 
@@ -282,7 +286,14 @@ GStringPathPart
     :   '.' IdentifierInGString
     ;
 RollBackOne
-    :   . -> popMode, channel(HIDDEN)
+    :   . {
+            // a trick to handle GStrings followed by EOF properly
+            if (EOF == _input.LA(1) && ('"' == _input.LA(-1) || '/' == _input.LA(-1))) {
+                setType(GStringEnd);
+            } else {
+                setChannel(HIDDEN);
+            }
+          } -> popMode
     ;
 
 
@@ -771,14 +782,14 @@ ELVIS_ASSIGN    : '?=';
 CapitalizedIdentifier
     :   [A-Z] JavaLetterOrDigit*
 
-    // Groovy's identifier can be unicode escape
+    // FIXME REMOVE THE FOLLOWING ALTERNATIVE. Groovy's identifier can be unicode escape(e.g. def \u4e00\u9fa5 = '123'), which will impact the performance and is pointless to support IMO
     |   [A-Z] (JavaLetterOrDigit | UnicodeEscape)*
     ;
 
 Identifier
     :   JavaLetter JavaLetterOrDigit*
 
-    // Groovy's identifier can be unicode escape
+    // FIXME REMOVE THE FOLLOWING ALTERNATIVE. Groovy's identifier can be unicode escape(e.g. def \u4e00\u9fa5 = '123'), which will impact the performance and is pointless to support IMO
     |   (JavaLetter | UnicodeEscape) (JavaLetterOrDigit | UnicodeEscape)*
     ;
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4 b/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
index 75129c9..6775320 100644
--- a/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
+++ b/subprojects/groovy-parser-antlr4/src/main/antlr4/org/apache/groovy/parser/antlr4/GroovyParser.g4
@@ -111,14 +111,25 @@ options {
     }
 
     @Override
-    public String genPositionInfo() {
+    public int getErrorLine() {
         Token token = _input.LT(-1);
 
         if (null == token) {
-            return "";
+            return -1;
         }
 
-        return formatPositionInfo(token.getLine(), token.getCharPositionInLine() + 1 + token.getText().length());
+        return token.getLine();
+    }
+
+    @Override
+    public int getErrorColumn() {
+        Token token = _input.LT(-1);
+
+        if (null == token) {
+            return -1;
+        }
+
+        return token.getCharPositionInLine() + 1 + token.getText().length();
     }
 }
 
@@ -369,7 +380,11 @@ options { baseContext = type; }
     ;
 
 type
-    :   primitiveType (LBRACK RBRACK)*
+    :   (   primitiveType
+        |
+            // !!! ERROR ALTERNATIVE !!!
+            VOID { require(false, "void is not allowed here", -4); }
+        ) (LBRACK RBRACK)*
     |   generalClassOrInterfaceType (LBRACK RBRACK)*
     ;
 
@@ -631,7 +646,7 @@ locals[ boolean isInsideLoop ]
     }
 }
     :   CONTINUE
-        { $isInsideLoop }?<fail={"the continue statement is only allowed inside loops"}>
+        { require($isInsideLoop, "the continue statement is only allowed inside loops", -8); }
         identifier?
     ;
 
@@ -651,7 +666,7 @@ locals[ boolean isInsideLoop, boolean isInsideSwitch ]
     }
 }
     :   BREAK
-        { $isInsideLoop || $isInsideSwitch }?<fail={"the break statement is only allowed inside loops or switches"}>
+        { require($isInsideLoop || $isInsideSwitch, "the break statement is only allowed inside loops or switches", -5); }
         identifier?
     ;
 
@@ -750,7 +765,15 @@ switchLabel
 
 forControl
     :   enhancedForControl
-    |   forInit? SEMI expression? SEMI forUpdate?
+    |   classicalForControl
+    ;
+
+enhancedForControl
+    :   variableModifiersOpt type? variableDeclaratorId (COLON | IN) expression
+    ;
+
+classicalForControl
+    :   forInit? SEMI expression? SEMI forUpdate?
     ;
 
 forInit
@@ -762,10 +785,6 @@ forUpdate
     :   expressionList[false]
     ;
 
-enhancedForControl
-    :   variableModifiersOpt type? variableDeclaratorId (COLON | IN) expression
-    ;
-
 
 // EXPRESSIONS
 
@@ -782,7 +801,7 @@ expressionList[boolean canSpread]
     ;
 
 expressionListElement[boolean canSpread]
-    :   (   MUL { $canSpread }?<fail={"spread is not allowed here"}>
+    :   (   MUL { require($canSpread, "spread operator is not allowed here", -1); }
         |
         ) expression
     ;
@@ -1061,7 +1080,7 @@ locals[boolean empty = true]
         )?
         (
             COMMA
-            { !$empty }?<fail={"Empty list constructor should not contain any comma(,)"}>
+            { require(!$empty, "Empty list constructor should not contain any comma(,)", -1); }
         )?
         RBRACK
     ;

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/groovy/org/apache/groovy/parser/antlr4/util/GroovyTestRig.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/groovy/org/apache/groovy/parser/antlr4/util/GroovyTestRig.groovy b/subprojects/groovy-parser-antlr4/src/main/groovy/org/apache/groovy/parser/antlr4/util/GroovyTestRig.groovy
index 243f460..798ed5f 100644
--- a/subprojects/groovy-parser-antlr4/src/main/groovy/org/apache/groovy/parser/antlr4/util/GroovyTestRig.groovy
+++ b/subprojects/groovy-parser-antlr4/src/main/groovy/org/apache/groovy/parser/antlr4/util/GroovyTestRig.groovy
@@ -34,7 +34,7 @@ import org.apache.groovy.parser.antlr4.GroovyLangParser
 @Log
 public class GroovyTestRig extends TestRig {
     public GroovyTestRig(String[] args) throws Exception {
-        super(['Groovy', 'compilationUnit', *args] as String[]);
+        super(['Groovy', args.contains('-lexer') ? 'tokens' : 'compilationUnit', *args] as String[]);
     }
 
     public void inspectParseTree() {
@@ -57,7 +57,7 @@ public class GroovyTestRig extends TestRig {
 
     public static void main(String[] args) {
         if (args.length == 0) {
-            log.info "Usage: [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname] [-trace] [-diagnostics] [-SLL] input-filename";
+            log.info "Usage: [-tokens] [-lexer] [-tree] [-gui] [-ps file.ps] [-encoding encodingname] [-trace] [-diagnostics] [-SLL] input-filename";
             return;
         }
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/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
index a02286f..087c291 100644
--- 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
@@ -35,10 +35,10 @@ 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.AnnotatedNode;
 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;
@@ -391,14 +391,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             return this.visitEnhancedForControl(ctx.enhancedForControl());
         }
 
-        if (asBoolean(ctx.SEMI())) { // e.g. for(int i = 0; i < 10; i++) {}
-            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);
+        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);
@@ -459,6 +453,16 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         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) {
@@ -850,7 +854,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         List<ModifierNode> modifierNodeList = ctx.getNodeMetaData(TYPE_DECLARATION_MODIFIERS);
         Objects.requireNonNull(modifierNodeList, "modifierNodeList should not be null");
 
-        ModifierManager modifierManager = new ModifierManager(modifierNodeList);
+        ModifierManager modifierManager = new ModifierManager(this, modifierNodeList);
         int modifiers = modifierManager.getClassModifiersOpValue();
 
         boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
@@ -1065,11 +1069,24 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             }
 
             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();
-            listExpression.addExpression(expression);
+
+            if (expression instanceof ListExpression) {
+                ((ListExpression) expression).getExpressions().forEach(listExpression::addExpression);
+            } else {
+                listExpression.addExpression(expression);
+            }
+
             listExpression.addExpression(
                     this.configureAST(
                             new ClassExpression(anonymousInnerClassNode),
@@ -1214,7 +1231,19 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             modifierNodeList = this.visitModifiersOpt(ctx.modifiersOpt());
         }
 
-        return new ModifierManager(modifierNodeList);
+        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
@@ -1233,6 +1262,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         // 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);
@@ -1254,14 +1285,14 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
 
         this.configureAST(methodNode, ctx);
 
-        validateMethodDeclaration(ctx, methodNode);
+        validateMethodDeclaration(ctx, methodNode, modifierManager);
 
         groovydocManager.handle(methodNode, ctx);
 
         return methodNode;
     }
 
-    private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode methodNode) {
+    private void validateMethodDeclaration(MethodDeclarationContext ctx, MethodNode methodNode, ModifierManager modifierManager) {
         boolean isAbstractMethod = methodNode.isAbstract();
         boolean hasMethodBody = asBoolean(methodNode.getCode());
 
@@ -1274,6 +1305,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
                 throw createParsingFailedException("You defined a method[" + methodNode.getName() + "] without body. Try adding a method body, or declare it abstract", 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) {
@@ -1320,25 +1357,36 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         }
 
         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 MethodNode createConstructorNodeForClass(String methodName, Parameter[] parameters, ClassNode[] exceptions, Statement code, ClassNode classNode, int modifiers) {
-        MethodNode methodNode;ConstructorCallExpression thisOrSuperConstructorCallExpression = this.checkThisAndSuperConstructorCall(code);
+    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);
         }
 
-        methodNode =
-                classNode.addConstructor(
-                        modifiers,
-                        parameters,
-                        exceptions,
-                        code);
-        return methodNode;
+        return classNode.addConstructor(
+                modifiers,
+                parameters,
+                exceptions,
+                code);
     }
 
     @Override
@@ -1398,7 +1446,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
             modifierNodeList = this.visitModifiersOpt(ctx.modifiersOpt());
         }
 
-        return new ModifierManager(modifierNodeList);
+        return new ModifierManager(this, modifierNodeList);
     }
 
     private DeclarationListStatement createMultiAssignmentDeclarationListStatement(VariableDeclarationContext ctx, ModifierManager modifierManager) {
@@ -3434,7 +3482,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         }
 
         if (asBoolean(ctx.statement())) {
-            return (Statement) this.visit(ctx.statement()); //this.configureAST((Statement) this.visit(ctx.statement()), ctx);
+            Object astNode = this.visit(ctx.statement()); //this.configureAST((Statement) this.visit(ctx.statement()), ctx);
+
+            if (astNode instanceof MethodNode) {
+                throw createParsingFailedException("Method definition not expected here", ctx);
+            } else {
+                return (Statement) astNode;
+            }
         }
 
         throw createParsingFailedException("Unsupported block statement: " + ctx.getText(), ctx);
@@ -3673,7 +3727,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         }
 
         Parameter parameter =
-                new ModifierManager(this.visitVariableModifiersOpt(variableModifiersOptContext))
+                new ModifierManager(this, this.visitVariableModifiersOpt(variableModifiersOptContext))
                         .processParameter(
                                 this.configureAST(
                                         new Parameter(classNode, this.visitVariableDeclaratorId(variableDeclaratorIdContext).getName()),
@@ -4051,6 +4105,15 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
     private CompilationFailedException createParsingFailedException(Throwable t) {
         if (t instanceof SyntaxException) {
             this.collectSyntaxError((SyntaxException) t);
+        } else if (t instanceof GroovySyntaxError) {
+            GroovySyntaxError groovySyntaxError = (GroovySyntaxError) t;
+
+            this.collectSyntaxError(
+                    new SyntaxException(
+                            groovySyntaxError.getMessage(),
+                            groovySyntaxError,
+                            groovySyntaxError.getLine(),
+                            groovySyntaxError.getColumn()));
         } else if (t instanceof Exception) {
             this.collectException((Exception) t);
         }
@@ -4198,266 +4261,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
         }
     }
 
-    /**
-     * Process modifiers for AST nodes
-     * <p>
-     * Created by Daniel.Sun on 2016/08/27.
-     */
-    private class ModifierManager {
-        private List<ModifierNode> modifierNodeList;
-
-        public ModifierManager(List<ModifierNode> modifierNodeList) {
-            this.validate(modifierNodeList);
-            this.modifierNodeList = Collections.unmodifiableList(asBoolean((Object) modifierNodeList) ? modifierNodeList : Collections.emptyList());
-        }
-
-        private void validate(List<ModifierNode> modifierNodeList) {
-            Map<ModifierNode, Integer> modifierNodeCounter = new LinkedHashMap<>(modifierNodeList.size());
-            int visibilityModifierCnt = 0;
-
-            for (ModifierNode modifierNode : modifierNodeList) {
-                Integer cnt = modifierNodeCounter.get(modifierNode);
-
-                if (null == cnt) {
-                    modifierNodeCounter.put(modifierNode, 1);
-                } else if (1 == cnt && !modifierNode.isRepeatable()) {
-                    throw createParsingFailedException("Cannot repeat modifier[" + modifierNode.getText() + "]", modifierNode);
-                }
-
-                if (modifierNode.isVisibilityModifier()) {
-                    visibilityModifierCnt++;
-
-                    if (visibilityModifierCnt > 1) {
-                        throw createParsingFailedException("Cannot specify modifier[" + modifierNode.getText() + "] when access scope has already been defined", modifierNode);
-                    }
-                }
-            }
-        }
-
-        // t    1: class modifiers value; 2: class member modifiers value
-        private int calcModifiersOpValue(int t) {
-            int result = 0;
-
-            for (ModifierNode modifierNode : modifierNodeList) {
-                result |= modifierNode.getOpcode();
-            }
-
-            if (!this.containsVisibilityModifier()) {
-                if (1 == t) {
-                    result |= Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC;
-                } else if (2 == t) {
-                    result |= Opcodes.ACC_PUBLIC;
-                }
-            }
-
-            return result;
-        }
-
-        public int getClassModifiersOpValue() {
-            return this.calcModifiersOpValue(1);
-        }
-
-        public int getClassMemberModifiersOpValue() {
-            return this.calcModifiersOpValue(2);
-        }
-
-        public List<AnnotationNode> getAnnotations() {
-            return modifierNodeList.stream()
-                    .filter(ModifierNode::isAnnotation)
-                    .map(ModifierNode::getAnnotationNode)
-                    .collect(Collectors.toList());
-        }
-
-        public boolean contains(int modifierType) {
-            return modifierNodeList.stream().anyMatch(e -> modifierType == e.getType());
-        }
-
-        public boolean containsAnnotations() {
-            return modifierNodeList.stream().anyMatch(ModifierNode::isAnnotation);
-        }
-
-        public boolean containsVisibilityModifier() {
-            return modifierNodeList.stream().anyMatch(ModifierNode::isVisibilityModifier);
-        }
-
-        public boolean containsNonVisibilityModifier() {
-            return modifierNodeList.stream().anyMatch(ModifierNode::isNonVisibilityModifier);
-        }
-
-        public Parameter processParameter(Parameter parameter) {
-            modifierNodeList.forEach(e -> {
-                parameter.setModifiers(parameter.getModifiers() | e.getOpcode());
-
-                if (e.isAnnotation()) {
-                    parameter.addAnnotation(e.getAnnotationNode());
-                }
-            });
-
-            return parameter;
-        }
-
-        public MethodNode processMethodNode(MethodNode mn) {
-            modifierNodeList.forEach(e -> {
-                mn.setModifiers(mn.getModifiers() | e.getOpcode());
-
-                if (e.isAnnotation()) {
-                    mn.addAnnotation(e.getAnnotationNode());
-                }
-            });
-
-            return mn;
-        }
-
-        public VariableExpression processVariableExpression(VariableExpression ve) {
-            modifierNodeList.forEach(e -> {
-                ve.setModifiers(ve.getModifiers() | e.getOpcode());
-
-                // local variable does not attach annotations
-            });
-
-            return ve;
-        }
-
-        public <T extends AnnotatedNode> T attachAnnotations(T node) {
-            this.getAnnotations().forEach(node::addAnnotation);
-
-            return node;
-        }
-    }
-
-    /**
-     * Represents a modifier, which is better to place in the package org.codehaus.groovy.ast
-     * <p>
-     * Created by Daniel.Sun on 2016/08/23.
-     */
-    public static class ModifierNode extends ASTNode {
-        private Integer type;
-        private Integer opcode; // ASM opcode
-        private String text;
-        private AnnotationNode annotationNode;
-        private boolean repeatable;
-
-        public static final int ANNOTATION_TYPE = -999;
-        public static final Map<Integer, Integer> MODIFIER_OPCODE_MAP = Collections.unmodifiableMap(new HashMap<Integer, Integer>() {
-            {
-                put(ANNOTATION_TYPE, 0);
-                put(DEF, 0);
-
-                put(NATIVE, Opcodes.ACC_NATIVE);
-                put(SYNCHRONIZED, Opcodes.ACC_SYNCHRONIZED);
-                put(TRANSIENT, Opcodes.ACC_TRANSIENT);
-                put(VOLATILE, Opcodes.ACC_VOLATILE);
-
-                put(PUBLIC, Opcodes.ACC_PUBLIC);
-                put(PROTECTED, Opcodes.ACC_PROTECTED);
-                put(PRIVATE, Opcodes.ACC_PRIVATE);
-                put(STATIC, Opcodes.ACC_STATIC);
-                put(ABSTRACT, Opcodes.ACC_ABSTRACT);
-                put(FINAL, Opcodes.ACC_FINAL);
-                put(STRICTFP, Opcodes.ACC_STRICT);
-                put(DEFAULT, 0); // no flag for specifying a default method in the JVM spec, hence no ACC_DEFAULT flag in ASM
-            }
-        });
-
-        public ModifierNode(Integer type) {
-            this.type = type;
-            this.opcode = MODIFIER_OPCODE_MAP.get(type);
-            this.repeatable = ANNOTATION_TYPE == type; // Only annotations are repeatable
-
-            if (!asBoolean((Object) this.opcode)) {
-                throw new IllegalArgumentException("Unsupported modifier type: " + type);
-            }
-        }
-
-        /**
-         * @param type the modifier type, which is same as the token type
-         * @param text text of the ast node
-         */
-        public ModifierNode(Integer type, String text) {
-            this(type);
-            this.text = text;
-        }
-
-        /**
-         * @param annotationNode the annotation node
-         * @param text           text of the ast node
-         */
-        public ModifierNode(AnnotationNode annotationNode, String text) {
-            this(ModifierNode.ANNOTATION_TYPE, text);
-            this.annotationNode = annotationNode;
-
-            if (!asBoolean(annotationNode)) {
-                throw new IllegalArgumentException("annotationNode can not be null");
-            }
-        }
-
-        /**
-         * Check whether the modifier is not an imagined modifier(annotation, def)
-         */
-        public boolean isModifier() {
-            return !this.isAnnotation() && !this.isDef();
-        }
-
-        public boolean isVisibilityModifier() {
-            return Objects.equals(PUBLIC, this.type)
-                    || Objects.equals(PROTECTED, this.type)
-                    || Objects.equals(PRIVATE, this.type);
-        }
-
-        public boolean isNonVisibilityModifier() {
-            return this.isModifier() && !this.isVisibilityModifier();
-        }
-
-        public boolean isAnnotation() {
-            return Objects.equals(ANNOTATION_TYPE, this.type);
-        }
-
-        public boolean isDef() {
-            return Objects.equals(DEF, this.type);
-        }
-
-        public Integer getType() {
-            return type;
-        }
-
-        public Integer getOpcode() {
-            return opcode;
-        }
-
-        public boolean isRepeatable() {
-            return repeatable;
-        }
-
-        @Override
-        public String getText() {
-            return text;
-        }
-
-        public AnnotationNode getAnnotationNode() {
-            return annotationNode;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            ModifierNode that = (ModifierNode) o;
-            return Objects.equals(type, that.type) &&
-                    Objects.equals(text, that.text) &&
-                    Objects.equals(annotationNode, that.annotationNode);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, text, annotationNode);
-        }
-
-        @Override
-        public String toString() {
-            return this.text;
-        }
-    }
-
     private final ModuleNode moduleNode;
     private final SourceUnit sourceUnit;
     private final ClassLoader classLoader; // Our ClassLoader, which provides information on external types

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
index 12bb63d..7ca8bba 100644
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/GroovySyntaxError.java
@@ -25,8 +25,10 @@ public class GroovySyntaxError extends AssertionError {
     public static final int LEXER = 0;
     public static final int PARSER = 1;
     private int source;
+    private int line;
+    private int column;
 
-    public GroovySyntaxError(String message, int source) {
+    public GroovySyntaxError(String message, int source, int line, int column) {
         super(message, null);
 
         if (source != LEXER && source != PARSER) {
@@ -34,9 +36,18 @@ public class GroovySyntaxError extends AssertionError {
         }
 
         this.source = source;
+        this.line = line;
+        this.column = column;
     }
 
     public int getSource() {
         return source;
     }
+    public int getLine() {
+        return line;
+    }
+
+    public int getColumn() {
+        return column;
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
new file mode 100644
index 0000000..a45e36c
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierManager.java
@@ -0,0 +1,198 @@
+/*
+ *  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 org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.objectweb.asm.Opcodes;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.apache.groovy.parser.antlr4.GroovyParser.*;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
+
+/**
+ * Process modifiers for AST nodes
+ * <p>
+ * Created by Daniel.Sun on 2016/08/27.
+ */
+class ModifierManager {
+    private static final Map<Class, List<Integer>> INVALID_MODIFIERS_MAP = Collections.unmodifiableMap(new HashMap<Class, List<Integer>>() {
+        {
+            put(ConstructorNode.class, Arrays.asList(STATIC, FINAL, ABSTRACT, NATIVE));
+            put(MethodNode.class, Arrays.asList(VOLATILE/*, TRANSIENT*/));
+        }
+    });
+    private AstBuilder astBuilder;
+    private List<ModifierNode> modifierNodeList;
+
+    public ModifierManager(AstBuilder astBuilder, List<ModifierNode> modifierNodeList) {
+        this.astBuilder = astBuilder;
+        this.validate(modifierNodeList);
+        this.modifierNodeList = Collections.unmodifiableList(asBoolean((Object) modifierNodeList) ? modifierNodeList : Collections.emptyList());
+    }
+
+    private void validate(List<ModifierNode> modifierNodeList) {
+        Map<ModifierNode, Integer> modifierNodeCounter = new LinkedHashMap<>(modifierNodeList.size());
+        int visibilityModifierCnt = 0;
+
+        for (ModifierNode modifierNode : modifierNodeList) {
+            Integer cnt = modifierNodeCounter.get(modifierNode);
+
+            if (null == cnt) {
+                modifierNodeCounter.put(modifierNode, 1);
+            } else if (1 == cnt && !modifierNode.isRepeatable()) {
+                throw astBuilder.createParsingFailedException("Cannot repeat modifier[" + modifierNode.getText() + "]", modifierNode);
+            }
+
+            if (modifierNode.isVisibilityModifier()) {
+                visibilityModifierCnt++;
+
+                if (visibilityModifierCnt > 1) {
+                    throw astBuilder.createParsingFailedException("Cannot specify modifier[" + modifierNode.getText() + "] when access scope has already been defined", modifierNode);
+                }
+            }
+        }
+    }
+
+    public void validate(MethodNode methodNode) {
+        validate(INVALID_MODIFIERS_MAP.get(MethodNode.class), methodNode);
+    }
+
+    public void validate(ConstructorNode constructorNode) {
+        validate(INVALID_MODIFIERS_MAP.get(ConstructorNode.class), constructorNode);
+    }
+
+    private void validate(List<Integer> invalidModifierList, MethodNode methodNode) {
+        modifierNodeList.forEach(e -> {
+            if (invalidModifierList.contains(e.getType())) {
+                throw astBuilder.createParsingFailedException(methodNode.getClass().getSimpleName().replace("Node", "") + " has an incorrect modifier '" + e + "'.", methodNode);
+            }
+        });
+    }
+
+    // t    1: class modifiers value; 2: class member modifiers value
+    private int calcModifiersOpValue(int t) {
+        int result = 0;
+
+        for (ModifierNode modifierNode : modifierNodeList) {
+            result |= modifierNode.getOpcode();
+        }
+
+        if (!this.containsVisibilityModifier()) {
+            if (1 == t) {
+                result |= Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC;
+            } else if (2 == t) {
+                result |= Opcodes.ACC_PUBLIC;
+            }
+        }
+
+        return result;
+    }
+
+    public int getClassModifiersOpValue() {
+        return this.calcModifiersOpValue(1);
+    }
+
+    public int getClassMemberModifiersOpValue() {
+        return this.calcModifiersOpValue(2);
+    }
+
+    public List<AnnotationNode> getAnnotations() {
+        return modifierNodeList.stream()
+                .filter(ModifierNode::isAnnotation)
+                .map(ModifierNode::getAnnotationNode)
+                .collect(Collectors.toList());
+    }
+
+    public boolean contains(int modifierType) {
+        return modifierNodeList.stream().anyMatch(e -> modifierType == e.getType());
+    }
+
+    public Optional<ModifierNode> get(int modifierType) {
+        return modifierNodeList.stream().filter(e -> modifierType == e.getType()).findFirst();
+    }
+
+    public boolean containsAnnotations() {
+        return modifierNodeList.stream().anyMatch(ModifierNode::isAnnotation);
+    }
+
+    public boolean containsVisibilityModifier() {
+        return modifierNodeList.stream().anyMatch(ModifierNode::isVisibilityModifier);
+    }
+
+    public boolean containsNonVisibilityModifier() {
+        return modifierNodeList.stream().anyMatch(ModifierNode::isNonVisibilityModifier);
+    }
+
+    public Parameter processParameter(Parameter parameter) {
+        modifierNodeList.forEach(e -> {
+            parameter.setModifiers(parameter.getModifiers() | e.getOpcode());
+
+            if (e.isAnnotation()) {
+                parameter.addAnnotation(e.getAnnotationNode());
+            }
+        });
+
+        return parameter;
+    }
+
+    public int clearVisibilityModifiers(int modifiers) {
+        return modifiers & ~Opcodes.ACC_PUBLIC & ~Opcodes.ACC_PROTECTED & ~Opcodes.ACC_PRIVATE;
+    }
+
+    public MethodNode processMethodNode(MethodNode mn) {
+        modifierNodeList.forEach(e -> {
+            mn.setModifiers((e.isVisibilityModifier() ? clearVisibilityModifiers(mn.getModifiers()) : mn.getModifiers()) | e.getOpcode());
+
+            if (e.isAnnotation()) {
+                mn.addAnnotation(e.getAnnotationNode());
+            }
+        });
+
+        return mn;
+    }
+
+    public VariableExpression processVariableExpression(VariableExpression ve) {
+        modifierNodeList.forEach(e -> {
+            ve.setModifiers(ve.getModifiers() | e.getOpcode());
+
+            // local variable does not attach annotations
+        });
+
+        return ve;
+    }
+
+    public <T extends AnnotatedNode> T attachAnnotations(T node) {
+        this.getAnnotations().forEach(node::addAnnotation);
+
+        return node;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierNode.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierNode.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierNode.java
new file mode 100644
index 0000000..5d1007b
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/ModifierNode.java
@@ -0,0 +1,164 @@
+/*
+ *  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 org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.objectweb.asm.Opcodes;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.apache.groovy.parser.antlr4.GroovyParser.*;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
+
+/**
+ * Represents a modifier, which is better to place in the package org.codehaus.groovy.ast
+ * <p>
+ * Created by Daniel.Sun on 2016/08/23.
+ */
+public class ModifierNode extends ASTNode {
+    private Integer type;
+    private Integer opcode; // ASM opcode
+    private String text;
+    private AnnotationNode annotationNode;
+    private boolean repeatable;
+
+    public static final int ANNOTATION_TYPE = -999;
+    public static final Map<Integer, Integer> MODIFIER_OPCODE_MAP = Collections.unmodifiableMap(new HashMap<Integer, Integer>() {
+        {
+            put(ANNOTATION_TYPE, 0);
+            put(DEF, 0);
+
+            put(NATIVE, Opcodes.ACC_NATIVE);
+            put(SYNCHRONIZED, Opcodes.ACC_SYNCHRONIZED);
+            put(TRANSIENT, Opcodes.ACC_TRANSIENT);
+            put(VOLATILE, Opcodes.ACC_VOLATILE);
+
+            put(PUBLIC, Opcodes.ACC_PUBLIC);
+            put(PROTECTED, Opcodes.ACC_PROTECTED);
+            put(PRIVATE, Opcodes.ACC_PRIVATE);
+            put(STATIC, Opcodes.ACC_STATIC);
+            put(ABSTRACT, Opcodes.ACC_ABSTRACT);
+            put(FINAL, Opcodes.ACC_FINAL);
+            put(STRICTFP, Opcodes.ACC_STRICT);
+            put(DEFAULT, 0); // no flag for specifying a default method in the JVM spec, hence no ACC_DEFAULT flag in ASM
+        }
+    });
+
+    public ModifierNode(Integer type) {
+        this.type = type;
+        this.opcode = MODIFIER_OPCODE_MAP.get(type);
+        this.repeatable = ANNOTATION_TYPE == type; // Only annotations are repeatable
+
+        if (!asBoolean((Object) this.opcode)) {
+            throw new IllegalArgumentException("Unsupported modifier type: " + type);
+        }
+    }
+
+    /**
+     * @param type the modifier type, which is same as the token type
+     * @param text text of the ast node
+     */
+    public ModifierNode(Integer type, String text) {
+        this(type);
+        this.text = text;
+    }
+
+    /**
+     * @param annotationNode the annotation node
+     * @param text           text of the ast node
+     */
+    public ModifierNode(AnnotationNode annotationNode, String text) {
+        this(ModifierNode.ANNOTATION_TYPE, text);
+        this.annotationNode = annotationNode;
+
+        if (!asBoolean(annotationNode)) {
+            throw new IllegalArgumentException("annotationNode can not be null");
+        }
+    }
+
+    /**
+     * Check whether the modifier is not an imagined modifier(annotation, def)
+     */
+    public boolean isModifier() {
+        return !this.isAnnotation() && !this.isDef();
+    }
+
+    public boolean isVisibilityModifier() {
+        return Objects.equals(PUBLIC, this.type)
+                || Objects.equals(PROTECTED, this.type)
+                || Objects.equals(PRIVATE, this.type);
+    }
+
+    public boolean isNonVisibilityModifier() {
+        return this.isModifier() && !this.isVisibilityModifier();
+    }
+
+    public boolean isAnnotation() {
+        return Objects.equals(ANNOTATION_TYPE, this.type);
+    }
+
+    public boolean isDef() {
+        return Objects.equals(DEF, this.type);
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public Integer getOpcode() {
+        return opcode;
+    }
+
+    public boolean isRepeatable() {
+        return repeatable;
+    }
+
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    public AnnotationNode getAnnotationNode() {
+        return annotationNode;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ModifierNode that = (ModifierNode) o;
+        return Objects.equals(type, that.type) &&
+                Objects.equals(text, that.text) &&
+                Objects.equals(annotationNode, that.annotationNode);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, text, annotationNode);
+    }
+
+    @Override
+    public String toString() {
+        return this.text;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/PositionInfo.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/PositionInfo.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/PositionInfo.java
new file mode 100644
index 0000000..b59aabb
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/PositionInfo.java
@@ -0,0 +1,73 @@
+/*
+ *  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 java.util.Objects;
+
+/**
+ * Created by Daniel on 2017/4/22.
+ */
+public class PositionInfo {
+    private int line;
+    private int column;
+
+    public PositionInfo(int line, int column) {
+        this.line = line;
+        this.column = column;
+    }
+
+    public int getLine() {
+        return line;
+    }
+
+    public void setLine(int line) {
+        this.line = line;
+    }
+
+    public int getColumn() {
+        return column;
+    }
+
+    public void setColumn(int column) {
+        this.column = column;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PositionInfo that = (PositionInfo) o;
+        return line == that.line &&
+                column == that.column;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(line, column);
+    }
+
+    @Override
+    public String toString() {
+        if (-1 == line || -1 == column) {
+            return "";
+        }
+
+        return " @ line " + line + ", column " + column;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
index 811276f..eb3dbd9 100644
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
@@ -109,7 +109,7 @@ public class SemanticPredicates {
     }
 
     private static final Set<Integer> MODIFIER_SET =
-            Collections.unmodifiableSet(AstBuilder.ModifierNode.MODIFIER_OPCODE_MAP.keySet());
+            Collections.unmodifiableSet(ModifierNode.MODIFIER_OPCODE_MAP.keySet());
     /**
      * Distinguish between local variable declaration and method call, e.g. `a b`
      */
@@ -142,8 +142,8 @@ public class SemanticPredicates {
         tokenType = token.getType();
         tokenType3 = ts.LT(index + 2).getType();
 
-        return VOID == tokenType
-                ||  !(BuiltInPrimitiveType == tokenType || MODIFIER_SET.contains(tokenType))
+        return //VOID == tokenType ||
+                !(BuiltInPrimitiveType == tokenType || MODIFIER_SET.contains(tokenType))
                     && Character.isLowerCase(token.getText().codePointAt(0))
                     && !(ASSIGN == tokenType3 || (LT == tokenType2 || LBRACK == tokenType2));
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
index e79c73c..021e2f5 100644
--- a/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
+++ b/subprojects/groovy-parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/SyntaxErrorReportable.java
@@ -22,25 +22,37 @@ package org.apache.groovy.parser.antlr4;
  * A SyntaxErrorReportable is a recognizer that can report syntax error
  */
 public interface SyntaxErrorReportable {
-    default void require(boolean condition, String msg, boolean toAttachPositionInfo) {
+    default void require(boolean condition, String msg, int offset, boolean toAttachPositionInfo) {
         if (condition) {
             return;
         }
 
-        this.throwSyntaxError(msg, toAttachPositionInfo);
+        this.throwSyntaxError(msg, offset, toAttachPositionInfo);
+    }
+    default void require(boolean condition, String msg, boolean toAttachPositionInfo) {
+        require(condition, msg, 0, toAttachPositionInfo);
+    }
+    default void require(boolean condition, String msg, int offset) {
+        require(condition, msg, offset,false);
     }
     default void require(boolean condition, String msg) {
-        require(condition, msg, true);
+        require(condition, msg, false);
     }
 
-    default void throwSyntaxError(String msg, boolean toAttachPositionInfo) {
-        throw new GroovySyntaxError(msg + (toAttachPositionInfo ? this.genPositionInfo() : ""), this.getSyntaxErrorSource());
+    default void throwSyntaxError(String msg, int offset, boolean toAttachPositionInfo) {
+        PositionInfo positionInfo = this.genPositionInfo(offset);
+        throw new GroovySyntaxError(msg + (toAttachPositionInfo ? positionInfo.toString() : ""),
+                this.getSyntaxErrorSource(),
+                positionInfo.getLine(),
+                positionInfo.getColumn()
+        );
     }
 
-    default String formatPositionInfo(int line, int column) {
-        return " @ line " + line + ", column " + column;
+    int getSyntaxErrorSource();
+    default PositionInfo genPositionInfo(int offset) {
+        return new PositionInfo(getErrorLine(), getErrorColumn() + offset);
     }
 
-    int getSyntaxErrorSource();
-    String genPositionInfo();
+    int getErrorLine();
+    int getErrorColumn();
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 0750c37..6892237 100644
--- a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -18,18 +18,11 @@
  */
 package org.apache.groovy.parser.antlr4
 
-import org.codehaus.groovy.ast.ClassNode
-import org.codehaus.groovy.ast.FieldNode
-import org.codehaus.groovy.ast.MethodNode
-import org.codehaus.groovy.ast.Parameter
-import org.codehaus.groovy.ast.PropertyNode
+import org.codehaus.groovy.ast.*
 import org.codehaus.groovy.ast.stmt.AssertStatement
 import org.codehaus.groovy.ast.stmt.ExpressionStatement
 import org.codehaus.groovy.syntax.Token
 
-import static org.apache.groovy.parser.antlr4.TestUtils.doTest
-import static org.apache.groovy.parser.antlr4.TestUtils.doRunAndTest
-
 /**
  * Some basic test cases for the new parser
  *
@@ -43,12 +36,12 @@ class GroovyParserTest extends GroovyTestCase {
     void tearDown() {}
 
     void "test groovy core - Comments"() {
-        doTest('core/Comments_01.groovy', [ExpressionStatement]);
+        TestUtils.doTest('core/Comments_01.groovy', [ExpressionStatement]);
         doTestAttachedComments();
     }
 
     private static doTestAttachedComments() {
-        def (newAST, oldAST) = doTest('core/Comments_02.groovy');
+        def (newAST, oldAST) = TestUtils.doTest('core/Comments_02.groovy');
         List<ClassNode> classes = new ArrayList<>(newAST.classes).sort { c1, c2 -> c1.name <=> c2.name };
         List<MethodNode> methods = new ArrayList<>(newAST.methods).sort { m1, m2 -> m1.name <=> m2.name };
 
@@ -83,276 +76,285 @@ class GroovyParserTest extends GroovyTestCase {
     }
 
     void "test groovy core - PackageDeclaration"() {
-        doTest('core/PackageDeclaration_01.groovy');
-        doTest('core/PackageDeclaration_02.groovy');
-        doTest('core/PackageDeclaration_03.groovy');
-        doTest('core/PackageDeclaration_04.groovy');
-        doTest('core/PackageDeclaration_05.groovy');
-        doTest('core/PackageDeclaration_06.groovy');
+        TestUtils.doTest('core/PackageDeclaration_01.groovy');
+        TestUtils.doTest('core/PackageDeclaration_02.groovy');
+        TestUtils.doTest('core/PackageDeclaration_03.groovy');
+        TestUtils.doTest('core/PackageDeclaration_04.groovy');
+        TestUtils.doTest('core/PackageDeclaration_05.groovy');
+        TestUtils.doTest('core/PackageDeclaration_06.groovy');
     }
 
     void "test groovy core - ImportDeclaration"() {
-        doTest('core/ImportDeclaration_01.groovy');
-        doTest('core/ImportDeclaration_02.groovy');
-        doTest('core/ImportDeclaration_03.groovy');
-        doTest('core/ImportDeclaration_04.groovy');
-        doTest('core/ImportDeclaration_05.groovy');
-        doTest('core/ImportDeclaration_06.groovy');
-        doTest('core/ImportDeclaration_07.groovy');
-        doTest('core/ImportDeclaration_08.groovy');
+        TestUtils.doTest('core/ImportDeclaration_01.groovy');
+        TestUtils.doTest('core/ImportDeclaration_02.groovy');
+        TestUtils.doTest('core/ImportDeclaration_03.groovy');
+        TestUtils.doTest('core/ImportDeclaration_04.groovy');
+        TestUtils.doTest('core/ImportDeclaration_05.groovy');
+        TestUtils.doTest('core/ImportDeclaration_06.groovy');
+        TestUtils.doTest('core/ImportDeclaration_07.groovy');
+        TestUtils.doTest('core/ImportDeclaration_08.groovy');
     }
 
     void "test groovy core - Annotation"() {
-        doTest('core/Annotation_01.groovy');
-        doTest('core/Annotation_02.groovy');
-        doTest('core/Annotation_03.groovy');
-        doTest('core/Annotation_04.groovy');
-        doTest('core/Annotation_05.groovy');
-        doTest('core/Annotation_06.groovy');
-        doTest('core/Annotation_07.groovy');
-        doTest('core/Annotation_08.groovy');
-        doTest('core/Annotation_09.groovy');
-        doRunAndTest('core/Annotation_10x.groovy');
+        TestUtils.doTest('core/Annotation_01.groovy');
+        TestUtils.doTest('core/Annotation_02.groovy');
+        TestUtils.doTest('core/Annotation_03.groovy');
+        TestUtils.doTest('core/Annotation_04.groovy');
+        TestUtils.doTest('core/Annotation_05.groovy');
+        TestUtils.doTest('core/Annotation_06.groovy');
+        TestUtils.doTest('core/Annotation_07.groovy');
+        TestUtils.doTest('core/Annotation_08.groovy');
+        TestUtils.doTest('core/Annotation_09.groovy');
+        TestUtils.doRunAndTest('core/Annotation_10x.groovy');
     }
 
     void "test groovy core - Literal"() {
-        doTest('core/Literal_01.groovy');
-        doTest('core/Literal_02.groovy', [ExpressionStatement]);
-        doTest('core/Literal_03.groovy');
+        TestUtils.doTest('core/Literal_01.groovy');
+        TestUtils.doTest('core/Literal_02.groovy', [ExpressionStatement]);
+        TestUtils.doTest('core/Literal_03.groovy');
     }
 
     void "test groovy core - GString"() {
-        doTest('core/GString_01.groovy');
-        doTest('core/GString_02.groovy');
-        doTest('core/GString_03.groovy');
+        TestUtils.doTest('core/GString_01.groovy');
+        TestUtils.doTest('core/GString_02.groovy');
+        TestUtils.doTest('core/GString_03.groovy');
+        TestUtils.doTest('core/GString_04.groovy');
+        TestUtils.doTest('core/GString_05.groovy');
+        TestUtils.doTest('core/GString_06.groovy');
     }
 
     void "test groovy core - Closure"() {
-        doTest('core/Closure_01.groovy');
-        doTest('core/Closure_02.groovy');
-        doTest('core/Closure_03.groovy');
-        doTest('core/Closure_04.groovy');
-        doTest('core/Closure_05.groovy', [Parameter]);
-        doTest('core/Closure_06.groovy', [Parameter]);
-        doTest('core/Closure_07.groovy', [Parameter]);
-        doTest('core/Closure_08.groovy', [Parameter]);
-        doTest('core/Closure_09.groovy', [Parameter]);
-        doTest('core/Closure_10.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_01.groovy');
+        TestUtils.doTest('core/Closure_02.groovy');
+        TestUtils.doTest('core/Closure_03.groovy');
+        TestUtils.doTest('core/Closure_04.groovy');
+        TestUtils.doTest('core/Closure_05.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_06.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_07.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_08.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_09.groovy', [Parameter]);
+        TestUtils.doTest('core/Closure_10.groovy', [Parameter]);
     }
 
     void "test groovy core - Lambda"() {
-        doRunAndTest('core/Lambda_01x.groovy');
+        TestUtils.doRunAndTest('core/Lambda_01x.groovy');
     }
 
     void "test groovy core - MethodReference"() {
-        doRunAndTest('core/MethodReference_01x.groovy');
+        TestUtils.doRunAndTest('core/MethodReference_01x.groovy');
     }
 
     void "test groovy core - MethodPointer"() {
-        doRunAndTest('core/MethodPointer_01x.groovy');
+        TestUtils.doRunAndTest('core/MethodPointer_01x.groovy');
     }
 
     void "test groovy core - ElvisAssignment"() {
-        doRunAndTest('core/ElvisAssignment_01x.groovy');
+        TestUtils.doRunAndTest('core/ElvisAssignment_01x.groovy');
     }
 
     void "test groovy core - List"() {
-        doTest('core/List_01.groovy');
+        TestUtils.doTest('core/List_01.groovy');
     }
 
     void "test groovy core - Map"() {
-        doTest('core/Map_01.groovy');
+        TestUtils.doTest('core/Map_01.groovy');
     }
 
     void "test groovy core - Expression"() {
-        doTest('core/Expression_01.groovy');
-        doTest('core/Expression_02.groovy');
-        doTest('core/Expression_03.groovy');
-        doTest('core/Expression_04.groovy');
-        doTest('core/Expression_05.groovy');
-        doTest('core/Expression_06.groovy');
-        doTest('core/Expression_07.groovy');
-        doTest('core/Expression_08.groovy');
-        doTest('core/Expression_09.groovy');
-        doTest('core/Expression_10.groovy');
-        doTest('core/Expression_11.groovy');
-        doTest('core/Expression_12.groovy');
-        doTest('core/Expression_13.groovy');
-        doTest('core/Expression_14.groovy');
-        doTest('core/Expression_15.groovy');
-        doTest('core/Expression_16.groovy', [Parameter, ExpressionStatement]);
-        doTest('core/Expression_17.groovy');
-        doTest('core/Expression_18.groovy');
-        doTest('core/Expression_19.groovy');
-        doTest('core/Expression_20.groovy');
-        doRunAndTest('core/Expression_21x.groovy');
-        doTest('core/Expression_22x.groovy');
-        doRunAndTest('core/Expression_22x.groovy');
-        doRunAndTest('core/Expression_23x.groovy');
+        TestUtils.doTest('core/Expression_01.groovy');
+        TestUtils.doTest('core/Expression_02.groovy');
+        TestUtils.doTest('core/Expression_03.groovy');
+        TestUtils.doTest('core/Expression_04.groovy');
+        TestUtils.doTest('core/Expression_05.groovy');
+        TestUtils.doTest('core/Expression_06.groovy');
+        TestUtils.doTest('core/Expression_07.groovy');
+        TestUtils.doTest('core/Expression_08.groovy');
+        TestUtils.doTest('core/Expression_09.groovy');
+        TestUtils.doTest('core/Expression_10.groovy');
+        TestUtils.doTest('core/Expression_11.groovy');
+        TestUtils.doTest('core/Expression_12.groovy');
+        TestUtils.doTest('core/Expression_13.groovy');
+        TestUtils.doTest('core/Expression_14.groovy');
+        TestUtils.doTest('core/Expression_15.groovy');
+        TestUtils.doTest('core/Expression_16.groovy', [Parameter, ExpressionStatement]);
+        TestUtils.doTest('core/Expression_17.groovy');
+        TestUtils.doTest('core/Expression_18.groovy');
+        TestUtils.doTest('core/Expression_19.groovy');
+        TestUtils.doTest('core/Expression_20.groovy');
+        TestUtils.doRunAndTest('core/Expression_21x.groovy');
+        TestUtils.doTest('core/Expression_22x.groovy');
+        TestUtils.doRunAndTest('core/Expression_22x.groovy');
+        TestUtils.doRunAndTest('core/Expression_23x.groovy');
     }
 
     void "test groovy core - IdenticalOp"() {
-        doRunAndTest('core/IdenticalOp_01x.groovy');
+        TestUtils.doRunAndTest('core/IdenticalOp_01x.groovy');
     }
 
     void "test groovy core - Assert"() {
-        doTest('core/Assert_01.groovy');
-        doRunAndTest('core/Assert_02x.groovy');
-        doRunAndTest('core/Assert_03x.groovy');
+        TestUtils.doTest('core/Assert_01.groovy');
+        TestUtils.doRunAndTest('core/Assert_02x.groovy');
+        TestUtils.doRunAndTest('core/Assert_03x.groovy');
     }
 
     void "test groovy core - IfElse"() {
-        doTest('core/IfElse_01.groovy', [AssertStatement]);
+        TestUtils.doTest('core/IfElse_01.groovy', [AssertStatement]);
     }
 
     void "test groovy core - For"() {
-        doTest('core/For_01.groovy', [AssertStatement]);
-        doTest('core/For_02.groovy');
-        doTest('core/For_03.groovy');
-        doRunAndTest('core/For_04x.groovy');
-        doRunAndTest('core/For_05x.groovy');
+        TestUtils.doTest('core/For_01.groovy', [AssertStatement]);
+        TestUtils.doTest('core/For_02.groovy');
+        TestUtils.doTest('core/For_03.groovy');
+        TestUtils.doRunAndTest('core/For_04x.groovy');
+        TestUtils.doRunAndTest('core/For_05x.groovy');
     }
 
     void "test groovy core - While"() {
-        doTest('core/While_01.groovy');
-        doRunAndTest('core/While_02x.groovy');
+        TestUtils.doTest('core/While_01.groovy');
+        TestUtils.doRunAndTest('core/While_02x.groovy');
     }
 
     void "test groovy core - CodeBlock"() {
-        doRunAndTest('core/CodeBlock_01x.groovy');
+        TestUtils.doRunAndTest('core/CodeBlock_01x.groovy');
     }
 
     void "test groovy core - DoWhile"() {
-        doRunAndTest('core/DoWhile_01x.groovy');
-        doRunAndTest('core/DoWhile_02x.groovy');
-        doRunAndTest('core/DoWhile_03x.groovy');
-        doRunAndTest('core/DoWhile_04x.groovy');
+        TestUtils.doRunAndTest('core/DoWhile_01x.groovy');
+        TestUtils.doRunAndTest('core/DoWhile_02x.groovy');
+        TestUtils.doRunAndTest('core/DoWhile_03x.groovy');
+        TestUtils.doRunAndTest('core/DoWhile_04x.groovy');
     }
 
 
     void "test groovy core - TryCatch"() {
-        doTest('core/TryCatch_01.groovy');
+        TestUtils.doTest('core/TryCatch_01.groovy');
     }
 
     void "test groovy core - TryWithResources"() {
-        doRunAndTest('core/TryWithResources_01x.groovy');
+        TestUtils.doRunAndTest('core/TryWithResources_01x.groovy');
     }
 
     void "test groovy core - SafeIndex"() {
-        doRunAndTest('core/SafeIndex_01x.groovy');
-        doRunAndTest('core/SafeIndex_02x.groovy');
-        doRunAndTest('core/SafeIndex_03x.groovy');
+        TestUtils.doRunAndTest('core/SafeIndex_01x.groovy');
+        TestUtils.doRunAndTest('core/SafeIndex_02x.groovy');
+        TestUtils.doRunAndTest('core/SafeIndex_03x.groovy');
     }
 
     void "test groovy core - NegativeRelationalOperators"() {
-        doRunAndTest('core/NegativeRelationalOperators_01x.groovy');
-        doRunAndTest('core/NegativeRelationalOperators_02x.groovy');
+        TestUtils.doRunAndTest('core/NegativeRelationalOperators_01x.groovy');
+        TestUtils.doRunAndTest('core/NegativeRelationalOperators_02x.groovy');
     }
 
     void "test groovy core - DefaultMethod"() {
-        doRunAndTest('core/DefaultMethod_01x.groovy');
-        doRunAndTest('core/DefaultMethod_02x.groovy');
+        TestUtils.doRunAndTest('core/DefaultMethod_01x.groovy');
+        TestUtils.doRunAndTest('core/DefaultMethod_02x.groovy');
     }
 
 
     void "test groovy core - Switch"() {
-        doTest('core/Switch_01.groovy');
+        TestUtils.doTest('core/Switch_01.groovy');
     }
 
     void "test groovy core - Synchronized"() {
-        doTest('core/Synchronized_01.groovy');
+        TestUtils.doTest('core/Synchronized_01.groovy');
     }
 
     void "test groovy core - Return"() {
-        doTest('core/Return_01.groovy');
+        TestUtils.doTest('core/Return_01.groovy');
     }
 
     void "test groovy core - Throw"() {
-        doTest('core/Throw_01.groovy');
+        TestUtils.doTest('core/Throw_01.groovy');
     }
 
     void "test groovy core - Label"() {
-        doTest('core/Label_01.groovy');
+        TestUtils.doTest('core/Label_01.groovy');
     }
 
     void "test groovy core - LocalVariableDeclaration"() {
-        doTest('core/LocalVariableDeclaration_01.groovy', [Token]); // [class org.codehaus.groovy.syntax.Token][startLine]:: 9 != 8
+        TestUtils.doTest('core/LocalVariableDeclaration_01.groovy', [Token]); // [class org.codehaus.groovy.syntax.Token][startLine]:: 9 != 8
     }
 
     void "test groovy core - MethodDeclaration"() {
-        doTest('core/MethodDeclaration_01.groovy');
-        doTest('core/MethodDeclaration_02.groovy');
+        TestUtils.doTest('core/MethodDeclaration_01.groovy');
+        TestUtils.doTest('core/MethodDeclaration_02.groovy');
     }
 
     void "test groovy core - ClassDeclaration"() {
-        doTest('core/ClassDeclaration_01.groovy');
-        doTest('core/ClassDeclaration_02.groovy');
-        doTest('core/ClassDeclaration_03.groovy');
-        doTest('core/ClassDeclaration_04.groovy', [PropertyNode, FieldNode]);
-        doTest('core/ClassDeclaration_05.groovy', [ExpressionStatement]);
-        doTest('core/ClassDeclaration_06.groovy');
-        doTest('core/ClassDeclaration_07.groovy');
+        TestUtils.doTest('core/ClassDeclaration_01.groovy');
+        TestUtils.doTest('core/ClassDeclaration_02.groovy');
+        TestUtils.doTest('core/ClassDeclaration_03.groovy');
+        TestUtils.doTest('core/ClassDeclaration_04.groovy', [PropertyNode, FieldNode]);
+        TestUtils.doTest('core/ClassDeclaration_05.groovy', [ExpressionStatement]);
+        TestUtils.doTest('core/ClassDeclaration_06.groovy');
+        TestUtils.doTest('core/ClassDeclaration_07.groovy');
     }
 
     void "test groovy core - InterfaceDeclaration"() {
-        doTest('core/InterfaceDeclaration_01.groovy');
-        doTest('core/InterfaceDeclaration_02.groovy');
-        doTest('core/InterfaceDeclaration_03.groovy');
+        TestUtils.doTest('core/InterfaceDeclaration_01.groovy');
+        TestUtils.doTest('core/InterfaceDeclaration_02.groovy');
+        TestUtils.doTest('core/InterfaceDeclaration_03.groovy');
     }
 
     void "test groovy core - EnumDeclaration"() {
-        doTest('core/EnumDeclaration_01.groovy');
-        doTest('core/EnumDeclaration_02.groovy', [ExpressionStatement]);
-        doTest('core/EnumDeclaration_03.groovy');
+        TestUtils.doTest('core/EnumDeclaration_01.groovy');
+        TestUtils.doTest('core/EnumDeclaration_02.groovy', [ExpressionStatement]);
+        TestUtils.doTest('core/EnumDeclaration_03.groovy');
+        TestUtils.doTest('core/EnumDeclaration_04.groovy');
+        TestUtils.doTest('core/EnumDeclaration_05.groovy');
     }
 
     void "test groovy core - TraitDeclaration"() {
-        doTest('core/TraitDeclaration_01.groovy');
-        doTest('core/TraitDeclaration_02.groovy');
-        doTest('core/TraitDeclaration_03.groovy');
-        doTest('core/TraitDeclaration_04.groovy', [PropertyNode, FieldNode]);
-        doTest('core/TraitDeclaration_05.groovy');
+        TestUtils.doTest('core/TraitDeclaration_01.groovy');
+        TestUtils.doTest('core/TraitDeclaration_02.groovy');
+        TestUtils.doTest('core/TraitDeclaration_03.groovy');
+        TestUtils.doTest('core/TraitDeclaration_04.groovy', [PropertyNode, FieldNode]);
+        TestUtils.doTest('core/TraitDeclaration_05.groovy');
     }
 
     void "test groovy core - AnnotationDeclaration"() {
-        doTest('core/AnnotationDeclaration_01.groovy');
+        TestUtils.doTest('core/AnnotationDeclaration_01.groovy');
     }
 
     void "test groovy core - Command"() {
-        doTest('core/Command_01.groovy');
-        doTest('core/Command_02.groovy');
-        doTest('core/Command_03.groovy', [ExpressionStatement, Parameter]);
-        doTest('core/Command_04.groovy', [ExpressionStatement]);
-        doTest('core/Command_05.groovy');
-        doRunAndTest('core/Command_06x.groovy')
+        TestUtils.doTest('core/Command_01.groovy');
+        TestUtils.doTest('core/Command_02.groovy');
+        TestUtils.doTest('core/Command_03.groovy', [ExpressionStatement, Parameter]);
+        TestUtils.doTest('core/Command_04.groovy', [ExpressionStatement]);
+        TestUtils.doTest('core/Command_05.groovy');
+        TestUtils.doRunAndTest('core/Command_06x.groovy')
     }
 
     void "test groovy core - Unicode"() {
-        doTest('core/Unicode_01.groovy');
+        TestUtils.doTest('core/Unicode_01.groovy');
     }
 
     void "test groovy core - BreakingChanges"() {
-        doRunAndTest('core/BreakingChange_01x.groovy');
-        doRunAndTest('core/BreakingChange_02x.groovy');
-        doRunAndTest('core/BreakingChange_03x.groovy');
-        doRunAndTest('core/BreakingChange_04x.groovy');
+        TestUtils.doRunAndTest('core/BreakingChange_01x.groovy');
+        TestUtils.doRunAndTest('core/BreakingChange_02x.groovy');
+        TestUtils.doRunAndTest('core/BreakingChange_03x.groovy');
+        TestUtils.doRunAndTest('core/BreakingChange_04x.groovy');
     }
 
     void "test groovy core - Array"() {
-        doRunAndTest('core/Array_01x.groovy');
+        TestUtils.doRunAndTest('core/Array_01x.groovy');
     }
 
     void "test groovy core - Groovydoc"() {
-        doRunAndTest('core/Groovydoc_01x.groovy');
+        TestUtils.doRunAndTest('core/Groovydoc_01x.groovy');
+    }
+
+    void "test groovy core - Script"() {
+        TestUtils.doRunAndTest('core/Script_01x.groovy');
     }
 
     void "test groovy core - BUG"() {
-        doRunAndTest('bugs/BUG-GROOVY-4757.groovy');
-        doRunAndTest('bugs/GROOVY-3898.groovy');
-        doRunAndTest('bugs/BUG-GROOVY-5652.groovy');
-        doRunAndTest('bugs/BUG-GROOVY-4762.groovy');
-        doRunAndTest('bugs/BUG-GROOVY-4438.groovy');
-        doRunAndTest('bugs/BUG-GROOVY-6038.groovy');
-        doRunAndTest('bugs/BUG-GROOVY-2324.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-4757.groovy');
+        TestUtils.doRunAndTest('bugs/GROOVY-3898.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-5652.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-4762.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-4438.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-6038.groovy');
+        TestUtils.doRunAndTest('bugs/BUG-GROOVY-2324.groovy');
     }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
index 3514c75..67a68f8 100644
--- a/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
+++ b/subprojects/groovy-parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
@@ -20,9 +20,6 @@ package org.apache.groovy.parser.antlr4
 
 import org.apache.groovy.parser.antlr4.util.ASTComparatorCategory
 
-import static org.apache.groovy.parser.antlr4.TestUtils.COMMON_IGNORE_CLASS_LIST
-import static org.apache.groovy.parser.antlr4.TestUtils.shouldFail
-
 /**
  * Some syntax error test cases for the new parser
  *
@@ -141,11 +138,41 @@ class SyntaxErrorTest extends GroovyTestCase {
         TestUtils.doRunAndShouldFail('fail/Modifier_03x.groovy');
         TestUtils.doRunAndShouldFail('fail/Modifier_04x.groovy');
         TestUtils.doRunAndShouldFail('fail/Modifier_05x.groovy');
+        TestUtils.shouldFail('fail/Modifier_07.groovy');
+    }
+
+    void "test groovy core - ClassDeclaration"() {
+        TestUtils.doRunAndShouldFail('fail/ClassDeclaration_01x.groovy');
+    }
+
+    void "test groovy core - MethodDeclaration"() {
+        TestUtils.shouldFail('fail/MethodDeclaration_01.groovy');
+    }
+
+    void "test groovy core - ConstructorDeclaration"() {
+        TestUtils.shouldFail('fail/ConstructorDeclaration_01.groovy');
     }
 
+    void "test groovy core - ClosureListExpression"() {
+        TestUtils.shouldFail('fail/ClosureListExpression_01.groovy');
+        TestUtils.shouldFail('fail/ClosureListExpression_02.groovy');
+        TestUtils.shouldFail('fail/ClosureListExpression_03.groovy');
+        TestUtils.shouldFail('fail/ClosureListExpression_04.groovy');
+    }
+
+    void "test groovy core - InterfaceDeclaration"() {
+        TestUtils.shouldFail('fail/InterfaceDeclaration_01.groovy');
+    }
+
+    void "test groovy core - void"() {
+        TestUtils.doRunAndShouldFail('fail/Void_01x.groovy');
+        TestUtils.doRunAndShouldFail('fail/Void_02x.groovy');
+    }
+
+
     /**************************************/
     static unzipScriptAndShouldFail(String entryName, List ignoreClazzList, Map<String, String> replacementsMap=[:], boolean toCheckNewParserOnly = false) {
-        ignoreClazzList.addAll(COMMON_IGNORE_CLASS_LIST)
+        ignoreClazzList.addAll(TestUtils.COMMON_IGNORE_CLASS_LIST)
 
         TestUtils.unzipAndFail(SCRIPT_ZIP_PATH, entryName, TestUtils.addIgnore(ignoreClazzList, ASTComparatorCategory.LOCATION_IGNORE_LIST), replacementsMap, toCheckNewParserOnly)
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_04.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_04.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_04.groovy
new file mode 100644
index 0000000..e25feb0
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_04.groovy
@@ -0,0 +1,4 @@
+enum ListEnum1 {
+    ONE([111, 222])
+    ListEnum1(Object listArg){}
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_05.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_05.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_05.groovy
new file mode 100644
index 0000000..f53e0d3
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/EnumDeclaration_05.groovy
@@ -0,0 +1,4 @@
+enum ListEnum1 {
+    ONE([111, 222]) {}
+    ListEnum1(Object listArg){}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_04.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_04.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_04.groovy
new file mode 100644
index 0000000..00a8c02
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_04.groovy
@@ -0,0 +1 @@
+"At $date"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_05.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_05.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_05.groovy
new file mode 100644
index 0000000..67e5f5e
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_05.groovy
@@ -0,0 +1 @@
+"""At $date"""
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_06.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_06.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_06.groovy
new file mode 100644
index 0000000..e1446b9
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/GString_06.groovy
@@ -0,0 +1 @@
+/At $date/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/6f41416f/subprojects/groovy-parser-antlr4/src/test/resources/core/Script_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-parser-antlr4/src/test/resources/core/Script_01x.groovy b/subprojects/groovy-parser-antlr4/src/test/resources/core/Script_01x.groovy
new file mode 100644
index 0000000..2bc3c15
--- /dev/null
+++ b/subprojects/groovy-parser-antlr4/src/test/resources/core/Script_01x.groovy
@@ -0,0 +1,5 @@
+protected String getGroovySql() {
+    return "abc"
+}
+
+assert "abc" == getGroovySql()


Mime
View raw message