Ranides Atterwim 4 anni fa
parent
commit
48a1357ea0

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/collection/prototype/GenericKey.java

@@ -25,7 +25,7 @@ public class GenericKey<K,V> implements Function<GenericMap<K>, V>, Serializable
 
     @SuppressWarnings("unchecked")
     protected GenericKey(K id) {
-        this.type = (IClass<V>)IClass.typeinfo(getClass()).params().get(1);
+        this.type = (IClass<V>)IClass.typefor(this).context().typeinfo("K");;
         this.id = id;
     }
     

+ 4 - 2
assira.core/src/main/java/net/ranides/assira/reflection/IContext.java

@@ -23,9 +23,11 @@ public interface IContext {
     boolean derived(Type type);
 
     <R> IClass<R> typeinfo(Class<R> type);
-    
+
     IClass<?> typeinfo(Type type);
-    
+
+    IClass<?> typeinfo(String type);
+
     <R> IClass<R> typefor(R object);
     
     IClasses typesinfo(Type... types);

+ 17 - 3
assira.core/src/main/java/net/ranides/assira/reflection/impl/AContext.java

@@ -43,8 +43,8 @@ public class AContext implements IContext, Serializable {
 
     @Override
     public final IContext derive(Type type) {
-        if(type instanceof ParameterizedType) {
-            return RContext.create(this, (ParameterizedType)type);
+        if(type!=null && type!=Object.class && !derived(type)) {
+            return RContext.create(this, type);
         } else {
             return this;
         }
@@ -81,7 +81,12 @@ public class AContext implements IContext, Serializable {
     public final IClass<?> typeinfo(Type type) {
         return itypeinfo(type);
     }
-    
+
+    @Override
+    public IClass<?> typeinfo(String type) {
+        return resolveNS(type);
+    }
+
     @SuppressWarnings("rawtypes")
     private IClass itypeinfo(Type type) {
         if(type instanceof Class<?>) {
@@ -103,6 +108,11 @@ public class AContext implements IContext, Serializable {
         return NULL;
     }
 
+    protected IClass<?> resolveNS(String type) {
+        Type rtype = resolve(type);
+        return rtype != null ? typeinfo(rtype) : null;
+    }
+
     protected IClass<?> resolveTV(TypeVariable<?> type) {
         Type rtype = resolve(type);
         // sprawdzamy czy udało się znaleźć jakiś inny typ, jeśli wynikiem jest podany argument,
@@ -114,6 +124,10 @@ public class AContext implements IContext, Serializable {
         }
     }
 
+    protected Type resolve(String type) {
+        return null;
+    }
+
     protected Type resolve(TypeVariable<?> type) {
         return type;
     }

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

@@ -42,7 +42,13 @@ public class GContext extends AContext implements Serializable {
     }
 
     @Override
-    public IClass<?> resolveTV(TypeVariable type) {
+    protected IClass<?> resolveNS(String type) {
+        IClass<?> ic = params.get(type);
+        return ic!=null ? ic : super.typeinfo(type);
+    }
+
+    @Override
+    protected IClass<?> resolveTV(TypeVariable type) {
         IClass<?> ic = params.get(type.getName());
         return ic!=null ? ic : super.typeinfo(type);
     }

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

@@ -16,7 +16,6 @@ import net.ranides.assira.reflection.*;
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
@@ -30,47 +29,16 @@ import java.util.function.Supplier;
 public class RClass<T> extends AClass<T> implements Serializable {
 
     private final Class<T> type;
-    
-    private final Supplier<IContext> icontext = LazyReference.concurrent(this::icontext);
-    
+
     RClass(IContext context, Class<T> type) {
-        super(context);
+        super(context.derive(type));
         this.type = type;
     }
     
     @Override
     public List<IClass<?>> params() {
-        Type gtype = type.getGenericSuperclass();
         IContext c = context();
-
-        if(c.derived(gtype)) {
-            // remove recursive generic params
-            if(gtype instanceof ParameterizedType) {
-                ParameterizedType ptype = (ParameterizedType) gtype;
-                return ListUtils.map(Arrays.asList(ptype.getActualTypeArguments()), this::asRawParam);
-            } else {
-                return ListUtils.map(Arrays.asList(type.getTypeParameters()), this::asRawParam);
-            }
-        } else {
-            if (gtype instanceof ParameterizedType) {
-                return FClass.newClass(context(), type, (ParameterizedType) gtype).params();
-            } else {
-                return ListUtils.map(Arrays.asList(type.getTypeParameters()), c::typeinfo);
-            }
-        }
-    }
-
-    private IClass<?> asRawParam(Type v) {
-        return new SClass(v.getTypeName(), Object.class);
-    }
-
-    @Override
-    public IContext context() {
-        return icontext.get();
-    }
-    
-    private IContext icontext() {
-        return super.context().derive(type.getGenericSuperclass());
+        return ListUtils.map(Arrays.asList(type.getTypeParameters()), c::typeinfo);
     }
 
     @Override

+ 53 - 9
assira.core/src/main/java/net/ranides/assira/reflection/impl/RContext.java

@@ -28,30 +28,55 @@ public final class RContext extends AContext implements Serializable {
 
     private final AContext parent;
 
-    private final ParameterizedType derived;
+    private final Type derived;
 
     private final RTList<TypeVariable> keys = new RTList<>();
     
     private final RTList<Type> vars = new RTList<>();
     
-    private RContext(IContext parent, ParameterizedType type) {
+    private RContext(IContext parent, Type type) {
         this.parent = (AContext)parent;
         this.derived = type;
         add(type);
     }
     
-    static IContext create(IContext parent, ParameterizedType type) {
+    static IContext create(IContext parent, Type type) {
         return CACHE.get(parent, type, () -> new RContext(parent, type));
     }
     
-    private void add(ParameterizedType type) {
+    private void add(Type type) {
+        if(type instanceof Class<?>) {
+            addc((Class<?>)type);
+        }
+        if(type instanceof ParameterizedType) {
+            addp((ParameterizedType)type);
+        }
+    }
+
+    private void addc(Class<?> ctype) {
+        Class<?> sc = ctype.getSuperclass();
+
+        if(sc == null || sc.equals(Object.class)) {
+            return;
+        }
+
+        if(sc.getTypeParameters().length != 0) {
+            add(ctype.getGenericSuperclass());
+        }
+
+        add(sc);
+        try {
+            add(ctype.getEnclosingClass());
+        } catch (IncompatibleClassChangeError e) {
+            // ca be thrown by dynamic classes: it is not our fault :-)
+        }
+    }
+
+    private void addp(ParameterizedType type) {
         keys.addAll(raw(type).getTypeParameters());
         vars.addAll(type.getActualTypeArguments());
-        
-        Type owner = type.getOwnerType();
-        if(owner instanceof ParameterizedType) {
-            add((ParameterizedType)owner);
-        }
+
+        add(type.getOwnerType());
     }
 
     private static Class<?> raw(ParameterizedType type) {
@@ -63,6 +88,16 @@ public final class RContext extends AContext implements Serializable {
         return derived.equals(type) || parent.derived(type);
     }
 
+    @Override
+    protected Type resolve(String type) {
+        for(int i=0, n=keys.size(); i<n; i++) {
+            if( keys.get(i).getName().equals(type) ) {
+                return resolve0(vars.get(i));
+            }
+        }
+        return parent.resolve(type);
+    }
+
     @Override
     protected Type resolve(TypeVariable type) {
         for(int i=0, n=keys.size(); i<n; i++) {
@@ -108,6 +143,15 @@ public final class RContext extends AContext implements Serializable {
         private final RTList<String> keys;
         private final RTList<IClass<?>> vars;
 
+        protected Type resolve(String type) {
+            for(int i=0, n=keys.size(); i<n; i++) {
+                if( keys.get(i).equals(type) ) {
+                    return vars.get(i).reflective();
+                }
+            }
+            return parent.resolve(type);
+        }
+
         @Override
         protected Type resolve(TypeVariable type) {
             for(int i=0, n=keys.size(); i<n; i++) {

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

@@ -146,15 +146,13 @@ public class AClassTest {
 
 
         String foo1raw = "net.ranides.assira.reflection.impl.AClassTest$Foo";
-        String foo1fqn = foo1raw + "<" + foo1raw + ">";
 
         String bar1raw = "net.ranides.assira.reflection.impl.AClassTest$Bar";
-        String bar1fqn = bar1raw + "<" + bar1raw + ">";
 
-        assertEquals(foo1fqn, foo.toString());
-        assertEquals(bar1fqn, bar.toString());
+        assertEquals(foo1raw, foo.toString());
+        assertEquals(bar1raw, bar.toString());
 
-        assertEquals("["+bar1raw+"]", bar.params().toString());
+        assertEquals("[]", bar.params().toString());
 
         assertTrue(foo.isInstance(Foo.A));
         assertTrue(bar.isInstance(Bar.A));
@@ -169,10 +167,9 @@ public class AClassTest {
         IClass<?> spec = new TypeToken<MySpec1<MySpec2>>() {};
 
         String exp1 = ResolveFormatUtils.nformat(
-            "{MySpec1}<{MySpec2}<{supplier}<{MySpec2}>>>",
+            "{MySpec1}<{MySpec2}>",
             "MySpec1 = net.ranides.assira.reflection.impl.AClassTest$MySpec1",
-            "MySpec2 = net.ranides.assira.reflection.impl.AClassTest$MySpec2",
-            "supplier = java.util.function.Supplier"
+            "MySpec2 = net.ranides.assira.reflection.impl.AClassTest$MySpec2"
         );
 
         assertEquals(exp1, spec.toString());
@@ -180,10 +177,7 @@ public class AClassTest {
 
     @Test
     public void testRecursiveBuilder() {
-        String exp1 = ResolveFormatUtils.nformat(
-            "{MyBuilder2}<{MyBuilder2}>",
-            "MyBuilder2 = net.ranides.assira.reflection.impl.AClassTest$MyBuilder2"
-        );
+        String exp1 = "net.ranides.assira.reflection.impl.AClassTest$MyBuilder2";
 
         String exp2 = "net.ranides.assira.reflection.impl.AClassTest$MyBuilder3";
 
@@ -271,11 +265,7 @@ public class AClassTest {
     public void testRecursiveString() {
         IClass<?> type = IClass.typeinfo(ThisSomething.class);
 
-        String ex0 = ResolveFormatUtils.nformat(
-            "{this}<{float}>",
-            "this  = net.ranides.assira.reflection.impl.AClassTest$ThisSomething",
-            "float = java.lang.Float"
-        );
+        String ex0 = "net.ranides.assira.reflection.impl.AClassTest$ThisSomething";
 
         String ex1 = ResolveFormatUtils.nformat(
             "void {some}<{float}>.run1({some}<{float}> x)",