Ranides Atterwim 5 år sedan
förälder
incheckning
c1326a6716

+ 1 - 0
assira.lambda/lombok.config

@@ -0,0 +1 @@
+lombok.addLombokGeneratedAnnotation = true

+ 5 - 0
assira.lambda/pom.xml

@@ -65,6 +65,11 @@
             <groupId>net.ranides</groupId>
             <artifactId>assira.junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>

+ 169 - 0
assira.lambda/src/main/java/net/ranides/assira/reflection/CPInspector.java

@@ -0,0 +1,169 @@
+package net.ranides.assira.reflection;
+
+import lombok.experimental.UtilityClass;
+
+import net.ranides.assira.annotations.Meta;
+import net.ranides.assira.collection.iterators.ForwardSpliterator;
+import net.ranides.assira.reflection.util.MethodUtils;
+import net.ranides.assira.trace.ExceptionUtils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.function.Consumer;
+import java.util.function.IntFunction;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+@UtilityClass
+public class CPInspector {
+
+    @Meta.UnstableAPI
+    public static ConstantAdapter11 getConstantPool(Class<?> type) {
+        return AdapterFactory.getSystem().cast(Li.ADAPTER, MethodUtils.$invoke(Li.GET_CONSTANT_POOL, type));
+    }
+
+    /**
+     *
+     * @param clazz
+     * @return all methods referenced in class' bytecode
+     */
+    @Meta.UnstableAPI
+    public static Stream<Method> getMethods(Class<?> clazz) {
+        ConstantAdapter cp = getConstantPool(clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp.getSize(), cp::getMethodAt), false)
+            .filter(m -> m instanceof Method)
+            .map(m -> (Method)m);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Meta.UnstableAPI
+    public static <T> Stream<Constructor<T>> getConstructors(Class<T> clazz) {
+        ConstantAdapter cp = getConstantPool(clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp.getSize(), cp::getMethodAt), false)
+            .filter(m -> m instanceof Constructor<?>)
+            .map(m -> (Constructor<T>)m);
+    }
+
+    /**
+     *
+     * @param clazz
+     * @return fields referenced in class' bytecode
+     */
+    @Meta.UnstableAPI
+    public static Stream<Field> getFields(Class<?> clazz) {
+        ConstantAdapter cp = getConstantPool(clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp.getSize(), cp::getFieldAt), false);
+    }
+
+    /**
+     *
+     * @param clazz
+     * @return types referenced in class' bytecode
+     */
+    @Meta.UnstableAPI
+    public static Stream<Class<?>> getClasses(Class<?> clazz) {
+        ConstantAdapter cp = getConstantPool(clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp.getSize(), cp::getClassAt), false);
+    }
+
+    /**
+     *
+     * @param clazz
+     * @return string constants referenced in class' bytecode
+     */
+    @Meta.UnstableAPI
+    public static Stream<String> getStrings(Class<?> clazz) {
+        ConstantAdapter cp = getConstantPool(clazz);
+        return StreamSupport.stream(new CPSpliterator<>(cp.getSize(), cp::getUTF8At), false);
+    }
+
+    public interface ConstantAdapter {
+
+        int getSize();
+
+        Class<?> getClassAt(int var1);
+
+        Class<?> getClassAtIfLoaded(int var1);
+
+        Member getMethodAt(int var1);
+
+        Member getMethodAtIfLoaded(int var1);
+
+        Field getFieldAt(int var1);
+
+        Field getFieldAtIfLoaded(int var1);
+
+        String[] getMemberRefInfoAt(int var1);
+
+        int getIntAt(int var1);
+
+        long getLongAt(int var1);
+
+        float getFloatAt(int var1);
+
+        double getDoubleAt(int var1);
+
+        String getStringAt(int var1);
+
+        String getUTF8At(int var1);
+
+    }
+
+    public interface ConstantAdapter11 extends ConstantAdapter {
+        int getClassRefIndexAt(int index);
+
+        int getNameAndTypeRefIndexAt(int index);
+
+        String[] getNameAndTypeRefInfoAt(int index);
+
+        //public ConstantPool.Tag11 getTagAt(int index);
+
+    }
+
+    private static final class Li {
+
+        public static final IClass<ConstantAdapter11> ADAPTER = IClass.typeinfo(ConstantAdapter11.class);
+
+        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);
+            }
+        }
+
+    }
+
+    private static final class CPSpliterator<T> extends ForwardSpliterator<T> {
+
+        private final IntFunction<T> function;
+        private final int max;
+        private int index;
+
+
+        public CPSpliterator(int size, IntFunction<T> function) {
+            this.function = function;
+            this.max = size;
+            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) { // NOPMD
+                    // do nothing
+                }
+            }
+            return false;
+        }
+
+    }
+}

