]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ValueFromMethod.java
(refs #7326) Better handling of exceptions in Java->SCL interface
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / ValueFromMethod.java
index bccfa892832a05c2a024f5a7b0f3258c3e35c6c3..1c8c6431f89b16310fd41232b8fd580294463215 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.internal.codegen.utils;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 import org.simantics.scl.runtime.function.FunctionImpl1;
@@ -11,6 +12,227 @@ import org.simantics.scl.runtime.tuple.Tuple0;
 
 public class ValueFromMethod {
 
+    private static final class Arity1Func extends FunctionImpl1<Object, Object> {
+        private final Method method;
+        private final boolean returnsVoid;
+
+        private Arity1Func(Method method, boolean returnsVoid) {
+            this.method = method;
+            this.returnsVoid = returnsVoid;
+        }
+
+        @Override
+        public Object apply(Object p0) {
+            try {
+                Object ret = method.invoke(null, p0);
+                return returnsVoid ? Tuple0.INSTANCE : ret;
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    Throwable cause = e.getCause();
+                    if(cause instanceof RuntimeException)
+                        throw (RuntimeException)cause;
+                    else
+                        throw new RuntimeException(cause);
+                }
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return method == null ? 0 : method.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Arity1Func other = (Arity1Func) obj;
+            return method.equals(other.method);
+        }
+    }
+
+    private static final class Arity2Func extends FunctionImpl2<Object, Object, Object> {
+        private final Method method;
+        private final boolean returnsVoid;
+
+        private Arity2Func(Method method, boolean returnsVoid) {
+            this.method = method;
+            this.returnsVoid = returnsVoid;
+        }
+
+        @Override
+        public Object apply(Object p0, Object p1) {
+            try {
+                Object ret = method.invoke(null, p0, p1);
+                return returnsVoid ? Tuple0.INSTANCE : ret;
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    Throwable cause = e.getCause();
+                    if(cause instanceof RuntimeException)
+                        throw (RuntimeException)cause;
+                    else
+                        throw new RuntimeException(cause);
+                }
+                throw new RuntimeException(e);
+            }
+        }
+        
+        @Override
+        public int hashCode() {
+            return method == null ? 0 : method.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Arity2Func other = (Arity2Func) obj;
+            return method.equals(other.method);
+        }
+    }
+
+    private static final class Arity3Func extends FunctionImpl3<Object, Object, Object, Object> {
+        private final Method method;
+        private final boolean returnsVoid;
+
+        private Arity3Func(Method method, boolean returnsVoid) {
+            this.method = method;
+            this.returnsVoid = returnsVoid;
+        }
+
+        @Override
+        public Object apply(Object p0, Object p1, Object p2) {
+            try {
+                Object ret = method.invoke(null, p0, p1, p2);
+                return returnsVoid ? Tuple0.INSTANCE : ret;
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    Throwable cause = e.getCause();
+                    if(cause instanceof RuntimeException)
+                        throw (RuntimeException)cause;
+                    else
+                        throw new RuntimeException(cause);
+                }
+                throw new RuntimeException(e);
+            }
+        }
+        
+        @Override
+        public int hashCode() {
+            return method == null ? 0 : method.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Arity3Func other = (Arity3Func) obj;
+            return method.equals(other.method);
+        }
+    }
+
+    private static final class Arity4Func extends FunctionImpl4<Object, Object, Object, Object, Object> {
+        private final Method method;
+        private final boolean returnsVoid;
+
+        private Arity4Func(Method method, boolean returnsVoid) {
+            this.method = method;
+            this.returnsVoid = returnsVoid;
+        }
+
+        @Override
+        public Object apply(Object p0, Object p1, Object p2, Object p3) {
+            try {
+                Object ret = method.invoke(null, p0, p1, p2, p3);
+                return returnsVoid ? Tuple0.INSTANCE : ret;
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    Throwable cause = e.getCause();
+                    if(cause instanceof RuntimeException)
+                        throw (RuntimeException)cause;
+                    else
+                        throw new RuntimeException(cause);
+                }
+                throw new RuntimeException(e);
+            }
+        }
+        
+        @Override
+        public int hashCode() {
+            return method == null ? 0 : method.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Arity4Func other = (Arity4Func) obj;
+            return method.equals(other.method);
+        }
+    }
+
+    private static final class ArityNFunc extends FunctionImplN {
+        private final Method method;
+        private final boolean returnsVoid;
+
+        private ArityNFunc(int arity, Method method, boolean returnsVoid) {
+            super(arity);
+            this.method = method;
+            this.returnsVoid = returnsVoid;
+        }
+
+        @Override
+        public Object doApply(Object... ps) {
+            try {
+                Object ret =  method.invoke(null, ps);
+                return returnsVoid ? Tuple0.INSTANCE : ret;
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    Throwable cause = e.getCause();
+                    if(cause instanceof RuntimeException)
+                        throw (RuntimeException)cause;
+                    else
+                        throw new RuntimeException(cause);
+                }
+                throw new RuntimeException(e);
+            }
+        }
+        
+        @Override
+        public int hashCode() {
+            return method == null ? 0 : method.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            ArityNFunc other = (ArityNFunc) obj;
+            return method.equals(other.method);
+        }
+    }
+
     public static Object getValueFromStaticMethod(final Method method) throws ReflectiveOperationException {
         int arity = method.getParameterTypes().length;
         final boolean returnsVoid = method.getReturnType().equals(void.class);
@@ -20,65 +242,15 @@ public class ValueFromMethod {
             return returnsVoid ? Tuple0.INSTANCE : ret;
         }
         case 1:
-            return new FunctionImpl1<Object,Object>() {
-                @Override
-                public Object apply(Object p0) {
-                    try {
-                        Object ret = method.invoke(null, p0);
-                        return returnsVoid ? Tuple0.INSTANCE : ret;
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
+            return new Arity1Func(method, returnsVoid);
         case 2:
-            return new FunctionImpl2<Object,Object,Object>() {
-                @Override
-                public Object apply(Object p0, Object p1) {
-                    try {
-                        Object ret = method.invoke(null, p0, p1);
-                        return returnsVoid ? Tuple0.INSTANCE : ret;
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
+            return new Arity2Func(method, returnsVoid);
         case 3:
-            return new FunctionImpl3<Object,Object,Object,Object>() {
-                @Override
-                public Object apply(Object p0, Object p1, Object p2) {
-                    try {
-                        Object ret = method.invoke(null, p0, p1, p2);
-                        return returnsVoid ? Tuple0.INSTANCE : ret;
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
+            return new Arity3Func(method, returnsVoid);
         case 4:
-            return new FunctionImpl4<Object,Object,Object,Object,Object>() {
-                @Override
-                public Object apply(Object p0, Object p1, Object p2, Object p3) {
-                    try {
-                        Object ret = method.invoke(null, p0, p1, p2, p3);
-                        return returnsVoid ? Tuple0.INSTANCE : ret;
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
+            return new Arity4Func(method, returnsVoid);
         default:
-            return new FunctionImplN(arity) {
-                @Override
-                public Object doApply(Object... ps) {
-                    try {
-                        Object ret =  method.invoke(null, ps);
-                        return returnsVoid ? Tuple0.INSTANCE : ret;
-                    } catch (ReflectiveOperationException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
+            return new ArityNFunc(arity, method, returnsVoid);
         }
     }