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 2021/03/29 18:15:35 UTC
[groovy] branch GROOVY_3_0_X updated (f745b82 -> ffb6856)
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 f745b82 GROOVY-9974: extract generics connections: Closure<T> vs SAM return type
new ed35751 GROOVY-5728: anon. inner can use private constructor when super is outer
new ffb6856 GROOVY-8104: fix this$0 for closure with anon. inner class of inner type
The 2 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/InnerClassCompletionVisitor.java | 31 +++++++++++++++++--
.../groovy/classgen/InnerClassVisitor.java | 29 +++++++++++------
src/test/gls/innerClass/InnerClassTest.groovy | 36 ++++++++++++++++++----
.../stc/AnonymousInnerClassSTCTest.groovy | 17 ++++++++++
4 files changed, 96 insertions(+), 17 deletions(-)
[groovy] 01/02: GROOVY-5728: anon. inner can use private
constructor when super is outer
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 ed3575178050b467c5cdfecf2314a0a030df44f7
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Mar 20 10:51:07 2021 -0500
GROOVY-5728: anon. inner can use private constructor when super is outer
---
.../classgen/InnerClassCompletionVisitor.java | 31 ++++++++++++++++++++--
.../stc/AnonymousInnerClassSTCTest.groovy | 17 ++++++++++++
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
index 37336f0..eb4103e 100644
--- a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
@@ -46,8 +46,11 @@ import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorSuperX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorThisX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
@@ -73,7 +76,7 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme
}
@Override
- public void visitClass(ClassNode node) {
+ public void visitClass(final ClassNode node) {
classNode = node;
thisField = null;
InnerClassNode innerClass = null;
@@ -94,9 +97,33 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme
}
@Override
- public void visitConstructor(ConstructorNode node) {
+ public void visitConstructor(final ConstructorNode node) {
addThisReference(node);
super.visitConstructor(node);
+ // an anonymous inner class may use a private constructor (via a bridge) if its super class is also an outer class
+ if (((InnerClassNode) classNode).isAnonymous() && classNode.getOuterClasses().contains(classNode.getSuperClass())) {
+ ConstructorNode superCtor = classNode.getSuperClass().getDeclaredConstructor(node.getParameters());
+ if (superCtor != null && superCtor.isPrivate()) {
+ ClassNode superClass = classNode.getUnresolvedSuperClass();
+ makeBridgeConstructor(superClass, node.getParameters()); // GROOVY-5728
+ ConstructorCallExpression superCtorCall = getFirstIfSpecialConstructorCall(node.getCode());
+ ((TupleExpression) superCtorCall.getArguments()).addExpression(castX(superClass, nullX()));
+ }
+ }
+ }
+
+ private static void makeBridgeConstructor(final ClassNode c, final Parameter[] p) {
+ Parameter[] newP = new Parameter[p.length + 1];
+ for (int i = 0; i < p.length; i += 1) {
+ newP[i] = new Parameter(p[i].getType(), "p" + i);
+ }
+ newP[p.length] = new Parameter(c, "$anonymous");
+
+ if (c.getDeclaredConstructor(newP) == null) {
+ TupleExpression args = new TupleExpression();
+ for (int i = 0; i < p.length; i += 1) args.addExpression(varX(newP[i]));
+ addGeneratedConstructor(c, ACC_SYNTHETIC, newP, ClassNode.EMPTY_ARRAY, stmt(ctorThisX(args)));
+ }
}
private static String getTypeDescriptor(ClassNode node, boolean isStatic) {
diff --git a/src/test/groovy/transform/stc/AnonymousInnerClassSTCTest.groovy b/src/test/groovy/transform/stc/AnonymousInnerClassSTCTest.groovy
index 1fb7aac..822a712 100644
--- a/src/test/groovy/transform/stc/AnonymousInnerClassSTCTest.groovy
+++ b/src/test/groovy/transform/stc/AnonymousInnerClassSTCTest.groovy
@@ -207,4 +207,21 @@ class AnonymousInnerClassSTCTest extends StaticTypeCheckingTestCase {
}
'''
}
+
+ // GROOVY-5728
+ void testPrivateConstructorAndPublicStaticFactory() {
+ assertScript '''
+ abstract class A {
+ private A() { }
+ abstract answer()
+ static A create() {
+ return new A() { // IllegalAccessError when A$1 calls private constructor
+ def answer() { 42 }
+ }
+ }
+ }
+
+ assert A.create().answer() == 42
+ '''
+ }
}
[groovy] 02/02: GROOVY-8104: fix this$0 for closure with anon.
inner class of inner type
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 ffb6856474f7cf138eabd594fc22bb06fa7cf0e3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Mar 21 13:21:33 2021 -0500
GROOVY-8104: fix this$0 for closure with anon. inner class of inner type
3_0_X backport
class Outer {
class Inner {
// requires Outer reference
}
def x = { ->
new Inner() { // this.this$0 returns closure; call getThisObject()
}
}
}
---
.../groovy/classgen/InnerClassVisitor.java | 29 +++++++++++------
src/test/gls/innerClass/InnerClassTest.groovy | 36 ++++++++++++++++++----
2 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitor.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitor.java
index 4826404..2222c58 100644
--- a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitor.java
@@ -33,7 +33,7 @@ import org.codehaus.groovy.ast.VariableScope;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.TupleExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
@@ -48,6 +48,11 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.attrX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+
public class InnerClassVisitor extends InnerClassVisitorHelper implements Opcodes {
private ClassNode classNode;
@@ -290,14 +295,20 @@ public class InnerClassVisitor extends InnerClassVisitorHelper implements Opcode
// if constructor call is not in outer class, don't pass 'this' implicitly. Return.
if (parent == null) return;
- //add this parameter to node
- Expression argsExp = call.getArguments();
- if (argsExp instanceof TupleExpression) {
- TupleExpression argsListExp = (TupleExpression) argsExp;
- Expression this0 = VariableExpression.THIS_EXPRESSION;
- for (int i = 0; i != level; ++i)
- this0 = new PropertyExpression(this0, "this$0");
- argsListExp.getExpressions().add(0, this0);
+ Expression args = call.getArguments();
+ if (args instanceof TupleExpression) {
+ Expression this0 = varX("this"); // bypass closure
+ for (int i = 0; i != level; ++i) {
+ this0 = attrX(this0, constX("this$0"));
+ // GROOVY-8104: an anonymous inner class may still have closure nesting
+ if (i == 0 && classNode.getDeclaredField("this$0").getType().equals(ClassHelper.CLOSURE_TYPE)) {
+ MethodCallExpression getThis = callX(this0, "getThisObject");
+ getThis.setImplicitThis(false);
+ this0 = getThis;
+ }
+ }
+
+ ((TupleExpression) args).getExpressions().add(0, this0);
}
}
}
diff --git a/src/test/gls/innerClass/InnerClassTest.groovy b/src/test/gls/innerClass/InnerClassTest.groovy
index 3e56772..c280d6f 100644
--- a/src/test/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/gls/innerClass/InnerClassTest.groovy
@@ -18,7 +18,6 @@
*/
package gls.innerClass
-import groovy.test.NotYetImplemented
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilationFailedException
@@ -273,13 +272,38 @@ final class InnerClassTest {
'''
}
- @Test @NotYetImplemented
- void testNonStaticInnerClass2() {
- shouldFail CompilationFailedException, '''
+ @Test // GROOVY-8104
+ void testNonStaticInnerClass5() {
+ assertScript '''
class A {
- class B {}
+ void foo() {
+ C c = new C()
+ ['1','2','3'].each { obj ->
+ c.baz(obj, new I() {
+ @Override
+ void bar(Object o) {
+ B b = new B() // Could not find matching constructor for: A$B(A$_foo_closure1)
+ }
+ })
+ }
+ }
+
+ class B {
+ }
+ }
+
+ class C {
+ void baz(Object o, I i) {
+ i.bar(o)
+ }
}
- def x = new A.B() // requires reference to A
+
+ interface I {
+ void bar(Object o)
+ }
+
+ A a = new A()
+ a.foo()
'''
}