Mariusz Czarnowski hace 3 años
padre
commit
fc641bb1c0

+ 3 - 3
assira.core/src/main/java/net/ranides/assira/reflection/IAttribute.java

@@ -214,9 +214,9 @@ public enum IAttribute {
      * Allowed for classes and methods.
      */
     SYMBOLIC        (0x0800_0000),
-    
-    //RESERVED        (0x00800000),
-    
+
+    RESOLVED        (0x0080_0000, 0)
+
     ;
 
     /**

+ 2 - 0
assira.core/src/main/java/net/ranides/assira/reflection/IAttributes.java

@@ -234,6 +234,8 @@ public class IAttributes {
         int mask = getModifiers(reflective);
         if( 0 != type.getTypeParameters().length) {
             mask |= PARAMETERIZED.mask;
+        } else {
+            mask |= RESOLVED.mask;
         }
         if( ClassTraits.isBoxed(type)) {
             mask |= BOXED.mask;

+ 8 - 0
assira.core/src/main/java/net/ranides/assira/reflection/IClass.java

@@ -570,4 +570,12 @@ public interface IClass<T> extends IElement, Comparable<IClass<?>> {
     @Meta.Alias("attribute(BOOLEAN)")
     boolean isBoolean();
 
+    /**
+     * Alias for {@code attribute(IAttribute.RESOLVED)}.
+     *
+     * @return boolean
+     */
+    @Meta.Alias("attribute(RESOLVED)")
+    boolean isResolved();
+
 }

+ 5 - 0
assira.core/src/main/java/net/ranides/assira/reflection/impl/AClass.java

@@ -295,6 +295,11 @@ public abstract class AClass<T> extends AElement implements IClass<T>, Serializa
         return attribute(IAttribute.BOOLEAN);
     }
 
