You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2017/05/10 22:26:40 UTC
[12/50] [abbrv] groovy git commit: Fix some tests which have not been
covered by Parrot before
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/53b4f900
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/53b4f900
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/53b4f900
Branch: refs/heads/parrot
Commit: 53b4f90073e44b339c618cf3c40375e4508ed100
Parents: ac6bf0a
Author: sunlan <su...@apache.org>
Authored: Fri May 5 20:26:01 2017 +0800
Committer: paulk <pa...@asert.com.au>
Committed: Thu May 11 08:06:12 2017 +1000
----------------------------------------------------------------------
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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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/53b4f900/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()