private static MethodHandle createSAMTransform ( Object arg , Class parameter ) { Method method = CachedSAMClass . getSAMMethod ( parameter ) ; if ( method == null ) return null ; // TODO: have to think about how to optimize this! if ( parameter . isInterface ( ) ) { if ( Traits . isTrait ( parameter ) ) { // the following code will basically do this: // Map<String,Closure> impl = Collections.singletonMap(method.getName(),arg); // return ProxyGenerator.INSTANCE.instantiateAggregate(impl,Collections.singletonList(clazz)); // TO_SAMTRAIT_PROXY is a handle (Object,Object,ProxyGenerator,Class)GroovyObject // where the second object is the input closure, everything else // needs to be provide and is in remaining order: method name, // ProxyGenerator.INSTANCE and singletonList(parameter) MethodHandle ret = TO_SAMTRAIT_PROXY ; ret = MethodHandles . insertArguments ( ret , 2 , ProxyGenerator . INSTANCE , Collections . singletonList ( parameter ) ) ; ret = MethodHandles . insertArguments ( ret , 0 , method . getName ( ) ) ; return ret ; } // the following code will basically do this: // return Proxy.newProxyInstance( // arg.getClass().getClassLoader(), // new Class[]{parameter}, // new ConvertedClosure((Closure) arg)); // TO_REFLECTIVE_PROXY will do that for us, though // input is the closure, the method name, the class loader and the // class[]. All of that but the closure must be provided here MethodHandle ret = TO_REFLECTIVE_PROXY ; ret = MethodHandles . insertArguments ( ret , 1 , method . getName ( ) , arg . getClass ( ) . getClassLoader ( ) , new Class [ ] { parameter } ) ; return ret ; } else { // the following code will basically do this: //Map<String, Object> m = Collections.singletonMap(method.getName(), arg); //return ProxyGenerator.INSTANCE. // instantiateAggregateFromBaseClass(m, parameter); // TO_GENERATED_PROXY is a handle (Object,Object,ProxyGenerator,Class)GroovyObject // where the second object is the input closure, everything else // needs to be provide and is in remaining order: method name, // ProxyGenerator.INSTANCE and parameter MethodHandle ret = TO_GENERATED_PROXY ; ret = MethodHandles . insertArguments ( ret , 2 , ProxyGenerator . INSTANCE , parameter ) ; ret = MethodHandles . insertArguments ( ret , 0 , method . getName ( ) ) ; return ret ; } }
creates a method handle able to transform the given Closure into a SAM type if the given parameter is a SAM type