Selaa lähdekoodia

constant pool - work in progress

Ranides Atterwim 10 vuotta sitten
vanhempi
commit
bad29c1d37

+ 0 - 168
assira/src/main/java/net/ranides/assira/reflection/impl/CPIClass.java

@@ -1,168 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.reflection.impl;
-
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.function.IntFunction;
-import net.ranides.assira.reflection.GenericAnnotations;
-import net.ranides.assira.reflection.GenericAttribute;
-import net.ranides.assira.reflection.GenericClass;
-import net.ranides.assira.reflection.GenericClasses;
-import net.ranides.assira.reflection.GenericFields;
-import net.ranides.assira.reflection.GenericMethods;
-import net.ranides.assira.reflection.util.MethodUtils;
-import net.ranides.assira.trace.ExceptionUtils;
-import sun.reflect.ConstantPool;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class CPIClass implements GenericClass{
-
-	// @todo (assira #0) implement CPIClass (ConstantPool)
-	
-	// przerobimy to na GenericMethod lambdaType(Object object)
-	public static Class<?> lambdaType(Object object) {
-		return ilambdaType(object.getClass());
-	}
-	
-    public static Class<?> ilambdaType(Class<?> clazz) {
-		if(!clazz.isSynthetic()) {
-			throw new IllegalArgumentException(clazz + " is not lambda");
-		}
-		
-		ConstantPool cp = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
-		
-		for(int i=0, n=cp.getSize(); i<n; i++) {
-			try {
-				Member member = cp.getMethodAt(i);
-				if(member instanceof Method) {
-					Method method = (Method)member;
-//					System.out.printf("    %s%n", method.getReturnType().getSimpleName());
-					return method.getReturnType();
-				}
-			} catch(IllegalArgumentException $0) {
-				continue;
-			}
-			
-		}
-		
-		throw new UnsupportedOperationException(clazz + " is unrecognized");
-		
-//		for(int i=0, n=cp.getSize(); i<n; i++) {
-////			tryprint(i, "class  ", cp::getClassAt);		// nudne
-//			tryprint(i, "field  ", cp::getFieldAt);
-//			
-////			tryprint(i, "refinfo", cp::getMemberRefInfoAt);	// niepotrzebne
-//			tryprint(i, "method ", cp::getMethodAt);
-//			
-////			tryprint(i, "string", cp::getStringAt);		// może wyjebać VM
-////			tryprint(i, "UTF8   ", cp::getUTF8At);		// nudne
-////			tryprint(i, "double ", cp::getDoubleAt);	// nudne
-////			tryprint(i, "float  ", cp::getFloatAt);		// nudne
-////			tryprint(i, "int    ", cp::getIntAt);		// nudne
-////			tryprint(i, "long   ", cp::getLongAt);		// nudne
-//		}
-    }
-	
-	private static void tryprint(int i, String type, IntFunction<Object> function) {
-		try {
-			Object object = function.apply(i);
-			String text = String.valueOf(object);
-			if(object instanceof String[]) {
-				text = Arrays.toString((String[])object);
-			}
-			if((object instanceof Member) && !(object instanceof Method)) {
-				text = "? " + text;
-			}
-			
-			System.out.printf("    [%d] %s = %s%n", i, type, text);
-		} catch(IllegalArgumentException $0) { 
-			// ignore
-		}
-	}
-
-	@Override
-	public GenericClass[] params() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericFields fields() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericMethods constructors() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericMethods methods() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericClass parent() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericClasses parents() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericClass outer() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericClasses inner() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public Class<?> reflective() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public String name() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public Set<GenericAttribute> attributes() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-
-	@Override
-	public GenericAnnotations annotations() {
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-	}
-    
-	private static final class Li { // NOPMD - lazy init idiom
-		
-		public static final Method GET_CONSTANT_POOL;
-		
-		static {
-			try {
-				GET_CONSTANT_POOL = Class.class.getDeclaredMethod("getConstantPool");
-				GET_CONSTANT_POOL.setAccessible(true);
-			} catch(ReflectiveOperationException cause) {
-				throw ExceptionUtils.rethrow(cause);
-			}
-		}
-		
-	}
-    
-}

+ 99 - 0
assira/src/main/java/net/ranides/assira/reflection/impl/CPInspector.java

