Przeglądaj źródła

constant pool: work in progress

Ranides Atterwim 10 lat temu
rodzic
commit
722a625b15

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

@@ -0,0 +1,168 @@
+/*
+ * @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);
+			}
+		}
+		
+	}
+    
+}

+ 0 - 26
assira/src/main/java/net/ranides/assira/reflection/impl/CPReader.java

@@ -1,26 +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 net.ranides.assira.reflection.GenericClass;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class CPReader {
-
-    public CPReader(Class<?> clazz) {
-        // @todo (assira #0) implement ConstantPool reader
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-    
-    public GenericClass resolve() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-    
-}

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

@@ -7,7 +7,7 @@
 package net.ranides.assira.reflection.util;
 
 import net.ranides.assira.reflection.GenericClass;
-import net.ranides.assira.reflection.impl.CPReader;
+import net.ranides.assira.reflection.impl.CPIClass;
 
 /**
  *
@@ -37,13 +37,4 @@ public final class ClassInspector {
         throw new UnsupportedOperationException("Not supported yet.");
     }
     
-    /**
-     * Collect information from ConstantPool
-     * @param clazz
-     * @return 
-     */
-    public static GenericClass cp(Class<?> clazz) {
-        return new CPReader(clazz).resolve();
-    }
-    
 }

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

@@ -71,5 +71,10 @@ public final class MethodUtils {
             throw ExceptionUtils.rethrow(cause);
         } 
     }
+	
+	@SuppressWarnings("unchecked")
+	public static <T> T $invoke(Method method, Object that, Object... arguments) {
+		return (T)invoke(method, that, arguments);
+	}
     
 }

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

@@ -0,0 +1,84 @@
+/*
+ * @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;
+	}
+	
+}