From f03cbb6fc741aa92fbec8d877d152270a4ba32c5 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 4 Oct 2019 00:21:28 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D1=82=D0=B8=D0=BF=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5=20java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../annimon/ownlang/modules/java/java.java | 84 +++++++++++++++++-- src/test/resources/modules/java/classes.own | 2 +- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/annimon/ownlang/modules/java/java.java b/src/main/java/com/annimon/ownlang/modules/java/java.java index 58ef5fc..890f89b 100644 --- a/src/main/java/com/annimon/ownlang/modules/java/java.java +++ b/src/main/java/com/annimon/ownlang/modules/java/java.java @@ -8,6 +8,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -167,7 +168,7 @@ public final class java implements Module { return findConstructorAndInstantiate(args, clazz.getConstructors()); } - private Value cast(Value... args) { + private Value cast(Value[] args) { Arguments.check(1, args.length); return objectToValue(clazz, clazz.cast(((ObjectValue)args[0]).object)); } @@ -337,7 +338,15 @@ public final class java implements Module { boolean assignable = unboxed != null; final Object object = valueToObject(arg); assignable = assignable && (object != null); - assignable = assignable && (unboxed.isAssignableFrom(object.getClass())); + if (assignable && unboxed.isArray() && object.getClass().isArray()) { + final Class uComponentType = unboxed.getComponentType(); + final Class oComponentType = object.getClass().getComponentType(); + assignable = assignable && (uComponentType != null); + assignable = assignable && (oComponentType != null); + assignable = assignable && (uComponentType.isAssignableFrom(oComponentType)); + } else { + assignable = assignable && (unboxed.isAssignableFrom(object.getClass())); + } if (assignable) continue; return false; @@ -460,7 +469,7 @@ public final class java implements Module { } return result; } - + private static Object[] valuesToObjects(Value[] args) { Object[] result = new Object[args.length]; for (int i = 0; i < args.length; i++) { @@ -490,11 +499,72 @@ public final class java implements Module { private static Object arrayToObject(ArrayValue value) { final int size = value.size(); - final Object[] result = new Object[size]; - for (int i = 0; i < size; i++) { - result[i] = valueToObject(value.get(i)); + final Object[] array = new Object[size]; + if (size == 0) { + return array; + } + + Class elementsType = null; + for (int i = 0; i < size; i++) { + array[i] = valueToObject(value.get(i)); + if (i == 0) { + elementsType = array[0].getClass(); + } else { + elementsType = mostCommonType(elementsType, array[i].getClass()); + } + } + + if (elementsType.equals(Object[].class)) { + return array; + } + return typedArray(array, size, elementsType); + } + + private static T[] typedArray(U[] elements, int newLength, Class elementsType) { + @SuppressWarnings("unchecked") + T[] copy = (T[]) Array.newInstance(elementsType, newLength); + System.arraycopy(elements, 0, copy, 0, Math.min(elements.length, newLength)); + return copy; + } + + private static Class mostCommonType(Class c1, Class c2) { + if (c1.equals(c2)) { + return c1; + } else if (c1.isAssignableFrom(c2)) { + return c1; + } else if (c2.isAssignableFrom(c1)) { + return c2; + } + final Class s1 = c1.getSuperclass(); + final Class s2 = c2.getSuperclass(); + if (s1 == null && s2 == null) { + final List> upperTypes = Arrays.asList( + Object.class, void.class, boolean.class, char.class, + byte.class, short.class, int.class, long.class, + float.class, double.class); + for (Class type : upperTypes) { + if (c1.equals(type) && c2.equals(type)) { + return s1; + } + } + return Object.class; + } else if (s1 == null || s2 == null) { + if (c1.equals(c2)) { + return c1; + } + if (c1.isInterface() && c1.isAssignableFrom(c2)) { + return c1; + } + if (c2.isInterface() && c2.isAssignableFrom(c1)) { + return c2; + } + } + + if (s1 != null) { + return mostCommonType(s1, c2); + } else { + return mostCommonType(c1, s2); } - return result; } // } diff --git a/src/test/resources/modules/java/classes.own b/src/test/resources/modules/java/classes.own index bfd12ce..0aaecbf 100644 --- a/src/test/resources/modules/java/classes.own +++ b/src/test/resources/modules/java/classes.own @@ -38,7 +38,7 @@ def testInvokeMethodSameName() { def testNonDefaultConstructor() { StringBuilder = newClass("java.lang.StringBuilder") - sb = StringBuilder.`new`("text") + sb = new StringBuilder("text") assertEquals("text", sb.toString()) }