private static MethodHandle getBlockEscape(Signature signature) { Signature voidSignature = signature.changeReturn(void.class); MethodHandle escape = BLOCK_ESCAPES.get(voidSignature); if (escape == null) { escape = SmartBinder.from(voidSignature) .permute("block") .invoke(ESCAPE_BLOCK) .handle(); BLOCK_ESCAPES.put(voidSignature, escape); } return escape; }
private static MethodHandle getBlockEscape(Signature signature) { Signature voidSignature = signature.changeReturn(void.class); MethodHandle escape = BLOCK_ESCAPES.get(voidSignature); if (escape == null) { escape = SmartBinder.from(voidSignature) .permute("block") .invoke(ESCAPE_BLOCK) .handle(); BLOCK_ESCAPES.put(voidSignature, escape); } return escape; }
/** * Replace the return value with the given value, performing no other * processing of the original value. * * @param type the type for the new return value * @param value the new value to return * @return a new SmartHandle that returns the given value */ public SmartHandle returnValue(Class<?> type, Object value) { return new SmartHandle(signature.changeReturn(type), MethodHandles.filterReturnValue(handle, MethodHandles.constant(type, value))); }
/** * Use the given filter function to transform the return value at this * point in the binder. The filter will be inserted into the handle, and * return values will pass through it before continuing. * * The filter's argument must match the expected return value downstream * from this point in the binder, and the return value must match the * return value at this point in the binder. * * @param filter the function to use to transform the return value at this point * @return a new SmartBinder with the filter applied */ public SmartBinder filterReturn(MethodHandle filter) { return new SmartBinder(this, signature().changeReturn(filter.type().returnType()), binder.filterReturn(filter)); }
/** * Cast the return value to the given type. * * Example: Our current signature is (String)String but the method this * handle will eventually call returns CharSequence. * * <code>binder = binder.castReturn(CharSequence.class);</code> * * Our handle will now successfully find and call the target method and * propagate the returned CharSequence as a String. * * @param type the new type for the return value * @return a new SmartBinder */ public SmartBinder castReturn(Class<?> type) { return new SmartBinder(this, signature().changeReturn(type), binder.cast(type, binder.type().parameterArray())); }
/** * Use the given filter function to transform the return value at this * point in the binder. The filter will be inserted into the handle, and * return values will pass through it before continuing. * * The filter's argument must match the expected return value downstream * from this point in the binder, and the return value must match the * return value at this point in the binder. * * @param filter the function to use to transform the return value at this point * @return a new SmartBinder with the filter applied */ public SmartBinder filterReturn(SmartHandle filter) { return new SmartBinder(this, signature().changeReturn(filter.signature().type().returnType()), binder.filterReturn(filter.handle())); }
/** * Pass all arguments to the given function and insert the resulting value * as newName into the argument list. * * @param newName the name of the new first argument where the fold * function's result will be passed * @param function a function which will receive all arguments and have its * return value inserted into the call chain * @return a new SmartBinder with the fold applied */ public SmartBinder fold(String newName, SmartHandle function) { if (Arrays.equals(signature().argNames(), function.signature().argNames())) { return fold(newName, function.handle()); } else { return fold(newName, signature().changeReturn(function.signature().type().returnType()).permuteWith(function).handle()); } }
.from(signature.changeReturn(boolean.class)) .permute("self") .insert(0, "selfClass", RubyClass.class, testClass)
.from(signature.changeReturn(boolean.class)) .permute("self") .insert(0, "selfClass", RubyClass.class, testClass)