Skip to content

Commit c382c4e

Browse files
committed
Возможность доступа к статтическим полям и методам
1 parent 47b5932 commit c382c4e

File tree

1 file changed

+94
-82
lines changed
  • src/main/java/com/annimon/ownlang/lib/modules

1 file changed

+94
-82
lines changed

src/main/java/com/annimon/ownlang/lib/modules/java.java

Lines changed: 94 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)