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