You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/11/21 10:46:28 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-8446: syntax error for
void[] or void...
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 913d5c9c GROOVY-8446: syntax error for void[] or void...
913d5c9c is described below
commit 913d5c9ce2d83f95cfffb8d9712ef08eb662af1c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Nov 16 14:04:20 2019 -0600
GROOVY-8446: syntax error for void[] or void...
GROOVY-9203: anonymous inners start at "$1" for each enclosing class
---
.../codehaus/groovy/antlr/AntlrParserPlugin.java | 425 +++++++++------------
.../java/org/codehaus/groovy/ast/ModuleNode.java | 27 +-
.../{Groovy7973Bug.groovy => Groovy7973.groovy} | 34 +-
src/test/groovy/bugs/Groovy8446.groovy | 59 +++
4 files changed, 272 insertions(+), 273 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
index 4b44eae..94032a6 100644
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
+++ b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
@@ -127,20 +127,21 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;
/**
- * A parser plugin which adapts the JSR Antlr Parser to the Groovy runtime
+ * A parser plugin which adapts the JSR Antlr Parser to the Groovy runtime.
*/
public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, GroovyTokenTypes {
private static class AnonymousInnerClassCarrier extends Expression {
ClassNode innerClass;
+ @Override
public Expression transformExpression(ExpressionTransformer transformer) {
return null;
}
@@ -179,16 +180,15 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected AST ast;
private ClassNode classNode;
private MethodNode methodNode;
- private String[] tokenNames;
- private int innerClassCounter = 1;
- private boolean enumConstantBeingDef = false;
- private boolean forStatementBeingDef = false;
- private boolean annotationBeingDef = false;
- private boolean firstParamIsVarArg = false;
- private boolean firstParam = false;
-
- public /*final*/ Reduction parseCST(final SourceUnit sourceUnit, Reader reader) throws CompilationFailedException {
- final SourceBuffer sourceBuffer = new SourceBuffer();
+ protected String[] tokenNames;
+ private boolean enumConstantBeingDef;
+ private boolean forStatementBeingDef;
+ private boolean annotationBeingDef;
+ private boolean firstParamIsVarArg;
+ private boolean firstParam;
+
+ public Reduction parseCST(SourceUnit sourceUnit, Reader reader) throws CompilationFailedException {
+ SourceBuffer sourceBuffer = new SourceBuffer();
transformCSTIntoAST(sourceUnit, reader, sourceBuffer);
processAST();
return outputAST(sourceUnit, sourceBuffer);
@@ -199,8 +199,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
setController(sourceUnit);
- // TODO find a way to inject any GroovyLexer/GroovyRecognizer
-
UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader, sourceBuffer);
UnicodeLexerSharedInputState inputState = new UnicodeLexerSharedInputState(unicodeReader);
GroovyLexer lexer = new GroovyLexer(inputState);
@@ -238,14 +236,13 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
public Reduction outputAST(final SourceUnit sourceUnit, final SourceBuffer sourceBuffer) {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ return AccessController.doPrivileged(new PrivilegedAction<Reduction>() {
+ @Override
+ public Reduction run() {
outputASTInVariousFormsIfNeeded(sourceUnit, sourceBuffer);
return null;
}
});
-
- return null; //new Reduction(Tpken.EOF);
}
private void outputASTInVariousFormsIfNeeded(SourceUnit sourceUnit, SourceBuffer sourceBuffer) {
@@ -253,7 +250,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
String formatProp = System.getProperty("ANTLR.AST".toLowerCase()); // uppercase to hide from jarjar
if ("xml".equals(formatProp)) {
- saveAsXML(sourceUnit.getName(), ast);
+ XStreamUtils.serialize(sourceUnit.getName() + ".antlr", ast);
}
// 'pretty printer' output of AST
@@ -297,7 +294,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if ("html".equals(formatProp)) {
try {
PrintStream out = new PrintStream(new FileOutputStream(sourceUnit.getName() + ".html"));
- List<VisitorAdapter> v = new ArrayList<VisitorAdapter>();
+ List<VisitorAdapter> v = new ArrayList<>();
v.add(new NodeAsHTMLPrinter(out, tokenNames));
v.add(new SourcePrinter(out, tokenNames));
Visitor visitors = new CompositeVisitor(v);
@@ -309,10 +306,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
}
- private static void saveAsXML(String name, AST ast) {
- XStreamUtils.serialize(name+".antlr", ast);
- }
-
public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException {
setClassLoader(classLoader);
makeModule();
@@ -323,7 +316,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
// set the script source position
-
ClassNode scriptClassNode = output.getScriptClassDummy();
if (scriptClassNode != null) {
List<Statement> statements = output.getStatementBlock().getStatements();
@@ -336,15 +328,15 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
scriptClassNode.setLastLineNumber(lastStatement.getLastLineNumber());
}
}
- }
- catch (ASTRuntimeException e) {
+ } catch (ASTRuntimeException e) {
throw new ASTParserException(e.getMessage() + ". File: " + sourceUnit.getName(), e);
}
+ ast = null;
return output;
}
/**
- * Converts the Antlr AST to the Groovy AST
+ * Converts the Antlr AST to the Groovy AST.
*/
protected void convertGroovy(AST node) {
while (node != null) {
@@ -380,10 +372,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
annotationDef(node);
break;
- default: {
- Statement statement = statement(node);
- output.addStatement(statement);
- }
+ default:
+ output.addStatement(statement(node));
}
node = node.getNextSibling();
}
@@ -393,15 +383,13 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
//-------------------------------------------------------------------------
protected void packageDef(AST packageDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = packageDef.getFirstChild();
if (isType(ANNOTATIONS, node)) {
processAnnotations(annotations, node);
node = node.getNextSibling();
}
- String name = qualifiedName(node);
- // TODO should we check package node doesn't already exist? conflict?
- PackageNode packageNode = setPackage(name, annotations);
+ PackageNode packageNode = setPackage(qualifiedName(node), annotations);
configureAST(packageNode, packageDef);
}
@@ -411,7 +399,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
output.putNodeMetaData(ImportNode.class, ImportNode.class);
boolean isStatic = importNode.getType() == STATIC_IMPORT;
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = importNode.getFirstChild();
if (isType(ANNOTATIONS, node)) {
@@ -419,11 +407,13 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
node = node.getNextSibling();
}
+ ImportNode imp;
String alias = null;
+ AST aliasNode = null;
if (isType(LITERAL_as, node)) {
//import is like "import Foo as Bar"
node = node.getFirstChild();
- AST aliasNode = node.getNextSibling();
+ aliasNode = node.getNextSibling();
alias = identifier(aliasNode);
}
@@ -433,6 +423,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
ClassNode type = ClassHelper.make(name);
configureAST(type, importNode);
addImport(type, name, alias, annotations);
+ imp = last(output.getImports());
+ configureAST(imp, importNode);
return;
}
@@ -446,14 +438,17 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
ClassNode type = ClassHelper.make(packageName);
configureAST(type, importNode);
addStaticStarImport(type, packageName, annotations);
+ imp = output.getStaticStarImports().get(packageName);
+ configureAST(imp, importNode);
} else {
// import is like "import foo.*"
addStarImport(packageName, annotations);
+ imp = last(output.getStarImports());
+ configureAST(imp, importNode);
}
- if (alias != null) throw new GroovyBugError(
- "imports like 'import foo.* as Bar' are not " +
- "supported and should be caught by the grammar");
+ if (alias != null)
+ throw new GroovyBugError("imports like 'import foo.* as Bar' are not supported and should be caught by the grammar");
} else {
String name = identifier(nameNode);
if (isStatic) {
@@ -462,18 +457,22 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
ClassNode type = ClassHelper.make(packageName);
configureAST(type, importNode);
addStaticImport(type, name, alias, annotations);
+ imp = output.getStaticImports().get(alias == null ? name : alias);
+ configureAST(imp, importNode);
} else {
// import is like "import foo.Bar"
ClassNode type = ClassHelper.make(packageName + "." + name);
configureAST(type, importNode);
addImport(type, name, alias, annotations);
+ imp = last(output.getImports());
+ configureAST(imp, importNode);
}
}
} finally {
// we're using node metadata here in order to fix GROOVY-6094
// without breaking external APIs
Object node = output.getNodeMetaData(ImportNode.class);
- if (node!=null && node!=ImportNode.class) {
+ if (node != null && node != ImportNode.class) {
configureAST((ImportNode)node, importNode);
}
output.removeNodeMetaData(ImportNode.class);
@@ -490,7 +489,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected void annotationDef(AST classDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = classDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
@@ -532,14 +531,12 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected void interfaceDef(AST classDef) {
- int oldInnerClassCounter = innerClassCounter;
innerInterfaceDef(classDef);
classNode = null;
- innerClassCounter = oldInnerClassCounter;
}
protected void innerInterfaceDef(AST classDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = classDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
@@ -580,21 +577,16 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
classNode.setGenericsTypes(genericsType);
configureAST(classNode, classDef);
- int oldClassCount = innerClassCounter;
-
assertNodeType(OBJBLOCK, node);
objectBlock(node);
output.addClass(classNode);
classNode = outerClass;
- innerClassCounter = oldClassCount;
}
protected void classDef(AST classDef) {
- int oldInnerClassCounter = innerClassCounter;
innerClassDef(classDef);
classNode = null;
- innerClassCounter = oldInnerClassCounter;
}
private ClassNode getClassOrScript(ClassNode node) {
@@ -602,31 +594,42 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return output.getScriptClassDummy();
}
+ private static int anonymousClassCount(ClassNode node) {
+ int count = 0;
+ for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext();) {
+ InnerClassNode innerClass = it.next();
+ if (innerClass.isAnonymous()) {
+ count += 1;
+ }
+ }
+ return count;
+ }
+
protected Expression anonymousInnerClassDef(AST node) {
ClassNode oldNode = classNode;
ClassNode outerClass = getClassOrScript(oldNode);
- String fullName = outerClass.getName() + '$' + innerClassCounter;
- innerClassCounter++;
+ String innerClassName = outerClass.getName() + "$" + (anonymousClassCount(outerClass) + 1);
if (enumConstantBeingDef) {
- classNode = new EnumConstantClassNode(outerClass, fullName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
+ classNode = new EnumConstantClassNode(outerClass, innerClassName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
} else {
- classNode = new InnerClassNode(outerClass, fullName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
+ classNode = new InnerClassNode(outerClass, innerClassName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
}
((InnerClassNode) classNode).setAnonymous(true);
classNode.setEnclosingMethod(methodNode);
+ configureAST(classNode, node);
assertNodeType(OBJBLOCK, node);
objectBlock(node);
- output.addClass(classNode);
+
AnonymousInnerClassCarrier ret = new AnonymousInnerClassCarrier();
ret.innerClass = classNode;
+ output.addClass(classNode);
classNode = oldNode;
-
return ret;
}
protected void innerClassDef(AST classDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
if (isType(TRAIT_DEF, classDef)) {
annotations.add(new AnnotationNode(ClassHelper.make("groovy.transform.Trait")));
@@ -687,13 +690,10 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
// have here to ensure it won't be the inner class
output.addClass(classNode);
- int oldClassCount = innerClassCounter;
-
assertNodeType(OBJBLOCK, node);
objectBlock(node);
classNode = outerClass;
- innerClassCounter = oldClassCount;
}
protected void objectBlock(AST objectBlock) {
@@ -750,7 +750,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected void enumDef(AST enumNode) {
assertNodeType(ENUM_DEF, enumNode);
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = enumNode.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
@@ -770,10 +770,11 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
String enumName = (classNode != null ? name : dot(getPackageName(), name));
ClassNode enumClass = EnumHelper.makeEnumNode(enumName, modifiers, interfaces, classNode);
enumClass.setSyntheticPublic(syntheticPublic);
- ClassNode oldNode = classNode;
enumClass.addAnnotations(annotations);
+ configureAST(enumClass, enumNode);
+
+ ClassNode oldNode = classNode;
classNode = enumClass;
- configureAST(classNode, enumNode);
assertNodeType(OBJBLOCK, node);
objectBlock(node);
classNode = oldNode;
@@ -784,7 +785,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected void enumConstantDef(AST node) {
enumConstantBeingDef = true;
assertNodeType(ENUM_CONSTANT_DEF, node);
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST element = node.getFirstChild();
if (isType(ANNOTATIONS, element)) {
processAnnotations(annotations, element);
@@ -861,7 +862,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected void methodDef(AST methodDef) {
MethodNode oldNode = methodNode;
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = methodDef.getFirstChild();
GenericsType[] generics = null;
@@ -910,7 +911,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if (isType(LITERAL_throws, node)) {
AST throwsNode = node.getFirstChild();
- List<ClassNode> exceptionList = new ArrayList<ClassNode>();
+ List<ClassNode> exceptionList = new ArrayList<>();
throwsList(throwsNode, exceptionList);
exceptions = exceptionList.toArray(exceptions);
node = node.getNextSibling();
@@ -925,9 +926,10 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if ((modifiers & Opcodes.ACC_ABSTRACT) == 0) {
if (node == null) {
throw new ASTRuntimeException(methodDef, "You defined a method without a body. Try adding a body, or declare it abstract.");
+ } else {
+ assertNodeType(SLIST, node);
+ code = statementList(node);
}
- assertNodeType(SLIST, node);
- code = statementList(node);
} else if (node != null) {
if (classNode != null && classNode.isAnnotationDefinition()) {
code = statement(node);
@@ -972,7 +974,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected void constructorDef(AST constructorDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = constructorDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
@@ -992,7 +994,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
ClassNode[] exceptions = ClassNode.EMPTY_ARRAY;
if (isType(LITERAL_throws, node)) {
AST throwsNode = node.getFirstChild();
- List<ClassNode> exceptionList = new ArrayList<ClassNode>();
+ List<ClassNode> exceptionList = new ArrayList<>();
throwsList(throwsNode, exceptionList);
exceptions = exceptionList.toArray(exceptions);
node = node.getNextSibling();
@@ -1013,7 +1015,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected void fieldDef(AST fieldDef) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
AST node = fieldDef.getFirstChild();
int modifiers = 0;
@@ -1048,7 +1050,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
initialValue = getDefaultValueForPrimitive(type);
}
-
FieldNode fieldNode = new FieldNode(name, modifiers, type, classNode, initialValue);
fieldNode.addAnnotations(annotations);
configureAST(fieldNode, fieldDef);
@@ -1098,6 +1099,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
public static Expression getDefaultValueForPrimitive(ClassNode type) {
+ if (type != null) type = type.redirect();
+
if (type == ClassHelper.int_TYPE) {
return new ConstantExpression(0);
}
@@ -1126,7 +1129,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected ClassNode[] interfaces(AST node) {
- List<ClassNode> interfaceList = new ArrayList<ClassNode>();
+ List<ClassNode> interfaceList = new ArrayList<>();
for (AST implementNode = node.getFirstChild(); implementNode != null; implementNode = implementNode.getNextSibling()) {
interfaceList.add(makeTypeWithArguments(implementNode));
}
@@ -1146,7 +1149,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if (isType(IMPLICIT_PARAMETERS, parametersNode)) return Parameter.EMPTY_ARRAY;
return null;
} else {
- List<Parameter> parameters = new ArrayList<Parameter>();
+ List<Parameter> parameters = new ArrayList<>();
AST firstParameterNode = null;
do {
firstParam = (firstParameterNode == null);
@@ -1174,7 +1177,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected Parameter parameter(AST paramNode) {
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
boolean variableParameterDef = isType(VARIABLE_PARAMETER_DEF, paramNode);
AST node = paramNode.getFirstChild();
@@ -1187,7 +1190,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
ClassNode type = ClassHelper.DYNAMIC_TYPE;
if (isType(TYPE, node)) {
type = makeTypeWithArguments(node);
- if (variableParameterDef) type = type.makeArray();
+ if (variableParameterDef)
+ type = makeArray(type, node);
node = node.getNextSibling();
}
@@ -1314,8 +1318,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected AnnotationNode annotation(AST annotationNode) {
annotationBeingDef = true;
AST node = annotationNode.getFirstChild();
- String name = qualifiedName(node);
- AnnotationNode annotatedNode = new AnnotationNode(ClassHelper.make(name));
+ AnnotationNode annotatedNode = new AnnotationNode(ClassHelper.make(qualifiedName(node)));
configureAST(annotatedNode, annotationNode);
while (true) {
node = node.getNextSibling();
@@ -1335,7 +1338,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return annotatedNode;
}
-
// Statements
//-------------------------------------------------------------------------
@@ -1421,10 +1423,10 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected Statement statementListNoChild(AST node, AST alternativeConfigureNode) {
BlockStatement block = siblingsToBlockStatement(node);
// alternativeConfigureNode is used only to set the source position
- if (node != null) {
- configureAST(block, node);
- } else {
+ if (alternativeConfigureNode != null) {
configureAST(block, alternativeConfigureNode);
+ } else if (node != null) {
+ configureAST(block, node);
}
return block;
}
@@ -1554,7 +1556,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected Expression declarationExpression(AST variableDef) {
AST node = variableDef.getFirstChild();
ClassNode type = null;
- List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
+ List<AnnotationNode> annotations = new ArrayList<>();
int modifiers = 0;
if (isType(MODIFIERS, node)) {
// force check of modifier conflicts
@@ -1631,20 +1633,18 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
Expression expression = expression(node);
Statement defaultStatement = EmptyStatement.INSTANCE;
- List list = new ArrayList();
+ List<CaseStatement> caseStatements = new ArrayList<>();
for (node = node.getNextSibling(); isType(CASE_GROUP, node); node = node.getNextSibling()) {
Statement tmpDefaultStatement;
AST child = node.getFirstChild();
if (isType(LITERAL_case, child)) {
- List cases = new LinkedList();
// default statement can be grouped with previous case
- tmpDefaultStatement = caseStatements(child, cases);
- list.addAll(cases);
+ tmpDefaultStatement = caseStatements(child, caseStatements);
} else {
tmpDefaultStatement = statement(child.getNextSibling());
}
- if (tmpDefaultStatement != EmptyStatement.INSTANCE) {
- if (defaultStatement == EmptyStatement.INSTANCE) {
+ if (!(tmpDefaultStatement instanceof EmptyStatement)) {
+ if (defaultStatement instanceof EmptyStatement) {
defaultStatement = tmpDefaultStatement;
} else {
throw new ASTRuntimeException(switchNode, "The default case is already defined.");
@@ -1654,13 +1654,13 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if (node != null) {
unknownAST(node);
}
- SwitchStatement switchStatement = new SwitchStatement(expression, list, defaultStatement);
+ SwitchStatement switchStatement = new SwitchStatement(expression, caseStatements, defaultStatement);
configureAST(switchStatement, switchNode);
return switchStatement;
}
- protected Statement caseStatements(AST node, List cases) {
- List<Expression> expressions = new LinkedList<Expression>();
+ protected Statement caseStatements(AST node, List<CaseStatement> cases) {
+ List<Expression> expressions = new ArrayList<>();
Statement statement = EmptyStatement.INSTANCE;
Statement defaultStatement = EmptyStatement.INSTANCE;
AST nextSibling = node;
@@ -1677,10 +1677,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
statement = statement(nextSibling);
}
}
- Iterator iterator = expressions.iterator();
- while (iterator.hasNext()) {
- Expression expr = (Expression) iterator.next();
- Statement stmt;
+ for (Iterator<Expression> iterator = expressions.iterator(); iterator.hasNext(); ) {
+ Expression expr = iterator.next();
+ CaseStatement stmt;
if (iterator.hasNext()) {
stmt = new CaseStatement(expr, EmptyStatement.INSTANCE);
} else {
@@ -1721,7 +1720,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
AST node = tryNode.getNextSibling();
// let's do the catch nodes
- List<CatchStatement> catches = new ArrayList<CatchStatement>();
+ List<CatchStatement> catches = new ArrayList<>();
for (; isType(LITERAL_catch, node); node = node.getNextSibling()) {
final List<CatchStatement> catchStatements = catchStatement(node);
catches.addAll(catchStatements);
@@ -1746,9 +1745,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected List<CatchStatement> catchStatement(AST catchNode) {
AST node = catchNode.getFirstChild();
- List<CatchStatement> catches = new LinkedList<CatchStatement>();
+ List<CatchStatement> catches = new ArrayList<>();
if (MULTICATCH == node.getType()) {
- final AST multicatches = node.getFirstChild();
+ AST multicatches = node.getFirstChild();
if (multicatches.getType() != MULTICATCH_TYPES) {
// catch (e)
// catch (def e)
@@ -1759,7 +1758,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
catches.add(answer);
} else {
// catch (Exception e)
- // catch (Exception1 | Exception2 e)
+ // catch (java.lang.Exception e)
+ // catch (Exception1 | foo.bar.Exception2 e)
AST exceptionNodes = multicatches.getFirstChild();
String variable = identifier(multicatches.getNextSibling());
while (exceptionNodes != null) {
@@ -1797,7 +1797,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return whileStatement;
}
-
// Expressions
//-------------------------------------------------------------------------
@@ -1825,7 +1824,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
int type = node.getType();
switch (type) {
case EXPR:
- return expression(node.getFirstChild());
+ Expression expression = expression(node.getFirstChild());
+ return expression;
case ELIST:
return expressionList(node);
@@ -1886,10 +1886,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case SPREAD_MAP_ARG:
return spreadMapExpression(node);
- // commented out of groovy.g due to non determinisms
- //case MEMBER_POINTER_DEFAULT:
- // return defaultMethodPointerExpression(node);
-
case MEMBER_POINTER:
return methodPointerExpression(node);
@@ -1905,14 +1901,15 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case TYPECAST:
return castExpression(node);
- // literals
-
case LITERAL_true:
return literalExpression(node, Boolean.TRUE);
+
case LITERAL_false:
return literalExpression(node, Boolean.FALSE);
+
case LITERAL_null:
return literalExpression(node, null);
+
case STRING_LITERAL:
return literalExpression(node, node.getText());
@@ -1946,23 +1943,19 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case UNARY_PLUS:
return unaryPlusExpression(node);
- // Prefix expressions
case INC:
return prefixExpression(node, Types.PLUS_PLUS);
case DEC:
return prefixExpression(node, Types.MINUS_MINUS);
- // Postfix expressions
case POST_INC:
return postfixExpression(node, Types.PLUS_PLUS);
case POST_DEC:
return postfixExpression(node, Types.MINUS_MINUS);
-
// Binary expressions
-
case ASSIGN:
return binaryExpression(Types.ASSIGN, node);
@@ -1993,18 +1986,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case GE:
return binaryExpression(Types.COMPARE_GREATER_THAN_EQUAL, node);
- /**
- * TODO treble equal?
- return binaryExpression(Types.COMPARE_IDENTICAL, node);
-
- case ???:
- return binaryExpression(Types.LOGICAL_AND_EQUAL, node);
-
- case ???:
- return binaryExpression(Types.LOGICAL_OR_EQUAL, node);
-
- */
-
case LAND:
return binaryExpression(Types.LOGICAL_AND, node);
@@ -2029,42 +2010,36 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case BXOR_ASSIGN:
return binaryExpression(Types.BITWISE_XOR_EQUAL, node);
-
case PLUS:
return binaryExpression(Types.PLUS, node);
case PLUS_ASSIGN:
return binaryExpression(Types.PLUS_EQUAL, node);
-
case MINUS:
return binaryExpression(Types.MINUS, node);
case MINUS_ASSIGN:
return binaryExpression(Types.MINUS_EQUAL, node);
-
case STAR:
return binaryExpression(Types.MULTIPLY, node);
case STAR_ASSIGN:
return binaryExpression(Types.MULTIPLY_EQUAL, node);
-
case STAR_STAR:
return binaryExpression(Types.POWER, node);
case STAR_STAR_ASSIGN:
return binaryExpression(Types.POWER_EQUAL, node);
-
case DIV:
return binaryExpression(Types.DIVIDE, node);
case DIV_ASSIGN:
return binaryExpression(Types.DIVIDE_EQUAL, node);
-
case MOD:
return binaryExpression(Types.MOD, node);
@@ -2099,7 +2074,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case REGEX_MATCH:
return binaryExpression(Types.MATCH_REGEX, node);
-
// Ranges
case RANGE_INCLUSIVE:
return rangeExpression(node, true);
@@ -2114,7 +2088,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return binaryExpression(Types.KEYWORD_IN, node);
case ANNOTATION:
- return new AnnotationConstantExpression(annotation(node));
+ expression = new AnnotationConstantExpression(annotation(node));
+ configureAST(expression, node);
+ return expression;
case CLOSURE_LIST:
return closureListExpression(node);
@@ -2150,7 +2126,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
private ClosureListExpression closureListExpression(AST node) {
isClosureListExpressionAllowedHere(node);
AST exprNode = node.getFirstChild();
- List<Expression> list = new LinkedList<Expression>();
+ List<Expression> list = new ArrayList<>();
while (exprNode != null) {
if (isType(EXPR, exprNode)) {
Expression expr = expression(exprNode);
@@ -2209,7 +2185,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return variableExpression;
}
- protected Expression literalExpression(AST node, Object value) {
+ protected ConstantExpression literalExpression(AST node, Object value) {
ConstantExpression constantExpression = new ConstantExpression(value, value instanceof Boolean);
configureAST(constantExpression, node);
return constantExpression;
@@ -2257,18 +2233,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return methodPointerExpression;
}
-/* commented out due to groovy.g non-determinisms
- protected Expression defaultMethodPointerExpression(AST node) {
- AST exprNode = node.getFirstChild();
- String methodName = exprNode.toString();
- MethodPointerExpression methodPointerExpression = new MethodPointerExpression(null, methodName);
- configureAST(methodPointerExpression, node);
- return methodPointerExpression;
- }
-*/
-
protected Expression listExpression(AST listNode) {
- List<Expression> expressions = new ArrayList<Expression>();
+ List<Expression> expressions = new ArrayList<>();
AST elist = listNode.getFirstChild();
assertNodeType(ELIST, elist);
@@ -2289,11 +2255,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return listExpression;
}
- /**
- * Typically only used for map constructors I think?
- */
protected Expression mapExpression(AST mapNode) {
- List expressions = new ArrayList();
+ List<MapEntryExpression> entryExpressions = new ArrayList<>();
AST elist = mapNode.getFirstChild();
if (elist != null) { // totally empty in the case of [:]
assertNodeType(ELIST, elist);
@@ -2304,15 +2267,15 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
break; // legal cases
case SPREAD_ARG:
assertNodeType(SPREAD_MAP_ARG, node);
- break; // helpful error
+ break;
default:
assertNodeType(LABELED_ARG, node);
- break; // helpful error
+ break;
}
- expressions.add(mapEntryExpression(node));
+ entryExpressions.add(mapEntryExpression(node));
}
}
- MapExpression mapExpression = new MapExpression(expressions);
+ MapExpression mapExpression = new MapExpression(entryExpressions);
configureAST(mapExpression, mapNode);
return mapExpression;
}
@@ -2336,7 +2299,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
}
-
protected Expression instanceofExpression(AST node) {
AST leftNode = node.getFirstChild();
Expression leftExpression = expression(leftNode);
@@ -2365,7 +2327,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
AST rightNode = leftNode.getNextSibling();
ClassNode type = makeTypeWithArguments(rightNode);
- return CastExpression.asExpression(type, leftExpression);
+ CastExpression asExpression = CastExpression.asExpression(type, leftExpression);
+ configureAST(asExpression, node);
+ return asExpression;
}
protected Expression castExpression(AST castNode) {
@@ -2381,7 +2345,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return castExpression;
}
-
protected Expression indexExpression(AST indexNode) {
AST bracket = indexNode.getFirstChild();
AST leftNode = bracket.getNextSibling();
@@ -2501,6 +2464,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if (property instanceof VariableExpression) {
VariableExpression ve = (VariableExpression) property;
property = new ConstantExpression(ve.getName());
+ property.setSourcePosition(ve);
}
PropertyExpression propertyExpression = new PropertyExpression(leftExpression, property, node.getType() != DOT);
@@ -2556,8 +2520,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
objectExpression = VariableExpression.SUPER_EXPRESSION;
}
} else if (isPrimitiveTypeLiteral(selector)) {
- throw new ASTRuntimeException(selector, "Primitive type literal: " + selector.getText()
- + " cannot be used as a method name");
+ throw new ASTRuntimeException(selector, "Primitive type literal: " + selector.getText() + " cannot be used as a method name");
} else if (isType(SELECT_SLOT, selector)) {
Expression field = expression(selector.getFirstChild(), true);
AttributeExpression attributeExpression = new AttributeExpression(objectExpression, field, node.getType() != DOT);
@@ -2576,7 +2539,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
objectExpression = expression(selector, true);
}
- // if node text is found to be "super"/"this" when a method call is being processed, it is a
+ // if node text is found to be "super"/"this" when a method call is being processed, it is a
// call like this(..)/super(..) after the first statement, which shouldn't be allowed. GROOVY-2836
if (selector.getText().equals("this") || selector.getText().equals("super")) {
if (!(annotationBeingDef && selector.getText().equals("super"))) {
@@ -2631,7 +2594,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
if (expressionNode == null) {
throw new ASTRuntimeException(elist, "No expression for the array constructor call");
}
- List size = arraySizeExpression(expressionNode);
+ List<Expression> size = arraySizeExpression(expressionNode);
ArrayExpression arrayExpression = new ArrayExpression(type, null, size);
configureAST(arrayExpression, constructorCallNode);
return arrayExpression;
@@ -2668,8 +2631,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return null;
}
- protected List arraySizeExpression(AST node) {
- List list;
+ protected List<Expression> arraySizeExpression(AST node) {
+ List<Expression> list;
Expression size = null;
if (isType(ARRAY_DECLARATOR, node)) {
AST right = node.getNextSibling();
@@ -2685,14 +2648,14 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
list = arraySizeExpression(child);
} else {
size = expression(node);
- list = new ArrayList();
+ list = new ArrayList<>();
}
list.add(size);
return list;
}
protected Expression enumArguments(AST elist) {
- List<Expression> expressionList = new ArrayList<Expression>();
+ List<Expression> expressionList = new ArrayList<>();
for (AST node = elist; node != null; node = node.getNextSibling()) {
Expression expression = expression(node);
expressionList.add(expression);
@@ -2703,7 +2666,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected Expression arguments(AST elist) {
- List expressionList = new ArrayList();
+ List expressionList = new ArrayList<>();
// FIXME: all labeled arguments should follow any unlabeled arguments
boolean namedArguments = false;
for (AST node = elist; node != null; node = node.getNextSibling()) {
@@ -2720,7 +2683,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
// let's remove any non-MapEntryExpression instances
// such as if the last expression is a ClosureExpression
// so let's wrap the named method calls in a Map expression
- List<Expression> argumentList = new ArrayList<Expression>();
+ List<Expression> argumentList = new ArrayList<>();
for (Object next : expressionList) {
Expression expression = (Expression) next;
if (!(expression instanceof MapEntryExpression)) {
@@ -2749,19 +2712,17 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
}
- private static void checkDuplicateNamedParams(AST elist, List expressionList) {
+ private static void checkDuplicateNamedParams(AST elist, List<MapEntryExpression> expressionList) {
if (expressionList.isEmpty()) return;
- Set<String> namedArgumentNames = new HashSet<String>();
- for (Object expression : expressionList) {
- MapEntryExpression meExp = (MapEntryExpression) expression;
+ Set<String> namedArgumentNames = new HashSet<>();
+ for (MapEntryExpression meExp : expressionList) {
if (meExp.getKeyExpression() instanceof ConstantExpression) {
String argName = meExp.getKeyExpression().getText();
if (!namedArgumentNames.contains(argName)) {
namedArgumentNames.add(argName);
} else {
- throw new ASTRuntimeException(elist, "Duplicate named parameter '" + argName
- + "' found.");
+ throw new ASTRuntimeException(elist, "Duplicate named parameter '" + argName + "' found.");
}
}
}
@@ -2783,7 +2744,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected Expression expressionList(AST node) {
- List<Expression> expressionList = new ArrayList<Expression>();
+ List<Expression> expressionList = new ArrayList<>();
for (AST child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
expressionList.add(expression(child));
}
@@ -2847,7 +2808,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case NUM_BIG_INT:
case NUM_INT:
case NUM_LONG:
- ConstantExpression constantLongExpression = new ConstantExpression(Numbers.parseInteger(unaryMinusExpr,"-" + text));
+ ConstantExpression constantLongExpression = new ConstantExpression(Numbers.parseInteger("-" + text));
configureAST(constantLongExpression, unaryMinusExpr);
return constantLongExpression;
@@ -2860,6 +2821,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected Expression unaryPlusExpression(AST unaryPlusExpr) {
AST node = unaryPlusExpr.getFirstChild();
+ UnaryPlusExpression unaryPlusExpression = new UnaryPlusExpression(expression(node));
+ configureAST(unaryPlusExpression, unaryPlusExpr);
switch (node.getType()) {
case NUM_DOUBLE:
case NUM_FLOAT:
@@ -2867,11 +2830,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
case NUM_BIG_INT:
case NUM_INT:
case NUM_LONG:
- return expression(node);
+ return unaryPlusExpression.getExpression();
default:
- UnaryPlusExpression unaryPlusExpression = new UnaryPlusExpression(expression(node));
- configureAST(unaryPlusExpression, unaryPlusExpr);
return unaryPlusExpression;
}
}
@@ -2895,8 +2856,8 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
}
protected Expression gstring(AST gstringNode) {
- List strings = new ArrayList();
- List values = new ArrayList();
+ List<ConstantExpression> strings = new ArrayList<>();
+ List<Expression> values = new ArrayList<>();
StringBuilder buffer = new StringBuilder();
@@ -2933,12 +2894,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return gStringExpression;
}
- protected ClassNode type(AST typeNode) {
- // TODO intern types?
- // TODO configureAST(...)
- return buildName(typeNode.getFirstChild());
- }
-
public static String qualifiedName(AST qualifiedNameNode) {
if (isType(IDENT, qualifiedNameNode)) {
return qualifiedNameNode.getText();
@@ -3025,7 +2980,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
private List<GenericsType> getTypeArgumentsList(AST node) {
assertNodeType(TYPE_ARGUMENTS, node);
- List<GenericsType> typeArgumentList = new LinkedList<GenericsType>();
+ List<GenericsType> typeArgumentList = new ArrayList<>();
AST typeArgument = node.getFirstChild();
while (typeArgument != null) {
@@ -3041,58 +2996,60 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
AST boundsRoot = rn.getNextSibling();
if (boundsRoot == null) return null;
assertNodeType(boundType, boundsRoot);
- LinkedList bounds = new LinkedList();
- for (AST boundsNode = boundsRoot.getFirstChild();
- boundsNode != null;
- boundsNode = boundsNode.getNextSibling()
- ) {
- ClassNode bound = null;
- bound = makeTypeWithArguments(boundsNode);
+ List<ClassNode> bounds = new ArrayList<>();
+ for (AST boundsNode = boundsRoot.getFirstChild(); boundsNode != null; boundsNode = boundsNode.getNextSibling()) {
+ ClassNode bound = makeTypeWithArguments(boundsNode);
configureAST(bound, boundsNode);
bounds.add(bound);
}
if (bounds.isEmpty()) return null;
- return (ClassNode[]) bounds.toArray(ClassNode.EMPTY_ARRAY);
+ return bounds.toArray(ClassNode.EMPTY_ARRAY);
}
protected GenericsType[] makeGenericsType(AST rootNode) {
AST typeParameter = rootNode.getFirstChild();
- LinkedList ret = new LinkedList();
+ List<GenericsType> generics = new ArrayList<>();
assertNodeType(TYPE_PARAMETER, typeParameter);
while (isType(TYPE_PARAMETER, typeParameter)) {
- AST typeNode = typeParameter.getFirstChild();
- ClassNode type = makeType(typeParameter);
-
- GenericsType gt = new GenericsType(type, makeGenericsBounds(typeNode, TYPE_UPPER_BOUNDS), null);
+ GenericsType gt = new GenericsType(makeType(typeParameter), makeGenericsBounds(typeParameter.getFirstChild(), TYPE_UPPER_BOUNDS), null);
configureAST(gt, typeParameter);
+ generics.add(gt);
- ret.add(gt);
typeParameter = typeParameter.getNextSibling();
}
- return (GenericsType[]) ret.toArray(GenericsType.EMPTY_ARRAY);
+ return generics.toArray(GenericsType.EMPTY_ARRAY);
}
protected ClassNode makeType(AST typeNode) {
ClassNode answer = ClassHelper.DYNAMIC_TYPE;
AST node = typeNode.getFirstChild();
if (node != null) {
- if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) {
- answer = makeType(node).makeArray();
+ if (isType(ARRAY_DECLARATOR, node) || isType(INDEX_OP, node)) {
+ answer = makeArray(makeTypeWithArguments(node), node);
} else {
checkTypeArgs(node, false);
answer = ClassHelper.make(qualifiedName(node));
if (answer.isUsingGenerics()) {
- ClassNode newAnswer = ClassHelper.makeWithoutCaching(answer.getName());
- newAnswer.setRedirect(answer);
- answer = newAnswer;
+ ClassNode proxy = ClassHelper.makeWithoutCaching(answer.getName());
+ proxy.setRedirect(answer);
+ answer = proxy;
}
+ configureAST(answer, node);
}
- configureAST(answer, node);
}
return answer;
}
+ private ClassNode makeArray(ClassNode elementType, AST node) {
+ if (elementType.equals(ClassHelper.VOID_TYPE)) {
+ throw new ASTRuntimeException(node.getFirstChild(), "void[] is an invalid type");
+ }
+ ClassNode arrayType = elementType.makeArray();
+ configureAST(arrayType, node);
+ return arrayType;
+ }
+
private boolean checkTypeArgs(AST node, boolean seenTypeArgs) {
if (isType(IDENT, node) && seenTypeArgs) {
throw new ASTRuntimeException(node, "Unexpected type arguments found prior to: " + qualifiedName(node));
@@ -3108,44 +3065,22 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return seenTypeArgs;
}
- /**
- * Performs a name resolution to see if the given name is a type from imports,
- * aliases or newly created classes
- */
- /*protected String resolveTypeName(String name, boolean safe) {
- if (name == null) {
- return null;
- }
- return resolveNewClassOrName(name, safe);
- }*/
-
- /**
- * Extracts an identifier from the Antlr AST and then performs a name resolution
- * to see if the given name is a type from imports, aliases or newly created classes
- */
protected ClassNode buildName(AST node) {
if (isType(TYPE, node)) {
node = node.getFirstChild();
}
- ClassNode answer = null;
- if (isType(DOT, node) || isType(OPTIONAL_DOT, node)) {
- answer = ClassHelper.make(qualifiedName(node));
- } else if (isPrimitiveTypeLiteral(node)) {
- answer = ClassHelper.make(node.getText());
- } else if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) {
- AST child = node.getFirstChild();
- answer = buildName(child).makeArray();
- configureAST(answer, node);
- return answer;
+ String name;
+ if (isType(ARRAY_DECLARATOR, node) || isType(INDEX_OP, node)) {
+ return makeArray(buildName(node.getFirstChild()), node);
+ } else if (isType(DOT, node) || isType(OPTIONAL_DOT, node)) {
+ name = qualifiedName(node);
} else {
- String identifier = node.getText();
- answer = ClassHelper.make(identifier);
+ name = node.getText();
}
+ ClassNode answer = ClassHelper.make(name);
AST nextSibling = node.getNextSibling();
- if (isType(INDEX_OP, nextSibling) || isType(ARRAY_DECLARATOR, node)) {
- answer = answer.makeArray();
- configureAST(answer, node);
- return answer;
+ if (isType(ARRAY_DECLARATOR, nextSibling) || isType(INDEX_OP, nextSibling)) {
+ return makeArray(answer, node);
} else {
configureAST(answer, node);
return answer;
@@ -3186,11 +3121,9 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return identifier(node);
}
-
// Helper methods
//-------------------------------------------------------------------------
-
/**
* Returns true if the modifiers flags contain a visibility modifier
*/
@@ -3200,16 +3133,13 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
protected void configureAST(ASTNode node, AST ast) {
if (ast == null)
- throw new ASTRuntimeException(ast, "PARSER BUG: Tried to configure " + node.getClass().getName() + " with null Node");
- node.setColumnNumber(ast.getColumn());
+ throw new ASTRuntimeException(ast, "PARSER BUG: Tried to configure " + node.getClass().getName() + " with null AST");
node.setLineNumber(ast.getLine());
+ node.setColumnNumber(ast.getColumn());
if (ast instanceof GroovySourceAST) {
- node.setLastColumnNumber(((GroovySourceAST) ast).getColumnLast());
node.setLastLineNumber(((GroovySourceAST) ast).getLineLast());
+ node.setLastColumnNumber(((GroovySourceAST) ast).getColumnLast());
}
-
- // TODO we could one day store the Antlr AST on the Groovy AST
- // node.setCSTNode(ast);
}
protected static Token makeToken(int typeCode, AST node) {
@@ -3221,7 +3151,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
return child != null ? child.getText() : null;
}
-
public static boolean isType(int typeCode, AST node) {
return node != null && node.getType() == typeCode;
}
diff --git a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
index 54f7e16..ceeb58c 100644
--- a/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ModuleNode.java
@@ -37,6 +37,7 @@ import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -87,7 +88,7 @@ public class ModuleNode extends ASTNode implements Opcodes {
public List<ClassNode> getClasses() {
if (createClassForStatements && (!statementBlock.isEmpty() || !methods.isEmpty() || isPackageInfo())) {
ClassNode mainClass = createStatementsClass();
- mainClassName = mainClass.getName();
+ mainClassName = mainClass.getName();
createClassForStatements = false;
classes.add(0, mainClass);
mainClass.setModule(this);
@@ -233,7 +234,7 @@ public class ModuleNode extends ASTNode implements Opcodes {
setScriptBaseClassFromConfig(scriptDummy);
return scriptDummy;
}
-
+
String name = getPackageName();
if (name == null) {
name = "";
@@ -273,13 +274,13 @@ public class ModuleNode extends ASTNode implements Opcodes {
}
}
}
-
+
protected ClassNode createStatementsClass() {
ClassNode classNode = getScriptClassDummy();
if (classNode.getName().endsWith("package-info")) {
return classNode;
}
-
+
handleMainMethodIfPresent(methods);
// return new Foo(new ShellContext(args)).run()
@@ -346,7 +347,7 @@ public class ModuleNode extends ASTNode implements Opcodes {
}
/*
- * If a main method is provided by user, account for it under run() as scripts generate their own 'main' so they can run.
+ * If a main method is provided by user, account for it under run() as scripts generate their own 'main' so they can run.
*/
private void handleMainMethodIfPresent(List methods) {
boolean found = false;
@@ -360,9 +361,8 @@ public class ModuleNode extends ASTNode implements Opcodes {
argTypeMatches = (argType.equals(ClassHelper.OBJECT_TYPE) || argType.getName().contains("String[]"));
retTypeMatches = (retType == ClassHelper.VOID_TYPE || retType == ClassHelper.OBJECT_TYPE);
-
- if(retTypeMatches && argTypeMatches) {
- if(found) {
+ if (retTypeMatches && argTypeMatches) {
+ if (found) {
throw new RuntimeException("Repetitive main method found.");
} else {
found = true;
@@ -412,8 +412,8 @@ public class ModuleNode extends ASTNode implements Opcodes {
public boolean isEmpty() {
return classes.isEmpty() && statementBlock.getStatements().isEmpty();
}
-
- public void sortClasses(){
+
+ public void sortClasses() {
if (isEmpty()) return;
List<ClassNode> classes = getClasses();
LinkedList<ClassNode> sorted = new LinkedList<ClassNode>();
@@ -449,18 +449,19 @@ public class ModuleNode extends ASTNode implements Opcodes {
}
public void addStaticImport(ClassNode type, String fieldName, String alias) {
- addStaticImport(type, fieldName, alias, new ArrayList<AnnotationNode>());
+ addStaticImport(type, fieldName, alias, Collections.<AnnotationNode>emptyList());
}
public void addStaticImport(ClassNode type, String fieldName, String alias, List<AnnotationNode> annotations) {
ImportNode node = new ImportNode(type, fieldName, alias);
node.addAnnotations(annotations);
- staticImports.put(alias, node);
+ ImportNode prev = staticImports.put(alias, node);
+ if (prev != null) staticImports.put(prev.toString(), prev);
storeLastAddedImportNode(node);
}
public void addStaticStarImport(String name, ClassNode type) {
- addStaticStarImport(name, type, new ArrayList<AnnotationNode>());
+ addStaticStarImport(name, type, Collections.<AnnotationNode>emptyList());
}
public void addStaticStarImport(String name, ClassNode type, List<AnnotationNode> annotations) {
diff --git a/src/test/groovy/bugs/Groovy7973Bug.groovy b/src/test/groovy/bugs/Groovy7973.groovy
similarity index 75%
rename from src/test/groovy/bugs/Groovy7973Bug.groovy
rename to src/test/groovy/bugs/Groovy7973.groovy
index a6ab96c..9c05c5b 100644
--- a/src/test/groovy/bugs/Groovy7973Bug.groovy
+++ b/src/test/groovy/bugs/Groovy7973.groovy
@@ -18,41 +18,47 @@
*/
package groovy.bugs
-class Groovy7973Bug extends GroovyTestCase {
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy7973 {
private static final String SCRIPT1 = '''
class Test {
def op1() { 'A'.with{ this.class.name } }
def op2a() { new Object() { def inner() {
- this.class.name + Test.this.class.name
+ Test.this.class.name + '::' + this.class.name
} } }
def op2b() { new Object() { def inner() {
- 'B'.with{ this.class.name + Test.this.class.name }
+ 'B'.with { Test.this.class.name + '::' + this.class.name }
} } }
def op3a() { new Object() { def inner() { new Object() { def innerinner() {
- this.class.name + Test$3.this.class.name + Test.this.class.name
+ Test.this.class.name + '::' + this.class.name
} } } } }
def op3b() { new Object() { def inner() { new Object() { def innerinner() {
- 'C'.with{ this.class.name + Test$5.this.class.name + Test.this.class.name }
+ 'C'.with { Test.this.class.name + '::' + this.class.name }
} } } } }
}
def t = new Test()
assert t.op1() == 'Test'
- assert t.op2a().inner() == 'Test$1Test'
- assert t.op2b().inner() == 'Test$2Test'
- assert t.op3a().inner().innerinner() == 'Test$3$4Test$3Test'
- assert t.op3b().inner().innerinner() == 'Test$5$6Test$5Test'
+ assert t.op2a().inner() == 'Test::Test$1'
+ assert t.op2b().inner() == 'Test::Test$2'
+ assert t.op3a().inner().innerinner() == 'Test::Test$3$1'
+ assert t.op3b().inner().innerinner() == 'Test::Test$4$1'
'''
private static final String SCRIPT2 = '''
class Test {
def op1() { this }
- def op2() { ''.with{ this } }
+ def op2() { ''.with { this } }
def op3() { new Object() { def inner() { this } } }
- def op4() { new Object() { def inner() { ''.with{ this } } } }
+ def op4() { new Object() { def inner() { ''.with { this } } } }
def op5() { new Object() { def inner() { Test.this } } }
- def op6() { new Object() { def inner() { ''.with{ Test.this } } } }
+ def op6() { new Object() { def inner() { ''.with { Test.this } } } }
class Inner {
def inner1() { this }
def inner2() { ''.with { this } }
@@ -76,18 +82,22 @@ class Groovy7973Bug extends GroovyTestCase {
assert inner.inner4().class.name == 'Test'
'''
+ @Test
void testClassDotThis() {
assertScript SCRIPT1
}
+ @Test
void testClassDotThis_CS() {
assertScript '@groovy.transform.CompileStatic\n' + SCRIPT1
}
+ @Test
void testClassDotThisAIC() {
assertScript SCRIPT2
}
+ @Test
void testClassDotThisAIC_CS() {
assertScript '@groovy.transform.CompileStatic\n' + SCRIPT2
}
diff --git a/src/test/groovy/bugs/Groovy8446.groovy b/src/test/groovy/bugs/Groovy8446.groovy
new file mode 100644
index 0000000..4668438
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8446.groovy
@@ -0,0 +1,59 @@
+/*
+ * 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 groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
+
+@CompileStatic
+final class Groovy8446 {
+
+ @Test
+ void testVoidArray0() {
+ assertScript '''
+ class C {
+ Void[] m() {}
+ }
+ println 'parsed'
+ '''
+ }
+
+ @Test
+ void testVoidArray1() {
+ def err = shouldFail '''
+ class C {
+ void[] m() {}
+ }
+ '''
+ assert err =~ /void\[\] is an invalid type/
+ }
+
+ @Test
+ void testVoidArray2() {
+ def err = shouldFail '''
+ class C {
+ def meth(void... args) {}
+ }
+ '''
+ assert err =~ /void\[\] is an invalid type|void is not allowed here/
+ }
+}