]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ValueFromMethod.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / ValueFromMethod.java
1 package org.simantics.scl.compiler.internal.codegen.utils;
2
3 import java.lang.reflect.Method;
4
5 import org.simantics.scl.runtime.function.FunctionImpl1;
6 import org.simantics.scl.runtime.function.FunctionImpl2;
7 import org.simantics.scl.runtime.function.FunctionImpl3;
8 import org.simantics.scl.runtime.function.FunctionImpl4;
9 import org.simantics.scl.runtime.function.FunctionImplN;
10 import org.simantics.scl.runtime.tuple.Tuple0;
11
12 public class ValueFromMethod {
13
14     private static final class Arity1Func extends FunctionImpl1<Object, Object> {
15         private final Method method;
16         private final boolean returnsVoid;
17
18         private Arity1Func(Method method, boolean returnsVoid) {
19             this.method = method;
20             this.returnsVoid = returnsVoid;
21         }
22
23         @Override
24         public Object apply(Object p0) {
25             try {
26                 Object ret = method.invoke(null, p0);
27                 return returnsVoid ? Tuple0.INSTANCE : ret;
28             } catch (ReflectiveOperationException e) {
29                 throw new RuntimeException(e);
30             }
31         }
32
33         @Override
34         public int hashCode() {
35             return method == null ? 0 : method.hashCode();
36         }
37
38         @Override
39         public boolean equals(Object obj) {
40             if (this == obj)
41                 return true;
42             if (obj == null)
43                 return false;
44             if (getClass() != obj.getClass())
45                 return false;
46             Arity1Func other = (Arity1Func) obj;
47             return method.equals(other.method);
48         }
49     }
50
51     private static final class Arity2Func extends FunctionImpl2<Object, Object, Object> {
52         private final Method method;
53         private final boolean returnsVoid;
54
55         private Arity2Func(Method method, boolean returnsVoid) {
56             this.method = method;
57             this.returnsVoid = returnsVoid;
58         }
59
60         @Override
61         public Object apply(Object p0, Object p1) {
62             try {
63                 Object ret = method.invoke(null, p0, p1);
64                 return returnsVoid ? Tuple0.INSTANCE : ret;
65             } catch (ReflectiveOperationException e) {
66                 throw new RuntimeException(e);
67             }
68         }
69         
70         @Override
71         public int hashCode() {
72             return method == null ? 0 : method.hashCode();
73         }
74
75         @Override
76         public boolean equals(Object obj) {
77             if (this == obj)
78                 return true;
79             if (obj == null)
80                 return false;
81             if (getClass() != obj.getClass())
82                 return false;
83             Arity2Func other = (Arity2Func) obj;
84             return method.equals(other.method);
85         }
86     }
87
88     private static final class Arity3Func extends FunctionImpl3<Object, Object, Object, Object> {
89         private final Method method;
90         private final boolean returnsVoid;
91
92         private Arity3Func(Method method, boolean returnsVoid) {
93             this.method = method;
94             this.returnsVoid = returnsVoid;
95         }
96
97         @Override
98         public Object apply(Object p0, Object p1, Object p2) {
99             try {
100                 Object ret = method.invoke(null, p0, p1, p2);
101                 return returnsVoid ? Tuple0.INSTANCE : ret;
102             } catch (ReflectiveOperationException e) {
103                 throw new RuntimeException(e);
104             }
105         }
106         
107         @Override
108         public int hashCode() {
109             return method == null ? 0 : method.hashCode();
110         }
111
112         @Override
113         public boolean equals(Object obj) {
114             if (this == obj)
115                 return true;
116             if (obj == null)
117                 return false;
118             if (getClass() != obj.getClass())
119                 return false;
120             Arity3Func other = (Arity3Func) obj;
121             return method.equals(other.method);
122         }
123     }
124
125     private static final class Arity4Func extends FunctionImpl4<Object, Object, Object, Object, Object> {
126         private final Method method;
127         private final boolean returnsVoid;
128
129         private Arity4Func(Method method, boolean returnsVoid) {
130             this.method = method;
131             this.returnsVoid = returnsVoid;
132         }
133
134         @Override
135         public Object apply(Object p0, Object p1, Object p2, Object p3) {
136             try {
137                 Object ret = method.invoke(null, p0, p1, p2, p3);
138                 return returnsVoid ? Tuple0.INSTANCE : ret;
139             } catch (ReflectiveOperationException e) {
140                 throw new RuntimeException(e);
141             }
142         }
143         
144         @Override
145         public int hashCode() {
146             return method == null ? 0 : method.hashCode();
147         }
148
149         @Override
150         public boolean equals(Object obj) {
151             if (this == obj)
152                 return true;
153             if (obj == null)
154                 return false;
155             if (getClass() != obj.getClass())
156                 return false;
157             Arity4Func other = (Arity4Func) obj;
158             return method.equals(other.method);
159         }
160     }
161
162     private static final class ArityNFunc extends FunctionImplN {
163         private final Method method;
164         private final boolean returnsVoid;
165
166         private ArityNFunc(int arity, Method method, boolean returnsVoid) {
167             super(arity);
168             this.method = method;
169             this.returnsVoid = returnsVoid;
170         }
171
172         @Override
173         public Object doApply(Object... ps) {
174             try {
175                 Object ret =  method.invoke(null, ps);
176                 return returnsVoid ? Tuple0.INSTANCE : ret;
177             } catch (ReflectiveOperationException e) {
178                 throw new RuntimeException(e);
179             }
180         }
181         
182         @Override
183         public int hashCode() {
184             return method == null ? 0 : method.hashCode();
185         }
186
187         @Override
188         public boolean equals(Object obj) {
189             if (this == obj)
190                 return true;
191             if (obj == null)
192                 return false;
193             if (getClass() != obj.getClass())
194                 return false;
195             ArityNFunc other = (ArityNFunc) obj;
196             return method.equals(other.method);
197         }
198     }
199
200     public static Object getValueFromStaticMethod(final Method method) throws ReflectiveOperationException {
201         int arity = method.getParameterTypes().length;
202         final boolean returnsVoid = method.getReturnType().equals(void.class);
203         switch(arity) {
204         case 0: {
205             Object ret = method.invoke(null);
206             return returnsVoid ? Tuple0.INSTANCE : ret;
207         }
208         case 1:
209             return new Arity1Func(method, returnsVoid);
210         case 2:
211             return new Arity2Func(method, returnsVoid);
212         case 3:
213             return new Arity3Func(method, returnsVoid);
214         case 4:
215             return new Arity4Func(method, returnsVoid);
216         default:
217             return new ArityNFunc(arity, method, returnsVoid);
218         }
219     }
220     
221 }