+    @Override
+    public final boolean isResolved() {
+        return attribute(IAttribute.RESOLVED);
+    }
+
     @Override
     public final int compareTo(IClass<?> object) {
         return RCompareUtils.compare(this, object);

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

@@ -9,6 +9,8 @@ package net.ranides.assira.reflection.impl;
 import net.ranides.assira.collection.iterators.ForwardIterator;
 import net.ranides.assira.collection.lists.ListUtils;
 import net.ranides.assira.collection.query.CQuery;
+import net.ranides.assira.functional.special.LazyFunction;
+import net.ranides.assira.generic.LazyReference;
 import net.ranides.assira.generic.SerializationUtils;
 import net.ranides.assira.reflection.*;
 
@@ -34,6 +36,8 @@ public class RClass<T> extends AClass<T> implements Serializable {
 
     private final Class<T> type;
 
+    private final LazyFunction<IAttributes> iattributes = LazyReference.concurrent();
+
     RClass(IContext context, Class<T> type) {
         super(context.derive(type));
         this.type = type;
@@ -120,8 +124,16 @@ public class RClass<T> extends AClass<T> implements Serializable {
     }
 
     @Override
-    public final IAttributes attributes() {
-        return IAttributes.of(type);
+    public IAttributes attributes() {
+        return iattributes.apply(this::iattributes);
+    }
+
+    protected IAttributes iattributes() {
+        IAttributes attrs = IAttributes.of(type);
+        if (!attrs.contains(IAttribute.RESOLVED) && params().stream().allMatch(IClass::isResolved)) {
+            attrs.add(IAttribute.RESOLVED);
+        }
+        return attrs;
     }
 
     @Override

+ 4 - 4
assira.core/src/main/java/net/ranides/assira/reflection/impl/RCompareUtils.java

@@ -151,7 +151,7 @@ public final class RCompareUtils {
      * @return boolean
      */
     public static boolean isInstance(IClass<?> type, Object object) {
-        return (object==null && !type.isPrimitive()) || isSuper(true, false, type, IClass.typefor(object));
+        return (object==null && !type.isPrimitive()) || isSuper(true, true, type, IClass.typefor(object));
     }
     
     // isuper.params().equals(iclass.params())
@@ -181,12 +181,12 @@ public final class RCompareUtils {
         Bound cw = new Bound(iclass);
         
         if(sw.wildcard || cw.wildcard) {
-            return isSuperBound(sw, cw) && (raw||matchParams(isuper, iclass));
+            return isSuperBound(sw, cw) && (raw || !isuper.isResolved() || !iclass.isResolved() || matchParams(isuper, iclass));
         }
         Class<?> sr = isuper.raw();
         Class<?> cr = iclass.raw();
-        
-        return isSuperRaw(box, sr, cr) && (raw||matchParams(isuper, iclass));
+
+        return isSuperRaw(box, sr, cr) && (raw || !isuper.isResolved() || !iclass.isResolved() || matchParams(isuper, iclass));
     }
     
     private static boolean isSuperRaw(boolean box, Class<?> isuper, Class<?> iclass) {

+ 13 - 0
assira.core/src/main/java/net/ranides/assira/reflection/impl/RPClass.java

@@ -15,6 +15,8 @@ import java.util.function.Supplier;
 import net.ranides.assira.collection.lists.ListUtils;
 import net.ranides.assira.generic.LazyReference;
 import net.ranides.assira.generic.SerializationUtils;
+import net.ranides.assira.reflection.IAttribute;
+import net.ranides.assira.reflection.IAttributes;
 import net.ranides.assira.reflection.IClass;
 import net.ranides.assira.reflection.IContext;
 
@@ -32,6 +34,8 @@ public class RPClass<T> extends RClass<T> implements Serializable {
     
     private final Supplier<IContext> icontext = LazyReference.concurrent(this::icontext);
 
+    private final Supplier<List<IClass<?>>> iparams = LazyReference.concurrent(this::iparams);
+
     RPClass(IContext context, Class<T> type, ParameterizedType ptype) {
         super(context, type);
         this.ptype = ptype;
@@ -48,9 +52,18 @@ public class RPClass<T> extends RClass<T> implements Serializable {
     
     @Override
     public List<IClass<?>> params() {
+        return iparams.get();
+    }
+
+    private List<IClass<?>> iparams() {
         IContext c = super.context();
         return ListUtils.map(Arrays.asList(ptype.getActualTypeArguments()), c::typeinfo);
     }
+
+    @Override
+    protected IAttributes iattributes() {
+        return IAttributes.of(raw()).add(IAttribute.RESOLVED);
+    }
     
     @Override
     public IClass<?> outer() {

+ 6 - 1
assira.core/src/test/java/net/ranides/assira/generic/TypeTokenTest.java

@@ -92,5 +92,10 @@ public class TypeTokenTest {
         assertEquals(IClass.typeinfo(String.class).hashCode(), c13.hashCode());
         assertEquals(IClass.typeinfo(List.class).hashCode(), c41.hashCode());
     }
-    
+
+    @Test
+    public void testResolved() {
+        TypeToken<?> c41 = new TypeToken<List<String>>(){};
+        assertTrue(c41.isResolved());
+    }
 }

+ 34 - 5
assira.core/src/test/java/net/ranides/assira/reflection/IAttributeTest.java

@@ -9,7 +9,10 @@ package net.ranides.assira.reflection;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 
+import java.util.Map;
+import java.util.TreeMap;
 import net.ranides.test.mockup.reflection.ForClassTraits;
+import org.junit.Ignore;
 import org.junit.Test;
 import static net.ranides.assira.junit.NewAssert.*;
 import static net.ranides.assira.reflection.IAttributes.*;
@@ -32,10 +35,10 @@ public class IAttributeTest {
     
     @Test
     public void testType() {
-        IAttributes ex1 = of(DECLARED, PUBLIC);
-        IAttributes ex2 = of(DECLARED, PRIVATE);
-        IAttributes ex3 = of(DECLARED, PACKAGE, STATIC, ABSTRACT, INTERFACE);
-        IAttributes ex4 = of(DECLARED, PACKAGE, FINAL);
+        IAttributes ex1 = of(DECLARED, PUBLIC, RESOLVED);
+        IAttributes ex2 = of(DECLARED, PRIVATE, RESOLVED);
+        IAttributes ex3 = of(DECLARED, PACKAGE, STATIC, ABSTRACT, INTERFACE, RESOLVED);
+        IAttributes ex4 = of(DECLARED, PACKAGE, FINAL, RESOLVED);
         
         assertEquals(ex1, of(ForClassTraits.PUBLIC));
         assertEquals(ex2, of(ForClassTraits.PRIVATE));
@@ -46,7 +49,7 @@ public class IAttributeTest {
     @Test
     public void testTypeParameterized() {
         IAttributes ex1 = of(DECLARED, PACKAGE, PARAMETERIZED);
-        IAttributes ex2 = of(DECLARED, PACKAGE);
+        IAttributes ex2 = of(DECLARED, PACKAGE, RESOLVED);
         
         assertEquals(ex1, of(ForClassTraits.PARAMS));
         assertEquals(ex2, of(ForClassTraits.NO_PARAMS));
@@ -105,6 +108,32 @@ public class IAttributeTest {
         assertEquals(ex2, of($param(ForMethodUtils.MCP.class, "fun6", 2)));
         assertEquals(ex1, of($param(ForMethodUtils.MCP.class, "fun7", 0)));
     }
+
+    @Test
+    public void testResolved() {
+        IAttributes ex1 = of(DECLARED, RESOLVED);
+
+        assertTrue(ex1.contains(RESOLVED));
+        assertTrue(ex1.contains(DECLARED));
+
+        assertFalse(ex1.contains(PRIVATE));
+        assertFalse(ex1.contains(PROTECTED));
+        assertFalse(ex1.contains(PACKAGE));
+        assertFalse(ex1.contains(PUBLIC));
+    }
+
+    @Ignore("manual")
+    @Test
+    public void dumpMask() {
+        Map<Integer, IAttribute> map = new TreeMap<>();
+        for(IAttribute attr : IAttribute.values()) {
+            map.put(attr.mask, attr);
+        }
+
+        for (IAttribute attr : map.values()) {
+            System.out.printf("%08x %s%n", attr.mask, attr.name());
+        }
+    }
     
     private static Method $method(Class<?> type, String name) {
         return IClass.typeinfo(type).methods().require(DECLARED).require(name).first().get().reflective();

+ 1 - 1
assira.core/src/test/java/net/ranides/assira/reflection/IClassTest.java

@@ -81,7 +81,7 @@ public class IClassTest {
         assertEquals(type2, IClass.typeinfo("java.util.Map<java.lang.String, java.lang.Float>"));
         assertEquals(type3, IClass.typeinfo("java.util.Map<java.util.List<java.lang.String>, java.lang.Float>"));
 
-        assertNotEquals(type1, IClass.typeinfo("java.util.Map<java.lang.String, java.lang.Float>"));
+        assertEquals(type1, IClass.typeinfo("java.util.Map<java.lang.String, java.lang.Float>"));
         assertNotEquals(type2, IClass.typeinfo("java.util.Map<java.lang.String, java.lang.Double>"));
         assertNotEquals(type3, IClass.typeinfo("java.util.Map<java.util.List<java.lang.Character>, java.lang.Float>"));
     }

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

@@ -127,10 +127,10 @@ public class AClassTest {
     
     @Test
     public void testVoid() {
-        IAttributes exp1 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, VOID);
-        IAttributes exp2 = of(PUBLIC, FINAL, DECLARED, BOXED, VOID);
-        IAttributes exp3 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, NUMBER, INTEGER);
-        IAttributes exp4 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, VOID);
+        IAttributes exp1 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, VOID, RESOLVED);
+        IAttributes exp2 = of(PUBLIC, FINAL, DECLARED, BOXED, VOID, RESOLVED);
+        IAttributes exp3 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, NUMBER, INTEGER, RESOLVED);
+        IAttributes exp4 = of(PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, VOID, RESOLVED);
         
         assertEquals(exp1, IClass.typeinfo(void.class).attributes());
         assertEquals(exp2, IClass.typeinfo(Void.class).attributes());

+ 2 - 2
assira.core/src/test/java/net/ranides/assira/reflection/impl/RFClassTest.java

@@ -41,7 +41,7 @@ public class RFClassTest {
         assertEquals(Collections.emptyList(), f1.inner().list());
         assertEquals(int.class, f1.reflective());
         assertEquals(true, f1.attributes().contains(IAttribute.PRIMITIVE));
-        assertEquals("[PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, NUMBER, INTEGER]", f1.attributes().toString());
+        assertEquals("[PUBLIC, FINAL, ABSTRACT, DECLARED, PRIMITIVE, NUMBER, INTEGER, RESOLVED]", f1.attributes().toString());
         assertEquals(Collections.emptyList(), f1.annotations().list());
         
         
@@ -70,7 +70,7 @@ public class RFClassTest {
         assertEquals("[]", f2.inner().toString());
         assertEquals(Prop.class, f2.reflective());
         assertEquals(false, f2.attributes().contains(IAttribute.PRIMITIVE));
-        assertEquals("[PRIVATE, STATIC, ABSTRACT, PARAMETERIZED, DECLARED]", f2.attributes().toString());
+        assertEquals("[PRIVATE, STATIC, ABSTRACT, PARAMETERIZED, DECLARED, RESOLVED]", f2.attributes().toString());
         assertEquals(Collections.emptyList(), f2.annotations().list());
     }
     

+ 6 - 4
assira.core/src/test/java/net/ranides/assira/reflection/impl/RWClassTest.java

@@ -7,6 +7,7 @@
 package net.ranides.assira.reflection.impl;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import net.ranides.assira.generic.TypeToken;
 import org.junit.Test;
 
 import net.ranides.assira.reflection.*;
@@ -36,11 +37,12 @@ public class RWClassTest {
         assertEquals("? super java.util.ArrayList<java.lang.Float>", ic1.reflective().toString());
         assertEquals(Object.class, ic1.raw());
 
-        // https://git.ranides.net/projects/assira/issues/24
-        // System.out.printf("%s%n", ic1);
-        // assertTrue(ic1.isInstance(new ArrayList<Float>()));
+        assertTrue(ic1.isSuper(new TypeToken<ArrayList<Float>>(){}));
+        assertFalse(ic1.isSuper(new TypeToken<ArrayList<Double>>(){}));
+
+        assertTrue(ic1.isInstance(new ArrayList<Float>()));     // should be true
+        assertTrue(ic1.isInstance(new ArrayList<Double>()));    // should be false, but it is raw object
 
-        assertFalse(ic1.isInstance(new ArrayList<Double>()));
         assertFalse(ic1.isInstance(new java.util.LinkedList<Float>()));
         assertEquals("[PUBLIC]", ic1.attributes().toString());
         assertEquals("[]", ic1.annotations().toString());