You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by sh...@apache.org on 2016/07/17 15:24:34 UTC

groovy git commit: GROOVY-7862: Statically compiled calls to protected methods of an outerclass' superclass result in IllegalAccessErrors (closes #351)

Repository: groovy
Updated Branches:
  refs/heads/master c7171fd9e -> 38c2a64c7


GROOVY-7862: Statically compiled calls to protected methods of an outerclass' superclass result in IllegalAccessErrors (closes #351)


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

Branch: refs/heads/master
Commit: 38c2a64c72e346e09cc9f9da7ceff5a65aa3da8e
Parents: c7171fd
Author: Shil Sinha <sh...@gmail.com>
Authored: Wed Jun 15 19:16:34 2016 -0400
Committer: Shil Sinha <sh...@apache.org>
Committed: Sun Jul 17 10:22:36 2016 -0400

----------------------------------------------------------------------
 .../classgen/asm/sc/StaticInvocationWriter.java | 16 +++++++---------
 .../stc/StaticTypeCheckingVisitor.java          | 14 +++++++++++---
 .../sc/MethodCallsStaticCompilationTest.groovy  | 20 ++++++++++++++++++++
 3 files changed, 38 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/38c2a64c/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 4fd48c9..18b91c7 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -177,9 +177,12 @@ public class StaticInvocationWriter extends InvocationWriter {
         ClassNode lookupClassNode;
         if (target.isProtected()) {
             lookupClassNode = controller.getClassNode();
-            if (controller.isInClosure()) {
+            while (lookupClassNode != null && !lookupClassNode.isDerivedFrom(target.getDeclaringClass())) {
                 lookupClassNode = lookupClassNode.getOuterClass();
             }
+            if (lookupClassNode == null) {
+                return false;
+            }
         } else {
             lookupClassNode = target.getDeclaringClass().redirect();
         }
@@ -187,15 +190,8 @@ public class StaticInvocationWriter extends InvocationWriter {
         MethodNode bridge = bridges==null?null:bridges.get(target);
         if (bridge != null) {
             Expression fixedReceiver = receiver;
-            ClassNode declaringClass = bridge.getDeclaringClass();
             if (implicitThis && !controller.isInClosure()) {
-                ClassNode classNode = controller.getClassNode();
-                while (!classNode.isDerivedFrom(declaringClass)
-                        && !classNode.implementsInterface(declaringClass)
-                        && classNode instanceof InnerClassNode) {
-                    classNode = classNode.getOuterClass();
-                }
-                fixedReceiver = new PropertyExpression(new ClassExpression(classNode), "this");
+                fixedReceiver = new PropertyExpression(new ClassExpression(lookupClassNode), "this");
             }
             ArgumentListExpression newArgs = new ArgumentListExpression(target.isStatic()?new ConstantExpression(null):fixedReceiver);
             for (Expression expression : args.getExpressions()) {
@@ -286,6 +282,8 @@ public class StaticInvocationWriter extends InvocationWriter {
                     controller.getSourceUnit().addError(
                             new SyntaxException("Method " + target.getName() + " is protected in " + target.getDeclaringClass().toString(false),
                                     src.getLineNumber(), src.getColumnNumber(), src.getLastLineNumber(), src.getLastColumnNumber()));
+                } else if (!node.isDerivedFrom(target.getDeclaringClass()) && tryBridgeMethod(target, receiver, implicitThis, args)) {
+                    return true;
                 }
             }
             if (receiver != null) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/38c2a64c/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index bf53f52..ce7158e 100644
--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -369,9 +369,17 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             if (packageName==null) {
                 packageName = "";
             }
-            if ((Modifier.isPrivate(mods) && sameModule)
-                    || (Modifier.isProtected(mods) && !packageName.equals(enclosingClassNode.getPackageName()))) {
-                addPrivateFieldOrMethodAccess(source, sameModule? declaringClass : enclosingClassNode, StaticTypesMarker.PV_METHODS_ACCESS, mn);
+            if ((Modifier.isPrivate(mods) && sameModule)) {
+                addPrivateFieldOrMethodAccess(source, declaringClass, StaticTypesMarker.PV_METHODS_ACCESS, mn);
+            } else if (Modifier.isProtected(mods) && !packageName.equals(enclosingClassNode.getPackageName())
+                    && !implementsInterfaceOrIsSubclassOf(enclosingClassNode, declaringClass)) {
+                ClassNode cn = enclosingClassNode;
+                while ((cn = cn.getOuterClass()) != null) {
+                    if (implementsInterfaceOrIsSubclassOf(cn, declaringClass)) {
+                        addPrivateFieldOrMethodAccess(source, cn, StaticTypesMarker.PV_METHODS_ACCESS, mn);
+                        break;
+                    }
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/38c2a64c/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
index d392153..95d2b08 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/MethodCallsStaticCompilationTest.groovy
@@ -217,6 +217,7 @@ import groovy.transform.TypeCheckingMode//import org.codehaus.groovy.classgen.as
         '''
     }
 
+    //GROOVY-7863
     void testDoublyNestedPrivateMethodAccess() {
         assertScript '''
             class A {
@@ -239,6 +240,25 @@ import groovy.transform.TypeCheckingMode//import org.codehaus.groovy.classgen.as
         '''
     }
 
+    //GROOVY-7862
+    void testProtectedCallFromInnerClassInSeparatePackage() {
+        assertScript '''
+            import org.codehaus.groovy.classgen.asm.sc.MethodCallsStaticCompilationTest.Base
+            class SubBase extends Base {
+                class Inner {
+                    int test() {
+                        foo()
+                    }
+                }
+
+                int innerTest() {
+                    new Inner().test()
+                }
+            }
+            assert new SubBase().innerTest() == 123
+        '''
+    }
+
     public static class Base {
         protected int foo() {
             123