Pārlūkot izejas kodu

change: IMethod#handle(interface)

Ranides Atterwim 9 gadi atpakaļ
vecāks
revīzija
be274951ab

+ 2 - 2
assira/src/main/java/net/ranides/assira/reflection/IMethod.java

@@ -105,8 +105,8 @@ public interface IMethod extends IElement {
     
     MethodHandle handle();
     
-    <F> F functor(IClass<F> functor);
+    <F> F handle(Class<F> functor);
     
-    MethodHandle handle(IClass<?> functor);
+    <F> F handle(IClass<F> functor);
     
 }

+ 8 - 6
assira/src/main/java/net/ranides/assira/reflection/impl/AMethod.java

@@ -87,20 +87,22 @@ public abstract class AMethod implements IMethod {
 	}
 
     @Override
-    public <F> F functor(IClass<F> functor) {
-        return (F)MethodHandleProxies.asInterfaceInstance(functor.raw(), handle());
+    public <F> F handle(Class<F> functor) {
+        return handle(IClass.typeinfo(functor));
     }
 
     @Override
-    public MethodHandle handle(IClass<?> functor) {
+    public <F> F handle(IClass<F> functor) {
         try {
             Class<?> rfunctor = functor.raw();
             
             IMethod method = IClass.typeinfo(rfunctor).methods().require(DECLARED).discard(SYNTHETIC).discard(BRIDGE).first();
-        
-            return site(method, functor.raw()).getTarget();
+
+            // invoke vs invokeExact:
+            // http://stackoverflow.com/questions/28196829/java-8-generic-lambdametafactory
+            return (F)site(method, functor.raw()).getTarget().invoke();
             
-        } catch(LambdaConversionException cause) {
+        } catch(Throwable cause) {
             throw ExceptionUtils.rethrow(cause);
         }
     }

+ 7 - 1
assira/src/main/java/net/ranides/assira/reflection/impl/LMethod.java

@@ -8,6 +8,7 @@
 package net.ranides.assira.reflection.impl;
 
 import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleProxies;
 import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Set;
@@ -109,7 +110,12 @@ public final class LMethod extends AMethod implements IMethod {
 	public MethodHandle handle() {
         return handle;
 	}
-
+    
+    @Override
+    public <F> F handle(IClass<F> functor) {
+        return (F)MethodHandleProxies.asInterfaceInstance(functor.raw(), handle());
+    }
+    
 	@Override
 	public IAnnotations annotations() {
         return method.annotations();

+ 33 - 26
assira/src/test/java/net/ranides/assira/reflection/IMethodTest.java

@@ -11,6 +11,7 @@ import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Supplier;
+import net.ranides.assira.generic.TypeToken;
 import static net.ranides.assira.reflection.IAttribute.*;
 import static net.ranides.assira.reflection.mockup.ForIClass.*;
 import org.junit.Test;
@@ -178,28 +179,6 @@ public class IMethodTest {
     }
     
 
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testToHandle() throws Throwable {
-        
-        Object that = new MTRecord(300);
-        IMethod m1 = IClass.typefor(that).method("sum");
-        IMethod m2 = IClass.typefor(that).method("mul");
-        
-        MTFunction<MTRecord> f11 = (MTFunction<MTRecord>)m1.handle(MTFunction.GENERIC).invokeExact();
-        MTFunction<MTRecord> f12 = (MTFunction)m1.handle(MTFunction.RAW).invokeExact();
-        
-        assertEquals(107, f11.calculate(new MTRecord(100), 3, 4));
-        assertEquals(208, f12.calculate(new MTRecord(200), 3, 5));
-        
-        MTFunction<MTRecord> f21 = (MTFunction<MTRecord>)m2.handle(MTFunction.GENERIC).invokeExact();
-        MTFunction<MTRecord> f22 = (MTFunction)m2.handle(MTFunction.RAW).invokeExact();
-        
-        assertEquals(112, f21.calculate(new MTRecord(100), 3, 4));
-        assertEquals(215, f22.calculate(new MTRecord(200), 3, 5));
-    }
-    
-    @SuppressWarnings("unchecked")
     @Test
     public void testToFunctor() throws Throwable {
         
@@ -207,19 +186,47 @@ public class IMethodTest {
         IMethod m1 = IClass.typefor(that).method("sum");
         IMethod m2 = IClass.typefor(that).method("mul");
         
-        MTFunction<MTRecord> f11 = m1.functor(MTFunction.GENERIC);
-        MTFunction<MTRecord> f12 = m1.functor(MTFunction.RAW);
+        MTFunction<MTRecord> f11 = m1.handle(MTFunction.GENERIC);
+        MTFunction<MTRecord> f12 = m1.handle(MTFunction.RAW);
         
         assertEquals(309, f11.calculate(new MTRecord(300), 3, 6));
         assertEquals(410, f12.calculate(new MTRecord(400), 3, 7));
         
-        MTFunction<MTRecord> f21 = m2.functor(MTFunction.GENERIC);
-        MTFunction<MTRecord> f22 = m2.functor(MTFunction.RAW);
+        MTFunction<MTRecord> f21 = m2.handle(MTFunction.GENERIC);
+        MTFunction<MTRecord> f22 = m2.handle(MTFunction.RAW);
         
         assertEquals(318, f21.calculate(new MTRecord(300), 3, 6));
         assertEquals(421, f22.calculate(new MTRecord(400), 3, 7));
     }
     
+    @Test
+    public void testToFunctorConstruct() {
+        IMethod c1 = IClass.typeinfo(MTRecord.class)
+            .constructors()
+            .first();
+        
+        MTFunction.Generator g1 = c1.handle(new TypeToken<MTFunction.Generator>(){});
+        MTFunction.Generator g2 = c1.handle(MTFunction.Generator.class);
+
+        assertEquals(503, g1.build(500).sum(1, 2));
+        assertEquals(603, g2.build(600).sum(1, 2));
+    }
+    
+    @Test
+    public void testToFunctorLambda() {
+        MTFunction.Lame f1 = (a,b,c) -> a.intValue() + b + c;
+        MTFunction.LameLong f2 = (a,b,c) -> (int)a + b + c;
+
+        IMethod m1 = IMethod.function(f1);
+        IMethod m2 = IMethod.function(f2);
+        
+        MTFunction<Long> g1 = m1.handle(new TypeToken<MTFunction<Long>>(){});
+        MTFunction<Long> g2 = m2.handle(new TypeToken<MTFunction<Long>>(){});
+
+        assertEquals(503, g1.calculate(500L, 1, 2));
+        assertEquals(607, g2.calculate(600L, 3, 4));
+    }
+    
     private void testAPI(Set<IAttribute> exp, Object function1, Object function2, Object function3, Object function4, Object function5) {
         IMethod m1 = IMethod.function(function1);
 		IMethod m2 = IMethod.function(function2);

+ 18 - 0
assira/src/test/java/net/ranides/assira/reflection/mockup/MTFunction.java

@@ -38,4 +38,22 @@ public interface MTFunction<T> {
         }
         
     };
+    
+    interface Generator {
+        
+        MTRecord build(int value);
+        
+    }
+    
+    interface Lame {
+        
+        int run(Long a, int b, int c);
+        
+    }
+    
+    interface LameLong {
+        
+        int run(long a, int b, int c);
+        
+    }
 }