@@ -173,6 +173,19 @@ private Value cast(Value... args) {
173173 return objectToValue (clazz , clazz .cast (((ObjectValue )args [0 ]).object ));
174174 }
175175
176+ @ Override
177+ public boolean containsKey (Value key ) {
178+ return getValue (clazz , null , key .asString ()) != null ;
179+ }
180+
181+ @ Override
182+ public Value get (Value key ) {
183+ if (super .containsKey (key )) {
184+ return super .get (key );
185+ }
186+ return getValue (clazz , null , key .asString ());
187+ }
188+
176189 @ Override
177190 public String toString () {
178191 return "ClassValue " + clazz .toString ();
@@ -195,76 +208,12 @@ public ObjectValue(Object object) {
195208
196209 @ Override
197210 public boolean containsKey (Value key ) {
198- return getValue (key .asString ()) != null ;
211+ return getValue (object . getClass (), object , key .asString ()) != null ;
199212 }
200213
201214 @ Override
202215 public Value get (Value key ) {
203- return getValue (key .asString ());
204- }
205-
206- private Value getValue (String key ) {
207- // Trying to get field
208- try {
209- final Field field = object .getClass ().getField (key );
210- return objectToValue (field .getType (), field .get (object ));
211- } catch (NoSuchFieldException | SecurityException |
212- IllegalArgumentException | IllegalAccessException ex ) {
213- // ignore and go to the next step
214- }
215-
216- // Trying to invoke method
217- try {
218- final Method [] allMethods = object .getClass ().getMethods ();
219- final List <Method > methods = new ArrayList <>();
220- for (Method method : allMethods ) {
221- if (method .getName ().equals (key )) {
222- methods .add (method );
223- }
224- }
225- if (methods .size () == 0 ) {
226- return FunctionValue .EMPTY ;
227- }
228- return new FunctionValue (methodsToFunction (methods ));
229- } catch (SecurityException ex ) {
230- // ignore and go to the next step
231- }
232-
233- return NULL ;
234-
235- }
236-
237- private Function methodsToFunction (List <Method > methods ) {
238- return (args ) -> {
239- for (Method method : methods ) {
240- if (method .getParameterCount () != args .length ) continue ;
241- if (!isMatch (args , method .getParameterTypes ())) continue ;
242- try {
243- final Object result = method .invoke (object , valuesToObjects (args ));
244- if (method .getReturnType () != void .class ) {
245- return objectToValue (result );
246- }
247- return NumberValue .ONE ;
248- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
249- // skip
250- }
251- }
252- return null ;
253- };
254- }
255-
256- private boolean isMatch (Value [] args , Class <?>[] types ) {
257- for (int i = 0 ; i < args .length ; i ++) {
258- final Value arg = args [i ];
259- final Class <?> clazz = types [i ];
260-
261- if (arg == NULL ) continue ;
262- if (unboxed (clazz ).isAssignableFrom (unboxed (valueToObject (arg ).getClass ()))) {
263- continue ;
264- }
265- return false ;
266- }
267- return true ;
216+ return getValue (object .getClass (), object , key .asString ());
268217 }
269218
270219 @ Override
@@ -276,22 +225,6 @@ public String asString() {
276225 public String toString () {
277226 return "ObjectValue " + asString ();
278227 }
279-
280- private Class <?> unboxed (Class <?> clazz ) {
281- if (clazz == null ) return null ;
282- if (clazz .isPrimitive ()) {
283- if (int .class == clazz ) return Integer .class ;
284- if (boolean .class == clazz ) return Boolean .class ;
285- if (double .class == clazz ) return Double .class ;
286- if (float .class == clazz ) return Float .class ;
287- if (long .class == clazz ) return Long .class ;
288- if (byte .class == clazz ) return Byte .class ;
289- if (char .class == clazz ) return Character .class ;
290- if (short .class == clazz ) return Short .class ;
291- if (void .class == clazz ) return Void .class ;
292- }
293- return clazz ;
294- }
295228 }
296229//</editor-fold>
297230
@@ -330,6 +263,85 @@ private Value toValue(Value... args) {
330263
331264
332265 //<editor-fold defaultstate="collapsed" desc="Helpers">
266+ private static Value getValue (Class <?> clazz , Object object , String key ) {
267+ // Trying to get field
268+ try {
269+ final Field field = clazz .getField (key );
270+ return objectToValue (field .getType (), field .get (object ));
271+ } catch (NoSuchFieldException | SecurityException |
272+ IllegalArgumentException | IllegalAccessException ex ) {
273+ // ignore and go to the next step
274+ }
275+
276+ // Trying to invoke method
277+ try {
278+ final Method [] allMethods = clazz .getMethods ();
279+ final List <Method > methods = new ArrayList <>();
280+ for (Method method : allMethods ) {
281+ if (method .getName ().equals (key )) {
282+ methods .add (method );
283+ }
284+ }
285+ if (methods .size () == 0 ) {
286+ return FunctionValue .EMPTY ;
287+ }
288+ return new FunctionValue (methodsToFunction (object , methods ));
289+ } catch (SecurityException ex ) {
290+ // ignore and go to the next step
291+ }
292+
293+ return NULL ;
294+ }
295+
296+ private static Function methodsToFunction (Object object , List <Method > methods ) {
297+ return (args ) -> {
298+ for (Method method : methods ) {
299+ if (method .getParameterCount () != args .length ) continue ;
300+ if (!isMatch (args , method .getParameterTypes ())) continue ;
301+ try {
302+ final Object result = method .invoke (object , valuesToObjects (args ));
303+ if (method .getReturnType () != void .class ) {
304+ return objectToValue (result );
305+ }
306+ return NumberValue .ONE ;
307+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
308+ // skip
309+ }
310+ }
311+ return null ;
312+ };
313+ }
314+
315+ private static boolean isMatch (Value [] args , Class <?>[] types ) {
316+ for (int i = 0 ; i < args .length ; i ++) {
317+ final Value arg = args [i ];
318+ final Class <?> clazz = types [i ];
319+
320+ if (arg == NULL ) continue ;
321+ if (unboxed (clazz ).isAssignableFrom (unboxed (valueToObject (arg ).getClass ()))) {
322+ continue ;
323+ }
324+ return false ;
325+ }
326+ return true ;
327+ }
328+
329+ private static Class <?> unboxed (Class <?> clazz ) {
330+ if (clazz == null ) return null ;
331+ if (clazz .isPrimitive ()) {
332+ if (int .class == clazz ) return Integer .class ;
333+ if (boolean .class == clazz ) return Boolean .class ;
334+ if (double .class == clazz ) return Double .class ;
335+ if (float .class == clazz ) return Float .class ;
336+ if (long .class == clazz ) return Long .class ;
337+ if (byte .class == clazz ) return Byte .class ;
338+ if (char .class == clazz ) return Character .class ;
339+ if (short .class == clazz ) return Short .class ;
340+ if (void .class == clazz ) return Void .class ;
341+ }
342+ return clazz ;
343+ }
344+
333345 private static ArrayValue array (Class <?>[] classes ) {
334346 final ArrayValue result = new ArrayValue (classes .length );
335347 for (int i = 0 ; i < classes .length ; i ++) {
0 commit comments