Ranides Atterwim 4 jaren geleden
bovenliggende
commit
66f6fa5aa9

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/reflection/impl/RClass.java

@@ -44,7 +44,7 @@ public class RClass<T> extends AClass<T> implements Serializable {
         IContext c = context();
 
         if(c.derived(gtype)) {
-//            // remove recursive generic params
+            // remove recursive generic params
             if(gtype instanceof ParameterizedType) {
                 ParameterizedType ptype = (ParameterizedType) gtype;
                 return ListUtils.map(Arrays.asList(ptype.getActualTypeArguments()), this::asRawParam);

+ 103 - 5
assira.core/src/test/java/net/ranides/assira/reflection/impl/AClassTest.java

@@ -8,18 +8,22 @@ package net.ranides.assira.reflection.impl;
 
 import org.junit.Test;
 
+import net.ranides.assira.generic.TypeToken;
 import net.ranides.assira.reflection.*;
 import net.ranides.assira.reflection.mockup.ForBeanModel;
 import net.ranides.assira.text.ResolveFormatUtils;
 
+import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.function.Supplier;
 
 import static net.ranides.assira.junit.NewAssert.*;
 import static net.ranides.assira.reflection.IAttribute.*;
 import static net.ranides.assira.reflection.IAttributes.of;
+import static org.junit.Assert.assertEquals;
 
 /**
  *
@@ -137,8 +141,6 @@ public class AClassTest {
 
     @Test
     public void testRecursiveEnum() {
-        IClass<?> raw = IClass.typeinfo(Enum.class);
-
         IClass<?> foo = IClass.typeinfo(Foo.class);
         IClass<?> bar = IClass.typeinfo(Bar.class);
 
@@ -159,14 +161,110 @@ public class AClassTest {
 
         assertFalse(foo.isInstance(Bar.A));
         assertFalse(bar.isInstance(Foo.A));
+    }
+
+
+    @Test
+    public void testRecursiveOthers() {
+        IClass<?> spec = new TypeToken<MySpec1<MySpec2>>() {};
+
+        String exp1 = ResolveFormatUtils.nformat(
+            "{MySpec1}<{MySpec2}<{supplier}<{MySpec2}>>>",
+            "MySpec1 = net.ranides.assira.reflection.impl.AClassTest$MySpec1",
+            "MySpec2 = net.ranides.assira.reflection.impl.AClassTest$MySpec2",
+            "supplier = java.util.function.Supplier"
+        );
+
+        assertEquals(exp1, spec.toString());
+    }
+
+    @Test
+    public void testRecursiveBuilder() {
+        String exp1 = ResolveFormatUtils.nformat(
+            "{MyBuilder2}<{MyBuilder2}>",
+            "MyBuilder2 = net.ranides.assira.reflection.impl.AClassTest$MyBuilder2"
+        );
+
+        String exp2 = "net.ranides.assira.reflection.impl.AClassTest$MyBuilder3";
+
 
+        IClass<?> builder2 = new TypeToken<MyBuilder2>() {};
+        IClass<?> builder3 = new TypeToken<MyBuilder3>() {};
+        IClass<?> mylist = new TypeToken<MyArrayList>() {};
 
+        IMethod append1 = builder2.method("append1").get();
+        IMethod append2 = builder2.method("append2").get();
 
-//        System.out.println(raw.isSuper(foo));
-//        System.out.println(raw.isSuper(bar));
+        IMethod append0 = builder3.method("append0").get();
+        IMethod append3 = builder3.method("append3").get();
 
+        IMethod listAt = mylist.method("at").get();
+        IMethod listAvg = mylist.method("average").get();
+
+        assertEquals(exp1, append1.returns().toString());
+        assertEquals(exp1, append2.returns().toString());
+
+//        assertEquals(exp2, append0.returns().toString()); // sorry, we can't deduce interface arguments
+        assertEquals(exp2, append3.returns().toString());
+
+//        System.out.println(listAt.returns().toString()); // sorry, we can't deduce interface arguments
+        assertEquals("double", listAvg.returns().toString());
+    }
+
+    private interface MySpec1<T extends AbstractList<Supplier<T>>>  {
+
+    }
+
+    private static abstract class MySpec2 extends AbstractList<Supplier<MySpec2>> {
+
+    }
+
+    public static class MyBuilder1<P extends MyBuilder1<P>> {
+
+        public P append1() {
+            return null;
+        }
+
+    }
+
+    private static class MyBuilder2 extends MyBuilder1<MyBuilder2> {
+
+        public MyBuilder2 append2() {
+            return null;
+        }
+
+    }
+
+    public interface MyBuilder0<P extends MyBuilder0<P>> {
+
+        default P append0() {
+            return null;
+        }
+
+    }
+
+    private static class MyBuilder3 implements MyBuilder0<MyBuilder3> {
+
+        public MyBuilder3 append3() {
+            return null;
+        }
+
+    }
+
+    public interface MyList<T> {
+
+        default T at(int index) {
+            return null;
+        }
+
+    }
+
+    private static class MyArrayList implements MyList<Integer> {
+
+        public double average() {
+            return 0.0;
+        }
 
-//        System.out.println(IClass.typeinfo(Hello.A));
     }
 
     @Test