@@ -0,0 +1,99 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.reflection.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.IntFunction;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import net.ranides.assira.collection.iterators.ForwardSpliterator;
+import net.ranides.assira.reflection.util.MethodUtils;
+import net.ranides.assira.trace.ExceptionUtils;
+import sun.reflect.ConstantPool;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class CPInspector {
+    
+    private CPInspector() {
+        /* utility class */
+    }
+
+    public static Stream<Method> getMethods(Class<?> clazz) {
+        ConstantPool cp = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
+        return StreamSupport
+            .stream(new CPSpliterator<>(cp, cp::getMethodAt), false)
+            .filter(m -> m instanceof Method)
+            .map(m -> (Method)m);
+    }
+    
+    public static Stream<Field> getFields(Class<?> clazz) {
+        ConstantPool cp = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp, cp::getFieldAt), false);
+    }
+    
+    public static Stream<Class<?>> getClasses(Class<?> clazz) {
+        ConstantPool cp = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp, cp::getClassAt), false);
+    }
+    
+    public static Stream<String> getStrings(Class<?> clazz) {
+        ConstantPool cp = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp, cp::getUTF8At), false);
+    }
+    
+    private static final class CPSpliterator<T> extends ForwardSpliterator<T> {
+        
+        private final ConstantPool cp;
+        private final IntFunction<T> function;
+        private final int max;
+        private int index;
+        
+
+        public CPSpliterator(ConstantPool cp, IntFunction<T> function) {
+            this.cp = cp;
+            this.function = function;
+            this.max = cp.getSize();
+            this.index = 0;
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super T> action) {
+            while(index<max) {
+                try {
+                    action.accept(function.apply(index++));
+                    return true;
+                } catch(IllegalArgumentException $0) { 
+                    // do nothing
+                }
+            }
+            return false;
+        }
+        
+    }
+
+	private static final class Li { // NOPMD - lazy init idiom
+		
+		public static final Method GET_CONSTANT_POOL;
+		
+		static {
+			try {
+				GET_CONSTANT_POOL = Class.class.getDeclaredMethod("getConstantPool");
+				GET_CONSTANT_POOL.setAccessible(true);
+			} catch(ReflectiveOperationException cause) {
+				throw ExceptionUtils.rethrow(cause);
+			}
+		}
+		
+	}
+    
+}

+ 18 - 1
assira/src/main/java/net/ranides/assira/reflection/util/ClassInspector.java

@@ -6,8 +6,10 @@
  */
 package net.ranides.assira.reflection.util;
 
+import java.lang.reflect.Method;
 import net.ranides.assira.reflection.GenericClass;
