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/25 15:51:19 UTC

[groovy] 02/02: vmplugin: parameter names from class

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

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

commit 01025ba74d6c12baeab6dc205fd01f259fd4859d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Feb 25 09:36:28 2022 -0600

    vmplugin: parameter names from class
    
    2_5_X backport
---
 .../org/codehaus/groovy/vmplugin/v5/Java5.java     | 97 +++++++++++-----------
 .../org/codehaus/groovy/vmplugin/v7/Java7.java     |  9 +-
 .../org/codehaus/groovy/vmplugin/v8/Java8.java     | 45 ++++------
 3 files changed, 67 insertions(+), 84 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java b/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
index 5d95d62..2e02afa 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
@@ -50,6 +50,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.MalformedParameterizedTypeException;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -61,11 +62,24 @@ import java.util.List;
  * java 5 based functions
  */
 public class Java5 implements VMPlugin {
+
     private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
-    private static final Class[] PLUGIN_DGM = {PluginDefaultGroovyMethods.class};
     private static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
     private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
 
+    @Override
+    public int getVersion() {
+        return 5;
+    }
+
+    public Class[] getPluginDefaultGroovyMethods() {
+        return new Class[]{PluginDefaultGroovyMethods.class};
+    }
+
+    public Class[] getPluginStaticGroovyMethods() {
+        return EMPTY_CLASS_ARRAY;
+    }
+
     public void setAdditionalClassInformation(ClassNode cn) {
         setGenericsTypes(cn);
     }
@@ -148,14 +162,15 @@ public class Java5 implements VMPlugin {
     private ClassNode configureWildcardType(WildcardType wildcardType) {
         ClassNode base = ClassHelper.makeWithoutCaching("?");
         base.setRedirect(ClassHelper.OBJECT_TYPE);
-        //TODO: more than one lower bound for wildcards?
+
         ClassNode[] lowers = configureTypes(wildcardType.getLowerBounds());
-        ClassNode lower = null;
-        // TODO: is it safe to remove this? What was the original intention?
-        if (lowers != null) lower = lowers[0];
+        ClassNode[] uppers = configureTypes(wildcardType.getUpperBounds());
+        // beware of [Object] upper bounds; often it's <?> or <? super T>
+        if (lowers != null || wildcardType.getTypeName().equals("?")) {
+            uppers = null;
+        }
 
-        ClassNode[] upper = configureTypes(wildcardType.getUpperBounds());
-        GenericsType t = new GenericsType(base, upper, lower);
+        GenericsType t = new GenericsType(base, uppers, lowers != null ? lowers[0] : null);
         t.setWildcard(true);
 
         ClassNode ref = ClassHelper.makeWithoutCaching(Object.class, false);
@@ -196,14 +211,6 @@ public class Java5 implements VMPlugin {
         return gts;
     }
 
-    public Class[] getPluginDefaultGroovyMethods() {
-        return PLUGIN_DGM;
-    }
-
-    public Class[] getPluginStaticGroovyMethods() {
-        return EMPTY_CLASS_ARRAY;
-    }
-
     private void setAnnotationMetaData(Annotation[] annotations, AnnotatedNode an) {
         for (Annotation annotation : annotations) {
             AnnotationNode node = new AnnotationNode(ClassHelper.make(annotation.annotationType()));
@@ -373,7 +380,7 @@ public class Java5 implements VMPlugin {
             Method[] methods = clazz.getDeclaredMethods();
             for (Method m : methods) {
                 ClassNode ret = makeClassNode(compileUnit, m.getGenericReturnType(), m.getReturnType());
-                Parameter[] params = processParameters(compileUnit, m);
+                Parameter[] params = makeParameters(compileUnit, m.getGenericParameterTypes(), m.getParameterTypes(), m.getParameterAnnotations(), m);
                 ClassNode[] exceptions = makeClassNodes(compileUnit, m.getGenericExceptionTypes(), m.getExceptionTypes());
                 MethodNode mn = new MethodNode(m.getName(), m.getModifiers(), ret, params, exceptions, null);
                 mn.setSynthetic(m.isSynthetic());
@@ -384,15 +391,7 @@ public class Java5 implements VMPlugin {
             }
             Constructor[] constructors = clazz.getDeclaredConstructors();
             for (Constructor ctor : constructors) {
-                Type[] types = ctor.getGenericParameterTypes();
-                Parameter[] params1 = Parameter.EMPTY_ARRAY;
-                if (types.length > 0) {
-                    params1 = new Parameter[types.length];
-                    for (int i = 0; i < params1.length; i++) {
-                        params1[i] = makeParameter(compileUnit, types[i], ctor.getParameterTypes()[i], getConstructorParameterAnnotations(ctor)[i], "param" + i);
-                    }
-                }
-                Parameter[] params = params1;
+                Parameter[] params = makeParameters(compileUnit, ctor.getGenericParameterTypes(), ctor.getParameterTypes(), getConstructorParameterAnnotations(ctor), ctor);
                 ClassNode[] exceptions = makeClassNodes(compileUnit, ctor.getGenericExceptionTypes(), ctor.getExceptionTypes());
                 ConstructorNode cn = classNode.addConstructor(ctor.getModifiers(), params, exceptions, null);
                 setAnnotationMetaData(ctor.getAnnotations(), cn);
@@ -414,18 +413,6 @@ public class Java5 implements VMPlugin {
         }
     }
 
-    protected Parameter[] processParameters(CompileUnit compileUnit, Method m) {
-        Type[] types = m.getGenericParameterTypes();
-        Parameter[] params = Parameter.EMPTY_ARRAY;
-        if (types.length > 0) {
-            params = new Parameter[types.length];
-            for (int i = 0; i < params.length; i++) {
-                params[i] = makeParameter(compileUnit, types[i], m.getParameterTypes()[i], m.getParameterAnnotations()[i], "param" + i);
-            }
-        }
-        return params;
-    }
-
     /**
      * Synthetic parameters such as those added for inner class constructors may
      * not be included in the parameter annotations array. This is the case when
@@ -514,23 +501,36 @@ public class Java5 implements VMPlugin {
         return back.getPlainNodeReference();
     }
 
-    protected Parameter makeParameter(CompileUnit cu, Type type, Class cl, Annotation[] annotations, String name) {
-        ClassNode cn = makeClassNode(cu, type, cl);
-        Parameter parameter = new Parameter(cn, name);
-        setAnnotationMetaData(annotations, parameter);
-        return parameter;
+    private Parameter[] makeParameters(CompileUnit cu, Type[] types, Class[] cls, Annotation[][] parameterAnnotations, Member member) {
+        Parameter[] params = Parameter.EMPTY_ARRAY;
+        int n = types.length;
+        if (n > 0) {
+            params = new Parameter[n];
+            String[] names = new String[n];
+            fillParameterNames(names, member);
+            for (int i = 0; i < n; i += 1) {
+                setAnnotationMetaData(parameterAnnotations[i],
+                    params[i] = new Parameter(makeClassNode(cu, types[i], cls[i]), names[i]));
+            }
+        }
+        return params;
+    }
+
+    protected void fillParameterNames(String[] names, Member member) {
+        for (int i = 0, n = names.length; i < n; i += 1) {
+            names[i] = (i < ARGS.length ? ARGS[i] : "arg" + i);
+        }
     }
 
-    public void invalidateCallSites() {}
+    // arbitrary choice of first ten; maintaining this array prevents many thousands of "argN" string/char[] instances
+    private static final String[] ARGS = {"arg0", "arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg8", "arg9"};
 
-    @Override
-    public Object getInvokeSpecialHandle(Method m, Object receiver){
-        throw new GroovyBugError("getInvokeSpecialHandle requires at least JDK 7 wot private access to Lookup");
+    public void invalidateCallSites() {
     }
 
     @Override
-    public int getVersion() {
-        return 5;
+    public Object getInvokeSpecialHandle(Method m, Object receiver){
+        throw new GroovyBugError("getInvokeSpecialHandle requires at least JDK 7 wot private access to Lookup");
     }
 
     @Override
@@ -538,4 +538,3 @@ public class Java5 implements VMPlugin {
         throw new GroovyBugError("invokeHandle requires at least JDK 7");
     }
 }
-
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v7/Java7.java b/src/main/java/org/codehaus/groovy/vmplugin/v7/Java7.java
index 792ff14..782b70b 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v7/Java7.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v7/Java7.java
@@ -34,10 +34,6 @@ import java.security.PrivilegedAction;
  * ahead of this one.
  */
 public class Java7 extends Java6 {
-    @Override
-    public void invalidateCallSites() {
-    	IndyInterface.invalidateSwitchPoints();
-    }
 
     @Override
     public int getVersion() {
@@ -45,6 +41,11 @@ public class Java7 extends Java6 {
     }
 
     @Override
+    public void invalidateCallSites() {
+        IndyInterface.invalidateSwitchPoints();
+    }
+
+    @Override
     public Object getInvokeSpecialHandle(final Method method, final Object receiver) {
         if (getLookupConstructor() == null) {
             return super.getInvokeSpecialHandle(method, receiver);
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
index 3c1bc32..89a1ad6 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
@@ -20,20 +20,17 @@ package org.codehaus.groovy.vmplugin.v8;
 
 import groovy.lang.GroovyRuntimeException;
 import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.CompileUnit;
-import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.vmplugin.v7.Java7;
 
 import java.lang.annotation.ElementType;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.lang.reflect.Parameter;
 
 /**
  * Java 8 based functions.
@@ -42,24 +39,14 @@ import java.util.List;
  */
 public class Java8 extends Java7 {
 
-    private final Class<?>[] PLUGIN_DGM;
-
-    public Java8() {
-        super();
-        List<Class<?>> dgmClasses = new ArrayList<>();
-        Collections.addAll(dgmClasses, (Class<?>[]) super.getPluginDefaultGroovyMethods());
-        dgmClasses.add(PluginDefaultGroovyMethods.class);
-        PLUGIN_DGM = dgmClasses.toArray(new Class<?>[0]);
-    }
-
     @Override
-    public Class<?>[] getPluginDefaultGroovyMethods() {
-        return PLUGIN_DGM;
+    public int getVersion() {
+        return 8;
     }
 
     @Override
-    public int getVersion() {
-        return 8;
+    public Class<?>[] getPluginDefaultGroovyMethods() {
+        return new Class[]{org.codehaus.groovy.vmplugin.v5.PluginDefaultGroovyMethods.class, PluginDefaultGroovyMethods.class};
     }
 
     @Override
@@ -74,19 +61,15 @@ public class Java8 extends Java7 {
     }
 
     @Override
-    protected Parameter[] processParameters(CompileUnit compileUnit, Method m) {
-        java.lang.reflect.Parameter[] parameters = m.getParameters();
-        Type[] types = m.getGenericParameterTypes();
-        Parameter[] params = Parameter.EMPTY_ARRAY;
-        if (types.length > 0) {
-            params = new Parameter[types.length];
-            for (int i = 0; i < params.length; i++) {
-                java.lang.reflect.Parameter p = parameters[i];
-                String name = p.isNamePresent() ? p.getName() : "param" + i;
-                params[i] = makeParameter(compileUnit, types[i], m.getParameterTypes()[i], m.getParameterAnnotations()[i], name);
+    protected void fillParameterNames(String[] names, Member member) {
+        try {
+            Parameter[] parameters = ((Executable) member).getParameters();
+            for (int i = 0, n = names.length; i < n; i += 1) {
+                names[i] = parameters[i].getName();
             }
+        } catch (RuntimeException e) {
+            super.fillParameterNames(names, member);
         }
-        return params;
     }
 
     private static class LookupHolder {