소스 검색

new semantic: lazy evaluation of ReflectUtils#access
new: IExecutable, IField #accessible
fix: TraceUtils: works without "sun.reflect.Reflection"

Mariusz Sieroń 6 년 전
부모
커밋
335f72f9e3
23개의 변경된 파일95개의 추가작업 그리고 26개의 파일을 삭제
  1. 1 0
      assira/src/main/java/net/ranides/assira/generic/EnumFactory.java
  2. 3 0
      assira/src/main/java/net/ranides/assira/reflection/IConstructor.java
  3. 3 0
      assira/src/main/java/net/ranides/assira/reflection/IConstructors.java
  4. 2 0
      assira/src/main/java/net/ranides/assira/reflection/IExecutable.java
  5. 2 0
      assira/src/main/java/net/ranides/assira/reflection/IExecutables.java
  6. 5 3
      assira/src/main/java/net/ranides/assira/reflection/IField.java
  7. 3 1
      assira/src/main/java/net/ranides/assira/reflection/IFields.java
  8. 3 0
      assira/src/main/java/net/ranides/assira/reflection/IMethod.java
  9. 3 0
      assira/src/main/java/net/ranides/assira/reflection/IMethods.java
  10. 2 2
      assira/src/main/java/net/ranides/assira/reflection/ResolvePattern.java
  11. 1 1
      assira/src/main/java/net/ranides/assira/reflection/impl/AClass.java
  12. 7 1
      assira/src/main/java/net/ranides/assira/reflection/impl/AConstructors.java
  13. 6 9
      assira/src/main/java/net/ranides/assira/reflection/impl/AExecutables.java
  14. 5 0
      assira/src/main/java/net/ranides/assira/reflection/impl/AFields.java
  15. 6 0
      assira/src/main/java/net/ranides/assira/reflection/impl/AMethods.java
  16. 7 0
      assira/src/main/java/net/ranides/assira/reflection/impl/LMethod.java
  17. 8 2
      assira/src/main/java/net/ranides/assira/reflection/impl/RConstructor.java
  18. 8 1
      assira/src/main/java/net/ranides/assira/reflection/impl/RField.java
  19. 7 1
      assira/src/main/java/net/ranides/assira/reflection/impl/RMethod.java
  20. 3 1
      assira/src/main/java/net/ranides/assira/reflection/ResolveUtils.java
  21. 4 0
      assira/src/main/java/net/ranides/assira/trace/TraceUtils.java
  22. 1 0
      assira/src/test/java/net/ranides/assira/reflection/ResolvePatternTest.java
  23. 5 4
      assira/src/test/java/net/ranides/assira/reflection/impl/RConstructorTest.java

+ 1 - 0
assira/src/main/java/net/ranides/assira/generic/EnumFactory.java

