|
|
@@ -1,192 +0,0 @@
|
|
|
-/*
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
- * @copyright Ranides Atterwim
|
|
|
- * @license WTFPL
|
|
|
- * @url http://ranides.net/projects/assira.drafts
|
|
|
- */
|
|
|
-
|
|
|
-package net.ranides.assira.reflection;
|
|
|
-
|
|
|
-import java.lang.reflect.Array;
|
|
|
-import java.lang.reflect.Method;
|
|
|
-import java.lang.reflect.ParameterizedType;
|
|
|
-import java.util.function.Function;
|
|
|
-import net.ranides.asm.Type;
|
|
|
-import net.ranides.assira.trace.ExceptionUtils;
|
|
|
-import sun.reflect.ConstantPool;
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
- */
|
|
|
-public class LambdaParams {
|
|
|
-
|
|
|
- public static void main(String[] args) throws Exception {
|
|
|
- LambdaParams that = new LambdaParams();
|
|
|
- System.out.printf("(Integer a) -> String %n");
|
|
|
- that.runme( (Integer a) -> "A" );
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- System.out.printf("(int[] a) -> Float %n");
|
|
|
- that.runme( (int[] a) -> 11.0f );
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- System.out.printf("(String a) -> Character %n");
|
|
|
- that.runme( OtherLambda::flow );
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- System.out.printf("(Params2 a) -> Integer %n");
|
|
|
- that.runme( (Param2 v) -> 3*OtherLambda.flow("s") );
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- System.out.printf("(String) -> Integer %n");
|
|
|
- that.runme( new Function<String, Integer>() {
|
|
|
- @Override
|
|
|
- public Integer apply(String t) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- });
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- System.out.printf("(Float) -> Double %n");
|
|
|
- that.runme( new Hello(22));
|
|
|
- System.out.printf("%n%n");
|
|
|
-
|
|
|
- Function<Integer, ?> f31 = (Integer a) -> "A";
|
|
|
- Function f32 = f31;
|
|
|
-
|
|
|
- System.out.printf("(Integer) -> String %n");
|
|
|
- that.runme(f32);
|
|
|
- System.out.printf("%n%n");
|
|
|
- }
|
|
|
-
|
|
|
- public <T,R> void runme(Function<T,R> function) throws Exception {
|
|
|
- System.out.printf("type = %s%n", typeof(function));
|
|
|
- }
|
|
|
-
|
|
|
- public static Class<?> typeof(Function function) throws Exception {
|
|
|
- if(!function.getClass().isSynthetic()) {
|
|
|
- return typeof_generic(function);
|
|
|
- } else {
|
|
|
- return typeof_lambda(function);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static Class<?> typeof_lambda(Function function) {
|
|
|
- ConstantPool cp = Li.get(function.getClass());
|
|
|
-
|
|
|
- for(int i=0; i<cp.getSize(); i++) {
|
|
|
- String[] info;
|
|
|
- try {
|
|
|
- info = cp.getMemberRefInfoAt(i);
|
|
|
- } catch(Exception ex) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- String parent = info[0];
|
|
|
- if("java/lang/Object".equals(parent) || "java/lang/Class".equals(parent)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- try {
|
|
|
- if(1 != Type.getArgumentTypes(info[2]).length) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- } catch(Exception ex) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- return vm2class(function.getClass().getClassLoader(), Type.getReturnType(info[2]).getDescriptor());
|
|
|
- }
|
|
|
- throw new AssertionError("Deduction of return type failed. Unsupported lambda: " + function);
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressWarnings("PMD")
|
|
|
- private static Class<?> vm2class(ClassLoader loader, String vmtype) {
|
|
|
- try {
|
|
|
- if(vmtype.startsWith("[")) {
|
|
|
- return Array.newInstance(vm2class(loader, vmtype.substring(1)), 0).getClass();
|
|
|
- }
|
|
|
- if(vmtype.startsWith("L") && vmtype.endsWith(";")) {
|
|
|
- return Class.forName(vmtype.substring(1,vmtype.length()-1).replace('/', '.'), false, loader);
|
|
|
- }
|
|
|
- if("Z".equals(vmtype)) {
|
|
|
- return boolean.class;
|
|
|
- }
|
|
|
- if("B".equals(vmtype)) {
|
|
|
- return byte.class;
|
|
|
- }
|
|
|
- if("C".equals(vmtype)) {
|
|
|
- return char.class;
|
|
|
- }
|
|
|
- if("S".equals(vmtype)) {
|
|
|
- return short.class;
|
|
|
- }
|
|
|
- if("I".equals(vmtype)) {
|
|
|
- return int.class;
|
|
|
- }
|
|
|
- if("J".equals(vmtype)) {
|
|
|
- return long.class;
|
|
|
- }
|
|
|
- if("F".equals(vmtype)) {
|
|
|
- return float.class;
|
|
|
- }
|
|
|
- if("D".equals(vmtype)) {
|
|
|
- return double.class;
|
|
|
- }
|
|
|
- if("V".equals(vmtype)) {
|
|
|
- return void.class;
|
|
|
- }
|
|
|
- } catch(ClassNotFoundException cause) {
|
|
|
- throw ExceptionUtils.rethrow(cause);
|
|
|
- }
|
|
|
- throw new AssertionError("Unknown type: " + vmtype);
|
|
|
- }
|
|
|
-
|
|
|
- private static Class<?> typeof_generic(Object function) {
|
|
|
- ParameterizedType it = getGenericInterface(function.getClass(), Function.class);
|
|
|
- java.lang.reflect.Type pt = it.getActualTypeArguments()[1];
|
|
|
- if(pt instanceof Class<?>) {
|
|
|
- return (Class<?>)pt;
|
|
|
- }
|
|
|
- if(pt instanceof ParameterizedType) {
|
|
|
- return (Class<?>)(((ParameterizedType)pt).getRawType());
|
|
|
- }
|
|
|
- throw new AssertionError("Deduction of return type failed. Unsupported function: " + function);
|
|
|
- }
|
|
|
-
|
|
|
- private static ParameterizedType getGenericInterface(Class<?> type, Class<?> intface) {
|
|
|
- for(java.lang.reflect.Type t : type.getGenericInterfaces()) {
|
|
|
- ParameterizedType pt = (ParameterizedType)t;
|
|
|
- if( intface.equals(pt.getRawType()) ) {
|
|
|
- return pt;
|
|
|
- }
|
|
|
- }
|
|
|
- throw new AssertionError(type.getName() + " does not implement " + intface.getName());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private static final class Li { // NOPMD - lazy init idiom
|
|
|
-
|
|
|
- public static final Method GET_CONSTANT_POOL;
|
|
|
-
|
|
|
- static {
|
|
|
- try {
|
|
|
- GET_CONSTANT_POOL = Class.class.getDeclaredMethod("getConstantPool");
|
|
|
- GET_CONSTANT_POOL.setAccessible(true);
|
|
|
- } catch(ReflectiveOperationException cause) {
|
|
|
- throw ExceptionUtils.rethrow(cause);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static ConstantPool get(Class<?> type) {
|
|
|
- try {
|
|
|
- return (ConstantPool) GET_CONSTANT_POOL.invoke(type);
|
|
|
- } catch (ReflectiveOperationException cause) {
|
|
|
- throw ExceptionUtils.rethrow(cause);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|