groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject [groovy] branch master updated: Minor refactoring: extract duplicated code of caches (#944)
Date Sat, 01 Jun 2019 16:37:13 GMT
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new e0033ff  Minor refactoring: extract duplicated code of caches (#944)
e0033ff is described below

commit e0033ff2866c32decdd26c4356ed0f64573623c5
Author: Daniel.Sun <sunlan@apache.org>
AuthorDate: Sat Jun 1 11:37:07 2019 -0500

    Minor refactoring: extract duplicated code of caches (#944)
---
 .../stc/AbstractExtensionMethodCache.java          | 135 +++++++++++++++++++++
 .../groovy/transform/stc/ExtensionMethodCache.java |  54 +++++++++
 .../transform/stc/StaticTypeCheckingSupport.java   | 130 +-------------------
 .../transform/MacroCallTransformingVisitor.java    |   4 +-
 .../groovy/macro/transform/MacroMethodsCache.java  | 104 +++-------------
 5 files changed, 209 insertions(+), 218 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
b/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
new file mode 100644
index 0000000..ae620ef
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/transform/stc/AbstractExtensionMethodCache.java
@@ -0,0 +1,135 @@
+package org.codehaus.groovy.transform.stc;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.runtime.m12n.ExtensionModule;
+import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner;
+import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule;
+import org.codehaus.groovy.runtime.memoize.EvictableCache;
+import org.codehaus.groovy.runtime.memoize.StampedCommonCache;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
+
+/**
+ * @since 3.0.0
+ */
+public abstract class AbstractExtensionMethodCache {
+    private final EvictableCache<ClassLoader, Map<String, List<MethodNode>>>
cache = new StampedCommonCache<>(new WeakHashMap<>());
+
+    public Map<String, List<MethodNode>> get(ClassLoader loader) {
+        return cache.getAndPut(loader, this::getMethodsFromClassLoader);
+    }
+
+    private Map<String, List<MethodNode>> getMethodsFromClassLoader(ClassLoader
classLoader) {
+        final List<ExtensionModule> modules = new LinkedList<>();
+        ExtensionModuleScanner scanner = new ExtensionModuleScanner(
+                module -> {
+                    if (!(module instanceof MetaInfExtensionModule)) return;
+
+                    boolean skip = false;
+                    for (ExtensionModule extensionModule : modules) {
+                        if (extensionModule.getName().equals(module.getName())) {
+                            skip = true;
+                            break;
+                        }
+                    }
+                    if (!skip) modules.add(module);
+                },
+                classLoader
+        );
+        scanner.scanClasspathModules();
+
+        return makeMethodsUnmodifiable(getMethods(modules));
+    }
+
+    /**
+     * Returns a map which contains, as the key, the name of a class. The value
+     * consists of a list of MethodNode, one for each groovy default method found
+     * which is applicable for this class.
+     *
+     * @param modules extension modules
+     * @return
+     */
+    private Map<String, List<MethodNode>> getMethods(List<ExtensionModule>
modules) {
+        Set<Class> instanceExtClasses = new LinkedHashSet<>();
+        Set<Class> staticExtClasses = new LinkedHashSet<>();
+        for (ExtensionModule module : modules) {
+            MetaInfExtensionModule extensionModule = (MetaInfExtensionModule) module;
+            instanceExtClasses.addAll(extensionModule.getInstanceMethodsExtensionClasses());
+            staticExtClasses.addAll(extensionModule.getStaticMethodsExtensionClasses());
+        }
+        Map<String, List<MethodNode>> methods = new HashMap<>();
+
+        addAdditionalClassesToScan(instanceExtClasses, staticExtClasses);
+
+        scan(methods, staticExtClasses, true);
+        scan(methods, instanceExtClasses, false);
+
+        return methods;
+    }
+
+    private Map<String, List<MethodNode>> makeMethodsUnmodifiable(Map<String,
List<MethodNode>> methods) {
+        for (Map.Entry<String, List<MethodNode>> entry : methods.entrySet())
{
+            methods.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
+        }
+
+        return Collections.unmodifiableMap(methods);
+    }
+
+    protected abstract void addAdditionalClassesToScan(Set<Class> instanceExtClasses,
Set<Class> staticExtClasses);
+
+    private void scan(Map<String, List<MethodNode>> accumulator, Iterable<Class>
allClasses, boolean isStatic) {
+        Predicate<MethodNode> methodFilter = getMethodFilter();
+        Function<MethodNode, String> methodMapper = getMethodMapper();
+
+        for (Class dgmLikeClass : allClasses) {
+            ClassNode cn = makeWithoutCaching(dgmLikeClass, true);
+            for (MethodNode methodNode : cn.getMethods()) {
+                if (!(methodNode.isStatic() && methodNode.isPublic()) || methodNode.getParameters().length
== 0) continue;
+                if (methodFilter.test(methodNode)) continue;
+
+                accumulate(accumulator, isStatic, methodNode, methodMapper);
+            }
+        }
+    }
+
+    protected abstract Predicate<MethodNode> getMethodFilter();
+    protected abstract Function<MethodNode, String> getMethodMapper();
+
+    private void accumulate(Map<String, List<MethodNode>> accumulator, boolean
isStatic, MethodNode metaMethod,
+                                   Function<MethodNode, String> mapperFunction) {
+
+        Parameter[] types = metaMethod.getParameters();
+        Parameter[] parameters = new Parameter[types.length - 1];
+        System.arraycopy(types, 1, parameters, 0, parameters.length);
+        ExtensionMethodNode node = new ExtensionMethodNode(
+                metaMethod,
+                metaMethod.getName(),
+                metaMethod.getModifiers(),
+                metaMethod.getReturnType(),
+                parameters,
+                ClassNode.EMPTY_ARRAY, null,
+                isStatic);
+        node.setGenericsTypes(metaMethod.getGenericsTypes());
+        ClassNode declaringClass = types[0].getType();
+        node.setDeclaringClass(declaringClass);
+
+        String key = mapperFunction.apply(metaMethod);
+
+        List<MethodNode> nodes = accumulator.computeIfAbsent(key, k -> new ArrayList<>());
+        nodes.add(node);
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/ExtensionMethodCache.java b/src/main/java/org/codehaus/groovy/transform/stc/ExtensionMethodCache.java
new file mode 100644
index 0000000..03ff0b1
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/transform/stc/ExtensionMethodCache.java
@@ -0,0 +1,54 @@
+package org.codehaus.groovy.transform.stc;
+
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
+import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods;
+import org.codehaus.groovy.runtime.m12n.ExtensionModule;
+import org.codehaus.groovy.vmplugin.VMPluginFactory;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * This class is used to make extension methods lookup faster. Basically, it will only
+ * collect the list of extension methods (see {@link ExtensionModule} if the list of
+ * extension modules has changed. It avoids recomputing the whole list each time we perform
+ * a method lookup.
+ */
+public class ExtensionMethodCache extends AbstractExtensionMethodCache {
+    public static final ExtensionMethodCache INSTANCE = new ExtensionMethodCache();
+
+    private ExtensionMethodCache() {}
+
+    @Override
+    protected void addAdditionalClassesToScan(Set<Class> instanceExtClasses, Set<Class>
staticExtClasses) {
+        Collections.addAll(instanceExtClasses, DefaultGroovyMethods.DGM_LIKE_CLASSES);
+        Collections.addAll(instanceExtClasses, DefaultGroovyMethods.ADDITIONAL_CLASSES);
+        staticExtClasses.add(DefaultGroovyStaticMethods.class);
+
+        instanceExtClasses.add(StaticTypeCheckingSupport.ObjectArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.BooleanArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.CharArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.ByteArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.ShortArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.IntArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.LongArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.FloatArrayStaticTypesHelper.class);
+        instanceExtClasses.add(StaticTypeCheckingSupport.DoubleArrayStaticTypesHelper.class);
+
+        Collections.addAll(instanceExtClasses, VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods());
+        Collections.addAll(staticExtClasses, VMPluginFactory.getPlugin().getPluginStaticGroovyMethods());
+    }
+
+    @Override
+    protected Predicate<MethodNode> getMethodFilter() {
+        return m -> !m.getAnnotations(StaticTypeCheckingSupport.Deprecated_TYPE).isEmpty();
+    }
+
+    @Override
+    protected Function<MethodNode, String> getMethodMapper() {
+        return m -> m.getParameters()[0].getType().getName();
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 2bad3ba..1490814 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -43,17 +43,9 @@ import org.codehaus.groovy.ast.tools.WideningCategories;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.CompilerConfiguration;
 import org.codehaus.groovy.control.Phases;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods;
-import org.codehaus.groovy.runtime.m12n.ExtensionModule;
-import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner;
-import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule;
-import org.codehaus.groovy.runtime.memoize.EvictableCache;
-import org.codehaus.groovy.runtime.memoize.StampedCommonCache;
 import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;
 import org.codehaus.groovy.tools.GroovyClass;
 import org.codehaus.groovy.transform.trait.Traits;
-import org.codehaus.groovy.vmplugin.VMPluginFactory;
 import org.objectweb.asm.Opcodes;
 
 import java.lang.reflect.InvocationTargetException;
@@ -71,7 +63,6 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
-import java.util.WeakHashMap;
 import java.util.regex.Matcher;
 
 import static java.lang.Math.min;
@@ -169,7 +160,7 @@ public abstract class StaticTypeCheckingSupport {
     protected static final ClassNode Deprecated_TYPE = makeWithoutCaching(Deprecated.class);
     protected static final ClassNode Matcher_TYPE = makeWithoutCaching(Matcher.class);
     protected static final ClassNode ArrayList_TYPE = makeWithoutCaching(ArrayList.class);
-    protected static final ExtensionMethodCache EXTENSION_METHOD_CACHE = new ExtensionMethodCache();
+    protected static final AbstractExtensionMethodCache EXTENSION_METHOD_CACHE = ExtensionMethodCache.INSTANCE;
     protected static final Map<ClassNode, Integer> NUMBER_TYPES = Collections.unmodifiableMap(
             new HashMap<ClassNode, Integer>() {
                 private static final long serialVersionUID = 8841951852732042766L;
@@ -320,7 +311,7 @@ public abstract class StaticTypeCheckingSupport {
     }
 
     protected static void findDGMMethodsForClassNode(final ClassLoader loader, ClassNode
clazz, String name, TreeSet<MethodNode> accumulator) {
-        List<MethodNode> fromDGM = EXTENSION_METHOD_CACHE.getExtensionMethods(loader).get(clazz.getName());
+        List<MethodNode> fromDGM = EXTENSION_METHOD_CACHE.get(loader).get(clazz.getName());
         if (fromDGM != null) {
             for (MethodNode node : fromDGM) {
                 if (node.getName().equals(name)) accumulator.add(node);
@@ -2286,123 +2277,6 @@ public abstract class StaticTypeCheckingSupport {
 
 
     /**
-     * This class is used to make extension methods lookup faster. Basically, it will only
-     * collect the list of extension methods (see {@link ExtensionModule} if the list of
-     * extension modules has changed. It avoids recomputing the whole list each time we perform
-     * a method lookup.
-     */
-    private static class ExtensionMethodCache {
-        private final EvictableCache<ClassLoader, Map<String, List<MethodNode>>>
cache = new StampedCommonCache<ClassLoader, Map<String, List<MethodNode>>>(new
WeakHashMap<ClassLoader, Map<String, List<MethodNode>>>());
-
-        public Map<String, List<MethodNode>> getExtensionMethods(ClassLoader
loader) {
-            return cache.getAndPut(
-                    loader,
-                    new EvictableCache.ValueProvider<ClassLoader, Map<String, List<MethodNode>>>()
{
-                        @Override
-                        public Map<String, List<MethodNode>> provide(final ClassLoader
key) {
-                            final List<ExtensionModule> modules = new LinkedList<ExtensionModule>();
-                            ExtensionModuleScanner scanner =
-                                    new ExtensionModuleScanner(
-                                            new ExtensionModuleScanner.ExtensionModuleListener()
{
-                                                public void onModule(final ExtensionModule
module) {
-                                                    boolean skip = false;
-                                                    for (ExtensionModule extensionModule
: modules) {
-                                                        if (extensionModule.getName().equals(module.getName()))
{
-                                                            skip = true;
-                                                            break;
-                                                        }
-                                                    }
-                                                    if (!skip) modules.add(module);
-                                                }
-                                            },
-                                            key
-                                    );
-                            scanner.scanClasspathModules();
-
-                            return Collections.unmodifiableMap(getDGMMethods(modules));
-                        }
-                    });
-        }
-
-        /**
-         * Returns a map which contains, as the key, the name of a class. The value
-         * consists of a list of MethodNode, one for each default groovy method found
-         * which is applicable for this class.
-         *
-         * @param modules
-         * @return
-         */
-        private static Map<String, List<MethodNode>> getDGMMethods(List<ExtensionModule>
modules) {
-            Set<Class> instanceExtClasses = new LinkedHashSet<Class>();
-            Set<Class> staticExtClasses = new LinkedHashSet<Class>();
-            for (ExtensionModule module : modules) {
-                if (module instanceof MetaInfExtensionModule) {
-                    MetaInfExtensionModule extensionModule = (MetaInfExtensionModule) module;
-                    instanceExtClasses.addAll(extensionModule.getInstanceMethodsExtensionClasses());
-                    staticExtClasses.addAll(extensionModule.getStaticMethodsExtensionClasses());
-                }
-            }
-            Map<String, List<MethodNode>> methods = new HashMap<String, List<MethodNode>>();
-            Collections.addAll(instanceExtClasses, DefaultGroovyMethods.DGM_LIKE_CLASSES);
-            Collections.addAll(instanceExtClasses, DefaultGroovyMethods.ADDITIONAL_CLASSES);
-            staticExtClasses.add(DefaultGroovyStaticMethods.class);
-
-            instanceExtClasses.add(ObjectArrayStaticTypesHelper.class);
-            instanceExtClasses.add(BooleanArrayStaticTypesHelper.class);
-            instanceExtClasses.add(CharArrayStaticTypesHelper.class);
-            instanceExtClasses.add(ByteArrayStaticTypesHelper.class);
-            instanceExtClasses.add(ShortArrayStaticTypesHelper.class);
-            instanceExtClasses.add(IntArrayStaticTypesHelper.class);
-            instanceExtClasses.add(LongArrayStaticTypesHelper.class);
-            instanceExtClasses.add(FloatArrayStaticTypesHelper.class);
-            instanceExtClasses.add(DoubleArrayStaticTypesHelper.class);
-
-            Collections.addAll(instanceExtClasses, VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods());
-            Collections.addAll(staticExtClasses, VMPluginFactory.getPlugin().getPluginStaticGroovyMethods());
-
-            scanClassesForDGMMethods(methods, staticExtClasses, true);
-            scanClassesForDGMMethods(methods, instanceExtClasses, false);
-
-            return methods;
-        }
-
-        private static void scanClassesForDGMMethods(Map<String, List<MethodNode>>
accumulator,
-                                                     Iterable<Class> allClasses, boolean
isStatic) {
-            for (Class dgmLikeClass : allClasses) {
-                ClassNode cn = makeWithoutCaching(dgmLikeClass, true);
-                for (MethodNode metaMethod : cn.getMethods()) {
-                    Parameter[] types = metaMethod.getParameters();
-                    if (metaMethod.isStatic() && metaMethod.isPublic() &&
types.length > 0
-                            && metaMethod.getAnnotations(Deprecated_TYPE).isEmpty())
{
-                        Parameter[] parameters = new Parameter[types.length - 1];
-                        System.arraycopy(types, 1, parameters, 0, parameters.length);
-                        ExtensionMethodNode node = new ExtensionMethodNode(
-                                metaMethod,
-                                metaMethod.getName(),
-                                metaMethod.getModifiers(),
-                                metaMethod.getReturnType(),
-                                parameters,
-                                ClassNode.EMPTY_ARRAY, null,
-                                isStatic);
-                        node.setGenericsTypes(metaMethod.getGenericsTypes());
-                        ClassNode declaringClass = types[0].getType();
-                        String declaringClassName = declaringClass.getName();
-                        node.setDeclaringClass(declaringClass);
-
-                        List<MethodNode> nodes = accumulator.get(declaringClassName);
-                        if (nodes == null) {
-                            nodes = new LinkedList<MethodNode>();
-                            accumulator.put(declaringClassName, nodes);
-                        }
-                        nodes.add(node);
-                    }
-                }
-            }
-        }
-
-    }
-
-    /**
      * @return true if the class node is either a GString or the LUB of String and GString.
      */
     public static boolean isGStringOrGStringStringLUB(ClassNode node) {
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
index 3109435..4e5c8d5 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroCallTransformingVisitor.java
@@ -34,6 +34,7 @@ import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.macro.runtime.MacroContext;
 import org.codehaus.groovy.macro.runtime.MacroStub;
 import org.codehaus.groovy.runtime.InvokerHelper;
+import org.codehaus.groovy.transform.stc.AbstractExtensionMethodCache;
 import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
 import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
 
@@ -58,6 +59,7 @@ class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
     private static final PropertyExpression MACRO_STUB_INSTANCE = new PropertyExpression(new
ClassExpression(MACRO_STUB_CLASS_NODE), "INSTANCE");
 
     private static final String MACRO_STUB_METHOD_NAME = "macroMethod";
+    private static final AbstractExtensionMethodCache MACRO_METHOD_CACHE = MacroMethodsCache.INSTANCE;
 
     private final SourceUnit sourceUnit;
     private final CompilationUnit unit;
@@ -114,7 +116,7 @@ class MacroCallTransformingVisitor extends ClassCodeVisitorSupport {
      * with @{@link org.codehaus.groovy.macro.runtime.Macro} annotation.
      */
     private List<MethodNode> findMacroMethods(String methodName, List<Expression>
callArguments) {
-        List<MethodNode> methods = MacroMethodsCache.get(classLoader).get(methodName);
+        List<MethodNode> methods = MACRO_METHOD_CACHE.get(classLoader).get(methodName);
 
         if (methods == null) {
             // Not a macro call
diff --git a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
index 9b84f21..184e0f1 100644
--- a/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
+++ b/subprojects/groovy-macro/src/main/groovy/org/codehaus/groovy/macro/transform/MacroMethodsCache.java
@@ -21,107 +21,33 @@ package org.codehaus.groovy.macro.transform;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.macro.runtime.Macro;
-import org.codehaus.groovy.runtime.m12n.ExtensionModule;
-import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner;
-import org.codehaus.groovy.runtime.m12n.MetaInfExtensionModule;
-import org.codehaus.groovy.runtime.memoize.EvictableCache;
-import org.codehaus.groovy.runtime.memoize.StampedCommonCache;
-import org.codehaus.groovy.transform.stc.ExtensionMethodNode;
+import org.codehaus.groovy.transform.stc.AbstractExtensionMethodCache;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
 
 /**
- * TODO share some code with {@link org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ExtensionMethodCache}
- *
  * @since 2.5.0
  */
-class MacroMethodsCache {
+class MacroMethodsCache extends AbstractExtensionMethodCache {
     private static final ClassNode MACRO_ANNOTATION_CLASS_NODE = ClassHelper.make(Macro.class);
-    private static final EvictableCache<ClassLoader, Map<String, List<MethodNode>>>
CACHE = new StampedCommonCache<ClassLoader, Map<String, List<MethodNode>>>(new
WeakHashMap<ClassLoader, Map<String, List<MethodNode>>>());
-
-    public static Map<String, List<MethodNode>> get(final ClassLoader classLoader)
{
-        return CACHE.getAndPut(classLoader, new EvictableCache.ValueProvider<ClassLoader,
Map<String, List<MethodNode>>>() {
-            @Override
-            public Map<String, List<MethodNode>> provide(ClassLoader key) {
-                return Collections.unmodifiableMap(getMacroMethodsFromClassLoader(key));
-            }
-        });
-    }
-
-    protected static Map<String, List<MethodNode>> getMacroMethodsFromClassLoader(ClassLoader
classLoader) {
-        final Map<String, List<MethodNode>> result = new HashMap<String, List<MethodNode>>();
-        ExtensionModuleScanner.ExtensionModuleListener listener = new ExtensionModuleScanner.ExtensionModuleListener()
{
-            @Override
-            public void onModule(ExtensionModule module) {
-                if (!(module instanceof MetaInfExtensionModule)) {
-                    return;
-                }
-
-                MetaInfExtensionModule extensionModule = (MetaInfExtensionModule) module;
-
-                scanExtClasses(result, extensionModule.getInstanceMethodsExtensionClasses(),
false);
-                scanExtClasses(result, extensionModule.getStaticMethodsExtensionClasses(),
true);
-            }
-        };
 
-        ExtensionModuleScanner macroModuleScanner = new ExtensionModuleScanner(listener,
classLoader);
+    public static final MacroMethodsCache INSTANCE = new MacroMethodsCache();
 
-        macroModuleScanner.scanClasspathModules();
+    private MacroMethodsCache() {}
 
-        for (Map.Entry<String, List<MethodNode>> entry : result.entrySet()) {
-            result.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
-        }
+    @Override
+    protected void addAdditionalClassesToScan(Set<Class> instanceExtClasses, Set<Class>
staticExtClasses) {}
 
-        return Collections.unmodifiableMap(result);
+    @Override
+    protected Predicate<MethodNode> getMethodFilter() {
+        return m -> m.getAnnotations(MACRO_ANNOTATION_CLASS_NODE).isEmpty();
     }
 
-    private static void scanExtClasses(Map<String, List<MethodNode>> accumulator,
List<Class> classes, boolean isStatic) {
-        for (Class dgmLikeClass : classes) {
-            ClassNode cn = ClassHelper.makeWithoutCaching(dgmLikeClass, true);
-            for (MethodNode metaMethod : cn.getMethods()) {
-                Parameter[] types = metaMethod.getParameters();
-                if (!(metaMethod.isStatic() && metaMethod.isPublic())) {
-                    continue;
-                }
-
-                if (types.length == 0) {
-                    continue;
-                }
-
-                if (metaMethod.getAnnotations(MACRO_ANNOTATION_CLASS_NODE).isEmpty()) {
-                    continue;
-                }
-
-                Parameter[] parameters = new Parameter[types.length - 1];
-                System.arraycopy(types, 1, parameters, 0, parameters.length);
-                ExtensionMethodNode node = new ExtensionMethodNode(
-                        metaMethod,
-                        metaMethod.getName(),
-                        metaMethod.getModifiers(),
-                        metaMethod.getReturnType(),
-                        parameters,
-                        ClassNode.EMPTY_ARRAY, null,
-                        isStatic);
-                node.setGenericsTypes(metaMethod.getGenericsTypes());
-                ClassNode declaringClass = types[0].getType();
-                node.setDeclaringClass(declaringClass);
-
-                List<MethodNode> macroMethods = accumulator.get(metaMethod.getName());
-
-                if (macroMethods == null) {
-                    macroMethods = new ArrayList<>();
-                    accumulator.put(metaMethod.getName(), macroMethods);
-                }
-
-                macroMethods.add(node);
-            }
-        }
+    @Override
+    protected Function<MethodNode, String> getMethodMapper() {
+        return m -> m.getName();
     }
 }


Mime
View raw message