argument = asInterfaceInstance(argumentProperty.getLambdaInterface(), (MethodHandle) argument); actualArguments.add(argument);
public static Object samFilter(Class<?> type, Object value) { if (value instanceof FunctionReference) { return MethodHandleProxies.asInterfaceInstance(type, ((FunctionReference) value).handle()); } return value; }
/** * Turns a function reference into an instance of a single-method interface. * * @param interfaceClass the target single-method interface class. * @param target the implementation function reference. * @return an instance of {@code interfaceClass}. * @see java.lang.invoke.MethodHandleProxies#asInterfaceInstance(Class, java.lang.invoke.MethodHandle) */ public static Object asInterfaceInstance(Object interfaceClass, Object target) { require(interfaceClass instanceof Class, "interfaceClass must be a Class"); require(target instanceof FunctionReference, "target must be a FunctionReference"); return MethodHandleProxies.asInterfaceInstance((Class<?>) interfaceClass, ((FunctionReference) target).handle()); }
@Override public <T> Node resolve(ParseSession session, TypeToken<T> type) { // Evaluate target instance final Object target = this.node.evaluate(session).checkNotNull(session, "method " + name + "() invocation"); // Resolve instance method final Method shape = MethodUtil.findFunctionalMethod(type.getRawType()); final Method method = MethodUtil.findMatchingMethod(target.getClass(), this.name, true, shape.getGenericParameterTypes(), shape.getReturnType() != void.class ? shape.getReturnType() : null, false); // Create proxy final MethodHandles.Lookup lookup = MethodHandles.publicLookup(); try { final MethodHandle handle = lookup.unreflect(method).bindTo(target); return new ConstNode(new ConstValue(MethodHandleProxies.asInterfaceInstance(type.getRawType(), handle))); } catch (Exception e) { throw new EvalException("failed to resolve method `" + this.name + "' in object of type " + target.getClass().getName(), e); } } }
@Override public <T> Node resolve(ParseSession session, TypeToken<T> type) { // Evaluate target instance final Object target = this.node.evaluate(session).checkNotNull(session, "method " + name + "() invocation"); // Resolve instance method final Method shape = MethodUtil.findFunctionalMethod(type.getRawType()); final Method method = MethodUtil.findMatchingMethod(target.getClass(), this.name, true, shape.getGenericParameterTypes(), shape.getReturnType() != void.class ? shape.getReturnType() : null, false); // Create proxy final MethodHandles.Lookup lookup = MethodHandles.publicLookup(); try { final MethodHandle handle = lookup.unreflect(method).bindTo(target); return new ConstNode(new ConstValue(MethodHandleProxies.asInterfaceInstance(type.getRawType(), handle))); } catch (Exception e) { throw new EvalException("failed to resolve method `" + this.name + "' in object of type " + target.getClass().getName(), e); } } }
@Override public <T> Node resolve(ParseSession session, TypeToken<T> type) { // Get lookup final MethodHandles.Lookup lookup = MethodHandles.lookup(); // Get handle to this.invoke() final MethodType invokeMethodType = MethodType.methodType(Object.class, ParseSession.class, Object[].class); final MethodHandle invokeHandle; try { invokeHandle = lookup.findVirtual(LambdaNode.class, "invoke", invokeMethodType).bindTo(this); } catch (IllegalAccessException | NoSuchMethodException e) { throw new RuntimeException("internal error", e); } // Insert ParseSession as first parameter final MethodHandle invokeHandleWithSession = MethodHandles.insertArguments(invokeHandle, 0, session); // Enable varargs collection final MethodHandle invokeHandleWithSessionAndVarargs = invokeHandleWithSession.asVarargsCollector(Object[].class); // Create proxy final Object proxy = MethodHandleProxies.asInterfaceInstance(type.getRawType(), invokeHandleWithSessionAndVarargs); // Return node containing proxy return new ConstNode(new ConstValue(proxy)); }
@Override public <T> Node resolve(ParseSession session, TypeToken<T> type) { // Get lookup final MethodHandles.Lookup lookup = MethodHandles.lookup(); // Get handle to this.invoke() final MethodType invokeMethodType = MethodType.methodType(Object.class, ParseSession.class, Object[].class); final MethodHandle invokeHandle; try { invokeHandle = lookup.findVirtual(LambdaNode.class, "invoke", invokeMethodType).bindTo(this); } catch (IllegalAccessException | NoSuchMethodException e) { throw new RuntimeException("internal error", e); } // Insert ParseSession as first parameter final MethodHandle invokeHandleWithSession = MethodHandles.insertArguments(invokeHandle, 0, session); // Enable varargs collection final MethodHandle invokeHandleWithSessionAndVarargs = invokeHandleWithSession.asVarargsCollector(Object[].class); // Create proxy final Object proxy = MethodHandleProxies.asInterfaceInstance(type.getRawType(), invokeHandleWithSessionAndVarargs); // Return node containing proxy return new ConstNode(new ConstValue(proxy)); }
argument = asInterfaceInstance(argumentProperty.getLambdaInterface(), (MethodHandle) argument); actualArguments.add(argument);
argument = asInterfaceInstance(argumentProperty.getLambdaInterface(), (MethodHandle) argument); actualArguments.add(argument);
return new ConstNode(new ConstValue(MethodHandleProxies.asInterfaceInstance(type.getRawType(), handle))); } catch (NoSuchMethodException | IllegalAccessException | RuntimeException e) { throw new EvalException("failed to resolve method " + cl.getName() + "::" + this.name + " for " + type, e);
return new ConstNode(new ConstValue(MethodHandleProxies.asInterfaceInstance(type.getRawType(), handle))); } catch (NoSuchMethodException | IllegalAccessException | RuntimeException e) { throw new EvalException("failed to resolve method " + cl.getName() + "::" + this.name + " for " + type, e);