-import net.ranides.assira.reflection.impl.CPIClass;
+import net.ranides.assira.reflection.GenericMethod;
+import net.ranides.assira.reflection.impl.CPInspector;
 
 /**
  *
@@ -37,4 +39,19 @@ public final class ClassInspector {
         throw new UnsupportedOperationException("Not supported yet.");
     }
     
+    public static GenericMethod methodInfo(Method method) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+    
+    public static GenericMethod lambdaInfo(Object object) {
+        Class<?> type = object.getClass();
+        if(!type.isSynthetic()) {
+			throw new IllegalArgumentException(type + " is not lambda");
+		}
+        Method method = CPInspector.getMethods(type).findFirst()
+            .orElseThrow(() -> new IllegalArgumentException(type + " is not lambda"));
+        
+        return methodInfo(method);
+    }
+    
 }

+ 1 - 0
assira/src/main/java/net/ranides/assira/reflection/util/MethodUtils.java

@@ -9,6 +9,7 @@ package net.ranides.assira.reflection.util;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Arrays;
+import net.ranides.assira.reflection.GenericMethod;
 import net.ranides.assira.trace.ExceptionUtils;
 
 /**

+ 0 - 84
assira/src/test/java/net/ranides/assira/reflection/impl/CPIClassTest.java

@@ -1,84 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.reflection.impl;
-
-import java.util.ArrayList;
-import java.util.function.Function;
-import org.junit.Test;
-import static net.ranides.assira.junit.NewAssert.*;
-import net.ranides.assira.reflection.mockup.ForClassTraits;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class CPIClassTest {
-	
-	public static void main(String[] args) {
-		new CPIClassTest().testCPI();
-	}
-	
-	@Test
-	public void testCPI() {
-
-		assertEquals(Float.class, CPIClass.lambdaType(pass1((int[] array) -> 5.7f)));
-		assertEquals(float[].class, CPIClass.lambdaType(pass1((int[] array) -> new float[2])));
-		assertEquals(Float[].class, CPIClass.lambdaType(pass1((int[] array) -> new Float[2])));
-		
-		assertEquals(Object.class, CPIClass.lambdaType(pass2((int[] array) -> 5.7f)));
-		assertEquals(Object.class, CPIClass.lambdaType(pass2((int[] array) -> new float[2])));
-		assertEquals(Object.class, CPIClass.lambdaType(pass2((int[] array) -> new Float[2])));
-		
-		int value = 1;
-		int[] array = new int[5];
-		Function<String, Character> function1 = s -> ' ';
-		Function<String, Character> function2 = s -> s.charAt(array[value]);
-		
-		assertEquals(Character.class, CPIClass.lambdaType(pass2(function1)));
-		assertEquals(Character.class, CPIClass.lambdaType(pass2(function2)));
-		assertEquals(Character.class, CPIClass.lambdaType(pass1((String s) -> s.charAt(array[value]))));
-		
-		assertEquals(Character.class, CPIClass.lambdaType(pass1((String s) -> s.charAt(array[value]))));
-		
-		
-		Function<String, Character> function3 = new Function<String, Character>() {
-			@Override
-			public Character apply(String t) {
-				return t.charAt(array[value]);
-			}
-		};
-		assertThrows(IllegalArgumentException.class, () -> {
-			CPIClass.lambdaType(function3);
-		});
-		assertThrows(IllegalArgumentException.class, () -> {
-			CPIClass.lambdaType(new Function<Integer, String>(){
-				@Override
-				public String apply(Integer $0) {
-					return "";
-				}
-			});
-		});
-		
-		
-		
-//		CPIClass.lambdaType(typeof2(function1));
-//		CPIClass.lambdaType(typeof2(function2));
-	}
-	
-//	private static Class<?> typeof(Object object) {
-//		return object.getClass();
-//	}
-	
-	private static <T,R> Object pass1(Function<T,R> object) {
-		return object;
-	}
-	
-	private static Object pass2(Function<?,?> object) {
-		return object;
-	}
-	
-}

+ 92 - 0
assira/src/test/java/net/ranides/assira/reflection/impl/CPInspectorTest.java

@@ -0,0 +1,92 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.reflection.impl;
+
+import java.util.ArrayList;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import static net.ranides.assira.junit.NewAssert.*;
+import net.ranides.assira.reflection.mockup.ForClassTraits;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class CPInspectorTest {
+	
+	public static void main(String[] args) {
+		new CPInspectorTest().testCPI();
+	}
+    
+    @Test
+    public void testCPI() {
+//        CPInspector.getMethods(type1((int[] array) -> 5.7f)).forEach(System.out::println);
+        
+        int value = 1;
+		int[] array = new int[5];
+		Function<String, Character> function2 = s -> s.charAt(array[value]);
+        CPInspector.getMethods(function2.getClass()).forEach(System.out::println);
+        CPInspector.getFields(function2.getClass()).forEach(System.out::println);
+    }
+	
+//	@Test
+//	public void testCPI() {
+//
+//		assertEquals(Float.class, CPInspector.lambdaType(pass1((int[] array) -> 5.7f)));
+//		assertEquals(float[].class, CPInspector.lambdaType(pass1((int[] array) -> new float[2])));
+//		assertEquals(Float[].class, CPInspector.lambdaType(pass1((int[] array) -> new Float[2])));
+//		
+//		assertEquals(Object.class, CPInspector.lambdaType(pass2((int[] array) -> 5.7f)));
+//		assertEquals(Object.class, CPInspector.lambdaType(pass2((int[] array) -> new float[2])));
+//		assertEquals(Object.class, CPInspector.lambdaType(pass2((int[] array) -> new Float[2])));
+//		
+//		int value = 1;
+//		int[] array = new int[5];
+//		Function<String, Character> function1 = s -> ' ';
+//		Function<String, Character> function2 = s -> s.charAt(array[value]);
+//		
+//		assertEquals(Character.class, CPInspector.lambdaType(pass2(function1)));
+//		assertEquals(Character.class, CPInspector.lambdaType(pass2(function2)));
+//		assertEquals(Character.class, CPInspector.lambdaType(pass1((String s) -> s.charAt(array[value]))));
+//		
+//		assertEquals(Character.class, CPInspector.lambdaType(pass1((String s) -> s.charAt(array[value]))));
+//		
+//		
+//		Function<String, Character> function3 = new Function<String, Character>() {
+//			@Override
+//			public Character apply(String t) {
+//				return t.charAt(array[value]);
+//			}
+//		};
+//		assertThrows(IllegalArgumentException.class, () -> {
+//			CPInspector.lambdaType(function3);
+//		});
+//		assertThrows(IllegalArgumentException.class, () -> {
+//			CPInspector.lambdaType(new Function<Integer, String>(){
+//				@Override
+//				public String apply(Integer $0) {
+//					return "";
+//				}
+//			});
+//		});
+//		
+//	}
+	
+	private static Class<?> type0(Object object) {
+		return object.getClass();
+	}
+	
+	private static <T,R> Class<?> type1(Function<T,R> object) {
+		return object.getClass();
+	}
+	
+	private static Class<?> type2(Function<?,?> object) {
+		return object.getClass();
+	}
+	
+}