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 2021/06/19 10:08:23 UTC

[groovy] branch danielsun/tweak-build updated: Tweak getting lookup

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch danielsun/tweak-build
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/danielsun/tweak-build by this push:
     new dd62bd0  Tweak getting lookup
dd62bd0 is described below

commit dd62bd0f7f9130ab2326643237ea4f1b96edaa75
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 19 18:04:53 2021 +0800

    Tweak getting lookup
---
 .../org/apache/groovy/lang/GroovyObjectHelper.java | 33 ++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/groovy/lang/GroovyObjectHelper.java b/src/main/java/org/apache/groovy/lang/GroovyObjectHelper.java
index 7782abd..52a2b8c 100644
--- a/src/main/java/org/apache/groovy/lang/GroovyObjectHelper.java
+++ b/src/main/java/org/apache/groovy/lang/GroovyObjectHelper.java
@@ -24,6 +24,8 @@ import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -45,18 +47,45 @@ public class GroovyObjectHelper {
         Lookup lookup = lookupAtomicRef.get();
         if (null != lookup) return Optional.of(lookup);
 
-        lookup = doLookup(groovyObject);
+
+        final Class<? extends GroovyObject> groovyObjectClass = groovyObject.getClass();
+        if (groovyObjectClass.isMemberClass() && Modifier.isStatic(groovyObjectClass.getModifiers())) {
+            List<Class<?>> classList = new ArrayList<>(3);
+            for (Class<?> clazz = groovyObjectClass; null != clazz; clazz = clazz.getEnclosingClass()) {
+                if (isNonStaticInnerClass(clazz)) {
+                    return Optional.empty();
+                }
+                classList.add(clazz);
+            }
+
+            Lookup caller = MethodHandles.lookup();
+            for (int i = classList.size() - 1; i >= 0; i--) {
+                Class<?> c = classList.get(i);
+                caller = doLookup(c, caller);
+                if (null == caller) {
+                    return Optional.empty();
+                }
+            }
+            lookup = caller;
+        } else {
+            lookup = doLookup(groovyObject);
+        }
+
         if (null != lookup) lookupAtomicRef.set(lookup);
 
         return Optional.ofNullable(lookup);
     }
 
+    private static boolean isNonStaticInnerClass(Class<?> clazz) {
+        return clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers());
+    }
+
     private static Lookup doLookup(GroovyObject groovyObject) {
         MethodHandles.Lookup lookup;
         try {
             final Class<? extends GroovyObject> groovyObjectClass = groovyObject.getClass();
             if (groovyObjectClass.isAnonymousClass() ||
-                    (groovyObjectClass.isMemberClass() && !Modifier.isStatic(groovyObjectClass.getModifiers()))) {
+                    (isNonStaticInnerClass(groovyObjectClass))) {
                 lookup = (MethodHandles.Lookup) MethodHandles.lookup()
                         .unreflect(findGetLookupMethod(groovyObjectClass))
                         .bindTo(groovyObject)