+ 2 - 3
assira.lambda/src/main/java/net/ranides/assira/reflection/LamdaReflect.java

@@ -3,15 +3,14 @@ package net.ranides.assira.reflection;
 import net.ranides.assira.annotations.Meta;
 import net.ranides.assira.reflection.impl.LMethodFactory;
 
-@Meta.UnstableAPI
-//@Deprecated(forRemoval=true)
-public class LamdaReflect {
+public class LambdaReflect {
 
     /**
      * Collect information for lambda expression
      * @param object
      * @return
      */
+    @Meta.UnstableAPI
     public static IMethod typeinfo(Object object) {
         return LMethodFactory.typeinfo(object);
     }

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

@@ -1,138 +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.collection.iterators.ForwardSpliterator;
-import net.ranides.assira.reflection.util.MethodUtils;
-import net.ranides.assira.trace.ExceptionUtils;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.function.Consumer;
-import java.util.function.IntFunction;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public final class CPInspector {
-
-    private CPInspector() {
-        /* utility class */
-    }
-
-    /**
-     * 
-     * @param clazz
-     * @return all methods referenced in class' bytecode
-     */
-    public static Stream<Method> getMethods(Class<?> clazz) {
-        CPP cp = new CPP(clazz);
-        return StreamSupport.stream(new CPSpliterator<>(cp.v.getSize(), cp.v::getMethodAt), false)
-            .filter(m -> m instanceof Method)
-            .map(m -> (Method)m);
-    }
-    
-    @SuppressWarnings("unchecked")
-    public static <T> Stream<Constructor<T>> getConstructors(Class<T> clazz) {
-        CPP cp = new CPP(clazz);
-        return StreamSupport.stream(new CPSpliterator<>(cp.v.getSize(), cp.v::getMethodAt), false)
-            .filter(m -> m instanceof Constructor<?>)
-            .map(m -> (Constructor<T>)m);
-    }
-    
-    /**
-     * 
-     * @param clazz
-     * @return fields referenced in class' bytecode
-     */
-    public static Stream<Field> getFields(Class<?> clazz) {
-        CPP cp = new CPP(clazz);
-        return StreamSupport.stream(new CPSpliterator<>(cp.v.getSize(), cp.v::getFieldAt), false);
-    }
-    
-    /**
-     * 
-     * @param clazz
-     * @return types referenced in class' bytecode
-     */
-    public static Stream<Class<?>> getClasses(Class<?> clazz) {
-        CPP cp = new CPP(clazz);
-        return StreamSupport.stream(new CPSpliterator<>(cp.v.getSize(), cp.v::getClassAt), false);
-    }
-    
-    /**
-     * 
-     * @param clazz
-     * @return string constants referenced in class' bytecode
-     */
-    public static Stream<String> getStrings(Class<?> clazz) {
-        CPP cp = new CPP(clazz);
-        return StreamSupport.stream(new CPSpliterator<>(cp.v.getSize(), cp.v::getUTF8At), false);
-    }
-        
-    private static final class CPSpliterator<T> extends ForwardSpliterator<T> {
-
-        private final IntFunction<T> function;
-        private final int max;
-        private int index;
-
-
-        public CPSpliterator(int size, IntFunction<T> function) {
-            this.function = function;
-            this.max = size;
-            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) { // NOPMD
-                    // 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);
-			}
-		}
-
-	}
-
-    // Cały cyrk z tym wrapperem tylko po to, aby nie mieć 20 warningów z powodu użycia klasy "sun.reflect".
-    // Mamy jedno użycie (tutaj). A reszta kodu używa typu niejawnie, używając pola "v"
-    //
-    // https://git.ranides.net/projects/assira/issues/25
-    private static final class CPP {
-
-        public final jdk.internal.reflect.ConstantPool v;
-
-        public CPP(Class<?> clazz) {
-            this.v = MethodUtils.$invoke(Li.GET_CONSTANT_POOL, clazz);
-        }
-
-    }
-    
-}

+ 22 - 23
assira.lambda/src/test/java/net/ranides/assira/reflection/LamdaReflectTest.java

@@ -4,7 +4,6 @@ import net.ranides.assira.generic.TypeToken;
 import org.junit.Test;
 
 import java.util.Arrays;
-import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Supplier;
@@ -13,7 +12,7 @@ import static net.ranides.assira.junit.NewAssert.assertThrows;
 import static net.ranides.assira.reflection.IAttribute.*;
 import static org.junit.Assert.assertEquals;
 
-public class LamdaReflectTest {
+public class LambdaReflectTest {
 
     public static final IClass<?> STRING = IClass.typeinfo(String.class);
 
@@ -46,7 +45,7 @@ public class LamdaReflectTest {
     @Test
     public void testInvalidLambda() {
         assertThrows(IllegalArgumentException.class, ()->{
-            LamdaReflect.typeinfo("Hello world");
+            LambdaReflect.typeinfo("Hello world");
         });
     }
 
@@ -167,8 +166,8 @@ public class LamdaReflectTest {
 
     @Test
     public void testInlineCall() {
-        IMethod m21 = LamdaReflect.typeinfo(pass2((Integer a) -> 3*a));
-        IMethod m11 = LamdaReflect.typeinfo(pass1((Integer a) -> 3*a));
+        IMethod m21 = LambdaReflect.typeinfo(pass2((Integer a) -> 3*a));
+        IMethod m11 = LambdaReflect.typeinfo(pass1((Integer a) -> 3*a));
 
         assertEquals(24, m21.call(8));
         assertEquals(24, m21.invoke(null, 8));
@@ -189,8 +188,8 @@ public class LamdaReflectTest {
         MTFunction.Lame f1 = (a,b,c) -> a.intValue() + b + c;
         MTFunction.LameLong f2 = (a,b,c) -> (int)a + b + c;
 
-        IMethod m1 = LamdaReflect.typeinfo(f1);
-        IMethod m2 = LamdaReflect.typeinfo(f2);
+        IMethod m1 = LambdaReflect.typeinfo(f1);
+        IMethod m2 = LambdaReflect.typeinfo(f2);
 
         MTFunction<Long> g1 = m1.handle(new TypeToken<MTFunction<Long>>(){});
         MTFunction<Long> g2 = m2.handle(new TypeToken<MTFunction<Long>>(){});
@@ -200,11 +199,11 @@ public class LamdaReflectTest {
     }
 
     private void testAPI(IAttributes exp, Object function1, Object function2, Object function3, Object function4, Object function5) {
-        IMethod m1 = LamdaReflect.typeinfo(function1);
-        IMethod m2 = LamdaReflect.typeinfo(function2);
-        IMethod m3 = LamdaReflect.typeinfo(function3);
-        IMethod m4 = LamdaReflect.typeinfo(function4);
-        IMethod m5 = LamdaReflect.typeinfo(function5);
+        IMethod m1 = LambdaReflect.typeinfo(function1);
+        IMethod m2 = LambdaReflect.typeinfo(function2);
+        IMethod m3 = LambdaReflect.typeinfo(function3);
+        IMethod m4 = LambdaReflect.typeinfo(function4);
+        IMethod m5 = LambdaReflect.typeinfo(function5);
 
         // name
         assertEquals("apply", m1.name());
@@ -254,11 +253,11 @@ public class LamdaReflectTest {
     }
 
     private void testLambdaCall(Object function1, Object function2, Object function3, Object function4, Object function5) {
-        IMethod m1 = LamdaReflect.typeinfo(function1);
-        IMethod m2 = LamdaReflect.typeinfo(function2);
-        IMethod m3 = LamdaReflect.typeinfo(function3);
-        IMethod m4 = LamdaReflect.typeinfo(function4);
-        IMethod m5 = LamdaReflect.typeinfo(function5);
+        IMethod m1 = LambdaReflect.typeinfo(function1);
+        IMethod m2 = LambdaReflect.typeinfo(function2);
+        IMethod m3 = LambdaReflect.typeinfo(function3);
+        IMethod m4 = LambdaReflect.typeinfo(function4);
+        IMethod m5 = LambdaReflect.typeinfo(function5);
 
         // call
         assertEquals('e', m1.call("hello!"));
@@ -289,11 +288,11 @@ public class LamdaReflectTest {
     }
 
     private void testFunctorCall(Object function1, Object function2, Object function3, Object function4, Object function5) {
-        IMethod m1 = LamdaReflect.typeinfo(function1);
-        IMethod m2 = LamdaReflect.typeinfo(function2);
-        IMethod m3 = LamdaReflect.typeinfo(function3);
-        IMethod m4 = LamdaReflect.typeinfo(function4);
-        IMethod m5 = LamdaReflect.typeinfo(function5);
+        IMethod m1 = LambdaReflect.typeinfo(function1);
+        IMethod m2 = LambdaReflect.typeinfo(function2);
+        IMethod m3 = LambdaReflect.typeinfo(function3);
+        IMethod m4 = LambdaReflect.typeinfo(function4);
+        IMethod m5 = LambdaReflect.typeinfo(function5);
 
         // call
         assertEquals('e', m1.call("hello!"));
@@ -345,7 +344,7 @@ public class LamdaReflectTest {
     }
 
     private void assertFunction2(Object function, IClass<?> ret, IClass<?>... args) {
-        IMethod m = LamdaReflect.typeinfo(function);
+        IMethod m = LambdaReflect.typeinfo(function);
 
 //        Class<?> type = function.getClass();
 //        System.out.printf(">>>> %s -> %s%n", m.arguments().types(), m.returns());

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

@@ -2,6 +2,8 @@ package net.ranides.assira.reflection.impl;
 
 import org.junit.Test;
 
+import net.ranides.assira.reflection.*;
+
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;

+ 18 - 1
assira/src/main/java/net/ranides/assira/collection/iterators/ForwardSpliterator.java

@@ -7,6 +7,8 @@
 package net.ranides.assira.collection.iterators;
 
 import java.util.Spliterators.AbstractSpliterator;
+import java.util.function.Consumer;
+import java.util.function.IntFunction;
 
 /**
  * 
@@ -17,5 +19,20 @@ public abstract class ForwardSpliterator<T> extends AbstractSpliterator<T> {
     public ForwardSpliterator() {
         super(Long.MAX_VALUE, IMMUTABLE);
     }
-    
+
+    public static <T> ForwardSpliterator<T> range(int begin, int end, IntFunction<T> function) {
+        return new ForwardSpliterator<T>() {
+            private int index = begin;
+
+            @Override
+            public boolean tryAdvance(Consumer<? super T> action) {
+                if(index<end) {
+                    action.accept(function.apply(index++));
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
 }

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

@@ -9,8 +9,6 @@ import static net.ranides.asm.Opcodes.*;
 
 public class AsmMethodBuilder {
 
-     // @todo (assira #8) see ASM GeneratorAdapter https://asm.ow2.io/javadoc/org/objectweb/asm/commons/GeneratorAdapter.html
-
     private final AsmClassBuilder parent;
 
     private final MethodVisitor mv;