You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/02/24 16:24:33 UTC
[groovy] branch GROOVY_3_0_X updated (6b55f30 -> 008ae028)
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a change to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git.
from 6b55f30 ignore non-stable versions when using dependencyUpdates
new 0c94914 GROOVY-5726: source range of method call in command expression
new 06fbe43 GROOVY-9259: interface w/ `default` supports `extends` for interface(s)
new cb9b1c6 GROOVY-10505: mark trait super methods as generated
new 008ae028 GROOVY-10478: SC: indicate dynamic resolution of trait super fallback
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../classgen/asm/sc/StaticInvocationWriter.java | 3 +-
.../groovy/transform/trait/TraitComposer.java | 98 +++++++++-------------
src/test/groovy/bugs/Groovy10478.groovy | 32 +++++++
.../bugs/{Groovy8815.groovy => Groovy9259.groovy} | 79 ++++++++++++-----
.../apache/groovy/parser/antlr4/AstBuilder.java | 61 +++++---------
5 files changed, 152 insertions(+), 121 deletions(-)
create mode 100644 src/test/groovy/bugs/Groovy10478.groovy
copy src/test/groovy/bugs/{Groovy8815.groovy => Groovy9259.groovy} (52%)
[groovy] 02/04: GROOVY-9259: interface w/ `default` supports `extends` for interface(s)
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 06fbe4371108ee81927e7709399c298834728c1c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Feb 19 16:48:23 2022 -0600
GROOVY-9259: interface w/ `default` supports `extends` for interface(s)
Conflicts:
src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
---
src/test/groovy/bugs/Groovy9259.groovy | 109 +++++++++++++++++++++
.../apache/groovy/parser/antlr4/AstBuilder.java | 13 ++-
2 files changed, 115 insertions(+), 7 deletions(-)
diff --git a/src/test/groovy/bugs/Groovy9259.groovy b/src/test/groovy/bugs/Groovy9259.groovy
new file mode 100644
index 0000000..2fdf302
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9259.groovy
@@ -0,0 +1,109 @@
+/*
+ * 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 org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy9259 {
+
+ @Test
+ void testInterfaceAndTrait() {
+ def config = new CompilerConfiguration(
+ targetDirectory: File.createTempDir(),
+ jointCompilationOptions: [memStub: true]
+ )
+
+ def parentDir = File.createTempDir()
+ try {
+ def a = new File(parentDir, 'J.java')
+ a.write '''
+ public interface J {
+ String m();
+ }
+ '''
+ def b = new File(parentDir, 'G.groovy')
+ b.write '''
+ interface G extends J {
+ default String m() {
+ 'G'
+ }
+ }
+ '''
+ def c = new File(parentDir, 'Main.groovy')
+ c.write '''
+ class C implements G {
+ @Override String m() {
+ 'C'
+ }
+ }
+
+ @groovy.transform.CompileStatic
+ void test() {
+ J obj = new C()
+ def x = obj.m()
+ assert x == 'C'
+ }
+ test()
+ '''
+
+ def loader = new GroovyClassLoader(this.class.classLoader)
+ def cu = new JavaAwareCompilationUnit(config, loader)
+ cu.addSources(a, b, c)
+ cu.compile()
+
+ loader.loadClass('Main').main()
+ } finally {
+ parentDir.deleteDir()
+ config.targetDirectory.deleteDir()
+ }
+ }
+
+ @Test
+ void testInterfacesAndTrait() {
+ assertScript '''
+ interface A {
+ String m()
+ }
+ interface B {
+ String m()
+ }
+ interface C extends A, B {
+ default String m() {
+ 'C'
+ }
+ }
+
+ @groovy.transform.CompileStatic
+ void test() {
+ A one = new C() {}
+ def x = one.m()
+ assert x == 'C'
+
+ B two = new C() {}
+ def y = two.m()
+ assert y == 'C'
+ }
+ test()
+ '''
+ }
+}
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 2029a5d..6d4e23b 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -1011,24 +1011,23 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
classNode.putNodeMetaData(CLASS_NAME, className);
- if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT()) || isInterfaceWithDefaultMethods) {
- ClassNode superClass;
+ if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT())) {
if (asBoolean(ctx.scs)) {
ClassNode[] scs = this.visitTypeList(ctx.scs);
if (scs.length > 1) {
throw createParsingFailedException("Cannot extend multiple classes", ctx.EXTENDS());
}
- superClass = scs[0];
- } else {
- superClass = ClassHelper.OBJECT_TYPE;
+ classNode.setSuperClass(scs[0]);
}
- classNode.setSuperClass(superClass);
classNode.setInterfaces(this.visitTypeList(ctx.is));
this.initUsingGenerics(classNode);
+ } else if (isInterfaceWithDefaultMethods) { // GROOVY-9259
+ classNode.setInterfaces(this.visitTypeList(ctx.scs));
+ this.initUsingGenerics(classNode);
+
} else if (isInterface) {
classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT);
- classNode.setSuperClass(ClassHelper.OBJECT_TYPE);
classNode.setInterfaces(this.visitTypeList(ctx.scs));
this.initUsingGenerics(classNode);
this.hackMixins(classNode);
[groovy] 04/04: GROOVY-10478: SC: indicate dynamic resolution of trait super fallback
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 008ae02815a79d27d082e6d883aa40eb98e17368
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Feb 23 17:57:23 2022 -0600
GROOVY-10478: SC: indicate dynamic resolution of trait super fallback
---
.../classgen/asm/sc/StaticInvocationWriter.java | 3 +-
.../groovy/transform/trait/TraitComposer.java | 2 ++
src/test/groovy/bugs/Groovy10478.groovy | 32 ++++++++++++++++++++++
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index b6f6900..d56e3c7 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -519,8 +519,7 @@ public class StaticInvocationWriter extends InvocationWriter {
@Override
public void makeCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spreadSafe, final boolean implicitThis) {
- ClassNode dynamicCallReturnType = origin.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
- if (dynamicCallReturnType != null) {
+ if (origin.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION) != null) {
StaticTypesWriterController staticController = (StaticTypesWriterController) controller;
if (origin instanceof MethodCallExpression) {
((MethodCallExpression) origin).setMethodTarget(null);
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index 78deb80..5a5c0c3 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -53,6 +53,7 @@ import org.codehaus.groovy.syntax.Token;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor;
import org.codehaus.groovy.transform.sc.StaticCompileTransformation;
+import org.codehaus.groovy.transform.stc.StaticTypesMarker;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
@@ -516,6 +517,7 @@ public abstract class TraitComposer {
);
MethodCallExpression superCall = callX(varX("super"), forwarderMethod.getName(), paramTuple);
+ superCall.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); //GROOVY-10478
superCall.setImplicitThis(false);
// if (this instanceof GeneratedGroovyProxy)
diff --git a/src/test/groovy/bugs/Groovy10478.groovy b/src/test/groovy/bugs/Groovy10478.groovy
new file mode 100644
index 0000000..a7e5868
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy10478.groovy
@@ -0,0 +1,32 @@
+package groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy10478 {
+
+ @Test
+ void testIndirectInterface() {
+ assertScript '''
+ trait A {
+ final String string = 'works'
+ }
+ interface B {
+ }
+ trait C implements A, B {
+ }
+ @groovy.transform.CompileStatic
+ class D implements C {
+ }
+
+ // VerifyError: Bad invokespecial instruction: interface method reference is in an indirect superinterface
+ // Location: D.Atrait$super$getString()Ljava/lang/String; @37: invokespecial
+ def cls = D.class
+ cls.name
+
+ String result = new D().string
+ assert result == 'works'
+ '''
+ }
+}
[groovy] 03/04: GROOVY-10505: mark trait super methods as generated
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit cb9b1c64283dceaf5063ea431fa44126050262f2
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Feb 23 17:33:17 2022 -0600
GROOVY-10505: mark trait super methods as generated
Conflicts:
src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
---
.../groovy/transform/trait/TraitComposer.java | 96 +++++++++-------------
1 file changed, 39 insertions(+), 57 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index b810a3f..78deb80 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -31,7 +31,6 @@ import org.codehaus.groovy.ast.PropertyNode;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.ArrayExpression;
import org.codehaus.groovy.ast.expr.BinaryExpression;
-import org.codehaus.groovy.ast.expr.BooleanExpression;
import org.codehaus.groovy.ast.expr.CastExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
@@ -39,11 +38,8 @@ import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.EmptyStatement;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.IfStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.ast.tools.GenericsUtils;
@@ -69,9 +65,16 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ifElseS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.isInstanceOfX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
@@ -118,7 +121,7 @@ public abstract class TraitComposer {
private static void checkTraitAllowed(final ClassNode bottomTrait, final SourceUnit unit) {
ClassNode superClass = bottomTrait.getSuperClass();
- if (superClass==null || ClassHelper.OBJECT_TYPE.equals(superClass)) return;
+ if (superClass == null || superClass.equals(ClassHelper.OBJECT_TYPE)) return;
if (!Traits.isTrait(superClass)) {
unit.addError(new SyntaxException("A trait can only inherit from another trait", superClass.getLineNumber(), superClass.getColumnNumber()));
}
@@ -470,18 +473,17 @@ public abstract class TraitComposer {
/**
* Creates a method to dispatch to "super traits" in a "stackable" fashion. The generated method looks like this:
- * <p>
- * <code>ReturnType trait$super$method(Class clazz, Arg1 arg1, Arg2 arg2, ...) {
- * if (SomeTrait.is(A) { return SomeOtherTrait$Trait$Helper.method(this, arg1, arg2) }
+ * <pre>ReturnType trait$super$method(Class clazz, Arg1 arg1, Arg2 arg2, ...) {
+ * if (SomeTrait.is(A) return SomeOtherTrait$Trait$Helper.method(this, arg1, arg2)
* super.method(arg1,arg2)
- * }</code>
- * </p>
+ * }
+ * </pre>
* @param targetNode
* @param forwarderMethod
* @param interfacesToGenerateForwarderFor
* @param genericsSpec
*/
- private static void doCreateSuperForwarder(ClassNode targetNode, MethodNode forwarderMethod, ClassNode[] interfacesToGenerateForwarderFor, Map<String,ClassNode> genericsSpec) {
+ private static void doCreateSuperForwarder(final ClassNode targetNode, final MethodNode forwarderMethod, final ClassNode[] interfacesToGenerateForwarderFor, final Map<String,ClassNode> genericsSpec) {
Parameter[] parameters = forwarderMethod.getParameters();
Parameter[] superForwarderParams = new Parameter[parameters.length];
for (int i = 0; i < parameters.length; i++) {
@@ -496,65 +498,45 @@ public abstract class TraitComposer {
if (targetNode.getDeclaredMethod(forwarderName, superForwarderParams) == null) {
ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, forwarderMethod.getReturnType());
Statement delegate = next == null ? createSuperFallback(forwarderMethod, returnType) : createDelegatingForwarder(forwarderMethod, next);
- MethodNode methodNode = targetNode.addMethod(forwarderName, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, returnType, superForwarderParams, ClassNode.EMPTY_ARRAY, delegate);
+
+ MethodNode methodNode = addGeneratedMethod(targetNode, forwarderName, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, returnType, superForwarderParams, ClassNode.EMPTY_ARRAY, delegate);
methodNode.setGenericsTypes(forwarderMethod.getGenericsTypes());
}
}
}
- private static Statement createSuperFallback(MethodNode forwarderMethod, ClassNode returnType) {
- ArgumentListExpression args = new ArgumentListExpression();
- Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
- for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
- args.addExpression(new VariableExpression(forwarderMethodParameter));
- }
- BinaryExpression instanceOfExpr = new BinaryExpression(new VariableExpression("this"), Token.newSymbol(Types.KEYWORD_INSTANCEOF, -1, -1), new ClassExpression(Traits.GENERATED_PROXY_CLASSNODE));
- MethodCallExpression superCall = new MethodCallExpression(
- new VariableExpression("super"),
- forwarderMethod.getName(),
- args
+ private static Statement createSuperFallback(final MethodNode forwarderMethod, final ClassNode returnType) {
+ ArgumentListExpression paramTuple = args(Arrays.stream(forwarderMethod.getParameters()).map(p -> varX(p)).toArray(Expression[]::new));
+
+ MethodCallExpression proxyTarget = callX(castX(Traits.GENERATED_PROXY_CLASSNODE, varX("this")), "getProxyTarget");
+ proxyTarget.setImplicitThis(false);
+
+ Expression proxyCall = callX(ClassHelper.make(InvokerHelper.class), "invokeMethod",
+ args(proxyTarget, constX(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, paramTuple.getExpressions()))
);
+
+ MethodCallExpression superCall = callX(varX("super"), forwarderMethod.getName(), paramTuple);
superCall.setImplicitThis(false);
- CastExpression proxyReceiver = new CastExpression(Traits.GENERATED_PROXY_CLASSNODE, new VariableExpression("this"));
- MethodCallExpression getProxy = new MethodCallExpression(proxyReceiver, "getProxyTarget", ArgumentListExpression.EMPTY_ARGUMENTS);
- getProxy.setImplicitThis(false);
- StaticMethodCallExpression proxyCall = new StaticMethodCallExpression(
- ClassHelper.make(InvokerHelper.class),
- "invokeMethod",
- new ArgumentListExpression(getProxy, new ConstantExpression(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, args.getExpressions()))
- );
- IfStatement stmt = new IfStatement(
- new BooleanExpression(instanceOfExpr),
- new ExpressionStatement(new CastExpression(returnType,proxyCall)),
- new ExpressionStatement(superCall)
+
+ // if (this instanceof GeneratedGroovyProxy)
+ // (ReturnType) InvokerHelper.invokeMethod(((GeneratedGroovyProxy) this).getProxyTarget(), "targetMethod", new Object[]{arguments})
+ // else
+ // super.targetMethod(arguments)
+ return ifElseS(
+ isInstanceOfX(varX("this"), Traits.GENERATED_PROXY_CLASSNODE),
+ stmt(castX(returnType, proxyCall)),
+ stmt(superCall)
);
- return stmt;
}
private static Statement createDelegatingForwarder(final MethodNode forwarderMethod, final ClassNode next) {
// generates --> next$Trait$Helper.method(this, arg1, arg2)
- TraitHelpersTuple helpers = Traits.findHelpers(next);
ArgumentListExpression args = new ArgumentListExpression();
- args.addExpression(new VariableExpression("this"));
- Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
- for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
- args.addExpression(new VariableExpression(forwarderMethodParameter));
- }
- StaticMethodCallExpression delegateCall = new StaticMethodCallExpression(
- helpers.getHelper(),
- forwarderMethod.getName(),
- args
- );
- Statement result;
- if (ClassHelper.VOID_TYPE.equals(forwarderMethod.getReturnType())) {
- BlockStatement stmt = new BlockStatement();
- stmt.addStatement(new ExpressionStatement(delegateCall));
- stmt.addStatement(new ReturnStatement(new ConstantExpression(null)));
- result = stmt;
- } else {
- result = new ReturnStatement(delegateCall);
- }
- return result;
+ args.addExpression(varX("this"));
+ for (Parameter p : forwarderMethod.getParameters()) args.addExpression(varX(p));
+ Expression delegateCall = callX(Traits.findHelper(next), forwarderMethod.getName(), args);
+
+ return forwarderMethod.isVoidMethod() ? block(stmt(delegateCall), returnS(nullX())) : returnS(delegateCall);
}
private static ClassNode[] copyExceptions(final ClassNode[] sourceExceptions) {
[groovy] 01/04: GROOVY-5726: source range of method call in command expression
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 0c94914c19af0a608ceda7738de99ee708f3604b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Feb 7 12:12:09 2022 -0600
GROOVY-5726: source range of method call in command expression
range of call only covered argument(s)
`foo bar baz` --> `this.foo(bar).baz`
Conflicts:
src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
---
.../apache/groovy/parser/antlr4/AstBuilder.java | 48 ++++++++--------------
1 file changed, 16 insertions(+), 32 deletions(-)
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index fe74d10..2029a5d 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -1866,7 +1866,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
boolean hasArgumentList = asBoolean(ctx.enhancedArgumentListInPar());
boolean hasCommandArgument = asBoolean(ctx.commandArgument());
- if (visitingArrayInitializerCount > 0 && (hasArgumentList || hasCommandArgument)) {
+ if ((hasArgumentList || hasCommandArgument) && visitingArrayInitializerCount > 0) {
// To avoid ambiguities, command chain expression should not be used in array initializer
// the old parser does not support either, so no breaking changes
// SEE http://groovy.329449.n5.nabble.com/parrot-Command-expressions-in-array-initializer-tt5752273.html
@@ -1875,13 +1875,9 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
Expression baseExpr = (Expression) this.visit(ctx.expression());
-
- if (hasArgumentList || hasCommandArgument) {
- if (baseExpr instanceof BinaryExpression) {
- if (!"[".equals(((BinaryExpression) baseExpr).getOperation().getText()) && !isInsideParentheses(baseExpr)) {
- throw createParsingFailedException("Unexpected input: '" + getOriginalText(ctx.expression()) + "'", ctx.expression());
- }
- }
+ if ((hasArgumentList || hasCommandArgument) && !isInsideParentheses(baseExpr)
+ && baseExpr instanceof BinaryExpression && !"[".equals(((BinaryExpression) baseExpr).getOperation().getText())) {
+ throw createParsingFailedException("Unexpected input: '" + getOriginalText(ctx.expression()) + "'", ctx.expression());
}
MethodCallExpression methodCallExpression = null;
@@ -1890,54 +1886,44 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
Expression arguments = this.visitEnhancedArgumentListInPar(ctx.enhancedArgumentListInPar());
if (baseExpr instanceof PropertyExpression) { // e.g. obj.a 1, 2
- methodCallExpression =
- configureAST(
- this.createMethodCallExpression(
- (PropertyExpression) baseExpr, arguments),
- arguments);
+ methodCallExpression = configureAST(this.createMethodCallExpression((PropertyExpression) baseExpr, arguments), ctx.expression(), arguments);
} else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) { // e.g. m {} a, b OR m(...) a, b
if (asBoolean(arguments)) {
// The error should never be thrown.
throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList");
}
-
methodCallExpression = (MethodCallExpression) baseExpr;
- } else if (
- !isInsideParentheses(baseExpr)
- && (baseExpr instanceof VariableExpression /* e.g. m 1, 2 */
- || baseExpr instanceof GStringExpression /* e.g. "$m" 1, 2 */
- || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)) /* e.g. "m" 1, 2 */)
- ) {
+
+ } else if (!isInsideParentheses(baseExpr)
+ && (baseExpr instanceof VariableExpression // e.g. m 1, 2
+ || baseExpr instanceof GStringExpression // e.g. "$m" 1, 2
+ || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)))) { // e.g. "m" 1, 2
validateInvalidMethodDefinition(baseExpr, arguments);
- methodCallExpression =
- configureAST(
- this.createMethodCallExpression(baseExpr, arguments),
- arguments);
+ methodCallExpression = configureAST(this.createMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
} else { // e.g. a[x] b, new A() b, etc.
- methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), arguments);
+ methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
}
- methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, true);
+ methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
if (!hasCommandArgument) {
- return configureAST(methodCallExpression, ctx);
+ return methodCallExpression;
}
}
if (hasCommandArgument) {
- baseExpr.putNodeMetaData(IS_COMMAND_EXPRESSION, true);
+ baseExpr.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
}
return configureAST(
(Expression) ctx.commandArgument().stream()
.map(e -> (Object) e)
- .reduce(null == methodCallExpression ? baseExpr : methodCallExpression,
+ .reduce(methodCallExpression != null ? methodCallExpression : baseExpr,
(r, e) -> {
CommandArgumentContext commandArgumentContext = (CommandArgumentContext) e;
commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r);
-
return this.visitCommandArgument(commandArgumentContext);
}
),
@@ -2091,7 +2077,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
Expression namePartExpr = this.visitNamePart(ctx.namePart());
GenericsType[] genericsTypes = this.visitNonWildcardTypeArguments(ctx.nonWildcardTypeArguments());
-
if (asBoolean(ctx.DOT())) {
boolean isSafeChain = this.isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
return this.createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, isSafeChain);
@@ -2490,7 +2475,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
public Tuple2<Token, Expression> visitIndexPropertyArgs(final IndexPropertyArgsContext ctx) {
List<Expression> expressionList = this.visitExpressionList(ctx.expressionList());
-
if (expressionList.size() == 1) {
Expression expr = expressionList.get(0);