@@ -26,6 +26,7 @@ public final class EnumFactory<E extends Enum<E>> {
             .require(IAttribute.ANY)
             .first()
             .orElseThrow(() -> new UnsupportedOperationException(INCOMPATIBLE_JDK))
+            .accessible()
             .accessor();
 
         values = typeinfo.field("$VALUES")

+ 3 - 0
assira/src/main/java/net/ranides/assira/reflection/IConstructor.java

@@ -29,6 +29,9 @@ public interface IConstructor<T> extends IExecutable {
     @Override
     IConstructors<T> collect();
 
+    @Override
+    IConstructor<T> accessible();
+
     Constructor<T> reflective();
 
     VarFunction<T> accessor();

+ 3 - 0
assira/src/main/java/net/ranides/assira/reflection/IConstructors.java

@@ -84,6 +84,9 @@ public interface IConstructors<T> extends IExecutables<IConstructor<T>> {
     @Override
     IConstructors<T> accepts(Object... arguments);
 
+    @Override
+    IConstructors<T> accessible();
+
     CQuery<Constructor<T>> reflective();
 
 }

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

@@ -82,5 +82,7 @@ public interface IExecutable extends IElement {
     <F> F handle(Class<F> functor);
     
     <F> F handle(IClass<F> functor);
+
+    IExecutable accessible();
     
 }

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

@@ -65,4 +65,6 @@ public interface IExecutables<T extends IExecutable> extends IElements<T> {
     IClasses parent();
 
     CQuery<MethodHandle> handle();
+
+    IExecutables accessible();
 }

+ 5 - 3
assira/src/main/java/net/ranides/assira/reflection/IField.java

@@ -40,9 +40,11 @@ public interface IField extends IElement {
     Field reflective();
 
     IField rewritable();
-    
+
+    IField accessible();
+
     MethodHandle getter();
-    
+
     MethodHandle setter();
-    
+
 }

+ 3 - 1
assira/src/main/java/net/ranides/assira/reflection/IFields.java

@@ -59,5 +59,7 @@ public interface IFields extends IElements<IField> {
     CQuery<Field> reflective();
 
     IFields rewritable();
-    
+
+    IFields accessible();
+
 }

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

@@ -38,6 +38,9 @@ public interface IMethod extends IExecutable {
     @Override
     IMethods collect();
 
+    @Override
+    IMethod accessible();
+
     Method reflective();
 
 }

+ 3 - 0
assira/src/main/java/net/ranides/assira/reflection/IMethods.java

@@ -87,6 +87,9 @@ public interface IMethods extends IExecutables<IMethod> {
     @Override
     IMethods accepts(Object... arguments);
 
+    @Override
+    IMethods accessible();
+
     CQuery<Method> reflective();
 
 }

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

@@ -351,7 +351,7 @@ public class ResolvePattern implements Serializable {
                 } 
                 Iterator<IField> f = field(model, name);
                 if(f.hasNext()) {
-                    return f.next().get(that);
+                    return f.next().accessible().get(that);
                 }
                 status.error = true;
                 return null;
@@ -370,7 +370,7 @@ public class ResolvePattern implements Serializable {
                 }
                 Iterator<IField> f = field(model, name);
                 if(f.hasNext()) {
-                    f.next().set(that, value);
+                    f.next().accessible().set(that, value);
                     return;
                 }
                 status.error = true;

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

@@ -103,7 +103,7 @@ public abstract class AClass<T> implements IClass<T> {
     @Override
     public final T construct(Object... arguments) {
         return (T)constructors()
-            .require(IAttribute.DECLARED).accepts(arguments).first().get().call(arguments);
+            .require(IAttribute.DECLARED).accepts(arguments).first().get().accessible().call(arguments);
     }
     
     @Override

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

@@ -172,7 +172,13 @@ public class AConstructors<T> extends AElements<IConstructor<T>> implements ICon
         return stream().map(IConstructor::reflective);
     }
 
-    @Override
+	@Override
+	public IConstructors<T> accessible() {
+		forEach(IConstructor::accessible);
+		return this;
+	}
+
+	@Override
     public CQuery<MethodHandle> handle() {
         return stream().map(m -> m.handle());
     }

+ 6 - 9
assira/src/main/java/net/ranides/assira/reflection/impl/AExecutables.java

@@ -9,14 +9,7 @@ package net.ranides.assira.reflection.impl;
 
 import net.ranides.assira.collection.query.CQuery;
 import net.ranides.assira.collection.query.CQueryBuilder;
-import net.ranides.assira.reflection.IAnnotations;
-import net.ranides.assira.reflection.IArguments;
-import net.ranides.assira.reflection.IAttribute;
-import net.ranides.assira.reflection.IClass;
-import net.ranides.assira.reflection.IClasses;
-import net.ranides.assira.reflection.IExecutable;
-import net.ranides.assira.reflection.IExecutables;
-import net.ranides.assira.reflection.IHints;
+import net.ranides.assira.reflection.*;
 
 import java.lang.annotation.Annotation;
 import java.lang.invoke.MethodHandle;
@@ -168,5 +161,9 @@ public class AExecutables extends AElements<IExecutable> implements IExecutables
         return stream().map(m -> m.handle());
     }
 
-    
+	@Override
+	public IExecutables accessible() {
+		forEach(IExecutable::accessible);
+		return this;
+	}
 }

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

@@ -133,4 +133,9 @@ public class AFields extends AElements<IField> implements IFields {
         return FElements.newClasses(AHints.EMPTY, stream(IField::parent));
     }
 
+    @Override
+    public IFields accessible() {
+        forEach(IField::accessible);
+        return this;
+    }
 }

+ 6 - 0
assira/src/main/java/net/ranides/assira/reflection/impl/AMethods.java

@@ -161,6 +161,12 @@ public class AMethods extends AElements<IMethod> implements IMethods {
         return stream().map(IMethod::reflective);
     }
 
