
io.qt.internal.JavaMethodHandles Maven / Gradle / Ivy
package io.qt.internal;
import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaConversionException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import io.qt.QtUtilities;
import io.qt.core.QDataStream;
import io.qt.core.QMetaObject;
import io.qt.internal.LibraryUtility.OperatingSystem;
/**
* @hidden
*/
final class JavaMethodHandles implements ReflectionUtility.MethodInvocationHandler{
interface ProxyFactory{
public T asInterfaceInstance(final Class intfc, final MethodHandle target);
}
public final ProxyFactory resolvedProxyFactory;
interface MetaFactory{
public CallSite metafactory(MethodHandles.Lookup caller,
String interfaceMethodName,
MethodType factoryType,
MethodType interfaceMethodType,
MethodHandle implementation,
MethodType dynamicMethodType) throws LambdaConversionException;
}
public final MetaFactory resolvedMetaFactory;
interface AccessClass{
public Class> accessClass(MethodHandles.Lookup lookup, Class> targetClass) throws IllegalAccessException;
}
public AccessClass lookupAccessClass;
JavaMethodHandles() {
ProxyFactory _resolvedProxyFactory = null;
// #### MethodHandleProxies are slower than lambdas ####
// try {
// _resolvedProxyFactory = java.lang.invoke.MethodHandleProxies::asInterfaceInstance;
// }catch(Throwable t) {}
resolvedProxyFactory = _resolvedProxyFactory;
MetaFactory _resolvedMetaFactory = null;
try {
if(LibraryUtility.operatingSystem==OperatingSystem.Android) {
java.lang.invoke.LambdaMetafactory.class.getMethod("metafactory", MethodHandles.Lookup.class,
String.class,
MethodType.class,
MethodType.class,
MethodHandle.class,
MethodType.class);
}
_resolvedMetaFactory = java.lang.invoke.LambdaMetafactory::metafactory;
}catch(Throwable t) {}
resolvedMetaFactory = _resolvedMetaFactory;
AccessClass _lookupAccessClass = null;
try {
if(LibraryUtility.operatingSystem==OperatingSystem.Android) {
MethodHandles.Lookup.class.getMethod("accessClass", Class.class);
}
_lookupAccessClass = MethodHandles.Lookup::accessClass;
}catch(Throwable e) {
_lookupAccessClass = (_lookup,_cls)->_cls;
}
lookupAccessClass = _lookupAccessClass;
}
static MethodType wrap(MethodType mt) {
mt = mt.wrap().changeReturnType(void.class);
return mt;
}
@Override
@SuppressWarnings("unchecked")
public Function functionFromMethod(Method method){
if(method==null)
return null;
try {
Lookup lookup = ReflectionUtility.privateLookup(method.getDeclaringClass());
MethodHandle handle = lookup.unreflect(method);
if(resolvedMetaFactory!=null) {
try {
CallSite site = resolvedMetaFactory.metafactory(ReflectionUtility.privateLookup(method.getDeclaringClass()),
"apply",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
handle,
wrap(handle.type()));
return (Function)site.getTarget().invokeExact();
} catch (Throwable e) {
}
}
if(resolvedProxyFactory!=null) {
try {
return resolvedProxyFactory.asInterfaceInstance(Function.class, handle);
} catch (Throwable e) {
}
}
return a->{
try {
return (B)handle.invoke(a);
} catch (RuntimeException | Error e) {
throw e;
}catch(Throwable t) {
throw new RuntimeException(t);
}
};
} catch (IllegalAccessException e) {
return null;
}
}
@Override
@SuppressWarnings("unchecked")
public BiConsumer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy