瀏覽代碼

#50 we return generic interfaces instead of raw interfaces

Ranides Atterwim 4 年之前
父節點
當前提交
2cdfd1c398

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

@@ -6,6 +6,8 @@
  */
 package net.ranides.assira.reflection.impl;
 
+import com.sun.scenario.effect.impl.sw.java.JSWBlend_SRC_OUTPeer;
+
 import net.ranides.assira.collection.iterators.ForwardIterator;
 import net.ranides.assira.collection.lists.ListUtils;
 import net.ranides.assira.collection.query.CQuery;
@@ -179,17 +181,17 @@ public class RClass<T> extends AClass<T> implements Serializable {
     }
     
     private CQuery<IClass<?>> getRInterfaces(AHints hints) {
-        IContext c = context();
+        CQuery<IClass<?>> declared = IClasses.typeinfo(type.getGenericInterfaces()).stream();
+
         if(hints.isDeclaredHint()) {
-            return CQuery.from()
-                .array(type.getInterfaces())
-                .map(i -> FClass.newClass(c,i));
+            return declared;
         } else {
+            CQuery<IClass<?>> inherited = parents().stream().unfold(c -> c.interfaces().require(IAttribute.DECLARED).stream());
             return CQuery.builder()
-                .withQuery(CQuery.from().iterable(()->new RawParents(type)).filter(Class::isInterface))
-                .withQuery(CQuery.from().iterable(()->new RawParents(type)).split(Class::getInterfaces))
+                .withQuery(declared)
+                .withQuery(inherited)
                 .build()
-                .map(i -> FClass.newClass(c,i));
+                .distinct();
         }
     }
     

+ 10 - 5
assira.core/src/main/java/net/ranides/assira/reflection/impl/RWClass.java

@@ -88,7 +88,7 @@ public class RWClass<T> extends AClass<T> implements Serializable {
     @Override
     public IClasses interfaces() {
         AHints attr = FElements.newHints();
-        return FElements.newClasses(attr, getInterfaces(attr));
+        return FElements.newClasses(attr, CQuery.from().query(attr, this::getInterfaces));
     }
     
     @Override
@@ -125,12 +125,17 @@ public class RWClass<T> extends AClass<T> implements Serializable {
     }
     
     private CQuery<IClass<?>> getInterfaces(AHints hints) {
+        CQuery<IClass<?>> declared = CQuery.from().array(upper).filter(IClass::isInterface);
+
         if(hints.isDeclaredHint()) {
-            return CQuery.from().array(upper)
-                .filter(m -> m.attributes().contains(IAttribute.INTERFACE));
+            return declared;
         } else {
-            return parents()
-                .stream().unfold(c->c.interfaces().stream());
+            CQuery<IClass<?>> inherited = parents().stream().unfold(c -> c.interfaces().require(IAttribute.DECLARED).stream());
+            return CQuery.builder()
+                .withQuery(declared)
+                .withQuery(inherited)
+                .build()
+                .distinct();
         }
     }
 

+ 54 - 0
assira.core/src/test/java/net/ranides/assira/reflection/impl/AClassTest.java

@@ -8,16 +8,23 @@ package net.ranides.assira.reflection.impl;
 
 import org.junit.Test;
 
+import net.ranides.assira.collection.lists.IntList;
+import net.ranides.assira.collection.sets.OpenSet;
+import net.ranides.assira.collection.sets.SetUtils;
 import net.ranides.assira.generic.TypeToken;
 import net.ranides.assira.reflection.*;
 import net.ranides.test.mockup.reflection.ForBeanModel;
 import net.ranides.assira.text.ResolveFormatUtils;
 
+import java.io.Serializable;
 import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Set;
 import java.util.function.Supplier;
 
 import static net.ranides.assira.junit.NewAssert.*;
@@ -203,6 +210,53 @@ public class AClassTest {
 
 //        System.out.println(listAt.returns().toString()); // sorry, we can't deduce interface arguments
         assertEquals("double", listAvg.returns().toString());
+
+        System.out.println();
+    }
+
+    @Test
+    public void testInterfaces() {
+        IClass<MyIntList> type1 = IClass.typeinfo(MyIntList.class);
+
+        Set<String> declare1 = type1.interfaces().require(DECLARED).stream(Object::toString).set();
+        Set<String> inherit1 = type1.interfaces().stream(Object::toString).set();
+
+        String[] expect1 = {
+            "net.ranides.assira.collection.lists.IntList",
+            "java.util.List<java.lang.Integer>",
+            "java.io.Serializable"
+        };
+
+        assertEquals(new OpenSet<>(expect1), declare1);
+        assertEquals(new OpenSet<>(expect1), inherit1);
+
+        IClass<MySubList> type2 = IClass.typeinfo(MySubList.class);
+        Set<String> declare2 = type2.interfaces().require(DECLARED).stream(Object::toString).set();
+        Set<String> inherit2 = type2.interfaces().stream(Object::toString).set();
+
+        String[] expect2 = {
+            "java.util.List<java.lang.Integer>",
+            "java.util.Queue<java.lang.Integer>"
+        };
+
+        String[] expect3 = {
+            "net.ranides.assira.collection.lists.IntList",
+            "java.util.List<java.lang.Integer>",
+            "java.util.Queue<java.lang.Integer>",
+            "java.io.Serializable"
+        };
+
+        assertEquals(new OpenSet<>(expect2), declare2);
+        assertEquals(new OpenSet<>(expect3), inherit2);
+    }
+
+
+    public abstract class MySubList extends MyIntList implements Queue<Integer>, List<Integer> {
+
+    }
+
+    public abstract class MyIntList implements List<Integer>, Serializable, IntList {
+
     }
 
     private interface MySpec1<T extends AbstractList<Supplier<T>>>  {