+	@Override
+	public IMethods accessible() {
+		forEach(IMethod::accessible);
+		return this;
+	}
+
     @Override
     public CQuery<MethodHandle> handle() {
         return stream().map(m -> m.handle());

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

@@ -14,6 +14,7 @@ import java.util.List;
 import java.util.Set;
 import net.ranides.assira.collection.query.CQuery;
 import net.ranides.assira.reflection.*;
+import net.ranides.assira.reflection.util.ReflectUtils;
 import net.ranides.assira.trace.ExceptionUtils;
 import static net.ranides.assira.reflection.IAttribute.*;
 
@@ -106,6 +107,12 @@ public final class LMethod extends AMethod implements IMethod {
         return method.reflective();
 	}
 
+    @Override
+    public IMethod accessible() {
+        ReflectUtils.access(method.reflective());
+        return this;
+    }
+
 	@Override
 	public MethodHandle handle() {
         return handle;

+ 8 - 2
assira/src/main/java/net/ranides/assira/reflection/impl/RConstructor.java

@@ -38,10 +38,10 @@ public final class RConstructor<T> extends AConstructor<T> {
 
 	RConstructor(IContext context, Constructor<?> method) {
         super(context);
-		ReflectUtils.access(method);
 		this.method = method;
         this.handle = LazyReference.concurrent(() -> {
             try {
+				ReflectUtils.access(method);
                 return MethodHandles.lookup().unreflectConstructor(method);
             } catch (IllegalAccessException cause) {
                 throw ExceptionUtils.rethrow(cause);
@@ -107,7 +107,13 @@ public final class RConstructor<T> extends AConstructor<T> {
     
 	@Override
 	public Constructor<T> reflective() {
-        throw new UnsupportedOperationException();
+		return (Constructor<T>)method;
+	}
+
+	@Override
+	public IConstructor<T> accessible() {
+		ReflectUtils.access(method);
+		return this;
 	}
 
 	@Override

+ 8 - 1
assira/src/main/java/net/ranides/assira/reflection/impl/RField.java

@@ -34,12 +34,12 @@ public class RField implements IField {
     private final Supplier<MethodHandle> setter;
     
     RField(boolean declared, IContext context, Field field) {
-        ReflectUtils.access(field);
         this.context = context;
         this.parent = context.typeinfo(field.getDeclaringClass());
         this.field = field;
         this.getter = LazyReference.concurrent(() -> {
             try {
+                ReflectUtils.access(field);
                 return MethodHandles.lookup().unreflectGetter(field);
             } catch (IllegalAccessException cause) {
                 throw ExceptionUtils.rethrow(cause);
@@ -47,6 +47,7 @@ public class RField implements IField {
         });
         this.setter = LazyReference.concurrent(() -> {
             try {
+                ReflectUtils.access(field);
                 return MethodHandles.lookup().unreflectSetter(field);
             } catch (IllegalAccessException cause) {
                 throw ExceptionUtils.rethrow(cause);
@@ -106,6 +107,12 @@ public class RField implements IField {
         return field;
     }
 
+    @Override
+    public IField accessible() {
+        ReflectUtils.access(field);
+        return this;
+    }
+
     @Override
     public IField rewritable() {
         ReflectUtils.rewritable(field);

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

@@ -34,10 +34,10 @@ public class RMethod extends AMethod implements IMethod {
 
     RMethod(boolean declared, IContext context, Method method, Object that) {
         super(context);
-        ReflectUtils.access(method);
 		this.method = method;
         this.handle = LazyReference.concurrent(() -> {
             try {
+				ReflectUtils.access(method);
                 MethodHandle m = MethodHandles.lookup().unreflect(method);
                 return null!=that ? m.bindTo(that) : m;
             } catch (IllegalAccessException cause) {
@@ -103,6 +103,12 @@ public class RMethod extends AMethod implements IMethod {
         return method;
 	}
 
+	@Override
+	public IMethod accessible() {
+		ReflectUtils.access(method);
+		return this;
+	}
+
 	@Override
 	public MethodHandle handle() {
         return handle.get();

+ 3 - 1
assira/src/main/java/net/ranides/assira/reflection/ResolveUtils.java

@@ -4,9 +4,11 @@
  * @license WTFPL
  * @url http://ranides.net/projects/assira
  */
-package net.ranides.assira.reflection;
+package net.ranides.assira.reflection.util;
 
 import net.ranides.assira.generic.Wrapper;
+import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.reflection.ResolvePattern;
 
 /**
  *

+ 4 - 0
assira/src/main/java/net/ranides/assira/trace/TraceUtils.java

@@ -193,6 +193,10 @@ public final class TraceUtils {
         
         private static final int FIRST = 3+2;
 
+        public SunResolver() {
+            $caller(0);
+        }
+
         @Override
         public Class<?> type(int index) {
             return $caller(FIRST+index);

+ 1 - 0
assira/src/test/java/net/ranides/assira/reflection/ResolvePatternTest.java

@@ -17,6 +17,7 @@ import net.ranides.assira.generic.SerializationUtils;
 import net.ranides.assira.generic.TypeToken;
 import net.ranides.assira.generic.Wrapper;
 import net.ranides.assira.reflection.mockup.ForResolver.*;
+import net.ranides.assira.reflection.util.ResolveUtils;
 import org.junit.Test;
 import static net.ranides.assira.junit.NewAssert.*;
 import net.ranides.assira.reflection.mockup.ForIClass;

+ 5 - 4
assira/src/test/java/net/ranides/assira/reflection/impl/RConstructorTest.java

@@ -53,11 +53,12 @@ public class RConstructorTest {
     @Test
     public void testTypeInfo() throws Exception {
         IConstructor<?> c1 = ic.constructors().require(c -> c.arguments().count()==3).first().get();
-        assertThrows(UnsupportedOperationException.class, ()->{
-            c1.reflective();
-        });
-        
+
+        assertNotNull(c1.reflective());
+
         Constructor<ForConstructor.Record> rc1 = ForConstructor.Record.class.getConstructor(int.class, int.class, int.class);
+        assertEquals(c1.reflective(), rc1);
+
         IConstructor<?> c2 = IConstructor.typeinfo(rc1);
         assertEquals(c1, c2);
     }