ソースを参照

fix: first/last: optional
fix: ResolveStrategy is immutable

Ranides Atterwim 9 年 前
コミット
84ed3f0fa2

+ 71 - 71
assira.benchmark/src/main/java/net/ranides/benchmark/app/BenchmarkRunner.java

@@ -1,71 +1,71 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/JMH benchmark sample: Java
- */
-package net.ranides.benchmark.app;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import net.ranides.assira.reflection.IClass;
-import net.ranides.assira.text.Charsets;
-import net.ranides.assira.text.IOStrings;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.runner.Runner;
-import org.openjdk.jmh.runner.RunnerException;
-import org.openjdk.jmh.runner.options.Options;
-import org.openjdk.jmh.runner.options.OptionsBuilder;
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class BenchmarkRunner {
-    
-    public static void run(Class<?> benchmark) throws RunnerException, IOException {
-        run(benchmark,3);
-    }
-    
-    public static void run(Class<?> benchmark, int iterations) throws RunnerException, IOException {
-        Map<String, String> names = IClass.typeinfo(benchmark)
-            .methods()
-            .require(BenchmarkName.class)
-            .collect(Collectors.toMap(m -> m.name(), m -> m.annotation(BenchmarkName.class).value()));
-        
-        File file = new File("../doc/"+benchmark.getSimpleName()+".csv");
-        Iterator<String> re = new Runner(options(benchmark,iterations))
-            .run()
-            .stream()
-            .map(r -> r.getAggregatedResult().getPrimaryResult())
-            .map(r -> String.format("%s,%.0f,%.0f,%s", 
-                names.getOrDefault(r.getLabel(), r.getLabel()),
-                r.getScore(), 
-                r.getScoreError(), 
-                r.getScoreUnit()
-            ))
-            .iterator();
-        
-        IOStrings.writeLines(file, Charsets.UTF8, re);
-    }
-    
-    public static Options options(Class<?> benchmark, int iterations) {
-        String name = benchmark.getSimpleName();
-        return new OptionsBuilder()
-            .include(".*" + name + ".*")
-            .timeUnit(TimeUnit.NANOSECONDS)
-            .mode(Mode.AverageTime)
-            .forks(3)
-            .measurementIterations(iterations)
-            .warmupIterations(3)
-            .build();
-    }
-    
-    public static void main(String[] args) {
-        
-    }
-    
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/JMH benchmark sample: Java
+ */
+package net.ranides.benchmark.app;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.text.Charsets;
+import net.ranides.assira.text.IOStrings;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class BenchmarkRunner {
+    
+    public static void run(Class<?> benchmark) throws RunnerException, IOException {
+        run(benchmark,3);
+    }
+    
+    public static void run(Class<?> benchmark, int iterations) throws RunnerException, IOException {
+        Map<String, String> names = IClass.typeinfo(benchmark)
+            .methods()
+            .require(BenchmarkName.class)
+            .collect(Collectors.toMap(m -> m.name(), m -> m.annotation(BenchmarkName.class).get().value()));
+        
+        File file = new File("../doc/"+benchmark.getSimpleName()+".csv");
+        Iterator<String> re = new Runner(options(benchmark,iterations))
+            .run()
+            .stream()
+            .map(r -> r.getAggregatedResult().getPrimaryResult())
+            .map(r -> String.format("%s,%.0f,%.0f,%s", 
+                names.getOrDefault(r.getLabel(), r.getLabel()),
+                r.getScore(), 
+                r.getScoreError(), 
+                r.getScoreUnit()
+            ))
+            .iterator();
+        
+        IOStrings.writeLines(file, Charsets.UTF8, re);
+    }
+    
+    public static Options options(Class<?> benchmark, int iterations) {
+        String name = benchmark.getSimpleName();
+        return new OptionsBuilder()
+            .include(".*" + name + ".*")
+            .timeUnit(TimeUnit.NANOSECONDS)
+            .mode(Mode.AverageTime)
+            .forks(3)
+            .measurementIterations(iterations)
+            .warmupIterations(3)
+            .build();
+    }
+    
+    public static void main(String[] args) {
+        
+    }
+    
+}

+ 91 - 91
assira.drafts/src/main/java/net/ranides/assira/lambda/LRunner.java

@@ -1,91 +1,91 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira.drafts
- */
-package net.ranides.assira.lambda;
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.LambdaConversionException;
-import java.lang.invoke.LambdaMetafactory;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Type;
-import java.util.List;
-import net.ranides.assira.reflection.IAttribute;
-import static net.ranides.assira.reflection.IAttribute.BRIDGE;
-import static net.ranides.assira.reflection.IAttribute.DECLARED;
-import static net.ranides.assira.reflection.IAttribute.SYNTHETIC;
-import net.ranides.assira.reflection.IClass;
-import net.ranides.assira.reflection.IMethod;
-import net.ranides.assira.reflection.IMethods;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class LRunner {
-    
-    private static Class<?> ttype(IClass<?> ic) {
-        Type t = ic.reflective();
-        return t instanceof Class ? (Class)t : Object.class;
-    }
-    
-    public static void main(String[] args) throws LambdaConversionException, Throwable {
-        IClass<Hello> ic = IClass.typeinfo(Hello.class);
-        
-        
-        MethodHandle mh = ic.method("sum").handle();
-
-        IClass<IFunction> icf = IClass.typeinfo(IFunction.class);
-        
-        IMethod mf = icf.methods().require(DECLARED).discard(SYNTHETIC).discard(BRIDGE).first();
-        System.out.println("f = " + mf);
-        
-        Class<?> rf = ttype(mf.returns());
-        Class<?>[] rfparams = mf.arguments().types().stream().map(t -> ttype(t)).array(Class[]::new);
-        MethodType fmt = MethodType.methodType(rf, rfparams);
-        System.out.println("R = " + fmt);
-        
-        CallSite cs = LambdaMetafactory.metafactory(
-                MethodHandles.lookup(),
-                "apply",
-                MethodType.methodType(IFunction.class),
-//                MethodType.methodType(int.class, Object.class, int.class, int.class), /*mh.type(),*/
-                fmt,
-                mh,
-                mh.type() 
-        );
-        
-        IFunction lambda=(IFunction)cs.getTarget().invokeExact();
-        
-        System.out.println("d = " + lambda.apply(new Hello(400), 3, 0));
-    }
-    
-    
-    public static interface IFunction<T> {
-        
-        int apply(T that, int a, int b);
-        
-    }
-    
-    public static class Hello {
-        
-        private final int seed;
-
-        public Hello(int seed) {
-            this.seed = seed;
-        }
-        
-        public int sum(int a, int b) {
-            return seed+a+b;
-        }
-        
-        public int mul(int a, int b) {
-            return seed+a*b;
-        }
-        
-    };
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.drafts
+ */
+package net.ranides.assira.lambda;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Type;
+import java.util.List;
+import net.ranides.assira.reflection.IAttribute;
+import static net.ranides.assira.reflection.IAttribute.BRIDGE;
+import static net.ranides.assira.reflection.IAttribute.DECLARED;
+import static net.ranides.assira.reflection.IAttribute.SYNTHETIC;
+import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.reflection.IMethod;
+import net.ranides.assira.reflection.IMethods;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class LRunner {
+    
+    private static Class<?> ttype(IClass<?> ic) {
+        Type t = ic.reflective();
+        return t instanceof Class ? (Class)t : Object.class;
+    }
+    
+    public static void main(String[] args) throws LambdaConversionException, Throwable {
+        IClass<Hello> ic = IClass.typeinfo(Hello.class);
+        
+        
+        MethodHandle mh = ic.method("sum").get().handle();
+
+        IClass<IFunction> icf = IClass.typeinfo(IFunction.class);
+        
+        IMethod mf = icf.methods().require(DECLARED).discard(SYNTHETIC).discard(BRIDGE).first().get();
+        System.out.println("f = " + mf);
+        
+        Class<?> rf = ttype(mf.returns());
+        Class<?>[] rfparams = mf.arguments().types().stream().map(t -> ttype(t)).array(Class[]::new);
+        MethodType fmt = MethodType.methodType(rf, rfparams);
+        System.out.println("R = " + fmt);
+        
+        CallSite cs = LambdaMetafactory.metafactory(
+                MethodHandles.lookup(),
+                "apply",
+                MethodType.methodType(IFunction.class),
+//                MethodType.methodType(int.class, Object.class, int.class, int.class), /*mh.type(),*/
+                fmt,
+                mh,
+                mh.type() 
+        );
+        
+        IFunction lambda=(IFunction)cs.getTarget().invokeExact();
+        
+        System.out.println("d = " + lambda.apply(new Hello(400), 3, 0));
+    }
+    
+    
+    public static interface IFunction<T> {
+        
+        int apply(T that, int a, int b);
+        
+    }
+    
+    public static class Hello {
+        
+        private final int seed;
+
+        public Hello(int seed) {
+            this.seed = seed;
+        }
+        
+        public int sum(int a, int b) {
+            return seed+a+b;
+        }
+        
+        public int mul(int a, int b) {
+            return seed+a*b;
+        }
+        
+    };
+}

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

@@ -81,56 +81,60 @@ public class ResolvePattern implements Serializable {
     }
     
     public Object get(Object that) {
+        ResolveStatus status = new ResolveStatus();
         for(int i=0,n=tokens.length-1; i<n; i++) {
-            that = iget(handler, that, tokens[i]);
-            if(handler.failed()) {
+            that = iget(status, that, tokens[i]);
+            if(status.error) {
                 return handler.get(this, tokens[i]);
             }
         }
-        Object out = iget(handler, that, tokens[tokens.length-1]);
-        if(handler.failed()) {
+        Object out = iget(status, that, tokens[tokens.length-1]);
+        if(status.error) {
             return handler.get(this);
         }
         return out;
     }
     
     public void set(Object that, Object value) {
+        ResolveStatus status = new ResolveStatus();
         for(int i=0,n=tokens.length-1; i<n; i++) {
-            that = iget(handler, that, tokens[i]);
-            if(handler.failed()) {
+            that = iget(status, that, tokens[i]);
+            if(status.error) {
                 handler.get(this, tokens[i]);
             }
         }
-        iset(handler, that, tokens[tokens.length-1], value);
-        if(handler.failed()) {
+        iset(status, that, tokens[tokens.length-1], value);
+        if(status.error) {
             handler.set(this);
         }
     }
     
     public Object replace(Object that, Object value) {
+        ResolveStatus status = new ResolveStatus();
         for(int i=0,n=tokens.length-1; i<n; i++) {
-            that = iget(handler, that, tokens[i]);
-            if(handler.failed()) {
+            that = iget(status, that, tokens[i]);
+            if(status.error) {
                 handler.get(this, tokens[i]);
             }
         }
-        Object out = ireplace(handler, that, tokens[tokens.length-1], value);
-        if(handler.failed()) {
+        Object out = ireplace(status, that, tokens[tokens.length-1], value);
+        if(status.error) {
             return handler.replace(this);
         }
         return out;
     }
     
     public IClass<?> type(Object that) {
+        ResolveStatus status = new ResolveStatus();
         IClass<?> type = IClass.typefor(that);
         for(int i=0,n=tokens.length-1; i<n; i++) {
-            type = itype(handler, type, tokens[i]);
-            if(handler.failed()) {
+            type = itype(status, type, tokens[i]);
+            if(status.error) {
                 return handler.type(this, tokens[i]);
             }
         }
-        IClass<?> out = itype(handler, type, tokens[tokens.length-1]);
-        if(handler.failed()) {
+        IClass<?> out = itype(status, type, tokens[tokens.length-1]);
+        if(status.error) {
             return handler.type(this);
         }
         return out;
@@ -140,43 +144,43 @@ public class ResolvePattern implements Serializable {
         return new RWrapper(that);
     }
     
-    private Object iget(ResolveStrategy handler, Object that, String name) {
+    private Object iget(ResolveStatus status, Object that, String name) {
         for(Model m : MODELS) {
             if(m.matches(that)) {
-                return m.get(handler, that, name);
+                return m.get(status, that, name);
             }
         }
-        handler.failure();
+        status.error = true;
         return null;
     }
     
-    private void iset(ResolveStrategy handler, Object that, String name, Object value) {
+    private void iset(ResolveStatus status, Object that, String name, Object value) {
         for(Model m : MODELS) {
             if(m.matches(that)) {
-                m.set(handler, that, name, value);
+                m.set(status, that, name, value);
                 return;
             }
         }
-        handler.failure();
+        status.error = true;
     }
     
-    private Object ireplace(ResolveStrategy handler, Object that, String name, Object value) {
+    private Object ireplace(ResolveStatus status, Object that, String name, Object value) {
         for(Model m : MODELS) {
             if(m.matches(that)) {
-                return m.replace(handler, that, name, value);
+                return m.replace(status, that, name, value);
             }
         }
-        handler.failure();
+        status.error = true;
         return null;
     }
     
-    private IClass<?> itype(ResolveStrategy handler, IClass<?> that, String name) {
+    private IClass<?> itype(ResolveStatus status, IClass<?> that, String name) {
         for(Model m : MODELS) {
             if(m.matchesType(that)) {
-                return m.type(handler, that, name);
+                return m.type(status, that, name);
             }
         }
-        handler.failure();
+        status.error = true;
         return null;
     }
     
@@ -198,19 +202,19 @@ public class ResolvePattern implements Serializable {
                 return IAttribute.ARRAY.matches(that);
             }
             @Override
-            public Object get(ResolveStrategy _h, Object that, String name) {
+            public Object get(ResolveStatus _s, Object that, String name) {
                 return NativeArray.wrap(that).get(Integer.parseInt(name));
             }
             @Override
-            public void set(ResolveStrategy _h, Object that, String name, Object value) {
+            public void set(ResolveStatus _s, Object that, String name, Object value) {
                 NativeArray.wrap(that).set(Integer.parseInt(name), value);
             }
             @Override
-            public Object replace(ResolveStrategy _h, Object that, String name, Object value) {
+            public Object replace(ResolveStatus _s, Object that, String name, Object value) {
                 return NativeArray.wrap(that).replace(Integer.parseInt(name), value);
             }
             @Override
-            public IClass<?> type(ResolveStrategy _h, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus _s, IClass<?> that, String name) {
                 return that.component();
             }
         },
@@ -224,17 +228,17 @@ public class ResolvePattern implements Serializable {
                 return that!=IClass.NULL && RCompareUtils.isRawSuper(IClass.typeinfo(List.class), that);
             }
             @Override
-            public Object get(ResolveStrategy _h, Object that, String name) {
+            public Object get(ResolveStatus _s, Object that, String name) {
                 return ((List<?>)that).get(Integer.parseInt(name));
             }
             @Override
             @SuppressWarnings("unchecked")
-            public void set(ResolveStrategy _h, Object that, String name, Object value) {
+            public void set(ResolveStatus _s, Object that, String name, Object value) {
                 ((List<Object>)that).set(Integer.parseInt(name), value);
             }
             @Override
             @SuppressWarnings("unchecked")
-            public Object replace(ResolveStrategy _h, Object that, String name, Object value) {
+            public Object replace(ResolveStatus _s, Object that, String name, Object value) {
                 List<Object> list = (List<Object>)that;
                 int index = Integer.parseInt(name);
                 Object prv = list.get(index);
@@ -242,7 +246,7 @@ public class ResolvePattern implements Serializable {
                 return prv;
             }
             @Override
-            public IClass<?> type(ResolveStrategy _h, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus _s, IClass<?> that, String name) {
                 return that.params().get(0);
             }
         },
@@ -256,21 +260,21 @@ public class ResolvePattern implements Serializable {
                 return that!=IClass.NULL && RCompareUtils.isRawSuper(IClass.typeinfo(Map.class), that);
             }
             @Override
-            public Object get(ResolveStrategy _h, Object that, String name) {
+            public Object get(ResolveStatus _s, Object that, String name) {
                 return ((Map<?,?>)that).get(name);
             }
             @Override
             @SuppressWarnings("unchecked")
-            public void set(ResolveStrategy _h, Object that, String name, Object value) {
+            public void set(ResolveStatus _s, Object that, String name, Object value) {
                 ((Map<String,Object>)that).put(name, value);
             }
             @Override
             @SuppressWarnings("unchecked")
-            public Object replace(ResolveStrategy _h, Object that, String name, Object value) {
+            public Object replace(ResolveStatus _s, Object that, String name, Object value) {
                 return ((Map<String,Object>)that).put(name, value);
             }
             @Override
-            public IClass<?> type(ResolveStrategy _h, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus _s, IClass<?> that, String name) {
                 return that.params().get(1);
             }
         },
@@ -284,7 +288,7 @@ public class ResolvePattern implements Serializable {
                 return that!=IClass.NULL && IClass.typeinfo(Matcher.class).isSuper(that);
             }
             @Override
-            public Object get(ResolveStrategy _h, Object that, String name) {
+            public Object get(ResolveStatus _s, Object that, String name) {
                 if(StringTraits.isNumber(name)) {
                     return ((Matcher)that).group(Integer.parseInt(name));
                 } else {
@@ -292,15 +296,15 @@ public class ResolvePattern implements Serializable {
                 }
             }
             @Override
-            public void set(ResolveStrategy _h, Object that, String name, Object value) {
+            public void set(ResolveStatus _s, Object that, String name, Object value) {
                 throw new UnsupportedOperationException("Matcher is immutable.");
             }
             @Override
-            public Object replace(ResolveStrategy _h, Object that, String name, Object value) {
+            public Object replace(ResolveStatus _s, Object that, String name, Object value) {
                 throw new UnsupportedOperationException("Matcher is immutable.");
             }
             @Override
-            public IClass<?> type(ResolveStrategy _h, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus _s, IClass<?> that, String name) {
                 return IClass.typeinfo(String.class);
             }
         },
@@ -314,19 +318,19 @@ public class ResolvePattern implements Serializable {
                 return that!=IClass.NULL && IClass.typeinfo(CharSequence.class).isSuper(that);
             }
             @Override
-            public Object get(ResolveStrategy _h, Object that, String name) {
+            public Object get(ResolveStatus _s, Object that, String name) {
                 return ((CharSequence)that).charAt(Integer.parseInt(name));
             }
             @Override
-            public void set(ResolveStrategy _h, Object that, String name, Object value) {
+            public void set(ResolveStatus _s, Object that, String name, Object value) {
                 throw new UnsupportedOperationException("CharSequence is immutable.");
             }
             @Override
-            public Object replace(ResolveStrategy _h, Object that, String name, Object value) {
+            public Object replace(ResolveStatus _s, Object that, String name, Object value) {
                 throw new UnsupportedOperationException("CharSequence is immutable.");
             }
             @Override
-            public IClass<?> type(ResolveStrategy _h, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus _s, IClass<?> that, String name) {
                 return IClass.typeinfo(char.class);
             }
         },
@@ -340,7 +344,7 @@ public class ResolvePattern implements Serializable {
                 return that!=IClass.NULL;
             }
             @Override
-            public Object get(ResolveStrategy handler, Object that, String name) {
+            public Object get(ResolveStatus status, Object that, String name) {
                 BeanModel model = BeanModel.typefor(that);
                 if(model.properties().containsKey(name)) {
                     return model.property(name).get().get(that);
@@ -349,7 +353,7 @@ public class ResolvePattern implements Serializable {
                 if(f.hasNext()) {
                     return f.next().get(that);
                 }
-                handler.failure();
+                status.error = true;
                 return null;
             }
 
@@ -358,7 +362,7 @@ public class ResolvePattern implements Serializable {
             }
             
             @Override
-            public void set(ResolveStrategy handler, Object that, String name, Object value) {
+            public void set(ResolveStatus status, Object that, String name, Object value) {
                 BeanModel model = BeanModel.typefor(that);
                 if(model.properties().containsKey(name)) {
                     model.property(name).get().set(that, value);
@@ -369,10 +373,10 @@ public class ResolvePattern implements Serializable {
                     f.next().set(that, value);
                     return;
                 }
-                handler.failure();
+                status.error = true;
             }
             @Override
-            public Object replace(ResolveStrategy handler, Object that, String name, Object value) {
+            public Object replace(ResolveStatus status, Object that, String name, Object value) {
                 BeanModel model = BeanModel.typefor(that);
                 if(model.properties().containsKey(name)) {
                     return model.property(name).get().replace(that, value);
@@ -381,11 +385,11 @@ public class ResolvePattern implements Serializable {
                 if(f.hasNext()) {
                     return f.next().replace(that, value);
                 }
-                handler.failure();
+                status.error = true;
                 return null;
             }
             @Override
-            public IClass<?> type(ResolveStrategy handler, IClass<?> that, String name) {
+            public IClass<?> type(ResolveStatus status, IClass<?> that, String name) {
                 BeanModel model = BeanModel.typeinfo(that);
                 if(model.properties().containsKey(name)) {
                     return model.property(name).get().type();
@@ -394,7 +398,7 @@ public class ResolvePattern implements Serializable {
                 if(f.hasNext()) {
                     return f.next().type();
                 }
-                handler.failure();
+                status.error = true;
                 return null;
             }
         };
@@ -403,13 +407,13 @@ public class ResolvePattern implements Serializable {
         
         public abstract boolean matches(Object that);
         
-        public abstract Object get(ResolveStrategy handler, Object that, String name);
+        public abstract Object get(ResolveStatus status, Object that, String name);
         
-        public abstract void set(ResolveStrategy handler, Object that, String name, Object value);
+        public abstract void set(ResolveStatus status, Object that, String name, Object value);
         
-        public abstract Object replace(ResolveStrategy handler, Object that, String name, Object value);
+        public abstract Object replace(ResolveStatus status, Object that, String name, Object value);
         
-        public abstract IClass<?> type(ResolveStrategy handler, IClass<?> that, String name);
+        public abstract IClass<?> type(ResolveStatus status, IClass<?> that, String name);
         
     }
     
@@ -443,6 +447,11 @@ public class ResolvePattern implements Serializable {
     
     }
     
+    private static final class ResolveStatus {
+        
+        public boolean error;
+        
+    }
     
     
 }

+ 0 - 12
assira/src/main/java/net/ranides/assira/reflection/ResolveStrategy.java

@@ -8,8 +8,6 @@ package net.ranides.assira.reflection;
 
 import java.io.Serializable;
 
-// @todo (assira #1) ResolvePattern.ErrorHandler
-
 public abstract class ResolveStrategy implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -22,8 +20,6 @@ public abstract class ResolveStrategy implements Serializable {
     
     public static final ResolveStrategy NULL = new EHDefault(null);
     
-    private boolean error = false;
-    
     protected ResolveStrategy() {
         // do nothing
     }
@@ -32,14 +28,6 @@ public abstract class ResolveStrategy implements Serializable {
         return new EHDefault(value);
     }
 
-    protected final void failure() {
-        this.error = true;
-    }
-
-    protected final boolean failed() {
-        return error;
-    }
-
     public abstract Object get(ResolvePattern resolver);
 
     public abstract Object get(ResolvePattern resolver, String token);

+ 0 - 1
assira/src/main/java/net/ranides/assira/text/ResolveDialect.java

@@ -283,7 +283,6 @@ public final class ResolveDialect {
 
         @Override
         public final void parse(String source, Object context) throws ParseException {
-//            iresolver.type(context)
             set(context, parse(source));
         }
         

+ 0 - 2
assira/src/main/java/net/ranides/assira/text/ResolveFormat.java

@@ -54,8 +54,6 @@ import net.ranides.assira.reflection.ResolveException;
 @SuppressFBWarnings("SE_BAD_FIELD")
 public class ResolveFormat implements Serializable {
     
-    // @todo (assira #3) ResolveFormat: error handling
-    
     private static final long serialVersionUID = 1L;
     
     private static final Pattern  REGEX_SPECIAL = Pattern.compile("([\\\\*+\\[\\]()\\$.?\\^|])");

+ 71 - 7
assira/src/test/java/net/ranides/assira/reflection/ResolvePatternTest.java

@@ -11,6 +11,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Predicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import net.ranides.assira.generic.SerializationUtils;
@@ -22,6 +23,7 @@ import static net.ranides.assira.junit.NewAssert.*;
 import net.ranides.assira.reflection.mockup.ForIClass;
 import net.ranides.assira.reflection.mockup.ForResolver;
 import net.ranides.assira.text.StringUtils;
+import net.ranides.assira.text.Wildcard;
 
 /**
  *
@@ -288,19 +290,81 @@ public class ResolvePatternTest {
     }
     
     @Test
-    public void testResolveUnknown() {
+    public void testStrategy_Format() {
         A context = new A();
-//        System.out.printf("%s%n", ResolvePattern.compile("list[1].name").get(context));
+        ResolveStrategy strategy = ResolveStrategy.FORMAT;
+        
+        assertEquals("{list[1].unknown}", ResolvePattern.compile(strategy, "list[1].unknown").get(context));
+        
+        assertEquals("{list[1].unknown.some}", ResolvePattern.compile(strategy, "list[1].unknown.some").get(context));
+        
+        assertEquals(IClass.typeinfo(String.class), ResolvePattern.compile(strategy, "list[1].unknown").type(context));
+        
+        assertEquals(IClass.typeinfo(String.class), ResolvePattern.compile(strategy, "list[1].unknown.some").type(context));
 
-//        System.out.printf("%s%n", ResolvePattern.compile("list[1].unknown").get(context));
+        assertThrows(ResolveException.class, "No writable expression: {list[1].unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown").set(context, 0);
+        });
+        assertThrows(ResolveException.class, "No writable expression: {list[1].unknown.some}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown.some").set(context, 0);
+        });
+        assertThrows(ResolveException.class, "No replaceable expression: {list[1].unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown").replace(context, 0);
+        });
+        assertThrows(ResolveException.class, "No replaceable expression: {list[1].unknown.some}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown.some").replace(context, 0);
+        });
+    }
+    
+    @Test
+    public void testStrategy_Silent() {
+        A context = new A();
+        ResolveStrategy strategy = ResolveStrategy.SILENT;
         
-        System.out.printf("%s%n", ResolvePattern.compile(ResolveStrategy.FORMAT, "list[1].unknown").get(context));
+        assertEquals(null, ResolvePattern.compile(strategy, "list[1].unknown").get(context));
         
-        System.out.printf("%s%n", ResolvePattern.compile(ResolveStrategy.FORMAT, "list[1].unknown.some").get(context));
+        assertEquals(null, ResolvePattern.compile(strategy, "list[1].unknown.some").get(context));
         
-        System.out.printf("%s%n", ResolvePattern.compile(ResolveStrategy.withDefault("##"), "list[1].unknown").get(context));
+        assertEquals(IClass.NULL, ResolvePattern.compile(strategy, "list[1].unknown").type(context));
         
-        System.out.printf("%s%n", ResolvePattern.compile(ResolveStrategy.withDefault("##"), "list[1].unknown.xxx").get(context));
+        assertEquals(IClass.NULL, ResolvePattern.compile(strategy, "list[1].unknown.some").type(context));
+        
+        ResolvePattern.compile(strategy, "list[1].unknown").set(context, 0);
+        ResolvePattern.compile(strategy, "list[1].unknown.some").set(context, 0);
+        ResolvePattern.compile(strategy, "list[1].unknown").replace(context, 0);
+        ResolvePattern.compile(strategy, "list[1].unknown.some").replace(context, 0);
     }
+    
+    @Test
+    public void testStrategy_Default() {
+        A context = new A();
+        ResolveStrategy strategy = ResolveStrategy.withDefault(777L);
+        
+        assertEquals(777L, ResolvePattern.compile(strategy, "list[1].unknown").get(context));
+        
+        assertThrows(ResolveException.class, "Invalid expression: {list[1].unknown.some} at {unknown}", ()->{
+            ResolvePattern.compile(ResolveStrategy.withDefault("##"), "list[1].unknown.some").get(context);
+        });
+        
+        assertEquals(IClass.typeinfo(Long.class), ResolvePattern.compile(strategy, "list[1].unknown").type(context));
+        
+        assertThrows(ResolveException.class, "Invalid expression: {list[1].unknown.some} at {unknown}", ()->{
+            ResolvePattern.compile(ResolveStrategy.withDefault("##"), "list[1].unknown.some").type(context);
+        });
+        
+        assertThrows(ResolveException.class, "No writable expression: {list[1].unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown").set(context, 0);
+        });
+        assertThrows(ResolveException.class, "Invalid expression: {list[1].unknown.some} at {unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown.some").set(context, 0);
+        });
+        assertThrows(ResolveException.class, "No replaceable expression: {list[1].unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown").replace(context, 0);
+        });
+        assertThrows(ResolveException.class, "Invalid expression: {list[1].unknown.some} at {unknown}", ()->{
+            ResolvePattern.compile(strategy, "list[1].unknown.some").replace(context, 0);
+        });
+    }
+    
         
 }