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 2022/08/06 14:25:02 UTC
[groovy] branch master updated: Minor tweak: avoid throwing exceptions and extract variables
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 3fa69b2343 Minor tweak: avoid throwing exceptions and extract variables
3fa69b2343 is described below
commit 3fa69b2343fd9dfdf23ffb930e3c90cfa58b2593
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Aug 6 21:47:34 2022 +0800
Minor tweak: avoid throwing exceptions and extract variables
---
.../reflection/stdclasses/CachedSAMClass.java | 94 ++++++++++++----------
1 file changed, 50 insertions(+), 44 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/reflection/stdclasses/CachedSAMClass.java b/src/main/java/org/codehaus/groovy/reflection/stdclasses/CachedSAMClass.java
index 60d545c183..7483619106 100644
--- a/src/main/java/org/codehaus/groovy/reflection/stdclasses/CachedSAMClass.java
+++ b/src/main/java/org/codehaus/groovy/reflection/stdclasses/CachedSAMClass.java
@@ -33,15 +33,15 @@ import java.lang.reflect.Proxy;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
public class CachedSAMClass extends CachedClass {
- private static final int ABSTRACT_STATIC_PRIVATE =
- Modifier.ABSTRACT|Modifier.PRIVATE|Modifier.STATIC;
+ private static final int ABSTRACT_STATIC_PRIVATE = Modifier.ABSTRACT | Modifier.PRIVATE | Modifier.STATIC;
private static final int VISIBILITY = 5; // public|protected
private static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
private final Method method;
@@ -49,7 +49,7 @@ public class CachedSAMClass extends CachedClass {
public CachedSAMClass(Class klazz, ClassInfo classInfo) {
super(klazz, classInfo);
method = getSAMMethod(klazz);
- if (method==null) throw new GroovyBugError("assigned method should not have been null!");
+ if (method == null) throw new GroovyBugError("assigned method should not have been null!");
}
@Override
@@ -66,26 +66,23 @@ public class CachedSAMClass extends CachedClass {
/* Should we make the following method private? */
@SuppressWarnings("unchecked")
public static Object coerceToSAM(Closure argument, Method method, Class clazz, boolean isInterface) {
- if (argument!=null && clazz.isAssignableFrom(argument.getClass())) {
+ if (argument != null && clazz.isAssignableFrom(argument.getClass())) {
return argument;
}
+
+ final String name = method.getName();
if (isInterface) {
if (Traits.isTrait(clazz)) {
- Map<String,Closure> impl = Collections.singletonMap(
- method.getName(),
- argument
- );
- return ProxyGenerator.INSTANCE.instantiateAggregate(impl,Collections.singletonList(clazz));
+ Map<String, Closure> impl = Collections.singletonMap(name, argument);
+ return ProxyGenerator.INSTANCE.instantiateAggregate(impl, Collections.singletonList(clazz));
}
return Proxy.newProxyInstance(
clazz.getClassLoader(),
- new Class[]{clazz},
+ new Class[] { clazz },
new ConvertedClosure(argument));
} else {
- Map<String, Object> m = new HashMap<String,Object>();
- m.put(method.getName(), argument);
- return ProxyGenerator.INSTANCE.
- instantiateAggregateFromBaseClass(m, clazz);
+ Map<String, Object> m = Collections.singletonMap(name, argument);
+ return ProxyGenerator.INSTANCE.instantiateAggregateFromBaseClass(m, clazz);
}
}
@@ -100,49 +97,51 @@ public class CachedSAMClass extends CachedClass {
}
@SuppressWarnings("removal") // TODO a future Groovy version should remove the security check
- private static Method[] getDeclaredMethods(final Class c) {
+ private static Method[] getDeclaredMethods(final Class<?> c) {
try {
Method[] methods = java.security.AccessController.doPrivileged((PrivilegedAction<Method[]>) c::getDeclaredMethods);
- if (methods!=null) return methods;
+ if (methods != null) return methods;
} catch (java.security.AccessControlException ace) {
// swallow and do as if no method is available
}
return EMPTY_METHOD_ARRAY;
}
- private static void getAbstractMethods(Class c, List<Method> current) {
- if (c==null || !Modifier.isAbstract(c.getModifiers())) return;
+ private static void getAbstractMethods(Class<?> c, List<Method> current) {
+ if (c == null || !Modifier.isAbstract(c.getModifiers())) return;
getAbstractMethods(c.getSuperclass(), current);
- for (Class ci : c.getInterfaces()) {
+ for (Class<?> ci : c.getInterfaces()) {
getAbstractMethods(ci, current);
}
for (Method m : getDeclaredMethods(c)) {
- if (Modifier.isPrivate(m.getModifiers())) continue;
- if (Modifier.isAbstract(m.getModifiers())) current.add(m);
+ final int modifiers = m.getModifiers();
+ if (Modifier.isPrivate(modifiers)) continue;
+ if (Modifier.isAbstract(modifiers)) current.add(m);
}
}
- private static boolean hasUsableImplementation(Class c, Method m) {
- if (c==m.getDeclaringClass()) return false;
+ private static boolean hasUsableImplementation(Class<?> c, Method m) {
+ if (c == m.getDeclaringClass()) return false;
Method found;
try {
found = c.getMethod(m.getName(), m.getParameterTypes());
- int asp = found.getModifiers() & ABSTRACT_STATIC_PRIVATE;
- int visible = found.getModifiers() & VISIBILITY;
- if (visible !=0 && asp == 0) return true;
- } catch (NoSuchMethodException e) {/*ignore*/}
- if (c==Object.class) return false;
+ final int modifiers = found.getModifiers();
+ int asp = modifiers & ABSTRACT_STATIC_PRIVATE;
+ int visible = modifiers & VISIBILITY;
+ if (visible != 0 && asp == 0) return true;
+ } catch (NoSuchMethodException ignore) {
+ }
+ if (c == Object.class) return false;
return hasUsableImplementation(c.getSuperclass(), m);
}
private static Method getSingleNonDuplicateMethod(List<Method> current) {
- if (current.isEmpty()) return null;
- if (current.size()==1) return current.get(0);
+ final int size = current.size();
+ if (size == 0) return null;
+ if (size == 1) return current.get(0);
Method m = current.remove(0);
for (Method m2 : current) {
- if (m.getName().equals(m2.getName()) &&
- Arrays.equals(m.getParameterTypes(), m2.getParameterTypes()))
- {
+ if (m.getName().equals(m2.getName()) && Arrays.equals(m.getParameterTypes(), m2.getParameterTypes())) {
continue;
}
return null;
@@ -168,32 +167,39 @@ public class CachedSAMClass extends CachedClass {
// if the class is not abstract there is no abstract method
if (!Modifier.isAbstract(c.getModifiers())) return null;
if (c.isInterface()) {
- Method[] methods = c.getMethods();
// res stores the first found abstract method
Method res = null;
- for (Method mi : methods) {
+ for (Method mi : c.getMethods()) {
// ignore methods, that are not abstract and from Object
if (!Modifier.isAbstract(mi.getModifiers())) continue;
// ignore trait methods which have a default implementation
- if (mi.getAnnotation(Traits.Implemented.class)!=null) continue;
- try {
- Object.class.getMethod(mi.getName(), mi.getParameterTypes());
- continue;
- } catch (NoSuchMethodException e) {/*ignore*/}
+ if (mi.getAnnotation(Traits.Implemented.class) != null) continue;
+
+ final String name = mi.getName();
+ // avoid throwing `NoSuchMethodException` as possible as we could
+ if (OBJECT_METHOD_NAME_SET.contains(name)) {
+ try {
+ Object.class.getMethod(name, mi.getParameterTypes());
+ continue;
+ } catch (NoSuchMethodException ignore) {
+ }
+ }
// we have two methods, so no SAM
- if (res!=null) return null;
+ if (res != null) return null;
res = mi;
}
return res;
} else {
-
- LinkedList<Method> methods = new LinkedList();
+ List<Method> methods = new LinkedList<>();
getAbstractMethods(c, methods);
if (methods.isEmpty()) return null;
methods.removeIf(m -> hasUsableImplementation(c, m));
return getSingleNonDuplicateMethod(methods);
}
}
+
+ private static final Set<String> OBJECT_METHOD_NAME_SET =
+ Collections.unmodifiableSet(Arrays.stream(Object.class.getMethods()).map(m -> m.getName()).collect(Collectors.toSet()));
}