8251538: Modernize and lint Dynalink code
Reviewed-by: sundar
This commit is contained in:
parent
9523001f65
commit
4b1b547020
@ -269,8 +269,7 @@ public class CallSiteDescriptor extends SecureLookupSupplier {
|
||||
final String mt = methodType.toString();
|
||||
final String l = getLookupPrivileged().toString();
|
||||
final String o = operation.toString();
|
||||
final StringBuilder b = new StringBuilder(o.length() + mt.length() + 1 + l.length());
|
||||
return b.append(o).append(mt).append('@').append(l).toString();
|
||||
return o + mt + '@' + l;
|
||||
}
|
||||
|
||||
private void assertChangeInvariants(final CallSiteDescriptor changed, final String caller) {
|
||||
|
@ -132,12 +132,9 @@ abstract class ClassMap<T> {
|
||||
final T newV = computeValue(clazz);
|
||||
assert newV != null;
|
||||
|
||||
final Boolean canReferenceDirectly = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
return InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader());
|
||||
}
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
final Boolean canReferenceDirectly = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) () -> InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader()),
|
||||
GET_CLASS_LOADER_CONTEXT);
|
||||
|
||||
// If allowed to strongly reference, put it in the fast map
|
||||
if(canReferenceDirectly) {
|
||||
|
@ -213,8 +213,7 @@ public final class DynamicLinker {
|
||||
|
||||
private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) {
|
||||
// Make a bound MH of invoke() for this linker and call site
|
||||
final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
|
||||
relinkCount));
|
||||
final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, relinkCount);
|
||||
// Make a MH that gathers all arguments to the invocation into an Object[]
|
||||
final MethodType type = callSite.getDescriptor().getMethodType();
|
||||
final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());
|
||||
|
@ -471,12 +471,9 @@ public final class DynamicLinkerFactory {
|
||||
}
|
||||
|
||||
private static ClassLoader getThreadContextClassLoader() {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader(),
|
||||
GET_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
|
||||
|
@ -246,7 +246,7 @@ public final class NamespaceOperation implements Operation {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return baseOperation.hashCode() + 31 * Arrays.hashCode(namespaces);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this namespace operation. Defined to
|
||||
|
@ -93,10 +93,10 @@ final class TypeConverterFactory {
|
||||
private final ConversionComparator[] comparators;
|
||||
private final MethodTypeConversionStrategy autoConversionStrategy;
|
||||
|
||||
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() {
|
||||
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<>() {
|
||||
@Override
|
||||
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
|
||||
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
|
||||
return new ClassMap<>(getClassLoader(sourceType)) {
|
||||
@Override
|
||||
protected MethodHandle computeValue(final Class<?> targetType) {
|
||||
try {
|
||||
@ -111,10 +111,10 @@ final class TypeConverterFactory {
|
||||
}
|
||||
};
|
||||
|
||||
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() {
|
||||
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<>() {
|
||||
@Override
|
||||
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
|
||||
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
|
||||
return new ClassMap<>(getClassLoader(sourceType)) {
|
||||
@Override
|
||||
protected MethodHandle computeValue(final Class<?> targetType) {
|
||||
if(!canAutoConvert(sourceType, targetType)) {
|
||||
@ -129,10 +129,10 @@ final class TypeConverterFactory {
|
||||
}
|
||||
};
|
||||
|
||||
private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<ClassMap<Boolean>>() {
|
||||
private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<>() {
|
||||
@Override
|
||||
protected ClassMap<Boolean> computeValue(final Class<?> sourceType) {
|
||||
return new ClassMap<Boolean>(getClassLoader(sourceType)) {
|
||||
return new ClassMap<>(getClassLoader(sourceType)) {
|
||||
@Override
|
||||
protected Boolean computeValue(final Class<?> targetType) {
|
||||
try {
|
||||
@ -148,12 +148,7 @@ final class TypeConverterFactory {
|
||||
};
|
||||
|
||||
private static ClassLoader getClassLoader(final Class<?> clazz) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return clazz.getClassLoader();
|
||||
}
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) clazz::getClassLoader, GET_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,10 +63,9 @@ package jdk.dynalink.beans;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
@ -172,7 +171,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
return str;
|
||||
}
|
||||
|
||||
final char c[] = str.toCharArray();
|
||||
final char[] c = str.toCharArray();
|
||||
c[0] = Character.toLowerCase(c0);
|
||||
return new String(c);
|
||||
}
|
||||
@ -232,8 +231,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
|
||||
}
|
||||
|
||||
private void addMember(final String name, final AccessibleObject ao, final Map<String, DynamicMethod> methodMap) {
|
||||
addMember(name, createDynamicMethod(ao), methodMap);
|
||||
private void addMember(final String name, final Executable m, final Map<String, DynamicMethod> methodMap) {
|
||||
addMember(name, createDynamicMethod(m), methodMap);
|
||||
}
|
||||
|
||||
private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) {
|
||||
@ -252,9 +251,9 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
* @param name the common name of the reflective members.
|
||||
* @return a dynamic method representing all the specified reflective members.
|
||||
*/
|
||||
static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObject> members, final Class<?> clazz, final String name) {
|
||||
static DynamicMethod createDynamicMethod(final Iterable<? extends Executable> members, final Class<?> clazz, final String name) {
|
||||
DynamicMethod dynMethod = null;
|
||||
for(final AccessibleObject method: members) {
|
||||
for(final Executable method: members) {
|
||||
dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
|
||||
}
|
||||
return dynMethod;
|
||||
@ -267,7 +266,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
* @param m the reflective member
|
||||
* @return the single dynamic method representing the reflective member
|
||||
*/
|
||||
private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) {
|
||||
private static SingleDynamicMethod createDynamicMethod(final Executable m) {
|
||||
if (m.isAnnotationPresent(CallerSensitive.class)) {
|
||||
// Method has @CallerSensitive annotation
|
||||
return new CallerSensitiveDynamicMethod(m);
|
||||
@ -282,8 +281,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
return new CallerSensitiveDynamicMethod(m);
|
||||
}
|
||||
// Proceed with non-caller sensitive
|
||||
final Member member = (Member)m;
|
||||
return new SimpleDynamicMethod(mh, member.getDeclaringClass(), member.getName(), m instanceof Constructor);
|
||||
return new SimpleDynamicMethod(mh, m.getDeclaringClass(), m.getName(), m instanceof Constructor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -294,7 +292,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
* @param m the method or constructor
|
||||
* @return the method handle
|
||||
*/
|
||||
private static MethodHandle unreflectSafely(final AccessibleObject m) {
|
||||
private static MethodHandle unreflectSafely(final Executable m) {
|
||||
if(m instanceof Method) {
|
||||
final Method reflMethod = (Method)m;
|
||||
final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod);
|
||||
@ -326,8 +324,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
@Override
|
||||
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
|
||||
throws Exception {
|
||||
final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
|
||||
|
||||
final MissingMemberHandlerFactory missingMemberHandlerFactory;
|
||||
final LinkerServices directLinkerServices;
|
||||
if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) {
|
||||
@ -436,14 +432,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
return getClassGuardedInvocationComponent(handler, type);
|
||||
}
|
||||
|
||||
static final <T> List<T> pop(final List<T> l) {
|
||||
return l.subList(1, l.size());
|
||||
}
|
||||
|
||||
MethodHandle getClassGuard(final CallSiteDescriptor desc) {
|
||||
return getClassGuard(desc.getMethodType());
|
||||
}
|
||||
|
||||
MethodHandle getClassGuard(final MethodType type) {
|
||||
return Guards.asType(classGuard, type);
|
||||
}
|
||||
@ -814,7 +802,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
|
||||
private static final MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
|
||||
"getPropertyGetterHandle", Object.class, Object.class), 1, Object.class);
|
||||
private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this);
|
||||
|
||||
@ -842,7 +830,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
|
||||
}
|
||||
|
||||
private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
|
||||
private static final MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
|
||||
"getDynamicMethod", Object.class, Object.class), 1, Object.class);
|
||||
private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);
|
||||
|
||||
@ -873,21 +861,21 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
* @return getter with same name, declared on the most generic superclass/interface of the declaring class
|
||||
*/
|
||||
private static Method getMostGenericGetter(final Method getter) {
|
||||
return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass());
|
||||
return getMostGenericGetter(getter.getName(), getter.getDeclaringClass());
|
||||
}
|
||||
|
||||
private static Method getMostGenericGetter(final String name, final Class<?> returnType, final Class<?> declaringClass) {
|
||||
private static Method getMostGenericGetter(final String name, final Class<?> declaringClass) {
|
||||
if(declaringClass == null) {
|
||||
return null;
|
||||
}
|
||||
// Prefer interfaces
|
||||
for(final Class<?> itf: declaringClass.getInterfaces()) {
|
||||
final Method itfGetter = getMostGenericGetter(name, returnType, itf);
|
||||
final Method itfGetter = getMostGenericGetter(name, itf);
|
||||
if(itfGetter != null) {
|
||||
return itfGetter;
|
||||
}
|
||||
}
|
||||
final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass());
|
||||
final Method superGetter = getMostGenericGetter(name, declaringClass.getSuperclass());
|
||||
if(superGetter != null) {
|
||||
return superGetter;
|
||||
}
|
||||
|
@ -93,17 +93,6 @@ class AccessibleMembersLookup {
|
||||
lookupAccessibleMembers(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an accessible method equivalent of a method.
|
||||
*
|
||||
* @param m the method whose accessible equivalent is requested.
|
||||
* @return the accessible equivalent for the method (can be the same as the passed in method), or null if there is
|
||||
* no accessible method equivalent.
|
||||
*/
|
||||
Method getAccessibleMethod(final Method m) {
|
||||
return m == null ? null : methods.get(new MethodSignature(m));
|
||||
}
|
||||
|
||||
Collection<Method> getMethods() {
|
||||
return methods.values();
|
||||
}
|
||||
@ -230,9 +219,8 @@ class AccessibleMembersLookup {
|
||||
// If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is
|
||||
// public, but some of its methods claim that their declaring class is non-public. We'll try superclasses
|
||||
// and implemented interfaces then looking for public ones.
|
||||
final Class<?>[] interfaces = clazz.getInterfaces();
|
||||
for(int i = 0; i < interfaces.length; i++) {
|
||||
lookupAccessibleMembers(interfaces[i]);
|
||||
for (final Class<?> itf: clazz.getInterfaces()) {
|
||||
lookupAccessibleMembers(itf);
|
||||
}
|
||||
final Class<?> superclass = clazz.getSuperclass();
|
||||
if(superclass != null) {
|
||||
|
@ -158,7 +158,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
|
||||
private enum CollectionType {
|
||||
ARRAY, LIST, MAP
|
||||
};
|
||||
}
|
||||
|
||||
private GuardedInvocationComponent getElementGetter(final ComponentLinkRequest req) throws Exception {
|
||||
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
|
||||
@ -241,7 +241,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
// Convert the key to a number if we're working with a list or array
|
||||
if (!isMap && name != null) {
|
||||
final Integer integer = convertKeyToInteger(name, linkerServices);
|
||||
if (integer == null || integer.intValue() < 0) {
|
||||
if (integer == null || integer < 0) {
|
||||
// key is not a non-negative integer, it can never address an
|
||||
// array or list element
|
||||
return INVALID_NAME;
|
||||
|
@ -133,7 +133,7 @@ import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||
* method.</p>
|
||||
*/
|
||||
public class BeansLinker implements GuardingDynamicLinker {
|
||||
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() {
|
||||
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<>() {
|
||||
@Override
|
||||
protected TypeBasedGuardingDynamicLinker computeValue(final Class<?> clazz) {
|
||||
// If ClassValue.put() were public, we could just pre-populate with these known mappings...
|
||||
|
@ -63,10 +63,8 @@ package jdk.dynalink.beans;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
@ -76,8 +74,6 @@ import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.SecureLookupSupplier;
|
||||
import jdk.dynalink.internal.AccessControlContextFactory;
|
||||
import jdk.dynalink.linker.support.Lookup;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
|
||||
|
||||
/**
|
||||
* A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is
|
||||
@ -90,21 +86,18 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
AccessControlContextFactory.createAccessControlContext(
|
||||
SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
// Typed as "AccessibleObject" as it can be either a method or a constructor.
|
||||
// If we were Java8-only, we could use java.lang.reflect.Executable
|
||||
private final AccessibleObject target;
|
||||
private final Executable target;
|
||||
private final MethodType type;
|
||||
|
||||
CallerSensitiveDynamicMethod(final AccessibleObject target) {
|
||||
CallerSensitiveDynamicMethod(final Executable target) {
|
||||
super(getName(target));
|
||||
this.target = target;
|
||||
this.type = getMethodType(target);
|
||||
}
|
||||
|
||||
private static String getName(final AccessibleObject target) {
|
||||
final Member m = (Member)target;
|
||||
private static String getName(final Executable m) {
|
||||
final boolean constructor = m instanceof Constructor;
|
||||
return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() :
|
||||
return getMethodNameWithSignature(getMethodType(m), constructor ? m.getName() :
|
||||
getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor);
|
||||
}
|
||||
|
||||
@ -113,12 +106,11 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
return type;
|
||||
}
|
||||
|
||||
private static MethodType getMethodType(final AccessibleObject ao) {
|
||||
final boolean isMethod = ao instanceof Method;
|
||||
final Class<?> rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor<?>)ao).getDeclaringClass();
|
||||
final Class<?>[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor<?>)ao).getParameterTypes();
|
||||
private static MethodType getMethodType(final Executable m) {
|
||||
final boolean isMethod = m instanceof Method;
|
||||
final Class<?> rtype = isMethod ? ((Method)m).getReturnType() : ((Constructor<?>)m).getDeclaringClass();
|
||||
final Class<?>[] ptypes = m.getParameterTypes();
|
||||
final MethodType type = MethodType.methodType(rtype, ptypes);
|
||||
final Member m = (Member)ao;
|
||||
return type.insertParameterTypes(0,
|
||||
isMethod ?
|
||||
Modifier.isStatic(m.getModifiers()) ?
|
||||
@ -129,18 +121,18 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
|
||||
@Override
|
||||
boolean isVarArgs() {
|
||||
return target instanceof Method ? ((Method)target).isVarArgs() : ((Constructor<?>)target).isVarArgs();
|
||||
return target.isVarArgs();
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle getTarget(final CallSiteDescriptor desc) {
|
||||
final MethodHandles.Lookup lookup = AccessController.doPrivileged(
|
||||
(PrivilegedAction<MethodHandles.Lookup>)()->desc.getLookup(),
|
||||
(PrivilegedAction<MethodHandles.Lookup>)desc::getLookup,
|
||||
GET_LOOKUP_CONTEXT);
|
||||
|
||||
if(target instanceof Method) {
|
||||
final MethodHandle mh = unreflect(lookup, (Method)target);
|
||||
if(Modifier.isStatic(((Member)target).getModifiers())) {
|
||||
if(Modifier.isStatic(target.getModifiers())) {
|
||||
return StaticClassIntrospector.editStaticMethodHandle(mh);
|
||||
}
|
||||
return mh;
|
||||
|
@ -102,12 +102,9 @@ class CheckRestrictedPackage {
|
||||
}
|
||||
// Do a package access check from within an access control context with no permissions
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
sm.checkPackageAccess(pkgName);
|
||||
return null;
|
||||
}
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
sm.checkPackageAccess(pkgName);
|
||||
return null;
|
||||
}, NO_PERMISSIONS_CONTEXT);
|
||||
} catch(final SecurityException e) {
|
||||
return true;
|
||||
|
@ -61,7 +61,6 @@
|
||||
package jdk.dynalink.beans;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
@ -94,10 +93,6 @@ final class ClassString {
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
ClassString(final MethodType type) {
|
||||
this(type.parameterArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if(!(other instanceof ClassString)) {
|
||||
@ -119,8 +114,8 @@ final class ClassString {
|
||||
public int hashCode() {
|
||||
if(hashCode == 0) {
|
||||
int h = 0;
|
||||
for(int i = 0; i < classes.length; ++i) {
|
||||
h ^= classes[i].hashCode();
|
||||
for(final Class<?> cls: classes) {
|
||||
h ^= cls.hashCode();
|
||||
}
|
||||
hashCode = h;
|
||||
}
|
||||
@ -133,16 +128,13 @@ final class ClassString {
|
||||
}
|
||||
|
||||
boolean isVisibleFrom(final ClassLoader classLoader) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
for(final Class<?> clazz: classes) {
|
||||
if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
|
||||
return false;
|
||||
}
|
||||
return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
|
||||
for(final Class<?> clazz: classes) {
|
||||
if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}, GET_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ import java.lang.invoke.MethodType;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import jdk.dynalink.linker.ConversionComparator.Comparison;
|
||||
import jdk.dynalink.linker.LinkerServices;
|
||||
import jdk.dynalink.linker.support.TypeUtilities;
|
||||
@ -81,29 +82,9 @@ class MaximallySpecific {
|
||||
* @return the list of maximally specific methods.
|
||||
*/
|
||||
static List<SingleDynamicMethod> getMaximallySpecificMethods(final List<SingleDynamicMethod> methods, final boolean varArgs) {
|
||||
return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null);
|
||||
return getMaximallySpecificMethods(methods, varArgs, null, null, SingleDynamicMethod::getMethodType);
|
||||
}
|
||||
|
||||
private abstract static class MethodTypeGetter<T> {
|
||||
abstract MethodType getMethodType(T t);
|
||||
}
|
||||
|
||||
private static final MethodTypeGetter<MethodHandle> METHOD_HANDLE_TYPE_GETTER =
|
||||
new MethodTypeGetter<MethodHandle>() {
|
||||
@Override
|
||||
MethodType getMethodType(final MethodHandle t) {
|
||||
return t.type();
|
||||
}
|
||||
};
|
||||
|
||||
private static final MethodTypeGetter<SingleDynamicMethod> DYNAMIC_METHOD_TYPE_GETTER =
|
||||
new MethodTypeGetter<SingleDynamicMethod>() {
|
||||
@Override
|
||||
MethodType getMethodType(final SingleDynamicMethod t) {
|
||||
return t.getMethodType();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime
|
||||
* specific conversion preferences.
|
||||
@ -115,21 +96,7 @@ class MaximallySpecific {
|
||||
*/
|
||||
static List<MethodHandle> getMaximallySpecificMethodHandles(final List<MethodHandle> methods, final boolean varArgs,
|
||||
final Class<?>[] argTypes, final LinkerServices ls) {
|
||||
return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific
|
||||
* conversion preferences.
|
||||
*
|
||||
* @param methods the list of methods
|
||||
* @param varArgs whether to assume the methods are varargs
|
||||
* @param argTypes concrete argument types for the invocation
|
||||
* @return the list of maximally specific methods.
|
||||
*/
|
||||
static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(final List<SingleDynamicMethod> methods,
|
||||
final boolean varArgs, final Class<?>[] argTypes, final LinkerServices ls) {
|
||||
return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER);
|
||||
return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, MethodHandle::type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,17 +109,17 @@ class MaximallySpecific {
|
||||
* @return the list of maximally specific methods.
|
||||
*/
|
||||
private static <T> List<T> getMaximallySpecificMethods(final List<T> methods, final boolean varArgs,
|
||||
final Class<?>[] argTypes, final LinkerServices ls, final MethodTypeGetter<T> methodTypeGetter) {
|
||||
final Class<?>[] argTypes, final LinkerServices ls, final Function<T, MethodType> methodTypeGetter) {
|
||||
if(methods.size() < 2) {
|
||||
return methods;
|
||||
}
|
||||
final LinkedList<T> maximals = new LinkedList<>();
|
||||
for(final T m: methods) {
|
||||
final MethodType methodType = methodTypeGetter.getMethodType(m);
|
||||
final MethodType methodType = methodTypeGetter.apply(m);
|
||||
boolean lessSpecific = false;
|
||||
for(final Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) {
|
||||
final T max = maximal.next();
|
||||
switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) {
|
||||
switch(isMoreSpecific(methodType, methodTypeGetter.apply(max), varArgs, argTypes, ls)) {
|
||||
case TYPE_1_BETTER: {
|
||||
maximal.remove();
|
||||
break;
|
||||
|
@ -67,9 +67,7 @@ import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -158,12 +156,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
invokables.removeAll(subtypingApplicables.getMethods());
|
||||
invokables.removeAll(methodInvocationApplicables.getMethods());
|
||||
invokables.removeAll(variableArityApplicables.getMethods());
|
||||
for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) {
|
||||
final SingleDynamicMethod m = it.next();
|
||||
if(!isApplicableDynamically(linkerServices, callSiteType, m)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
invokables.removeIf(m -> !isApplicableDynamically(linkerServices, callSiteType, m));
|
||||
|
||||
// If no additional methods can apply at invocation time, and there's more than one maximally specific method
|
||||
// based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an
|
||||
@ -206,12 +199,9 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
"getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
|
||||
|
||||
private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return callSiteDescriptor.getLookup().lookupClass().getClassLoader();
|
||||
}
|
||||
}, GET_CALL_SITE_CLASS_LOADER_CONTEXT);
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<ClassLoader>) () -> callSiteDescriptor.getLookup().lookupClass().getClassLoader(),
|
||||
GET_CALL_SITE_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -243,7 +233,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
// Case insensitive sorting, so e.g. "Object" doesn't come before "boolean".
|
||||
final Collator collator = Collator.getInstance();
|
||||
collator.setStrength(Collator.SECONDARY);
|
||||
Collections.sort(names, collator);
|
||||
names.sort(collator);
|
||||
|
||||
final String className = getClass().getName();
|
||||
// Class name length + length of signatures + 2 chars/per signature for indentation and newline +
|
||||
@ -257,7 +247,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
b.append(']');
|
||||
assert b.length() == totalLength;
|
||||
return b.toString();
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isApplicableDynamically(final LinkerServices linkerServices, final MethodType callSiteType,
|
||||
final SingleDynamicMethod m) {
|
||||
@ -327,7 +317,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
}
|
||||
|
||||
private boolean constructorFlagConsistent(final SingleDynamicMethod method) {
|
||||
return methods.isEmpty()? true : (methods.getFirst().isConstructor() == method.isConstructor());
|
||||
return methods.isEmpty() || methods.getFirst().isConstructor() == method.isConstructor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,7 +135,7 @@ class OverloadedMethod {
|
||||
MethodHandle.class, Object[].class);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private MethodHandle selectMethod(final Object[] args) throws NoSuchMethodException {
|
||||
private MethodHandle selectMethod(final Object[] args) {
|
||||
final Class<?>[] argTypes = new Class<?>[args.length];
|
||||
for(int i = 0; i < argTypes.length; ++i) {
|
||||
final Object arg = args[i];
|
||||
|
@ -248,7 +248,7 @@ abstract class SingleDynamicMethod extends DynamicMethod {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean canConvertTo(final LinkerServices linkerServices, final Class<?> to, final Object obj) {
|
||||
return obj == null ? false : linkerServices.canConvert(obj.getClass(), to);
|
||||
return obj != null && linkerServices.canConvert(obj.getClass(), to);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,7 +104,7 @@ import jdk.dynalink.StandardOperation;
|
||||
* {@link BeansLinker#getConstructorMethod(Class, String)}.
|
||||
*/
|
||||
public final class StaticClass implements Serializable {
|
||||
private static final ClassValue<StaticClass> staticClasses = new ClassValue<StaticClass>() {
|
||||
private static final ClassValue<StaticClass> staticClasses = new ClassValue<>() {
|
||||
@Override
|
||||
protected StaticClass computeValue(final Class<?> type) {
|
||||
return new StaticClass(type);
|
||||
|
@ -81,7 +81,7 @@ import jdk.dynalink.linker.support.Lookup;
|
||||
* Provides a linker for the {@link StaticClass} objects.
|
||||
*/
|
||||
class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
|
||||
private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<SingleClassStaticsLinker>() {
|
||||
private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<>() {
|
||||
@Override
|
||||
protected SingleClassStaticsLinker computeValue(final Class<?> clazz) {
|
||||
return new SingleClassStaticsLinker(clazz);
|
||||
|
@ -179,9 +179,8 @@ public class InternalTypeUtilities {
|
||||
if(sc != null) {
|
||||
collectAssignables(sc, c2, s);
|
||||
}
|
||||
final Class<?>[] itf = c1.getInterfaces();
|
||||
for(int i = 0; i < itf.length; ++i) {
|
||||
collectAssignables(itf[i], c2, s);
|
||||
for(final Class<?> itf: c1.getInterfaces()) {
|
||||
collectAssignables(itf, c2, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ public final class Guards {
|
||||
assert test.type().parameterCount() == 1;
|
||||
assert test.type().returnType() == Boolean.TYPE;
|
||||
return MethodHandles.permuteArguments(test.asType(test.type().changeParameterType(0, type.parameterType(pos))),
|
||||
type.changeReturnType(Boolean.TYPE), new int[] { pos });
|
||||
type.changeReturnType(Boolean.TYPE), pos);
|
||||
}
|
||||
|
||||
private static final MethodHandle IS_INSTANCE = Lookup.PUBLIC.findVirtual(Class.class, "isInstance",
|
||||
|
@ -64,7 +64,6 @@ import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
@ -72,8 +72,6 @@ import jdk.dynalink.linker.MethodTypeConversionStrategy;
|
||||
* Various static utility methods for working with Java types.
|
||||
*/
|
||||
public final class TypeUtilities {
|
||||
static final Class<Object> OBJECT_CLASS = Object.class;
|
||||
|
||||
private TypeUtilities() {
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,6 @@ package jdk.dynalink.support;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.linker.GuardedInvocation;
|
||||
@ -150,12 +149,9 @@ public class ChainedCallSite extends AbstractRelinkableCallSite {
|
||||
|
||||
// First, prune the chain of invalidated switchpoints, we always do this
|
||||
// We also remove any catches if the remove catches flag is set
|
||||
for(final Iterator<GuardedInvocation> it = newInvocations.iterator(); it.hasNext();) {
|
||||
final GuardedInvocation inv = it.next();
|
||||
if(inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
newInvocations.removeIf(inv ->
|
||||
inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)
|
||||
);
|
||||
|
||||
// prune() is allowed to invoke this method with invocation == null meaning we're just pruning the chain and not
|
||||
// adding any new invocations to it.
|
||||
|
Loading…
Reference in New Issue
Block a user