/** * Apply the chain of transforms and bind them to a constructor specified * using the end signature plus the given class. The constructor will * be retrieved using the given Lookup and must match the end signature's * arguments exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the constructor * @param target the constructor's class * @return the full handle chain, bound to the given constructor */ public MethodHandle invokeConstructorQuiet(MethodHandles.Lookup lookup, Class<?> target) { try { return invokeConstructor(lookup, target); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to a special method specified * using the end signature plus the given class and name. The method will * be retrieved using the given Lookup and must match the end signature * exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the method * @param name the name of the method to invoke * @param caller the calling class * @return the full handle chain, bound to the given method */ public MethodHandle invokeSpecialQuiet(MethodHandles.Lookup lookup, String name, Class<?> caller) { try { return invokeSpecial(lookup, name, caller); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to a static method specified * using the end signature plus the given class and method. The method will * be retrieved using the given Lookup and must match the end signature * exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to unreflect the method * @param method the Method to unreflect * @return the full handle chain, bound to the given method */ public MethodHandle invokeQuiet(MethodHandles.Lookup lookup, Method method) { try { return invoke(lookup, method); } catch (IllegalAccessException iae) { throw new InvalidTransformException(iae); } }
/** * Apply the chain of transforms and bind them to a static field retrieval specified * using the end signature plus the given class and name. The field must * match the end signature's return value and the end signature must take * no arguments. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the field * @param target the class in which the field is defined * @param name the field's name * @return the full handle chain, bound to the given field access */ public MethodHandle getStaticQuiet(MethodHandles.Lookup lookup, Class<?> target, String name) { try { return getStatic(lookup, target, name); } catch (IllegalAccessException | NoSuchFieldException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to an object field assignment specified * using the end signature plus the given class and name. The end signature must take * the target class or a subclass and the field's type as its arguments, and its return * type must be compatible with void. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the field * @param target the class in which the field is defined * @param name the field's name * @return the full handle chain, bound to the given field assignment */ public MethodHandle setStaticQuiet(MethodHandles.Lookup lookup, Class<?> target, String name) { try { return setStatic(lookup, target, name); } catch (IllegalAccessException | NoSuchFieldException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to a virtual method specified * using the end signature plus the given class and name. The method will * be retrieved using the given Lookup and must match the end signature * exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the method * @param name the name of the method to invoke * @return the full handle chain, bound to the given method */ public MethodHandle invokeVirtualQuiet(MethodHandles.Lookup lookup, String name) { try { return invokeVirtual(lookup, name); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to an object field retrieval specified * using the end signature plus the given class and name. The field must * match the end signature's return value and the end signature must take * the target class or a subclass as its only argument. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the field * @param name the field's name * @return the full handle chain, bound to the given field access */ public MethodHandle getFieldQuiet(MethodHandles.Lookup lookup, String name) { try { return getField(lookup, name); } catch (IllegalAccessException | NoSuchFieldException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to an object field assignment specified * using the end signature plus the given class and name. The end signature must take * the target class or a subclass and the field's type as its arguments, and its return * type must be compatible with void. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the field * @param name the field's name * @return the full handle chain, bound to the given field assignment */ public MethodHandle setFieldQuiet(MethodHandles.Lookup lookup, String name) { try { return setField(lookup, name); } catch (IllegalAccessException | NoSuchFieldException e) { throw new InvalidTransformException(e); } }
/** * Apply the chain of transforms and bind them to a static method specified * using the end signature plus the given class and name. The method will * be retrieved using the given Lookup and must match the end signature * exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the method * @param target the class in which to find the method * @param name the name of the method to invoke * @return the full handle chain, bound to the given method */ public MethodHandle invokeStaticQuiet(MethodHandles.Lookup lookup, Class<?> target, String name) { try { return invokeStatic(lookup, target, name); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
public MethodType down(MethodType type) { Class<?>[] types = new Class<?>[reorder.length]; for (int i = 0; i < reorder.length; i++) { int typeIndex = reorder[i]; if (typeIndex < 0 || typeIndex >= type.parameterCount()) { throw new InvalidTransformException("one or more permute indices (" + Arrays.toString(reorder) + ") out of bounds for " + source); } types[i] = type.parameterType(reorder[i]); } return MethodType.methodType(type.returnType(), types); }
public MethodType down(MethodType type) { int last = source.parameterCount() - 1; if (!source.parameterArray()[last].isArray()) { throw new InvalidTransformException("trailing argument is not []: " + source); } type = type.dropParameterTypes(last, last + 1); return type.appendParameterTypes(spreadTypes); }
} else { if (argType != type) { throw new InvalidTransformException("arguments matching " + pattern + " are not all of the same type");
public MethodType down(MethodType type) { int count = function.type().parameterCount(); switch (count) { case 0: return type.changeReturnType(void.class); case 1: return type.changeReturnType(function.type().parameterType(0)); default: throw new InvalidTransformException("return filter " + function + " does not accept zero or one argument"); } }
/** * Throw the current signature's sole Throwable argument. Return type * does not matter, since it will never return. * * @return a handle that has all transforms applied and which will eventually throw an exception */ public MethodHandle throwException() { if (type().parameterCount() != 1 || !Throwable.class.isAssignableFrom(type().parameterType(0))) { throw new InvalidTransformException("incoming signature must have one Throwable type as its sole argument: " + type()); } return invoke(MethodHandles.throwException(type().returnType(), type().parameterType(0).asSubclass(Throwable.class))); }
/** * Apply all transforms to an endpoint that does absolutely nothing. Useful for * creating exception handlers in void methods that simply ignore the exception. * * @return a handle that has all transforms applied and does nothing at its endpoint */ public MethodHandle nop() { if (type().returnType() != void.class) { throw new InvalidTransformException("must have void return type to nop: " + type()); } return invoke(Binder .from(type()) .drop(0, type().parameterCount()) .cast(Object.class) .constant(null)); }