From 9cd0c73960109329fc271ee3f13220966665c5c8 Mon Sep 17 00:00:00 2001 From: vmutafov Date: Fri, 16 Nov 2018 16:55:37 +0200 Subject: [PATCH 1/8] Add static and default interface methods support --- .gitignore | 1 + .../android-metadata-generator/build.gradle | 2 +- .../src/src/com/telerik/metadata/Builder.java | 81 ++- .../com/telerik/metadata/ClassDirectory.java | 3 +- .../com/telerik/metadata/bcl/MethodInfo.java | 22 + .../metadata/desc/MethodDescriptor.java | 1 + .../com/telerik/metadata/dx/MethodInfo.java | 28 +- test-app/runtime/CMakeLists.txt | 295 ++++----- test-app/runtime/build.gradle | 2 +- .../runtime/src/main/cpp/CallbackHandlers.cpp | 621 ++++++++++-------- .../runtime/src/main/cpp/CallbackHandlers.h | 130 ++-- ...redInterfaceCompanionClassNameResolver.cpp | 15 + ...garedInterfaceCompanionClassNameResolver.h | 26 + test-app/runtime/src/main/cpp/JEnv.cpp | 286 +++++--- test-app/runtime/src/main/cpp/JEnv.h | 3 + .../runtime/src/main/cpp/MetadataNode.cpp | 30 +- test-app/runtime/src/main/cpp/MetadataNode.h | 2 + .../runtime/src/main/cpp/com_tns_Runtime.cpp | 2 + .../src/main/java/com/tns/MethodResolver.java | 31 + 19 files changed, 998 insertions(+), 583 deletions(-) create mode 100644 test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp create mode 100644 test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h diff --git a/.gitignore b/.gitignore index 97a3f8edd..33733288b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ bin/ .settings .classpath +android-runtime.iml diff --git a/test-app/build-tools/android-metadata-generator/build.gradle b/test-app/build-tools/android-metadata-generator/build.gradle index 9bcb52ff5..b884acbf6 100644 --- a/test-app/build-tools/android-metadata-generator/build.gradle +++ b/test-app/build-tools/android-metadata-generator/build.gradle @@ -36,7 +36,7 @@ compileJava { compileJava.outputs.dir("$rootDir/dist/classes") dependencies { - compile 'org.apache.bcel:bcel:6.0' + compile 'org.apache.bcel:bcel:6.2' compile files("./src/libs/dx.jar") } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java index d8ca044bc..54061a7ea 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java @@ -1,10 +1,15 @@ package com.telerik.metadata; import java.io.File; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -124,7 +129,9 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod } MethodDescriptor[] allMethods = ClassUtil.getAllMethods(clazz); - MethodDescriptor[] methods = clazz.getMethods(); + MethodDescriptor[] classImplementedMethods = clazz.getMethods(); + MethodDescriptor[] interfaceImplementedMethods = getDefaultMethodsFromImplementedInterfaces(clazz, classImplementedMethods); + MethodDescriptor[] methods = concatenate(classImplementedMethods, interfaceImplementedMethods); Arrays.sort(methods, methodNameComparator); @@ -151,8 +158,8 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod && (m1.isPublic() || m1.isProtected()) && (isStatic == m1IsStatic) && (m1.getName().equals(mi.name) && (m1 - .getArgumentTypes().length == m - .getArgumentTypes().length))) { + .getArgumentTypes().length == m + .getArgumentTypes().length))) { if (++countUnique > 1) { break; } @@ -162,7 +169,7 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod TypeDescriptor[] params = m.getArgumentTypes(); mi.signature = getMethodSignature(root, m.getReturnType(), - params); + params); if (mi.signature != null) { if (isStatic) { @@ -195,7 +202,7 @@ private static void setFieldInfo(ClassDescriptor clazz, TreeNode node, TreeNode TypeDescriptor t = f.getType(); boolean isPrimitive = ClassUtil.isPrimitive(t); - fi.valueType = isPrimitive ? TreeNode.getPrimitive(t): getOrCreateNode(root, t); + fi.valueType = isPrimitive ? TreeNode.getPrimitive(t) : getOrCreateNode(root, t); fi.isFinalType = f.isFinal(); if (f.isStatic()) { @@ -242,8 +249,38 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr } } + private static MethodDescriptor[] getDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz, MethodDescriptor[] originalClassMethodDescriptors) { + HashSet defaultMethods = getAllDefaultMethodsFromImplementedInterfaces(clazz); + HashSet classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); + defaultMethods.removeAll(classMethods); + + return defaultMethods.toArray(new MethodDescriptor[0]); + } + + private static HashSet getAllDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz) { + return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); + } + + private static HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { + String[] implementedInterfacesNames = clazz.getInterfaceNames(); + + for (String implementedInterfaceName : implementedInterfacesNames) { + ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + + for (MethodDescriptor md : interfaceClass.getMethods()) { + if (!md.isStatic() && !md.isAbstract()) { + collectedDefaultMethods.add(md); + } + } + + collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); + } + + return collectedDefaultMethods; + } + private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) - throws Exception { + throws Exception { TreeNode node; String typeName = type.getSignature(); @@ -272,7 +309,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St if (ClassUtil.isArray(clazz)) { throw new UnsupportedOperationException("unexpected class=" - + clazz.getClassName()); + + clazz.getClassName()); } TreeNode node = root; @@ -307,7 +344,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St if (child == null) { child = node.createChild(outerClassname); child.nodeType = outer.isInterface() ? TreeNode.Interface - : TreeNode.Class; + : TreeNode.Class; if (outer.isStatic()) { child.nodeType |= TreeNode.Static; } @@ -324,7 +361,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St child.nodeType = tmp.nodeType; } else { child.nodeType = clazz.isInterface() ? TreeNode.Interface - : TreeNode.Class; + : TreeNode.Class; if (clazz.isStatic()) { child.nodeType |= TreeNode.Static; } @@ -337,8 +374,8 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St baseClass = ClassUtil.getClassByName(predefinedSuperClassname); } else { baseClass = clazz.isInterface() - ? ClassUtil.getClassByName("java.lang.Object") - : ClassUtil.getSuperclass(clazz); + ? ClassUtil.getClassByName("java.lang.Object") + : ClassUtil.getSuperclass(clazz); } if (baseClass != null) { node.baseClassNode = getOrCreateNode(root, baseClass, null); @@ -358,7 +395,7 @@ private static void copyBasePublicApi(ClassDescriptor baseClass, TreeNode node, } private static TreeNode createArrayNode(TreeNode root, String className) - throws Exception { + throws Exception { TreeNode currentNode = root; String currentClassname = className; @@ -385,7 +422,7 @@ private static TreeNode createArrayNode(TreeNode root, String className) } else { ClassDescriptor clazz = ClassRepo.findClass(name); child.nodeType = clazz.isInterface() ? TreeNode.Interface - : TreeNode.Class; + : TreeNode.Class; if (clazz.isStatic()) { child.nodeType |= TreeNode.Static; } @@ -397,7 +434,7 @@ private static TreeNode createArrayNode(TreeNode root, String className) } private static ArrayList getMethodSignature(TreeNode root, - TypeDescriptor retType, TypeDescriptor[] params) throws Exception { + TypeDescriptor retType, TypeDescriptor[] params) throws Exception { ArrayList sig = new ArrayList(); boolean isVoid = retType.equals(TypeDescriptor.VOID); @@ -405,14 +442,14 @@ private static ArrayList getMethodSignature(TreeNode root, if (!isVoid) { boolean isPrimitive = ClassUtil.isPrimitive(retType); node = isPrimitive ? TreeNode.getPrimitive(retType) - : getOrCreateNode(root, retType); + : getOrCreateNode(root, retType); } sig.add(node); for (TypeDescriptor param : params) { boolean isPrimitive = ClassUtil.isPrimitive(param); node = isPrimitive ? TreeNode.getPrimitive(param) - : getOrCreateNode(root, param); + : getOrCreateNode(root, param); if (node == null) { return null; } @@ -421,4 +458,16 @@ private static ArrayList getMethodSignature(TreeNode root, return sig; } + + private static T[] concatenate(T[] a, T[] b) { + int aLen = a.length; + int bLen = b.length; + + @SuppressWarnings("unchecked") + T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen); + System.arraycopy(a, 0, c, 0, aLen); + System.arraycopy(b, 0, c, aLen, bLen); + + return c; + } } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java index 305ef5779..6118daaad 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java @@ -40,7 +40,8 @@ private static void readDirectory(ClassDirectory dir, String path) throws IOException { List subDirs = new ArrayList(); File currentDir = new File(path); - for (File file : currentDir.listFiles()) { + File[] files = currentDir.listFiles(); + for (File file : files) { if (file.isFile()) { String name = file.getName(); if (name.endsWith(CLASS_EXT)) { diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java index 3c9510227..14e86cafb 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java @@ -6,6 +6,8 @@ import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.Type; +import java.lang.reflect.Modifier; + public class MethodInfo implements MethodDescriptor { private final Method m; @@ -33,6 +35,11 @@ public boolean isStatic() { return m.isStatic(); } + @Override + public boolean isAbstract() { + return m.isAbstract(); + } + @Override public String getName() { return m.getName(); @@ -62,4 +69,19 @@ public TypeDescriptor getReturnType() { public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { return null; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MethodInfo that = (MethodInfo) o; + + return m.equals(that.m); + } + + @Override + public int hashCode() { + return m.hashCode(); + } } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java index 545e5bb3e..0e51bd4b9 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java @@ -5,6 +5,7 @@ public interface MethodDescriptor { boolean isProtected(); boolean isSynthetic(); boolean isStatic(); + boolean isAbstract(); String getName(); String getSignature(); diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java index 52c657f41..07f3aea56 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java @@ -43,6 +43,11 @@ public boolean isStatic() { return AccessFlags.isStatic(method.getAccessFlags()); } + @Override + public boolean isAbstract() { + return AccessFlags.isAbstract(method.getAccessFlags()); + } + @Override public String getName() { Dex dex = dexFile.getDex(); @@ -59,12 +64,12 @@ public String getSignature() { MethodId methodId = dex.methodIds().get(method.getMethodIndex()); ProtoId methodProtoId = dex.protoIds().get(methodId.getProtoIndex()); short[] parameterTypes = dex.readTypeList(methodProtoId.getParametersOffset()).getTypes(); - String signature = "("; + StringBuilder signature = new StringBuilder("("); for (short paramId: parameterTypes) { - signature += typeNames.get(paramId); + signature.append(typeNames.get(paramId)); } - signature += ")" + getReturnType().getSignature(); - return signature; + signature.append(")").append(getReturnType().getSignature()); + return signature.toString(); } @Override @@ -156,4 +161,19 @@ public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { return null; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MethodInfo that = (MethodInfo) o; + + return getSignature().equals(that.getSignature()); + } + + @Override + public int hashCode() { + return getSignature().hashCode(); + } } diff --git a/test-app/runtime/CMakeLists.txt b/test-app/runtime/CMakeLists.txt index 201480572..f63980b0c 100644 --- a/test-app/runtime/CMakeLists.txt +++ b/test-app/runtime/CMakeLists.txt @@ -5,186 +5,187 @@ cmake_minimum_required(VERSION 3.4.1) # Add the ccache to the build system find_program(CCACHE_FOUND ccache) -if(CCACHE_FOUND AND (USE_CCACHE)) - MESSAGE( STATUS "## Using CCache when building!") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) -endif(CCACHE_FOUND AND (USE_CCACHE)) +if (CCACHE_FOUND AND (USE_CCACHE)) + MESSAGE(STATUS "## Using CCache when building!") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif (CCACHE_FOUND AND (USE_CCACHE)) # Command info: https://cmake.org/cmake/help/v3.4/command/message.html # we pass the android_ndk_root from gradle because for some reason # "-DANDROID_STL=c++_static" is just not enough for clang++ to find some libraries in the ndk -MESSAGE( STATUS "## ANDROID_NDK_ROOT: " ${ANDROID_NDK_ROOT} ) +MESSAGE(STATUS "## ANDROID_NDK_ROOT: " ${ANDROID_NDK_ROOT}) -if ( ANDROID_ABI MATCHES "arm64" ) +if (ANDROID_ABI MATCHES "arm64") set(ARCH_INCLUDE_DIR "aarch64-linux-android") -else() +else () set(ARCH_INCLUDE_DIR "arm-linux-androideabi") -endif() +endif () set(COMMON_CMAKE_ARGUMENTS "-std=c++11 -Werror -Wno-unused-result -mstackrealign -fexceptions -fno-builtin-stpcpy -fno-rtti") # Command info: https://cmake.org/cmake/help/v3.4/command/include_directories.html include_directories( - src/main/cpp - src/main/cpp/include - src/main/cpp/v8_inspector + src/main/cpp + src/main/cpp/include + src/main/cpp/v8_inspector - # hack to find some libraries from the ndk - ${ANDROID_NDK_ROOT}/sysroot/usr/include/${ARCH_INCLUDE_DIR}/ + # hack to find some libraries from the ndk + ${ANDROID_NDK_ROOT}/sysroot/usr/include/${ARCH_INCLUDE_DIR}/ ) -if ( OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD ) +if (OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD) set(CMAKE_CXX_FLAGS "${COMMON_CMAKE_ARGUMENTS} -O3 -fvisibility=hidden -ffunction-sections -fno-data-sections") -else() +else () set(CMAKE_CXX_FLAGS "${COMMON_CMAKE_ARGUMENTS} -g") -endif() +endif () -if ( NOT OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD ) +if (NOT OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD) # When building in Release mode we do not include the V8 inspector sources add_definitions(-DAPPLICATION_IN_DEBUG) set( - INSPECTOR_SOURCES - - src/main/cpp/com_tns_AndroidJsV8Inspector.cpp - src/main/cpp/JsV8InspectorClient.cpp - src/main/cpp/DOMDomainCallbackHandlers.cpp - src/main/cpp/NetworkDomainCallbackHandlers.cpp - - src/main/cpp/v8_inspector/src/inspector/protocol/CSS.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/DOM.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Log.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Network.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Overlay.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Page.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp - src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp - src/main/cpp/v8_inspector/src/inspector/utils/base64.cpp - src/main/cpp/v8_inspector/src/inspector/utils/v8-inspector-common.cpp - src/main/cpp/v8_inspector/src/inspector/utils/v8-network-request-data.cpp - src/main/cpp/v8_inspector/src/inspector/utils/v8-page-resources.cpp - src/main/cpp/v8_inspector/src/inspector/v8-css-agent-impl.cpp - src/main/cpp/v8_inspector/src/inspector/v8-dom-agent-impl.cpp - src/main/cpp/v8_inspector/src/inspector/v8-log-agent-impl.cpp - src/main/cpp/v8_inspector/src/inspector/v8-network-agent-impl.cpp - src/main/cpp/v8_inspector/src/inspector/v8-overlay-agent-impl.cpp - src/main/cpp/v8_inspector/src/inspector/v8-page-agent-impl.cpp - - src/main/cpp/v8_inspector/src/inspector/injected-script.cc - src/main/cpp/v8_inspector/src/inspector/inspected-context.cc - src/main/cpp/v8_inspector/src/inspector/remote-object-id.cc - src/main/cpp/v8_inspector/src/inspector/search-util.cc - src/main/cpp/v8_inspector/src/inspector/string-16.cc - src/main/cpp/v8_inspector/src/inspector/string-util.cc - src/main/cpp/v8_inspector/src/inspector/v8-console.cc - src/main/cpp/v8_inspector/src/inspector/v8-console-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-console-message.cc - src/main/cpp/v8_inspector/src/inspector/v8-debugger.cc - src/main/cpp/v8_inspector/src/inspector/v8-debugger-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-debugger-script.cc - src/main/cpp/v8_inspector/src/inspector/v8-function-call.cc - src/main/cpp/v8_inspector/src/inspector/v8-heap-profiler-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-injected-script-host.cc - src/main/cpp/v8_inspector/src/inspector/v8-inspector-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-inspector-session-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-internal-value-type.cc - src/main/cpp/v8_inspector/src/inspector/v8-profiler-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-regex.cc - src/main/cpp/v8_inspector/src/inspector/v8-runtime-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-schema-agent-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-stack-trace-impl.cc - src/main/cpp/v8_inspector/src/inspector/v8-value-utils.cc - src/main/cpp/v8_inspector/src/inspector/wasm-translation.cc + INSPECTOR_SOURCES + + src/main/cpp/com_tns_AndroidJsV8Inspector.cpp + src/main/cpp/JsV8InspectorClient.cpp + src/main/cpp/DOMDomainCallbackHandlers.cpp + src/main/cpp/NetworkDomainCallbackHandlers.cpp + + src/main/cpp/v8_inspector/src/inspector/protocol/CSS.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/DOM.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Log.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Network.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Overlay.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Page.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp + src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp + src/main/cpp/v8_inspector/src/inspector/utils/base64.cpp + src/main/cpp/v8_inspector/src/inspector/utils/v8-inspector-common.cpp + src/main/cpp/v8_inspector/src/inspector/utils/v8-network-request-data.cpp + src/main/cpp/v8_inspector/src/inspector/utils/v8-page-resources.cpp + src/main/cpp/v8_inspector/src/inspector/v8-css-agent-impl.cpp + src/main/cpp/v8_inspector/src/inspector/v8-dom-agent-impl.cpp + src/main/cpp/v8_inspector/src/inspector/v8-log-agent-impl.cpp + src/main/cpp/v8_inspector/src/inspector/v8-network-agent-impl.cpp + src/main/cpp/v8_inspector/src/inspector/v8-overlay-agent-impl.cpp + src/main/cpp/v8_inspector/src/inspector/v8-page-agent-impl.cpp + + src/main/cpp/v8_inspector/src/inspector/injected-script.cc + src/main/cpp/v8_inspector/src/inspector/inspected-context.cc + src/main/cpp/v8_inspector/src/inspector/remote-object-id.cc + src/main/cpp/v8_inspector/src/inspector/search-util.cc + src/main/cpp/v8_inspector/src/inspector/string-16.cc + src/main/cpp/v8_inspector/src/inspector/string-util.cc + src/main/cpp/v8_inspector/src/inspector/v8-console.cc + src/main/cpp/v8_inspector/src/inspector/v8-console-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-console-message.cc + src/main/cpp/v8_inspector/src/inspector/v8-debugger.cc + src/main/cpp/v8_inspector/src/inspector/v8-debugger-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-debugger-script.cc + src/main/cpp/v8_inspector/src/inspector/v8-function-call.cc + src/main/cpp/v8_inspector/src/inspector/v8-heap-profiler-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-injected-script-host.cc + src/main/cpp/v8_inspector/src/inspector/v8-inspector-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-inspector-session-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-internal-value-type.cc + src/main/cpp/v8_inspector/src/inspector/v8-profiler-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-regex.cc + src/main/cpp/v8_inspector/src/inspector/v8-runtime-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-schema-agent-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-stack-trace-impl.cc + src/main/cpp/v8_inspector/src/inspector/v8-value-utils.cc + src/main/cpp/v8_inspector/src/inspector/wasm-translation.cc ) -else() +else () # Debug builds will include the V8 inspector sources set(INSPECTOR_SOURCES) -endif() +endif () # Command info: https://cmake.org/cmake/help/v3.4/command/add_library.html # Creates(shared static) and names a library given relative sources # Gradle automatically packages shared libraries with your APK. add_library( - # Sets the name of the library. When it's built you can find it with lib prefix libNativeScript.so - NativeScript - - # Sets the library as a shared library. - SHARED - - # Runtime source - src/main/cpp/ArgConverter.cpp - src/main/cpp/ArrayBufferHelper.cpp - src/main/cpp/ArrayElementAccessor.cpp - src/main/cpp/ArrayHelper.cpp - src/main/cpp/AssetExtractor.cpp - src/main/cpp/CallbackHandlers.cpp - src/main/cpp/Constants.cpp - src/main/cpp/DirectBuffer.cpp - src/main/cpp/FieldAccessor.cpp - src/main/cpp/File.cpp - src/main/cpp/JEnv.cpp - src/main/cpp/JType.cpp - src/main/cpp/JniSignatureParser.cpp - src/main/cpp/JsArgConverter.cpp - src/main/cpp/JsArgToArrayConverter.cpp - src/main/cpp/Logger.cpp - src/main/cpp/ManualInstrumentation.cpp - src/main/cpp/MetadataMethodInfo.cpp - src/main/cpp/MetadataNode.cpp - src/main/cpp/MetadataReader.cpp - src/main/cpp/MetadataTreeNode.cpp - src/main/cpp/MethodCache.cpp - src/main/cpp/ModuleInternal.cpp - src/main/cpp/NativeScriptException.cpp - src/main/cpp/NumericCasts.cpp - src/main/cpp/ObjectManager.cpp - src/main/cpp/Profiler.cpp - src/main/cpp/ReadWriteLock.cpp - src/main/cpp/Runtime.cpp - src/main/cpp/SimpleAllocator.cpp - src/main/cpp/SimpleProfiler.cpp - src/main/cpp/Util.cpp - src/main/cpp/V8GlobalHelpers.cpp - src/main/cpp/V8StringConstants.cpp - src/main/cpp/WeakRef.cpp - src/main/cpp/com_tns_AssetExtractor.cpp - src/main/cpp/com_tns_Runtime.cpp - src/main/cpp/console/Console.cpp - - # V8 inspector source files will be included only in Release mode - ${INSPECTOR_SOURCES} + # Sets the name of the library. When it's built you can find it with lib prefix libNativeScript.so + NativeScript + + # Sets the library as a shared library. + SHARED + + # Runtime source + src/main/cpp/ArgConverter.cpp + src/main/cpp/ArrayBufferHelper.cpp + src/main/cpp/ArrayElementAccessor.cpp + src/main/cpp/ArrayHelper.cpp + src/main/cpp/AssetExtractor.cpp + src/main/cpp/CallbackHandlers.cpp + src/main/cpp/Constants.cpp + src/main/cpp/DirectBuffer.cpp + src/main/cpp/FieldAccessor.cpp + src/main/cpp/File.cpp + src/main/cpp/JEnv.cpp + src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp + src/main/cpp/JType.cpp + src/main/cpp/JniSignatureParser.cpp + src/main/cpp/JsArgConverter.cpp + src/main/cpp/JsArgToArrayConverter.cpp + src/main/cpp/Logger.cpp + src/main/cpp/ManualInstrumentation.cpp + src/main/cpp/MetadataMethodInfo.cpp + src/main/cpp/MetadataNode.cpp + src/main/cpp/MetadataReader.cpp + src/main/cpp/MetadataTreeNode.cpp + src/main/cpp/MethodCache.cpp + src/main/cpp/ModuleInternal.cpp + src/main/cpp/NativeScriptException.cpp + src/main/cpp/NumericCasts.cpp + src/main/cpp/ObjectManager.cpp + src/main/cpp/Profiler.cpp + src/main/cpp/ReadWriteLock.cpp + src/main/cpp/Runtime.cpp + src/main/cpp/SimpleAllocator.cpp + src/main/cpp/SimpleProfiler.cpp + src/main/cpp/Util.cpp + src/main/cpp/V8GlobalHelpers.cpp + src/main/cpp/V8StringConstants.cpp + src/main/cpp/WeakRef.cpp + src/main/cpp/com_tns_AssetExtractor.cpp + src/main/cpp/com_tns_Runtime.cpp + src/main/cpp/console/Console.cpp + + # V8 inspector source files will be included only in Release mode + ${INSPECTOR_SOURCES} ) -if ( OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD ) +if (OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD) set_target_properties(NativeScript PROPERTIES LINK_FLAGS -Wl,--allow-multiple-definition -Wl,--exclude-libs=ALL -Wl,--gc-sections) -else() +else () set_target_properties(NativeScript PROPERTIES LINK_FLAGS -Wl,--allow-multiple-definition) -endif() +endif () -MESSAGE( STATUS "# General cmake Info" ) -MESSAGE( STATUS "# PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} ) -MESSAGE( STATUS "# CMAKE_VERSION: " ${CMAKE_VERSION} ) -MESSAGE( STATUS "# CMAKE_C_COMPILER_ID: " ${CMAKE_C_COMPILER_ID} ) -MESSAGE( STATUS "# CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} ) -MESSAGE( STATUS "# CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS} ) -MESSAGE( STATUS "# CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} ) +MESSAGE(STATUS "# General cmake Info") +MESSAGE(STATUS "# PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR}) +MESSAGE(STATUS "# CMAKE_VERSION: " ${CMAKE_VERSION}) +MESSAGE(STATUS "# CMAKE_C_COMPILER_ID: " ${CMAKE_C_COMPILER_ID}) +MESSAGE(STATUS "# CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID}) +MESSAGE(STATUS "# CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) +MESSAGE(STATUS "# CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) # Command info: https://cmake.org/cmake/help/v3.4/command/target_link_libraries.html # linking v8 and inspector libraries to runtime(NativeScript library) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libzip.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_base.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_snapshot.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_init.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_initializers.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libplatform.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libsampler.a ) -target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libbase.a ) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libzip.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_base.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_snapshot.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_init.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_initializers.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libplatform.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libsampler.a) +target_link_libraries(NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}/libv8_libbase.a) # Command info: https://cmake.org/cmake/help/v3.4/command/find_library.html # Searches for a specified prebuilt library and stores the path as a @@ -192,11 +193,11 @@ target_link_libraries( NativeScript ${PROJECT_SOURCE_DIR}/src/main/libs/${ANDROI # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. -find_library( system-log log ) -find_library( system-android android ) -find_library( system-dl dl ) -find_library( system-z z ) +find_library(system-log log) +find_library(system-android android) +find_library(system-dl dl) +find_library(system-z z) # Command info: https://cmake.org/cmake/help/v3.4/command/target_link_libraries.html # Specifies libraries CMake should link to your target library. -target_link_libraries( NativeScript ${system-log} ${system-android} ${system-dl} ${system-z}) +target_link_libraries(NativeScript ${system-log} ${system-android} ${system-dl} ${system-z}) diff --git a/test-app/runtime/build.gradle b/test-app/runtime/build.gradle index b9ce2782f..83d9c0041 100644 --- a/test-app/runtime/build.gradle +++ b/test-app/runtime/build.gradle @@ -75,7 +75,7 @@ android { if (onlyX86) { abiFilters 'x86' } else { - abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a' + abiFilters 'x86'//, 'armeabi-v7a', 'arm64-v8a' } } } diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp index 17b05937c..f1fbb6ffc 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp @@ -22,7 +22,7 @@ using namespace v8; using namespace std; using namespace tns; -void CallbackHandlers::Init(Isolate* isolate) { +void CallbackHandlers::Init(Isolate *isolate) { JEnv env; JAVA_LANG_STRING = env.FindClass("java/lang/String"); @@ -32,29 +32,30 @@ void CallbackHandlers::Init(Isolate* isolate) { assert(RUNTIME_CLASS != nullptr); RESOLVE_CLASS_METHOD_ID = env.GetMethodID(RUNTIME_CLASS, "resolveClass", - "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Z)Ljava/lang/Class;"); + "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Z)Ljava/lang/Class;"); assert(RESOLVE_CLASS_METHOD_ID != nullptr); CURRENT_OBJECTID_FIELD_ID = env.GetFieldID(RUNTIME_CLASS, "currentObjectId", "I"); assert(CURRENT_OBJECTID_FIELD_ID != nullptr); MAKE_INSTANCE_STRONG_ID = env.GetMethodID(RUNTIME_CLASS, "makeInstanceStrong", - "(Ljava/lang/Object;I)V"); + "(Ljava/lang/Object;I)V"); assert(MAKE_INSTANCE_STRONG_ID != nullptr); GET_TYPE_METADATA = env.GetStaticMethodID(RUNTIME_CLASS, "getTypeMetadata", - "(Ljava/lang/String;I)[Ljava/lang/String;"); + "(Ljava/lang/String;I)[Ljava/lang/String;"); assert(GET_TYPE_METADATA != nullptr); ENABLE_VERBOSE_LOGGING_METHOD_ID = env.GetMethodID(RUNTIME_CLASS, "enableVerboseLogging", - "()V"); + "()V"); assert(ENABLE_VERBOSE_LOGGING_METHOD_ID != nullptr); DISABLE_VERBOSE_LOGGING_METHOD_ID = env.GetMethodID(RUNTIME_CLASS, "disableVerboseLogging", - "()V"); + "()V"); assert(ENABLE_VERBOSE_LOGGING_METHOD_ID != nullptr); - INIT_WORKER_METHOD_ID = env.GetStaticMethodID(RUNTIME_CLASS, "initWorker", "(Ljava/lang/String;Ljava/lang/String;I)V"); + INIT_WORKER_METHOD_ID = env.GetStaticMethodID(RUNTIME_CLASS, "initWorker", + "(Ljava/lang/String;Ljava/lang/String;I)V"); assert(INIT_WORKER_METHOD_ID != nullptr); @@ -63,12 +64,12 @@ void CallbackHandlers::Init(Isolate* isolate) { MethodCache::Init(); } -bool CallbackHandlers::RegisterInstance(Isolate* isolate, const Local& jsObject, - const std::string& fullClassName, - const ArgsWrapper& argWrapper, - const Local& implementationObject, +bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local &jsObject, + const std::string &fullClassName, + const ArgsWrapper &argWrapper, + const Local &implementationObject, bool isInterface, - const std::string& baseClassName) { + const std::string &baseClassName) { bool success; DEBUG_WRITE("RegisterInstance called for '%s'", fullClassName.c_str()); @@ -78,8 +79,9 @@ bool CallbackHandlers::RegisterInstance(Isolate* isolate, const Local& j JEnv env; - jclass generatedJavaClass = ResolveClass(isolate, baseClassName, fullClassName, implementationObject, - isInterface); + jclass generatedJavaClass = ResolveClass(isolate, baseClassName, fullClassName, + implementationObject, + isInterface); int javaObjectID = objectManager->GenerateNewObjectID(); @@ -87,7 +89,7 @@ bool CallbackHandlers::RegisterInstance(Isolate* isolate, const Local& j // resolve constructor auto mi = MethodCache::ResolveConstructorSignature(argWrapper, fullClassName, - generatedJavaClass, isInterface); + generatedJavaClass, isInterface); // while the "instance" is being created, if an exception is thrown during the construction // this scope will guarantee the "javaObjectID" will be set to -1 and won't have an invalid value @@ -118,14 +120,16 @@ bool CallbackHandlers::RegisterInstance(Isolate* isolate, const Local& j jclass instanceClass = env.FindClass(fullClassName); objectManager->SetJavaClass(jsObject, instanceClass); } else { - DEBUG_WRITE_FORCE("RegisterInstance failed with null new instance class: %s", fullClassName.c_str()); + DEBUG_WRITE_FORCE("RegisterInstance failed with null new instance class: %s", + fullClassName.c_str()); } return success; } -jclass CallbackHandlers::ResolveClass(Isolate* isolate, const string& baseClassName, const string& fullClassName, - const Local& implementationObject, bool isInterface) { +jclass CallbackHandlers::ResolveClass(Isolate *isolate, const string &baseClassName, + const string &fullClassName, + const Local &implementationObject, bool isInterface) { JEnv env; jclass globalRefToGeneratedClass = env.CheckForClassInCache(fullClassName); @@ -142,13 +146,13 @@ jclass CallbackHandlers::ResolveClass(Isolate* isolate, const string& baseClassN auto runtime = Runtime::GetRuntime(isolate); // create or load generated binding (java class) - jclass generatedClass = (jclass)env.CallObjectMethod(runtime->GetJavaRuntime(), - RESOLVE_CLASS_METHOD_ID, - (jstring) javaBaseClassName, - (jstring) javaFullClassName, - methodOverrides, - implementedInterfaces, - isInterface); + jclass generatedClass = (jclass) env.CallObjectMethod(runtime->GetJavaRuntime(), + RESOLVE_CLASS_METHOD_ID, + (jstring) javaBaseClassName, + (jstring) javaFullClassName, + methodOverrides, + implementedInterfaces, + isInterface); globalRefToGeneratedClass = env.InsertClassIntoCache(fullClassName, generatedClass); @@ -160,46 +164,47 @@ jclass CallbackHandlers::ResolveClass(Isolate* isolate, const string& baseClassN } // Called by ExtendMethodCallback when extending a class -string CallbackHandlers::ResolveClassName(Isolate* isolate, jclass& clazz) { +string CallbackHandlers::ResolveClassName(Isolate *isolate, jclass &clazz) { auto runtime = Runtime::GetRuntime(isolate); auto objectManager = runtime->GetObjectManager(); auto className = objectManager->GetClassName(clazz); return className; } -Local CallbackHandlers::GetArrayElement(Isolate* isolate, const Local& array, - uint32_t index, const string& arraySignature) { +Local CallbackHandlers::GetArrayElement(Isolate *isolate, const Local &array, + uint32_t index, const string &arraySignature) { return arrayElementAccessor.GetArrayElement(isolate, array, index, arraySignature); } -void CallbackHandlers::SetArrayElement(Isolate* isolate, const Local& array, uint32_t index, - const string& arraySignature, Local& value) { +void CallbackHandlers::SetArrayElement(Isolate *isolate, const Local &array, uint32_t index, + const string &arraySignature, Local &value) { arrayElementAccessor.SetArrayElement(isolate, array, index, arraySignature, value); } -Local CallbackHandlers::GetJavaField(Isolate* isolate, const Local& caller, - FieldCallbackData* fieldData) { +Local CallbackHandlers::GetJavaField(Isolate *isolate, const Local &caller, + FieldCallbackData *fieldData) { return fieldAccessor.GetJavaField(isolate, caller, fieldData); } -void CallbackHandlers::SetJavaField(Isolate* isolate, const Local& target, - const Local& value, FieldCallbackData* fieldData) { +void CallbackHandlers::SetJavaField(Isolate *isolate, const Local &target, + const Local &value, FieldCallbackData *fieldData) { fieldAccessor.SetJavaField(isolate, target, value, fieldData); } -void CallbackHandlers::CallJavaMethod(const Local& caller, const string& className, - const string& methodName, MetadataEntry* entry, bool isStatic, +void CallbackHandlers::CallJavaMethod(const Local &caller, const string &className, + const string &methodName, MetadataEntry *entry, + bool isFromInterface, bool isStatic, bool isSuper, - const v8::FunctionCallbackInfo& args) { + const v8::FunctionCallbackInfo &args) { SET_PROFILER_FRAME(); JEnv env; jclass clazz; jmethodID mid; - string* sig = nullptr; - string* returnType = nullptr; + string *sig = nullptr; + string *returnType = nullptr; auto retType = MethodReturnType::Unknown; MethodCache::CacheMethodInfo mi; @@ -208,8 +213,9 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& if (entry->memberId == nullptr) { clazz = env.FindClass(className); + if (clazz == nullptr) { - MetadataNode* callerNode = MetadataNode::GetNodeFromHandle(caller); + MetadataNode *callerNode = MetadataNode::GetNodeFromHandle(caller); const string callerClassName = callerNode->GetName(); DEBUG_WRITE("Cannot resolve class: %s while calling method: %s callerClassName: %s", @@ -221,9 +227,19 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& return; } - entry->memberId = isStatic ? - env.GetStaticMethodID(clazz, methodName, entry->sig) : - env.GetMethodID(clazz, methodName, entry->sig); + if (isStatic) { + if (isFromInterface) { + auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className, + methodName, + entry->sig); + entry->memberId = methodAndClassPair.first; + clazz = methodAndClassPair.second; + } else { + entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig); + } + } else { + entry->memberId = env.GetMethodID(clazz, methodName, entry->sig); + } if (entry->memberId == nullptr) { //todo: plamen5kov: throw exception here @@ -232,9 +248,19 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& return; } } else { - entry->memberId = isStatic ? - env.GetStaticMethodID(clazz, methodName, entry->sig) : - env.GetMethodID(clazz, methodName, entry->sig); + if (isStatic) { + if (isFromInterface) { + auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className, + methodName, + entry->sig); + entry->memberId = methodAndClassPair.first; + clazz = methodAndClassPair.second; + } else { + entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig); + } + } else { + entry->memberId = env.GetMethodID(clazz, methodName, entry->sig); + } if (entry->memberId == nullptr) { //todo: plamen5kov: throw exception here @@ -263,16 +289,16 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& return; } } else { - MetadataNode* callerNode = MetadataNode::GetNodeFromHandle(caller); + MetadataNode *callerNode = MetadataNode::GetNodeFromHandle(caller); const string callerClassName = callerNode->GetName(); DEBUG_WRITE("Resolving method on caller class: %s.%s on className %s", callerClassName.c_str(), methodName.c_str(), className.c_str()); mi = MethodCache::ResolveMethodSignature(callerClassName, methodName, args, isStatic); if (mi.mid == nullptr) { DEBUG_WRITE( - "Cannot resolve class=%s, method=%s, isStatic=%d, isSuper=%d, callerClass=%s", - className.c_str(), methodName.c_str(), isStatic, isSuper, - callerClassName.c_str()); + "Cannot resolve class=%s, method=%s, isStatic=%d, isSuper=%d, callerClass=%s", + className.c_str(), methodName.c_str(), isStatic, isSuper, + callerClassName.c_str()); return; } } @@ -304,7 +330,7 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& JniLocalRef callerJavaObject; - jvalue* javaArgs = argConverter.ToArgs(); + jvalue *javaArgs = argConverter.ToArgs(); auto runtime = Runtime::GetRuntime(isolate); auto objectManager = runtime->GetObjectManager(); @@ -314,190 +340,193 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& if (callerJavaObject.IsNull()) { stringstream ss; if (args.IsConstructCall()) { - ss << "No java object found on which to call \"" << methodName << "\" method. It is possible your Javascript object is not linked with the corresponding Java class. Try passing context(this) to the constructor function."; + ss << "No java object found on which to call \"" << methodName + << "\" method. It is possible your Javascript object is not linked with the corresponding Java class. Try passing context(this) to the constructor function."; } else { - ss << "Failed calling " << methodName << " on a " << className << " instance. The JavaScript instance no longer has available Java instance counterpart."; + ss << "Failed calling " << methodName << " on a " << className + << " instance. The JavaScript instance no longer has available Java instance counterpart."; } throw NativeScriptException(ss.str()); } } switch (retType) { - case MethodReturnType::Void: { - if (isStatic) { - env.CallStaticVoidMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - env.CallNonvirtualVoidMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - env.CallVoidMethodA(callerJavaObject, mid, javaArgs); - } - break; - } - case MethodReturnType::Boolean: { - jboolean result; - if (isStatic) { - result = env.CallStaticBooleanMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualBooleanMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallBooleanMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Void: { + if (isStatic) { + env.CallStaticVoidMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + env.CallNonvirtualVoidMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + env.CallVoidMethodA(callerJavaObject, mid, javaArgs); + } + break; } - args.GetReturnValue().Set(result != 0 ? True(isolate) : False(isolate)); - break; - } - case MethodReturnType::Byte: { - jbyte result; - if (isStatic) { - result = env.CallStaticByteMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualByteMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallByteMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Boolean: { + jboolean result; + if (isStatic) { + result = env.CallStaticBooleanMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualBooleanMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallBooleanMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set(result != 0 ? True(isolate) : False(isolate)); + break; } - args.GetReturnValue().Set(result); - break; - } - case MethodReturnType::Char: { - jchar result; - if (isStatic) { - result = env.CallStaticCharMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualCharMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallCharMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Byte: { + jbyte result; + if (isStatic) { + result = env.CallStaticByteMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualByteMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallByteMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set(result); + break; } + case MethodReturnType::Char: { + jchar result; + if (isStatic) { + result = env.CallStaticCharMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualCharMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallCharMethodA(callerJavaObject, mid, javaArgs); + } - JniLocalRef str(env.NewString(&result, 1)); - jboolean bol = true; - const char* resP = env.GetStringUTFChars(str, &bol); - args.GetReturnValue().Set(ArgConverter::ConvertToV8String(isolate, resP, 1)); - env.ReleaseStringUTFChars(str, resP); - break; - } - case MethodReturnType::Short: { - jshort result; - if (isStatic) { - result = env.CallStaticShortMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualShortMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallShortMethodA(callerJavaObject, mid, javaArgs); + JniLocalRef str(env.NewString(&result, 1)); + jboolean bol = true; + const char *resP = env.GetStringUTFChars(str, &bol); + args.GetReturnValue().Set(ArgConverter::ConvertToV8String(isolate, resP, 1)); + env.ReleaseStringUTFChars(str, resP); + break; } - args.GetReturnValue().Set(result); - break; - } - case MethodReturnType::Int: { - jint result; - if (isStatic) { - result = env.CallStaticIntMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualIntMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallIntMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Short: { + jshort result; + if (isStatic) { + result = env.CallStaticShortMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualShortMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallShortMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set(result); + break; } - args.GetReturnValue().Set(result); - break; + case MethodReturnType::Int: { + jint result; + if (isStatic) { + result = env.CallStaticIntMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualIntMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallIntMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set(result); + break; - } - case MethodReturnType::Long: { - jlong result; - if (isStatic) { - result = env.CallStaticLongMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualLongMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallLongMethodA(callerJavaObject, mid, javaArgs); } - auto jsLong = ArgConverter::ConvertFromJavaLong(isolate, result); - args.GetReturnValue().Set(jsLong); - break; - } - case MethodReturnType::Float: { - jfloat result; - if (isStatic) { - result = env.CallStaticFloatMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualFloatMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallFloatMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Long: { + jlong result; + if (isStatic) { + result = env.CallStaticLongMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualLongMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallLongMethodA(callerJavaObject, mid, javaArgs); + } + auto jsLong = ArgConverter::ConvertFromJavaLong(isolate, result); + args.GetReturnValue().Set(jsLong); + break; } - args.GetReturnValue().Set((double) result); //TODO: handle float value here correctly. - break; - } - case MethodReturnType::Double: { - jdouble result; - if (isStatic) { - result = env.CallStaticDoubleMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualDoubleMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallDoubleMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Float: { + jfloat result; + if (isStatic) { + result = env.CallStaticFloatMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualFloatMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallFloatMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set((double) result); //TODO: handle float value here correctly. + break; } - args.GetReturnValue().Set(result); - break; - } - case MethodReturnType::String: { - jobject result = nullptr; - bool exceptionOccurred; - - if (isStatic) { - result = env.CallStaticObjectMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualObjectMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallObjectMethodA(callerJavaObject, mid, javaArgs); + case MethodReturnType::Double: { + jdouble result; + if (isStatic) { + result = env.CallStaticDoubleMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualDoubleMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallDoubleMethodA(callerJavaObject, mid, javaArgs); + } + args.GetReturnValue().Set(result); + break; } + case MethodReturnType::String: { + jobject result = nullptr; + bool exceptionOccurred; + + if (isStatic) { + result = env.CallStaticObjectMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualObjectMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallObjectMethodA(callerJavaObject, mid, javaArgs); + } - if (result != nullptr) { - auto objectResult = ArgConverter::jstringToV8String(isolate, static_cast(result)); - args.GetReturnValue().Set(objectResult); - env.DeleteLocalRef(result); - } else { - args.GetReturnValue().Set(Null(isolate)); - } + if (result != nullptr) { + auto objectResult = ArgConverter::jstringToV8String(isolate, + static_cast(result)); + args.GetReturnValue().Set(objectResult); + env.DeleteLocalRef(result); + } else { + args.GetReturnValue().Set(Null(isolate)); + } - break; - } - case MethodReturnType::Object: { - jobject result = nullptr; - bool exceptionOccurred; - - if (isStatic) { - result = env.CallStaticObjectMethodA(clazz, mid, javaArgs); - } else if (isSuper) { - result = env.CallNonvirtualObjectMethodA(callerJavaObject, clazz, mid, javaArgs); - } else { - result = env.CallObjectMethodA(callerJavaObject, mid, javaArgs); + break; } + case MethodReturnType::Object: { + jobject result = nullptr; + bool exceptionOccurred; + + if (isStatic) { + result = env.CallStaticObjectMethodA(clazz, mid, javaArgs); + } else if (isSuper) { + result = env.CallNonvirtualObjectMethodA(callerJavaObject, clazz, mid, javaArgs); + } else { + result = env.CallObjectMethodA(callerJavaObject, mid, javaArgs); + } - if (result != nullptr) { - auto isString = env.IsInstanceOf(result, JAVA_LANG_STRING); + if (result != nullptr) { + auto isString = env.IsInstanceOf(result, JAVA_LANG_STRING); - Local objectResult; - if (isString) { - objectResult = ArgConverter::jstringToV8String(isolate, (jstring) result); - } else { - jint javaObjectID = objectManager->GetOrCreateObjectId(result); - objectResult = objectManager->GetJsObjectByJavaObject(javaObjectID); + Local objectResult; + if (isString) { + objectResult = ArgConverter::jstringToV8String(isolate, (jstring) result); + } else { + jint javaObjectID = objectManager->GetOrCreateObjectId(result); + objectResult = objectManager->GetJsObjectByJavaObject(javaObjectID); - if (objectResult.IsEmpty()) { - objectResult = objectManager->CreateJSWrapper(javaObjectID, *returnType, - result); + if (objectResult.IsEmpty()) { + objectResult = objectManager->CreateJSWrapper(javaObjectID, *returnType, + result); + } } + + args.GetReturnValue().Set(objectResult); + env.DeleteLocalRef(result); + } else { + args.GetReturnValue().Set(Null(isolate)); } - args.GetReturnValue().Set(objectResult); - env.DeleteLocalRef(result); - } else { - args.GetReturnValue().Set(Null(isolate)); + break; + } + default: { + assert(false); + break; } - - break; - } - default: { - assert(false); - break; - } } static uint32_t adjustMemCount = 0; @@ -507,14 +536,14 @@ void CallbackHandlers::CallJavaMethod(const Local& caller, const string& } } -void CallbackHandlers::AdjustAmountOfExternalAllocatedMemory(JEnv& env, Isolate* isolate) { +void CallbackHandlers::AdjustAmountOfExternalAllocatedMemory(JEnv &env, Isolate *isolate) { auto runtime = Runtime::GetRuntime(isolate); runtime->AdjustAmountOfExternalAllocatedMemory(); runtime->TryCallGC(); } -Local CallbackHandlers::CreateJSWrapper(Isolate* isolate, jint javaObjectID, - const string& typeName) { +Local CallbackHandlers::CreateJSWrapper(Isolate *isolate, jint javaObjectID, + const string &typeName) { auto runtime = Runtime::GetRuntime(isolate); auto objectManager = runtime->GetObjectManager(); @@ -522,12 +551,13 @@ Local CallbackHandlers::CreateJSWrapper(Isolate* isolate, jint javaObjec } -jobjectArray CallbackHandlers::GetImplementedInterfaces(JEnv& env, const Local& implementationObject) { +jobjectArray +CallbackHandlers::GetImplementedInterfaces(JEnv &env, const Local &implementationObject) { if (implementationObject.IsEmpty()) { return CallbackHandlers::GetJavaStringArray(env, 0); } - vector interfacesToImplement; + vector interfacesToImplement; auto propNames = implementationObject->GetOwnPropertyNames(); for (int i = 0; i < propNames->Length(); i++) { auto name = propNames->Get(i).As(); @@ -542,7 +572,8 @@ jobjectArray CallbackHandlers::GetImplementedInterfaces(JEnv& env, const LocalToObject(); auto isolate = implementationObject->GetIsolate(); - int length = interfacesArr->Get(v8::String::NewFromUtf8(isolate, "length"))->ToObject()->Uint32Value(); + int length = interfacesArr->Get( + v8::String::NewFromUtf8(isolate, "length"))->ToObject()->Uint32Value(); if (length > 0) { for (int i = 0; i < length; i++) { @@ -576,12 +607,13 @@ jobjectArray CallbackHandlers::GetImplementedInterfaces(JEnv& env, const Local& implementationObject) { +jobjectArray +CallbackHandlers::GetMethodOverrides(JEnv &env, const Local &implementationObject) { if (implementationObject.IsEmpty()) { return CallbackHandlers::GetJavaStringArray(env, 0); } - vector methodNames; + vector methodNames; auto propNames = implementationObject->GetOwnPropertyNames(); for (int i = 0; i < propNames->Length(); i++) { auto name = propNames->Get(i).As(); @@ -610,13 +642,13 @@ jobjectArray CallbackHandlers::GetMethodOverrides(JEnv& env, const Local return methodOverrides; } -void CallbackHandlers::LogMethodCallback(const v8::FunctionCallbackInfo& args) { +void CallbackHandlers::LogMethodCallback(const v8::FunctionCallbackInfo &args) { try { if ((args.Length() > 0) && args[0]->IsString()) { String::Utf8Value message(args[0]->ToString()); DEBUG_WRITE("%s", *message); } - } catch (NativeScriptException& e) { + } catch (NativeScriptException &e) { e.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -629,14 +661,15 @@ void CallbackHandlers::LogMethodCallback(const v8::FunctionCallbackInfo& args) { - auto nano = std::chrono::time_point_cast(std::chrono::system_clock::now()); +void CallbackHandlers::TimeCallback(const v8::FunctionCallbackInfo &args) { + auto nano = std::chrono::time_point_cast( + std::chrono::system_clock::now()); double duration = nano.time_since_epoch().count(); args.GetReturnValue().Set(duration); } void CallbackHandlers::DumpReferenceTablesMethodCallback( - const v8::FunctionCallbackInfo& args) { + const v8::FunctionCallbackInfo &args) { DumpReferenceTablesMethod(); } @@ -650,7 +683,7 @@ void CallbackHandlers::DumpReferenceTablesMethod() { env.CallStaticVoidMethod(vmDbgClass, mid); } } - } catch (NativeScriptException& e) { + } catch (NativeScriptException &e) { e.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -664,14 +697,14 @@ void CallbackHandlers::DumpReferenceTablesMethod() { } void CallbackHandlers::EnableVerboseLoggingMethodCallback( - const v8::FunctionCallbackInfo& args) { + const v8::FunctionCallbackInfo &args) { try { auto isolate = args.GetIsolate(); auto runtume = Runtime::GetRuntime(isolate); tns::LogEnabled = true; JEnv env; env.CallVoidMethod(runtume->GetJavaRuntime(), ENABLE_VERBOSE_LOGGING_METHOD_ID); - } catch (NativeScriptException& e) { + } catch (NativeScriptException &e) { e.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -685,14 +718,14 @@ void CallbackHandlers::EnableVerboseLoggingMethodCallback( } void CallbackHandlers::DisableVerboseLoggingMethodCallback( - const v8::FunctionCallbackInfo& args) { + const v8::FunctionCallbackInfo &args) { try { auto isolate = args.GetIsolate(); auto runtume = Runtime::GetRuntime(isolate); tns::LogEnabled = false; JEnv env; env.CallVoidMethod(runtume->GetJavaRuntime(), DISABLE_VERBOSE_LOGGING_METHOD_ID); - } catch (NativeScriptException& e) { + } catch (NativeScriptException &e) { e.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -705,17 +738,18 @@ void CallbackHandlers::DisableVerboseLoggingMethodCallback( } } -void CallbackHandlers::ExitMethodCallback(const v8::FunctionCallbackInfo& args) { +void CallbackHandlers::ExitMethodCallback(const v8::FunctionCallbackInfo &args) { auto msg = ArgConverter::ConvertToString(args[0].As()); DEBUG_WRITE_FATAL("FORCE EXIT: %s", msg.c_str()); exit(-1); } -void CallbackHandlers::CreateGlobalCastFunctions(Isolate* isolate, const Local& globalTemplate) { +void CallbackHandlers::CreateGlobalCastFunctions(Isolate *isolate, + const Local &globalTemplate) { castFunctions.CreateGlobalCastFunctions(isolate, globalTemplate); } -vector CallbackHandlers::GetTypeMetadata(const string& name, int index) { +vector CallbackHandlers::GetTypeMetadata(const string &name, int index) { JEnv env; string canonicalName = Util::ConvertFromJniToCanonicalName(name); @@ -724,17 +758,17 @@ vector CallbackHandlers::GetTypeMetadata(const string& name, int index) jint idx = index; JniLocalRef pubApi( - env.CallStaticObjectMethod(RUNTIME_CLASS, GET_TYPE_METADATA, (jstring) className, idx)); + env.CallStaticObjectMethod(RUNTIME_CLASS, GET_TYPE_METADATA, (jstring) className, idx)); jsize length = env.GetArrayLength(pubApi); assert(length > 0); - vector result; + vector result; for (jsize i = 0; i < length; i++) { JniLocalRef s(env.GetObjectArrayElement(pubApi, i)); - const char* pc = env.GetStringUTFChars(s, nullptr); + const char *pc = env.GetStringUTFChars(s, nullptr); result.push_back(string(pc)); env.ReleaseStringUTFChars(s, pc); } @@ -742,9 +776,9 @@ vector CallbackHandlers::GetTypeMetadata(const string& name, int index) return result; } -Local CallbackHandlers::CallJSMethod(Isolate* isolate, JNIEnv* _env, - const Local& jsObject, const string& methodName, - jobjectArray args) { +Local CallbackHandlers::CallJSMethod(Isolate *isolate, JNIEnv *_env, + const Local &jsObject, const string &methodName, + jobjectArray args) { SET_PROFILER_FRAME(); JEnv env(_env); @@ -793,7 +827,7 @@ Local CallbackHandlers::CallJSMethod(Isolate* isolate, JNIEnv* _env, return result; } -Local CallbackHandlers::FindClass(Isolate* isolate, const string& className) { +Local CallbackHandlers::FindClass(Isolate *isolate, const string &className) { Local clazz; JEnv env; @@ -812,7 +846,7 @@ Local CallbackHandlers::FindClass(Isolate* isolate, const string& classN return clazz; } -int CallbackHandlers::GetArrayLength(Isolate* isolate, const Local& arr) { +int CallbackHandlers::GetArrayLength(Isolate *isolate, const Local &arr) { auto runtime = Runtime::GetRuntime(isolate); auto objectManager = runtime->GetObjectManager(); @@ -825,10 +859,11 @@ int CallbackHandlers::GetArrayLength(Isolate* isolate, const Local& arr) return length; } -jobjectArray CallbackHandlers::GetJavaStringArray(JEnv& env, int length) { +jobjectArray CallbackHandlers::GetJavaStringArray(JEnv &env, int length) { if (length > CallbackHandlers::MAX_JAVA_STRING_ARRAY_LENGTH) { stringstream ss; - ss << "You are trying to override more methods than the limit of " << CallbackHandlers::MAX_JAVA_STRING_ARRAY_LENGTH; + ss << "You are trying to override more methods than the limit of " + << CallbackHandlers::MAX_JAVA_STRING_ARRAY_LENGTH; throw NativeScriptException(ss.str()); } @@ -836,21 +871,25 @@ jobjectArray CallbackHandlers::GetJavaStringArray(JEnv& env, int length) { return (jobjectArray) env.NewGlobalRef(tmpArr); } -void CallbackHandlers::NewThreadCallback(const v8::FunctionCallbackInfo& args) { +void CallbackHandlers::NewThreadCallback(const v8::FunctionCallbackInfo &args) { try { if (!args.IsConstructCall()) { throw NativeScriptException("Worker should be called as a constructor!"); } if (args.Length() > 1 || !args[0]->IsString()) { - throw NativeScriptException("Worker should be called with one string parameter (name of file to run)!"); + throw NativeScriptException( + "Worker should be called with one string parameter (name of file to run)!"); } auto thiz = args.This(); auto isolate = thiz->GetIsolate(); - auto currentExecutingScriptName = StackTrace::CurrentStackTrace(isolate, 1, StackTrace::kScriptName)->GetFrame(0)->GetScriptName(); - auto currentExecutingScriptNameStr = ArgConverter::ConvertToString(currentExecutingScriptName); + auto currentExecutingScriptName = StackTrace::CurrentStackTrace(isolate, 1, + StackTrace::kScriptName)->GetFrame( + 0)->GetScriptName(); + auto currentExecutingScriptNameStr = ArgConverter::ConvertToString( + currentExecutingScriptName); auto lastForwardSlash = currentExecutingScriptNameStr.find_last_of("/"); auto currentDir = currentExecutingScriptNameStr.substr(0, lastForwardSlash + 1); string fileSchema("file://"); @@ -864,7 +903,8 @@ void CallbackHandlers::NewThreadCallback(const v8::FunctionCallbackInfo(isolate, thiz); @@ -876,8 +916,9 @@ void CallbackHandlers::NewThreadCallback(const v8::FunctionCallbackInfo& args) { +void +CallbackHandlers::WorkerObjectPostMessageCallback(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -898,7 +940,7 @@ void CallbackHandlers::WorkerObjectPostMessageCallback(const v8::FunctionCallbac try { if (args.Length() != 1) { isolate->ThrowException(ArgConverter::ConvertToV8String(isolate, - "Failed to execute 'postMessage' on 'Worker': 1 argument required.")); + "Failed to execute 'postMessage' on 'Worker': 1 argument required.")); return; } @@ -923,8 +965,10 @@ void CallbackHandlers::WorkerObjectPostMessageCallback(const v8::FunctionCallbac env.CallStaticVoidMethod(RUNTIME_CLASS, mId, id, (jstring) jmsgRef); - DEBUG_WRITE("MAIN: WorkerObjectPostMessageCallback called postMessage on Worker object(id=%d)", id); - } catch (NativeScriptException& ex) { + DEBUG_WRITE( + "MAIN: WorkerObjectPostMessageCallback called postMessage on Worker object(id=%d)", + id); + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -937,7 +981,7 @@ void CallbackHandlers::WorkerObjectPostMessageCallback(const v8::FunctionCallbac } } -void CallbackHandlers::WorkerGlobalOnMessageCallback(Isolate* isolate, jstring message) { +void CallbackHandlers::WorkerGlobalOnMessageCallback(Isolate *isolate, jstring message) { auto context = isolate->GetCurrentContext(); try { @@ -965,14 +1009,14 @@ void CallbackHandlers::WorkerGlobalOnMessageCallback(Isolate* isolate, jstring m func->Call(Undefined(isolate), 1, args1); } else { DEBUG_WRITE( - "WORKER: WorkerGlobalOnMessageCallback couldn't fire a worker's `onmessage` callback because it isn't implemented!"); + "WORKER: WorkerGlobalOnMessageCallback couldn't fire a worker's `onmessage` callback because it isn't implemented!"); } if (tc.HasCaught()) { // TODO: Pete: Will catch exceptions thrown artificially in postMessage callbacks inside of 'onmessage' implementation CallWorkerScopeOnErrorHandle(isolate, tc); } - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -985,7 +1029,8 @@ void CallbackHandlers::WorkerGlobalOnMessageCallback(Isolate* isolate, jstring m } } -void CallbackHandlers::WorkerGlobalPostMessageCallback(const v8::FunctionCallbackInfo& args) { +void +CallbackHandlers::WorkerGlobalPostMessageCallback(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); HandleScope scope(isolate); @@ -996,7 +1041,7 @@ void CallbackHandlers::WorkerGlobalPostMessageCallback(const v8::FunctionCallbac // TODO: Pete: Discuss whether this is the way to go if (args.Length() != 1) { isolate->ThrowException(ArgConverter::ConvertToV8String(isolate, - "Failed to execute 'postMessage' on WorkerGlobalScope: 1 argument required.")); + "Failed to execute 'postMessage' on WorkerGlobalScope: 1 argument required.")); } if (tc.HasCaught()) { @@ -1016,7 +1061,7 @@ void CallbackHandlers::WorkerGlobalPostMessageCallback(const v8::FunctionCallbac env.CallStaticVoidMethod(RUNTIME_CLASS, mId, (jstring) jmsgRef); DEBUG_WRITE("WORKER: WorkerGlobalPostMessageCallback called."); - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1029,15 +1074,16 @@ void CallbackHandlers::WorkerGlobalPostMessageCallback(const v8::FunctionCallbac } } -void CallbackHandlers::WorkerObjectOnMessageCallback(Isolate* isolate, jint workerId, jstring message) { +void +CallbackHandlers::WorkerObjectOnMessageCallback(Isolate *isolate, jint workerId, jstring message) { try { auto workerFound = CallbackHandlers::id2WorkerMap.find(workerId); if (workerFound == CallbackHandlers::id2WorkerMap.end()) { // TODO: Pete: Throw exception DEBUG_WRITE( - "MAIN: WorkerObjectOnMessageCallback no worker instance was found with workerId=%d.", - workerId); + "MAIN: WorkerObjectOnMessageCallback no worker instance was found with workerId=%d.", + workerId); return; } @@ -1045,8 +1091,8 @@ void CallbackHandlers::WorkerObjectOnMessageCallback(Isolate* isolate, jint work if (workerPersistent->IsEmpty()) {// Object has been collected DEBUG_WRITE( - "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because the worker has been Garbage Collected.", - workerId); + "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because the worker has been Garbage Collected.", + workerId); CallbackHandlers::id2WorkerMap.erase(workerId); return; } @@ -1073,10 +1119,10 @@ void CallbackHandlers::WorkerObjectOnMessageCallback(Isolate* isolate, jint work func->Call(Undefined(isolate), 1, args1); } else { DEBUG_WRITE( - "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because it isn't implemented.", - workerId); + "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because it isn't implemented.", + workerId); } - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1089,7 +1135,8 @@ void CallbackHandlers::WorkerObjectOnMessageCallback(Isolate* isolate, jint work } } -void CallbackHandlers::WorkerObjectTerminateCallback(const v8::FunctionCallbackInfo& args) { +void +CallbackHandlers::WorkerObjectTerminateCallback(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); DEBUG_WRITE("WORKER: WorkerObjectTerminateCallback called."); @@ -1114,8 +1161,8 @@ void CallbackHandlers::WorkerObjectTerminateCallback(const v8::FunctionCallbackI if (!isTerminated.IsEmpty() && isTerminated->BooleanValue()) { DEBUG_WRITE( - "Main: WorkerObjectTerminateCallback - Worker(id=%d)'s terminate has already been called.", - id); + "Main: WorkerObjectTerminateCallback - Worker(id=%d)'s terminate has already been called.", + id); return; } @@ -1130,7 +1177,7 @@ void CallbackHandlers::WorkerObjectTerminateCallback(const v8::FunctionCallbackI // Remove persistent handle from id2WorkerMap CallbackHandlers::ClearWorkerPersistent(id); - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1143,7 +1190,7 @@ void CallbackHandlers::WorkerObjectTerminateCallback(const v8::FunctionCallbackI } } -void CallbackHandlers::WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo& args) { +void CallbackHandlers::WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo &args) { auto isolate = args.GetIsolate(); DEBUG_WRITE("WORKER: WorkerThreadCloseCallback called."); @@ -1155,7 +1202,7 @@ void CallbackHandlers::WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo< auto globalObject = context->Global(); auto isTerminating = globalObject->Get( - ArgConverter::ConvertToV8String(isolate, "isTerminating")); + ArgConverter::ConvertToV8String(isolate, "isTerminating")); if (!isTerminating.IsEmpty() && isTerminating->BooleanValue()) { DEBUG_WRITE("WORKER: WorkerThreadCloseCallback - Worker is currently terminating..."); @@ -1191,7 +1238,7 @@ void CallbackHandlers::WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo< "()V"); env.CallStaticVoidMethod(RUNTIME_CLASS, mId); - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1204,7 +1251,7 @@ void CallbackHandlers::WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo< } } -void CallbackHandlers::CallWorkerScopeOnErrorHandle(Isolate* isolate, TryCatch& tc) { +void CallbackHandlers::CallWorkerScopeOnErrorHandle(Isolate *isolate, TryCatch &tc) { try { TryCatch innerTc(isolate); @@ -1259,7 +1306,7 @@ void CallbackHandlers::CallWorkerScopeOnErrorHandle(Isolate* isolate, TryCatch& auto runtime = Runtime::GetRuntime(isolate); runtime->PassUncaughtExceptionFromWorkerToMainHandler(msg, stackTrace, source, lno); - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1272,15 +1319,18 @@ void CallbackHandlers::CallWorkerScopeOnErrorHandle(Isolate* isolate, TryCatch& } } -void CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate* isolate, jint workerId, jstring message, jstring stackTrace, jstring filename, jint lineno, jstring threadName) { +void +CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate *isolate, jint workerId, jstring message, + jstring stackTrace, jstring filename, jint lineno, + jstring threadName) { try { auto workerFound = CallbackHandlers::id2WorkerMap.find(workerId); if (workerFound == CallbackHandlers::id2WorkerMap.end()) { // TODO: Pete: Throw exception DEBUG_WRITE( - "MAIN: CallWorkerObjectOnErrorHandle no worker instance was found with workerId=%d.", - workerId); + "MAIN: CallWorkerObjectOnErrorHandle no worker instance was found with workerId=%d.", + workerId); return; } @@ -1288,8 +1338,8 @@ void CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate* isolate, jint work if (workerPersistent->IsEmpty()) {// Object has been collected DEBUG_WRITE( - "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because the worker has been Garbage Collected.", - workerId); + "MAIN: WorkerObjectOnMessageCallback couldn't fire a worker(id=%d) object's `onmessage` callback because the worker has been Garbage Collected.", + workerId); CallbackHandlers::id2WorkerMap.erase(workerId); return; } @@ -1329,8 +1379,10 @@ void CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate* isolate, jint work auto strThreadname = ArgConverter::jstringToString(threadName); auto strStackTrace = ArgConverter::jstringToString(stackTrace); - DEBUG_WRITE("Unhandled exception in '%s' thread. file: %s, line %d, message: %s\nStackTrace: %s", - strThreadname.c_str(), strFilename.c_str(), lineno, strMessage.c_str(), strStackTrace.c_str()); + DEBUG_WRITE( + "Unhandled exception in '%s' thread. file: %s, line %d, message: %s\nStackTrace: %s", + strThreadname.c_str(), strFilename.c_str(), lineno, strMessage.c_str(), + strStackTrace.c_str()); // Do not throw exception? // stringstream ss; @@ -1338,7 +1390,7 @@ void CallbackHandlers::CallWorkerObjectOnErrorHandle(Isolate* isolate, jint work // ", line: " << lineno << endl << strMessage << endl; // NativeScriptException ex(ss.str()); // throw ex; - } catch (NativeScriptException& ex) { + } catch (NativeScriptException &ex) { ex.ReThrowToV8(); } catch (std::exception e) { stringstream ss; @@ -1357,7 +1409,9 @@ void CallbackHandlers::ClearWorkerPersistent(int workerId) { auto workerFound = CallbackHandlers::id2WorkerMap.find(workerId); if (workerFound == CallbackHandlers::id2WorkerMap.end()) { - DEBUG_WRITE("MAIN | WORKER: ClearWorkerPersistent no worker instance was found with workerId=%d ! The worker may already be terminated.", workerId); + DEBUG_WRITE( + "MAIN | WORKER: ClearWorkerPersistent no worker instance was found with workerId=%d ! The worker may already be terminated.", + workerId); return; } @@ -1367,7 +1421,7 @@ void CallbackHandlers::ClearWorkerPersistent(int workerId) { id2WorkerMap.erase(workerId); } -void CallbackHandlers::TerminateWorkerThread(Isolate* isolate) { +void CallbackHandlers::TerminateWorkerThread(Isolate *isolate) { auto context = isolate->GetCurrentContext(); context->Exit(); @@ -1375,7 +1429,7 @@ void CallbackHandlers::TerminateWorkerThread(Isolate* isolate) { } int CallbackHandlers::nextWorkerId = 0; -std::map*> CallbackHandlers::id2WorkerMap; +std::map *> CallbackHandlers::id2WorkerMap; short CallbackHandlers::MAX_JAVA_STRING_ARRAY_LENGTH = 100; jclass CallbackHandlers::RUNTIME_CLASS = nullptr; @@ -1387,6 +1441,7 @@ jmethodID CallbackHandlers::GET_TYPE_METADATA = nullptr; jmethodID CallbackHandlers::ENABLE_VERBOSE_LOGGING_METHOD_ID = nullptr; jmethodID CallbackHandlers::DISABLE_VERBOSE_LOGGING_METHOD_ID = nullptr; jmethodID CallbackHandlers::INIT_WORKER_METHOD_ID = nullptr; + NumericCasts CallbackHandlers::castFunctions; ArrayElementAccessor CallbackHandlers::arrayElementAccessor; FieldAccessor CallbackHandlers::fieldAccessor; diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.h b/test-app/runtime/src/main/cpp/CallbackHandlers.h index 7067dd7a4..72fb2567b 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.h +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.h @@ -16,112 +16,143 @@ #include "include/v8.h" namespace tns { -class CallbackHandlers { + class CallbackHandlers { public: /* * Stores persistent handles of all 'Worker' objects initialized on the main thread * Note: No isolates different than that of the main thread should access this map */ - static std::map*> id2WorkerMap; + static std::map *> id2WorkerMap; static int nextWorkerId; - static void Init(v8::Isolate* isolate); + static void Init(v8::Isolate *isolate); - static v8::Local CreateJSWrapper(v8::Isolate* isolate, jint javaObjectID, const std::string& typeName); + static v8::Local + CreateJSWrapper(v8::Isolate *isolate, jint javaObjectID, const std::string &typeName); - static bool RegisterInstance(v8::Isolate* isolate, const v8::Local& jsObject, const std::string& fullClassName, const ArgsWrapper& argWrapper, const v8::Local& implementationObject, bool isInterface, const std::string& baseClassName = std::string()); + static bool RegisterInstance(v8::Isolate *isolate, const v8::Local &jsObject, + const std::string &fullClassName, + const ArgsWrapper &argWrapper, + const v8::Local &implementationObject, + bool isInterface, + const std::string &baseClassName = std::string()); - static jclass ResolveClass(v8::Isolate* isolate, const std::string& baseClassName, const std::string& fullClassName, const v8::Local& implementationObject, bool isInterface); + static jclass ResolveClass(v8::Isolate *isolate, const std::string &baseClassName, + const std::string &fullClassName, + const v8::Local &implementationObject, + bool isInterface); - static std::string ResolveClassName(v8::Isolate* isolate, jclass& clazz); + static std::string ResolveClassName(v8::Isolate *isolate, jclass &clazz); - static v8::Local GetArrayElement(v8::Isolate* isolate, const v8::Local& array, uint32_t index, const std::string& arraySignature); + static v8::Local + GetArrayElement(v8::Isolate *isolate, const v8::Local &array, uint32_t index, + const std::string &arraySignature); - static void SetArrayElement(v8::Isolate* isolate, const v8::Local& array, uint32_t index, const std::string& arraySignature, v8::Local& value); + static void + SetArrayElement(v8::Isolate *isolate, const v8::Local &array, uint32_t index, + const std::string &arraySignature, v8::Local &value); - static int GetArrayLength(v8::Isolate* isolate, const v8::Local& arr); + static int GetArrayLength(v8::Isolate *isolate, const v8::Local &arr); - static void CallJavaMethod(const v8::Local& caller, const std::string& className, const std::string& methodName, MetadataEntry* entry, bool isStatic, bool isSuper, const v8::FunctionCallbackInfo& args); + static void + CallJavaMethod(const v8::Local &caller, const std::string &className, + const std::string &methodName, MetadataEntry *entry, bool isFromInterface, + bool isStatic, bool isSuper, + const v8::FunctionCallbackInfo &args); - static v8::Local CallJSMethod(v8::Isolate* isolate, JNIEnv* _env, const v8::Local& jsObject, const std::string& methodName, jobjectArray args); + static v8::Local + CallJSMethod(v8::Isolate *isolate, JNIEnv *_env, const v8::Local &jsObject, + const std::string &methodName, jobjectArray args); - static v8::Local GetJavaField(v8::Isolate* isolate, const v8::Local& caller, FieldCallbackData* fieldData); + static v8::Local + GetJavaField(v8::Isolate *isolate, const v8::Local &caller, + FieldCallbackData *fieldData); - static void SetJavaField(v8::Isolate* isolate, const v8::Local& target, const v8::Local& value, FieldCallbackData* fieldData); + static void SetJavaField(v8::Isolate *isolate, const v8::Local &target, + const v8::Local &value, FieldCallbackData *fieldData); - static void LogMethodCallback(const v8::FunctionCallbackInfo& args); + static void LogMethodCallback(const v8::FunctionCallbackInfo &args); - static void TimeCallback(const v8::FunctionCallbackInfo& args); + static void TimeCallback(const v8::FunctionCallbackInfo &args); - static void DumpReferenceTablesMethodCallback(const v8::FunctionCallbackInfo& args); + static void + DumpReferenceTablesMethodCallback(const v8::FunctionCallbackInfo &args); static void DumpReferenceTablesMethod(); - static void ExitMethodCallback(const v8::FunctionCallbackInfo& args); + static void ExitMethodCallback(const v8::FunctionCallbackInfo &args); - static void CreateGlobalCastFunctions(v8::Isolate* isolate, const v8::Local& globalTemplate); + static void CreateGlobalCastFunctions(v8::Isolate *isolate, + const v8::Local &globalTemplate); - static std::vector GetTypeMetadata(const std::string& name, int index); + static std::vector GetTypeMetadata(const std::string &name, int index); /* * Gets all methods in the implementation object, and packs them in a jobjectArray * to pass them to Java Land, so that their corresponding Java callbacks are written when * the dexFactory generates the class */ - static jobjectArray GetMethodOverrides(JEnv& env, const v8::Local& implementationObject); + static jobjectArray + GetMethodOverrides(JEnv &env, const v8::Local &implementationObject); /* * Gets all interfaces declared in the 'interfaces' array inside the implementation object, * and packs them in a jobjectArray to pass them to Java Land, so that they may be * implemented when the dexFactory generates the corresponding class */ - static jobjectArray GetImplementedInterfaces(JEnv& env, const v8::Local& implementationObject); + static jobjectArray + GetImplementedInterfaces(JEnv &env, const v8::Local &implementationObject); - static void EnableVerboseLoggingMethodCallback(const v8::FunctionCallbackInfo& args); + static void + EnableVerboseLoggingMethodCallback(const v8::FunctionCallbackInfo &args); - static void DisableVerboseLoggingMethodCallback(const v8::FunctionCallbackInfo& args); + static void + DisableVerboseLoggingMethodCallback(const v8::FunctionCallbackInfo &args); - static v8::Local FindClass(v8::Isolate* isolate, const std::string& className); + static v8::Local FindClass(v8::Isolate *isolate, const std::string &className); - static void NewThreadCallback(const v8::FunctionCallbackInfo& args); + static void NewThreadCallback(const v8::FunctionCallbackInfo &args); /* * main -> worker messaging * Fired when a Worker instance's postMessage is called */ - static void WorkerObjectPostMessageCallback(const v8::FunctionCallbackInfo& args); + static void + WorkerObjectPostMessageCallback(const v8::FunctionCallbackInfo &args); /* * main -> worker messaging * Fired when worker object has "postMessage" and the worker has implemented "onMessage" handler * In case "onMessage" handler isn't implemented no exception is thrown */ - static void WorkerGlobalOnMessageCallback(v8::Isolate* isolate, jstring message); + static void WorkerGlobalOnMessageCallback(v8::Isolate *isolate, jstring message); /* * worker -> main thread messaging * Fired when a Worker script's "postMessage" is called */ - static void WorkerGlobalPostMessageCallback(const v8::FunctionCallbackInfo& args); + static void + WorkerGlobalPostMessageCallback(const v8::FunctionCallbackInfo &args); /* * worker -> main messaging * Fired when worker has sent a message to main and the worker object has implemented "onMessage" handler * In case "onMessage" handler isn't implemented no exception is thrown */ - static void WorkerObjectOnMessageCallback(v8::Isolate* isolate, jint workerId, jstring message); + static void + WorkerObjectOnMessageCallback(v8::Isolate *isolate, jint workerId, jstring message); /* * Fired when a Worker instance's terminate is called (immediately stops execution of the thread) */ - static void WorkerObjectTerminateCallback(const v8::FunctionCallbackInfo& args); + static void WorkerObjectTerminateCallback(const v8::FunctionCallbackInfo &args); /* * Fired when a Worker script's close is called */ - static void WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo& args); + static void WorkerGlobalCloseCallback(const v8::FunctionCallbackInfo &args); /* * Clears the persistent Worker object handle associated with a workerId @@ -132,7 +163,7 @@ class CallbackHandlers { /* * Terminates the currently executing Isolate. No scripts can be executed after this call */ - static void TerminateWorkerThread(v8::Isolate* isolate); + static void TerminateWorkerThread(v8::Isolate *isolate); /* * Is called when an unhandled exception is thrown inside the worker @@ -140,25 +171,28 @@ class CallbackHandlers { * Will make the exception "bubble up" through to main, to be handled by the Worker Object * if 'onerror' isn't implemented or returns false */ - static void CallWorkerScopeOnErrorHandle(v8::Isolate* isolate, v8::TryCatch& tc); + static void CallWorkerScopeOnErrorHandle(v8::Isolate *isolate, v8::TryCatch &tc); /* * Is called when an unhandled exception bubbles up from the worker scope to the main thread Worker Object * Will execute `onerror` if one is implemented for the Worker Object instance * Will throw a NativeScript Exception if 'onerror' isn't implemented or returns false */ - static void CallWorkerObjectOnErrorHandle(v8::Isolate* isolate, jint workerId, jstring message, jstring stackTrace, jstring filename, jint lineno, jstring threadName); + static void + CallWorkerObjectOnErrorHandle(v8::Isolate *isolate, jint workerId, jstring message, + jstring stackTrace, jstring filename, jint lineno, + jstring threadName); private: CallbackHandlers() { } - static void AdjustAmountOfExternalAllocatedMemory(JEnv& env, v8::Isolate* isolate); + static void AdjustAmountOfExternalAllocatedMemory(JEnv &env, v8::Isolate *isolate); /* * Helper method that creates a java string array for sending strings over JNI */ - static jobjectArray GetJavaStringArray(JEnv& env, int length); + static jobjectArray GetJavaStringArray(JEnv &env, int length); static short MAX_JAVA_STRING_ARRAY_LENGTH; @@ -187,21 +221,21 @@ class CallbackHandlers { static FieldAccessor fieldAccessor; struct JavaObjectIdScope { - JavaObjectIdScope(JEnv& env, jfieldID fieldId, jobject runtime, int javaObjectId) + JavaObjectIdScope(JEnv &env, jfieldID fieldId, jobject runtime, int javaObjectId) : _env(env), _fieldID(fieldId), _runtime(runtime) { - _env.SetIntField(_runtime, _fieldID, javaObjectId); - } + _env.SetIntField(_runtime, _fieldID, javaObjectId); + } - ~JavaObjectIdScope() { - _env.SetIntField(_runtime, _fieldID, -1); - } + ~JavaObjectIdScope() { + _env.SetIntField(_runtime, _fieldID, -1); + } - private: - JEnv _env; - jfieldID _fieldID; - jobject _runtime; + private: + JEnv _env; + jfieldID _fieldID; + jobject _runtime; }; -}; + }; } #endif /* CALLBACKHANDLERS_H_ */ diff --git a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp new file mode 100644 index 000000000..960cf2081 --- /dev/null +++ b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp @@ -0,0 +1,15 @@ +// +// Created by Vladimir Mutafov on 16.11.18. +// + +#include "DesugaredInterfaceCompanionClassNameResolver.h" + +std::string DesugaredInterfaceCompanionClassNameResolver::resolveD8InterfaceCompanionClassName( + std::string interfaceName) { + return interfaceName + D8_COMPANION_CLASS_SUFFIX; +} + +std::string DesugaredInterfaceCompanionClassNameResolver::resolveBazelInterfaceCompanionClassName( + std::string interfaceName) { + return interfaceName + BAZEL_COMPANION_CLASS_SUFFIX; +} diff --git a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h new file mode 100644 index 000000000..cb58e9477 --- /dev/null +++ b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h @@ -0,0 +1,26 @@ +// +// Created by Vladimir Mutafov on 16.11.18. +// + +#ifndef TEST_APP_DESUGAREDINTERFACECOMPANIONCLASSNAMERESOLVER_H +#define TEST_APP_DESUGAREDINTERFACECOMPANIONCLASSNAMERESOLVER_H + + +#include + +class DesugaredInterfaceCompanionClassNameResolver { + +public: + std::string resolveD8InterfaceCompanionClassName(std::string interfaceName); + + std::string resolveBazelInterfaceCompanionClassName(std::string interfaceName); + +private: + const std::string BAZEL_COMPANION_CLASS_SUFFIX = "$$CC"; + const std::string D8_COMPANION_CLASS_SUFFIX = "$-CC"; + + +}; + + +#endif //TEST_APP_DESUGAREDINTERFACECOMPANIONCLASSNAMERESOLVER_H diff --git a/test-app/runtime/src/main/cpp/JEnv.cpp b/test-app/runtime/src/main/cpp/JEnv.cpp index ee767353c..b0b477f78 100644 --- a/test-app/runtime/src/main/cpp/JEnv.cpp +++ b/test-app/runtime/src/main/cpp/JEnv.cpp @@ -2,14 +2,15 @@ #include #include "Util.h" #include "NativeScriptException.h" +#include "DesugaredInterfaceCompanionClassNameResolver.h" using namespace tns; using namespace std; JEnv::JEnv() - : m_env(nullptr) { - JNIEnv* env = nullptr; - jint ret = s_jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + : m_env(nullptr) { + JNIEnv *env = nullptr; + jint ret = s_jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); if ((ret != JNI_OK) || (env == nullptr)) { ret = s_jvm->AttachCurrentThread(&env, nullptr); @@ -20,8 +21,8 @@ JEnv::JEnv() m_env = env; } -JEnv::JEnv(JNIEnv* jniEnv) { - jint ret = s_jvm->GetEnv(reinterpret_cast(&jniEnv), JNI_VERSION_1_6); +JEnv::JEnv(JNIEnv *jniEnv) { + jint ret = s_jvm->GetEnv(reinterpret_cast(&jniEnv), JNI_VERSION_1_6); if ((ret != JNI_OK) || (jniEnv == nullptr)) { ret = s_jvm->AttachCurrentThread(&jniEnv, nullptr); @@ -39,182 +40,209 @@ JEnv::operator JNIEnv* () const { return m_env; } -jmethodID JEnv::GetMethodID(jclass clazz, const string& name, const string& sig) { +jmethodID JEnv::GetMethodID(jclass clazz, const string &name, const string &sig) { jmethodID mid = m_env->GetMethodID(clazz, name.c_str(), sig.c_str()); CheckForJavaException(); return mid; } -jmethodID JEnv::GetStaticMethodID(jclass clazz, const string& name, const string& sig) { + +jmethodID JEnv::GetStaticMethodID(jclass clazz, const string &name, const string &sig) { jmethodID mid = m_env->GetStaticMethodID(clazz, name.c_str(), sig.c_str()); CheckForJavaException(); return mid; } -jfieldID JEnv::GetFieldID(jclass clazz, const string& name, const string& sig) { +jfieldID JEnv::GetFieldID(jclass clazz, const string &name, const string &sig) { jfieldID fid = m_env->GetFieldID(clazz, name.c_str(), sig.c_str()); CheckForJavaException(); return fid; } -jfieldID JEnv::GetStaticFieldID(jclass clazz, const string& name, const string& sig) { + +jfieldID JEnv::GetStaticFieldID(jclass clazz, const string &name, const string &sig) { jfieldID fid = m_env->GetStaticFieldID(clazz, name.c_str(), sig.c_str()); CheckForJavaException(); return fid; } -void JEnv::CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +void JEnv::CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue *args) { m_env->CallStaticVoidMethodA(clazz, methodID, args); CheckForJavaException(); } -void JEnv::CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +void JEnv::CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { m_env->CallNonvirtualVoidMethodA(obj, clazz, methodID, args); CheckForJavaException(); } -void JEnv::CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +void JEnv::CallVoidMethodA(jobject obj, jmethodID methodID, jvalue *args) { m_env->CallVoidMethodA(obj, methodID, args); CheckForJavaException(); } -jboolean JEnv::CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jboolean JEnv::CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jboolean jbl = m_env->CallStaticBooleanMethodA(clazz, methodID, args); CheckForJavaException(); return jbl; } -jboolean JEnv::CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jboolean +JEnv::CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jboolean jbl = m_env->CallNonvirtualBooleanMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jbl; } -jboolean JEnv::CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jboolean JEnv::CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue *args) { jboolean jbl = m_env->CallBooleanMethodA(obj, methodID, args); CheckForJavaException(); return jbl; } -jbyte JEnv::CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jbyte JEnv::CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jbyte jbt = m_env->CallStaticByteMethodA(clazz, methodID, args); CheckForJavaException(); return jbt; } -jbyte JEnv::CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jbyte JEnv::CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jbyte jbt = m_env->CallNonvirtualByteMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jbt; } -jbyte JEnv::CallByteMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jbyte JEnv::CallByteMethodA(jobject obj, jmethodID methodID, jvalue *args) { jbyte jbt = m_env->CallByteMethodA(obj, methodID, args); CheckForJavaException(); return jbt; } -jchar JEnv::CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jchar JEnv::CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jchar jch = m_env->CallStaticCharMethodA(clazz, methodID, args); CheckForJavaException(); return jch; } -jchar JEnv::CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jchar JEnv::CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jchar jch = m_env->CallNonvirtualCharMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jch; } -jchar JEnv::CallCharMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jchar JEnv::CallCharMethodA(jobject obj, jmethodID methodID, jvalue *args) { jchar jch = m_env->CallCharMethodA(obj, methodID, args); CheckForJavaException(); return jch; } -jshort JEnv::CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jshort JEnv::CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jshort jsh = m_env->CallStaticShortMethodA(clazz, methodID, args); CheckForJavaException(); return jsh; } -jshort JEnv::CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jshort +JEnv::CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jshort jsh = m_env->CallNonvirtualShortMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jsh; } -jshort JEnv::CallShortMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jshort JEnv::CallShortMethodA(jobject obj, jmethodID methodID, jvalue *args) { jshort jsh = m_env->CallShortMethodA(obj, methodID, args); CheckForJavaException(); return jsh; } -jint JEnv::CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jint JEnv::CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jint ji = m_env->CallStaticIntMethodA(clazz, methodID, args); CheckForJavaException(); return ji; } -jint JEnv::CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jint JEnv::CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jint ji = m_env->CallNonvirtualIntMethodA(obj, clazz, methodID, args); CheckForJavaException(); return ji; } -jint JEnv::CallIntMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jint JEnv::CallIntMethodA(jobject obj, jmethodID methodID, jvalue *args) { jint ji = m_env->CallIntMethodA(obj, methodID, args); CheckForJavaException(); return ji; } -jlong JEnv::CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jlong JEnv::CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jlong jl = m_env->CallStaticLongMethodA(clazz, methodID, args); CheckForJavaException(); return jl; } -jlong JEnv::CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jlong JEnv::CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jlong jl = m_env->CallNonvirtualLongMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jl; } -jlong JEnv::CallLongMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jlong JEnv::CallLongMethodA(jobject obj, jmethodID methodID, jvalue *args) { jlong jl = m_env->CallLongMethodA(obj, methodID, args); CheckForJavaException(); return jl; } -jfloat JEnv::CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jfloat JEnv::CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jfloat jfl = m_env->CallStaticFloatMethodA(clazz, methodID, args); CheckForJavaException(); return jfl; } -jfloat JEnv::CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jfloat +JEnv::CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jfloat jfl = m_env->CallNonvirtualFloatMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jfl; } -jfloat JEnv::CallFloatMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jfloat JEnv::CallFloatMethodA(jobject obj, jmethodID methodID, jvalue *args) { jfloat jfl = m_env->CallFloatMethodA(obj, methodID, args); CheckForJavaException(); return jfl; } -jdouble JEnv::CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jdouble JEnv::CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jdouble jdb = m_env->CallStaticDoubleMethodA(clazz, methodID, args); CheckForJavaException(); return jdb; } -jdouble JEnv::CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jdouble +JEnv::CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jdouble jdb = m_env->CallNonvirtualDoubleMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jdb; } -jdouble JEnv::CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jdouble JEnv::CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue *args) { jdouble jdb = m_env->CallDoubleMethodA(obj, methodID, args); CheckForJavaException(); return jdb; } -jobject JEnv::CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue* args) { +jobject JEnv::CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue *args) { jobject jo = m_env->CallStaticObjectMethodA(clazz, methodID, args); CheckForJavaException(); return jo; } -jobject JEnv::CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue* args) { + +jobject +JEnv::CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args) { jobject jo = m_env->CallNonvirtualObjectMethodA(obj, clazz, methodID, args); CheckForJavaException(); return jo; } -jobject JEnv::CallObjectMethodA(jobject obj, jmethodID methodID, jvalue* args) { + +jobject JEnv::CallObjectMethodA(jobject obj, jmethodID methodID, jvalue *args) { jobject jo = m_env->CallObjectMethodA(obj, methodID, args); CheckForJavaException(); return jo; @@ -225,41 +253,49 @@ jobject JEnv::GetStaticObjectField(jclass clazz, jfieldID fieldID) { CheckForJavaException(); return jo; } + jboolean JEnv::GetStaticBooleanField(jclass clazz, jfieldID fieldID) { jboolean jbl = m_env->GetStaticBooleanField(clazz, fieldID); CheckForJavaException(); return jbl; } + jbyte JEnv::GetStaticByteField(jclass clazz, jfieldID fieldID) { jbyte jbt = m_env->GetStaticByteField(clazz, fieldID); CheckForJavaException(); return jbt; } + jchar JEnv::GetStaticCharField(jclass clazz, jfieldID fieldID) { jchar jch = m_env->GetStaticCharField(clazz, fieldID); CheckForJavaException(); return jch; } + jshort JEnv::GetStaticShortField(jclass clazz, jfieldID fieldID) { jshort jsh = m_env->GetStaticShortField(clazz, fieldID); CheckForJavaException(); return jsh; } + jint JEnv::GetStaticIntField(jclass clazz, jfieldID fieldID) { jint ji = m_env->GetStaticIntField(clazz, fieldID); CheckForJavaException(); return ji; } + jlong JEnv::GetStaticLongField(jclass clazz, jfieldID fieldID) { jlong jl = m_env->GetStaticLongField(clazz, fieldID); CheckForJavaException(); return jl; } + jfloat JEnv::GetStaticFloatField(jclass clazz, jfieldID fieldID) { jfloat jfl = m_env->GetStaticFloatField(clazz, fieldID); CheckForJavaException(); return jfl; } + jdouble JEnv::GetStaticDoubleField(jclass clazz, jfieldID fieldID) { jdouble jd = m_env->GetStaticDoubleField(clazz, fieldID); CheckForJavaException(); @@ -270,34 +306,42 @@ void JEnv::SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) { m_env->SetStaticObjectField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) { m_env->SetStaticBooleanField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) { m_env->SetStaticByteField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) { m_env->SetStaticCharField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) { m_env->SetStaticShortField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) { m_env->SetStaticIntField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) { m_env->SetStaticLongField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) { m_env->SetStaticFloatField(clazz, fieldID, value); CheckForJavaException(); } + void JEnv::SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) { m_env->SetStaticDoubleField(clazz, fieldID, value); CheckForJavaException(); @@ -308,41 +352,49 @@ jobject JEnv::GetObjectField(jobject obj, jfieldID fieldID) { CheckForJavaException(); return jo; } + jboolean JEnv::GetBooleanField(jobject obj, jfieldID fieldID) { jboolean jbl = m_env->GetBooleanField(obj, fieldID); CheckForJavaException(); return jbl; } + jbyte JEnv::GetByteField(jobject obj, jfieldID fieldID) { jbyte jbt = m_env->GetByteField(obj, fieldID); CheckForJavaException(); return jbt; } + jchar JEnv::GetCharField(jobject obj, jfieldID fieldID) { jchar jch = m_env->GetCharField(obj, fieldID); CheckForJavaException(); return jch; } + jshort JEnv::GetShortField(jobject obj, jfieldID fieldID) { jshort jsh = m_env->GetShortField(obj, fieldID); CheckForJavaException(); return jsh; } + jint JEnv::GetIntField(jobject obj, jfieldID fieldID) { jint ji = m_env->GetIntField(obj, fieldID); CheckForJavaException(); return ji; } + jlong JEnv::GetLongField(jobject obj, jfieldID fieldID) { jlong jl = m_env->GetLongField(obj, fieldID); CheckForJavaException(); return jl; } + jfloat JEnv::GetFloatField(jobject obj, jfieldID fieldID) { jfloat jfl = m_env->GetFloatField(obj, fieldID); CheckForJavaException(); return jfl; } + jdouble JEnv::GetDoubleField(jobject obj, jfieldID fieldID) { jdouble jd = m_env->GetDoubleField(obj, fieldID); CheckForJavaException(); @@ -353,45 +405,54 @@ void JEnv::SetObjectField(jobject obj, jfieldID fieldID, jobject value) { m_env->SetObjectField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) { m_env->SetBooleanField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetByteField(jobject obj, jfieldID fieldID, jbyte value) { m_env->SetByteField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetCharField(jobject obj, jfieldID fieldID, jchar value) { m_env->SetCharField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetShortField(jobject obj, jfieldID fieldID, jshort value) { m_env->SetShortField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetIntField(jobject obj, jfieldID fieldID, jint value) { m_env->SetIntField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetLongField(jobject obj, jfieldID fieldID, jlong value) { m_env->SetLongField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetFloatField(jobject obj, jfieldID fieldID, jfloat value) { m_env->SetFloatField(obj, fieldID, value); CheckForJavaException(); } + void JEnv::SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) { m_env->SetDoubleField(obj, fieldID, value); CheckForJavaException(); } -jstring JEnv::NewString(const jchar* unicodeChars, jsize len) { +jstring JEnv::NewString(const jchar *unicodeChars, jsize len) { jstring jst = m_env->NewString(unicodeChars, len); CheckForJavaException(); return jst; } -jstring JEnv::NewStringUTF(const char* bytes) { + +jstring JEnv::NewStringUTF(const char *bytes) { jstring jst = m_env->NewStringUTF(bytes); CheckForJavaException(); return jst; @@ -408,27 +469,30 @@ jobject JEnv::GetObjectArrayElement(jobjectArray array, jsize index) { CheckForJavaException(); return jo; } + void JEnv::SetObjectArrayElement(jobjectArray array, jsize index, jobject value) { m_env->SetObjectArrayElement(array, index, value); CheckForJavaException(); } -const char* JEnv::GetStringUTFChars(jstring str, jboolean* isCopy) { - const char* cc = m_env->GetStringUTFChars(str, isCopy); +const char *JEnv::GetStringUTFChars(jstring str, jboolean *isCopy) { + const char *cc = m_env->GetStringUTFChars(str, isCopy); CheckForJavaException(); return cc; } -void JEnv::ReleaseStringUTFChars(jstring str, const char* utf) { + +void JEnv::ReleaseStringUTFChars(jstring str, const char *utf) { m_env->ReleaseStringUTFChars(str, utf); CheckForJavaException(); } -const jchar* JEnv::GetStringChars(jstring str, jboolean* isCopy) { - const jchar* cjc = m_env->GetStringChars(str, isCopy); +const jchar *JEnv::GetStringChars(jstring str, jboolean *isCopy) { + const jchar *cjc = m_env->GetStringChars(str, isCopy); CheckForJavaException(); return cjc; } -void JEnv::ReleaseStringChars(jstring str, const jchar* chars) { + +void JEnv::ReleaseStringChars(jstring str, const jchar *chars) { m_env->ReleaseStringChars(str, chars); CheckForJavaException(); } @@ -445,7 +509,7 @@ const int JEnv::GetStringUTFLength(jstring str) { return ci; } -void JEnv::GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) { +void JEnv::GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { m_env->GetStringUTFRegion(str, start, len, buf); CheckForJavaException(); } @@ -454,7 +518,7 @@ jint JEnv::Throw(jthrowable obj) { return m_env->Throw(obj); } -jint JEnv::ThrowNew(jclass clazz, const string& message) { +jint JEnv::ThrowNew(jclass clazz, const string &message) { return m_env->ThrowNew(clazz, message.c_str()); } @@ -462,10 +526,12 @@ jthrowable JEnv::ExceptionOccurred() { jthrowable jt = m_env->ExceptionOccurred(); return jt; } + void JEnv::ExceptionDescribe() { m_env->ExceptionDescribe(); CheckForJavaException(); } + void JEnv::ExceptionClear() { m_env->ExceptionClear(); } @@ -487,15 +553,18 @@ jobject JEnv::NewGlobalRef(jobject obj) { // CheckForJavaException(); return jo; } + jweak JEnv::NewWeakGlobalRef(jobject obj) { jweak jw = m_env->NewWeakGlobalRef(obj); CheckForJavaException(); return jw; } + void JEnv::DeleteGlobalRef(jobject globalRef) { m_env->DeleteGlobalRef(globalRef); CheckForJavaException(); } + void JEnv::DeleteWeakGlobalRef(jweak obj) { m_env->DeleteWeakGlobalRef(obj); CheckForJavaException(); @@ -506,6 +575,7 @@ jobject JEnv::NewLocalRef(jobject ref) { CheckForJavaException(); return jo; } + void JEnv::DeleteLocalRef(jobject localRef) { m_env->DeleteLocalRef(localRef); } @@ -515,119 +585,141 @@ jbyteArray JEnv::NewByteArray(jsize length) { CheckForJavaException(); return jba; } + jbooleanArray JEnv::NewBooleanArray(jsize length) { jbooleanArray jba = m_env->NewBooleanArray(length); CheckForJavaException(); return jba; } + jcharArray JEnv::NewCharArray(jsize length) { jcharArray jca = m_env->NewCharArray(length); CheckForJavaException(); return jca; } + jshortArray JEnv::NewShortArray(jsize length) { jshortArray jsa = m_env->NewShortArray(length); CheckForJavaException(); return jsa; } + jintArray JEnv::NewIntArray(jsize length) { jintArray jia = m_env->NewIntArray(length); CheckForJavaException(); return jia; } + jlongArray JEnv::NewLongArray(jsize length) { jlongArray jla = m_env->NewLongArray(length); CheckForJavaException(); return jla; } + jfloatArray JEnv::NewFloatArray(jsize length) { jfloatArray jfa = m_env->NewFloatArray(length); CheckForJavaException(); return jfa; } + jdoubleArray JEnv::NewDoubleArray(jsize length) { jdoubleArray jda = m_env->NewDoubleArray(length); CheckForJavaException(); return jda; } -jbyte* JEnv::GetByteArrayElements(jbyteArray array, jboolean* isCopy) { - jbyte* jbt = m_env->GetByteArrayElements(array, isCopy); +jbyte *JEnv::GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + jbyte *jbt = m_env->GetByteArrayElements(array, isCopy); CheckForJavaException(); return jbt; } -void JEnv::ReleaseByteArrayElements(jbyteArray array, jbyte* elems, jint mode) { + +void JEnv::ReleaseByteArrayElements(jbyteArray array, jbyte *elems, jint mode) { m_env->ReleaseByteArrayElements(array, elems, mode); CheckForJavaException(); } -void JEnv::GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, jboolean* buf) { +void JEnv::GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, jboolean *buf) { m_env->GetBooleanArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte* buf) { + +void JEnv::GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf) { m_env->GetByteArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar* buf) { + +void JEnv::GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf) { m_env->GetCharArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort* buf) { + +void JEnv::GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf) { m_env->GetShortArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetIntArrayRegion(jintArray array, jsize start, jsize len, jint* buf) { + +void JEnv::GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf) { m_env->GetIntArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong* buf) { + +void JEnv::GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf) { m_env->GetLongArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat* buf) { + +void JEnv::GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf) { m_env->GetFloatArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble* buf) { + +void JEnv::GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf) { m_env->GetDoubleArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte* buf) { +void JEnv::SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte *buf) { m_env->SetByteArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, const jboolean* buf) { + +void JEnv::SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, const jboolean *buf) { m_env->SetBooleanArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetCharArrayRegion(jcharArray array, jsize start, jsize len, const jchar* buf) { + +void JEnv::SetCharArrayRegion(jcharArray array, jsize start, jsize len, const jchar *buf) { m_env->SetCharArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetShortArrayRegion(jshortArray array, jsize start, jsize len, const jshort* buf) { + +void JEnv::SetShortArrayRegion(jshortArray array, jsize start, jsize len, const jshort *buf) { m_env->SetShortArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint* buf) { + +void JEnv::SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint *buf) { m_env->SetIntArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetLongArrayRegion(jlongArray array, jsize start, jsize len, const jlong* buf) { + +void JEnv::SetLongArrayRegion(jlongArray array, jsize start, jsize len, const jlong *buf) { m_env->SetLongArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, const jfloat* buf) { + +void JEnv::SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, const jfloat *buf) { m_env->SetFloatArrayRegion(array, start, len, buf); CheckForJavaException(); } -void JEnv::SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, const jdouble* buf) { + +void JEnv::SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, const jdouble *buf) { m_env->SetDoubleArrayRegion(array, start, len, buf); CheckForJavaException(); } -jclass JEnv::FindClass(const string& className) { +jclass JEnv::FindClass(const string &className) { jclass global_class = CheckForClassInCache(className); if (global_class == nullptr) { @@ -637,7 +729,8 @@ jclass JEnv::FindClass(const string& className) { m_env->ExceptionClear(); string cannonicalClassName = Util::ConvertFromJniToCanonicalName(className); jstring s = m_env->NewStringUTF(cannonicalClassName.c_str()); - tmp = static_cast(m_env->CallStaticObjectMethod(RUNTIME_CLASS, GET_CACHED_CLASS_METHOD_ID, s)); + tmp = static_cast(m_env->CallStaticObjectMethod(RUNTIME_CLASS, + GET_CACHED_CLASS_METHOD_ID, s)); m_env->DeleteLocalRef(s); } @@ -648,7 +741,7 @@ jclass JEnv::FindClass(const string& className) { return global_class; } -jclass JEnv::CheckForClassInCache(const string& className) { +jclass JEnv::CheckForClassInCache(const string &className) { jclass global_class = nullptr; auto itFound = s_classCache.find(className); @@ -659,21 +752,22 @@ jclass JEnv::CheckForClassInCache(const string& className) { return global_class; } -jclass JEnv::InsertClassIntoCache(const string& className, jclass& tmp) { - auto global_class= reinterpret_cast(m_env->NewGlobalRef(tmp)); +jclass JEnv::InsertClassIntoCache(const string &className, jclass &tmp) { + auto global_class = reinterpret_cast(m_env->NewGlobalRef(tmp)); s_classCache.insert(make_pair(className, global_class)); m_env->DeleteLocalRef(tmp); return global_class; } -jobject JEnv::NewDirectByteBuffer(void* address, jlong capacity) { +jobject JEnv::NewDirectByteBuffer(void *address, jlong capacity) { jobject jo = m_env->NewDirectByteBuffer(address, capacity); CheckForJavaException(); return jo; } -void* JEnv::GetDirectBufferAddress(jobject buf) { - void* v = m_env->GetDirectBufferAddress(buf); + +void *JEnv::GetDirectBufferAddress(jobject buf) { + void *v = m_env->GetDirectBufferAddress(buf); CheckForJavaException(); return v; } @@ -690,14 +784,15 @@ jboolean JEnv::IsAssignableFrom(jclass clazz1, jclass clazz2) { return jbl; } -void JEnv::Init(JavaVM* jvm) { +void JEnv::Init(JavaVM *jvm) { assert(jvm != nullptr); s_jvm = jvm; JEnv env; RUNTIME_CLASS = env.FindClass("com/tns/Runtime"); assert(RUNTIME_CLASS != nullptr); - GET_CACHED_CLASS_METHOD_ID = env.GetStaticMethodID(RUNTIME_CLASS, "getCachedClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + GET_CACHED_CLASS_METHOD_ID = env.GetStaticMethodID(RUNTIME_CLASS, "getCachedClass", + "(Ljava/lang/String;)Ljava/lang/Class;"); assert(GET_CACHED_CLASS_METHOD_ID != nullptr); } @@ -725,7 +820,40 @@ void JEnv::CheckForJavaException() { } } -JavaVM* JEnv::s_jvm = nullptr; +JavaVM *JEnv::s_jvm = nullptr; map JEnv::s_classCache; jclass JEnv::RUNTIME_CLASS = nullptr; jmethodID JEnv::GET_CACHED_CLASS_METHOD_ID = nullptr; + +std::pair +JEnv::GetInterfaceStaticMethodIDAndJClass(const std::string &interfaceName, + const std::string &methodName, + const std::string &sig) { + + auto companionClassNameResolver = new DesugaredInterfaceCompanionClassNameResolver(); + std::string possibleCalleeNames[] = {interfaceName, + companionClassNameResolver->resolveBazelInterfaceCompanionClassName( + interfaceName), + companionClassNameResolver->resolveD8InterfaceCompanionClassName( + interfaceName)}; + + for (std::string calleeName: possibleCalleeNames) { + jclass clazz = this->FindClass(calleeName); + + if (clazz != NULL) { + jmethodID methodId = m_env->GetStaticMethodID(clazz, methodName.c_str(), sig.c_str()); + + if (ExceptionCheck() == JNI_FALSE) { + return std::make_pair(methodId, clazz); + } + + ExceptionClear(); + } + } + + throw NativeScriptException( + "Could not call static interface method with name: " + methodName + " and signature: " + + sig + " for interface: " + interfaceName); +} + + diff --git a/test-app/runtime/src/main/cpp/JEnv.h b/test-app/runtime/src/main/cpp/JEnv.h index 35834959a..8f1f483df 100644 --- a/test-app/runtime/src/main/cpp/JEnv.h +++ b/test-app/runtime/src/main/cpp/JEnv.h @@ -22,6 +22,9 @@ class JEnv { jmethodID GetMethodID(jclass clazz, const std::string& name, const std::string& sig); jmethodID GetStaticMethodID(jclass clazz, const std::string& name, const std::string& sig); + std::pair GetInterfaceStaticMethodIDAndJClass( + const std::string &interfaceName, const std::string &methodName, + const std::string &sig); jfieldID GetFieldID(jclass clazz, const std::string& name, const std::string& sig); jfieldID GetStaticFieldID(jclass clazz, const std::string& name, const std::string& sig); diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index 64a6ffb90..392c8f37c 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -119,6 +119,11 @@ string MetadataNode::GetName() { return m_name; } +bool MetadataNode::IsNodeTypeInterface() { + uint8_t nodeType = s_metadataReader.GetNodeType(m_treeNode); + return s_metadataReader.IsNodeTypeInterface(nodeType); +} + string MetadataNode::GetTypeMetadataName(Isolate* isolate, Local& value) { auto data = GetTypeMetadata(isolate, value.As()); @@ -419,6 +424,22 @@ vector MetadataNode::SetInstanceMethodsFromSt uint8_t* curPtr = s_metadataReader.GetValueData() + treeNode->offsetValue + 1; + auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; + + if(origin == "/data/data/org.nativescript.tsapp/files/app/com/vm/java/statics/test/impl/CarProducer"){ + DEBUG_WRITE_FORCE("::entry CarProducer"); + for(int i= 0; icandidates.size(); k+=1){ + auto entry22 = asd->candidates.at(k); + DEBUG_WRITE_FORCE("::entry %s", entry22.name.c_str()); + } + + } + } + + auto nodeType = s_metadataReader.GetNodeType(treeNode); auto curType = s_metadataReader.ReadTypeName(treeNode); @@ -435,7 +456,7 @@ vector MetadataNode::SetInstanceMethodsFromSt string lastMethodName; MethodCallbackData* callbackData = nullptr; - auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; + //auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; for (auto i = 0; i < instanceMethodCount; i++) { auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr); @@ -455,6 +476,7 @@ vector MetadataNode::SetInstanceMethodsFromSt } auto funcData = External::New(isolate, callbackData); + DEBUG_WRITE_FORCE("::test!!!!!!!!!!!!!! %s :::::: %s",origin.c_str(), entry.name.c_str()); auto funcTemplate = FunctionTemplate::New(isolate, MethodCallback, funcData); auto funcName = ConvertToV8String(entry.name); @@ -1006,7 +1028,8 @@ void MetadataNode::MethodCallback(const v8::FunctionCallbackInfo& inf if ((argLength == 0) && (methodName == V8StringConstants::VALUE_OF)) { info.GetReturnValue().Set(thiz); } else { - CallbackHandlers::CallJavaMethod(thiz, *className, methodName, entry, first.isStatic, isSuper, info); + bool isFromInterface = callbackData->node->IsNodeTypeInterface(); + CallbackHandlers::CallJavaMethod(thiz, *className, methodName, entry, isFromInterface, first.isStatic, isSuper, info); } } catch (NativeScriptException& e) { e.ReThrowToV8(); @@ -1894,4 +1917,5 @@ std::map MetadataNode::s_name2NodeCache; std::map MetadataNode::s_name2TreeNodeCache; std::map MetadataNode::s_treeNode2NodeCache; map MetadataNode::s_metadata_node_cache; -bool MetadataNode::s_profilerEnabled = false; \ No newline at end of file +bool MetadataNode::s_profilerEnabled = false; + diff --git a/test-app/runtime/src/main/cpp/MetadataNode.h b/test-app/runtime/src/main/cpp/MetadataNode.h index 35c657d12..77c36b8a6 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.h +++ b/test-app/runtime/src/main/cpp/MetadataNode.h @@ -39,6 +39,8 @@ class MetadataNode { std::string GetName(); + bool IsNodeTypeInterface(); + v8::Local CreateWrapper(v8::Isolate* isolate); v8::Local CreateJSWrapper(v8::Isolate* isolate, ObjectManager* objectManager); diff --git a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp index b51ad4099..ab9297303 100644 --- a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp @@ -2,6 +2,8 @@ #include "Runtime.h" #include "NativeScriptException.h" #include "CallbackHandlers.h" +#include "NativeScriptAssert.h" +#include "ArgConverter.h" #include using namespace std; diff --git a/test-app/runtime/src/main/java/com/tns/MethodResolver.java b/test-app/runtime/src/main/java/com/tns/MethodResolver.java index 96609d2ad..089c13348 100644 --- a/test-app/runtime/src/main/java/com/tns/MethodResolver.java +++ b/test-app/runtime/src/main/java/com/tns/MethodResolver.java @@ -1,6 +1,7 @@ package com.tns; import java.io.IOException; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -8,6 +9,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.List; import java.util.Map; class MethodResolver { @@ -512,9 +514,38 @@ public MethodFinder(Class clazz) { errorGettingMethods = true; } } + Method[] interfaceDefaultMethods = getInterfaceDefaultMethods(clazz); + declaredMethods = concatenate(declaredMethods, interfaceDefaultMethods); this.couldNotGetMethods = errorGettingMethods; } + private static T[] concatenate(T[] a, T[] b) { + int aLen = a.length; + int bLen = b.length; + + @SuppressWarnings("unchecked") + T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen); + System.arraycopy(a, 0, c, 0, aLen); + System.arraycopy(b, 0, c, aLen, bLen); + + return c; + } + + private Method[] getInterfaceDefaultMethods(Class clazz){ + List interfaceDefaultMethods = new ArrayList<>(); + Class[] interfaces = clazz.getInterfaces(); + for(Class interfaze: interfaces){ + for(Method method: interfaze.getMethods()) { + int methodModifiers = method.getModifiers(); + if(!Modifier.isAbstract(methodModifiers) && !Modifier.isStatic(methodModifiers)){ + interfaceDefaultMethods.add(method); + } + } + } + + return interfaceDefaultMethods.toArray(new Method[0]); + } + public boolean errorGettingMethods() { return couldNotGetMethods; } From 27786cdfcc1e3178bab0669b697ef2925b723759 Mon Sep 17 00:00:00 2001 From: vmutafov Date: Fri, 16 Nov 2018 16:55:37 +0200 Subject: [PATCH 2/8] Add static and default interface methods support --- .../src/src/com/telerik/metadata/Generator.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java index a3258f46a..c951c069e 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java @@ -8,6 +8,7 @@ import java.io.InputStreamReader; import java.security.InvalidParameterException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class Generator { @@ -23,12 +24,14 @@ public static void main(String[] args) throws Exception { List params = null; try { - metadataOutputDir = getFileRows(MDG_OUTPUT_DIR).get(0); + //metadataOutputDir = getFileRows(MDG_OUTPUT_DIR).get(0); + metadataOutputDir = "/Users/vmutafov/work/metadata-gen-out/"; } catch (Exception e) { throw new InvalidParameterException(String.format("You need to pass a file containing a single line: the output dir for the metadata generator1\n", e.getMessage())); } try { - params = getFileRows(MDG_JAVA_DEPENDENCIES); + //params = getFileRows(MDG_JAVA_DEPENDENCIES); + params = Arrays.asList("/Users/vmutafov/work/java_apps/jarTest/java-statics-test/target/java-statics-test-1.0-SNAPSHOT.jar"); } catch (Exception e) { throw new InvalidParameterException(String.format("You need to pass a file containing a list of jar/class paths, so metadata can be generated for them!\n", e.getMessage())); } From 18a569dc3f7f29f6865eb8e1f83a5a963be8ff3c Mon Sep 17 00:00:00 2001 From: vmutafov Date: Thu, 22 Nov 2018 11:33:17 +0200 Subject: [PATCH 3/8] Add static and default interface methods support --- .../src/src/com/telerik/metadata/Generator.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java index c951c069e..a3258f46a 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Generator.java @@ -8,7 +8,6 @@ import java.io.InputStreamReader; import java.security.InvalidParameterException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class Generator { @@ -24,14 +23,12 @@ public static void main(String[] args) throws Exception { List params = null; try { - //metadataOutputDir = getFileRows(MDG_OUTPUT_DIR).get(0); - metadataOutputDir = "/Users/vmutafov/work/metadata-gen-out/"; + metadataOutputDir = getFileRows(MDG_OUTPUT_DIR).get(0); } catch (Exception e) { throw new InvalidParameterException(String.format("You need to pass a file containing a single line: the output dir for the metadata generator1\n", e.getMessage())); } try { - //params = getFileRows(MDG_JAVA_DEPENDENCIES); - params = Arrays.asList("/Users/vmutafov/work/java_apps/jarTest/java-statics-test/target/java-statics-test-1.0-SNAPSHOT.jar"); + params = getFileRows(MDG_JAVA_DEPENDENCIES); } catch (Exception e) { throw new InvalidParameterException(String.format("You need to pass a file containing a list of jar/class paths, so metadata can be generated for them!\n", e.getMessage())); } From 2da4ff8f638f591d48813dc72a1f918648a04d84 Mon Sep 17 00:00:00 2001 From: vmutafov Date: Thu, 22 Nov 2018 11:33:17 +0200 Subject: [PATCH 4/8] Add static and default interface methods support --- .../com/telerik/metadata/ClassDirectory.java | 3 +-- .../com/telerik/metadata/bcl/MethodInfo.java | 2 -- ...redInterfaceCompanionClassNameResolver.cpp | 4 ---- ...garedInterfaceCompanionClassNameResolver.h | 4 ---- .../runtime/src/main/cpp/MetadataNode.cpp | 19 +------------------ .../runtime/src/main/cpp/com_tns_Runtime.cpp | 2 -- 6 files changed, 2 insertions(+), 32 deletions(-) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java index 6118daaad..305ef5779 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassDirectory.java @@ -40,8 +40,7 @@ private static void readDirectory(ClassDirectory dir, String path) throws IOException { List subDirs = new ArrayList(); File currentDir = new File(path); - File[] files = currentDir.listFiles(); - for (File file : files) { + for (File file : currentDir.listFiles()) { if (file.isFile()) { String name = file.getName(); if (name.endsWith(CLASS_EXT)) { diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java index 14e86cafb..fbf808444 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java @@ -6,8 +6,6 @@ import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.Type; -import java.lang.reflect.Modifier; - public class MethodInfo implements MethodDescriptor { private final Method m; diff --git a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp index 960cf2081..5101e4922 100644 --- a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp +++ b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.cpp @@ -1,7 +1,3 @@ -// -// Created by Vladimir Mutafov on 16.11.18. -// - #include "DesugaredInterfaceCompanionClassNameResolver.h" std::string DesugaredInterfaceCompanionClassNameResolver::resolveD8InterfaceCompanionClassName( diff --git a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h index cb58e9477..b9a06fc15 100644 --- a/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h +++ b/test-app/runtime/src/main/cpp/DesugaredInterfaceCompanionClassNameResolver.h @@ -1,7 +1,3 @@ -// -// Created by Vladimir Mutafov on 16.11.18. -// - #ifndef TEST_APP_DESUGAREDINTERFACECOMPANIONCLASSNAMERESOLVER_H #define TEST_APP_DESUGAREDINTERFACECOMPANIONCLASSNAMERESOLVER_H diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index 392c8f37c..cabb11bc5 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -424,22 +424,6 @@ vector MetadataNode::SetInstanceMethodsFromSt uint8_t* curPtr = s_metadataReader.GetValueData() + treeNode->offsetValue + 1; - auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; - - if(origin == "/data/data/org.nativescript.tsapp/files/app/com/vm/java/statics/test/impl/CarProducer"){ - DEBUG_WRITE_FORCE("::entry CarProducer"); - for(int i= 0; icandidates.size(); k+=1){ - auto entry22 = asd->candidates.at(k); - DEBUG_WRITE_FORCE("::entry %s", entry22.name.c_str()); - } - - } - } - - auto nodeType = s_metadataReader.GetNodeType(treeNode); auto curType = s_metadataReader.ReadTypeName(treeNode); @@ -456,7 +440,7 @@ vector MetadataNode::SetInstanceMethodsFromSt string lastMethodName; MethodCallbackData* callbackData = nullptr; - //auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; + auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name; for (auto i = 0; i < instanceMethodCount; i++) { auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr); @@ -476,7 +460,6 @@ vector MetadataNode::SetInstanceMethodsFromSt } auto funcData = External::New(isolate, callbackData); - DEBUG_WRITE_FORCE("::test!!!!!!!!!!!!!! %s :::::: %s",origin.c_str(), entry.name.c_str()); auto funcTemplate = FunctionTemplate::New(isolate, MethodCallback, funcData); auto funcName = ConvertToV8String(entry.name); diff --git a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp index ab9297303..b51ad4099 100644 --- a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp @@ -2,8 +2,6 @@ #include "Runtime.h" #include "NativeScriptException.h" #include "CallbackHandlers.h" -#include "NativeScriptAssert.h" -#include "ArgConverter.h" #include using namespace std; From 5231e673cf082856322783f68be06eee82c32c2e Mon Sep 17 00:00:00 2001 From: vmutafov Date: Thu, 22 Nov 2018 11:33:17 +0200 Subject: [PATCH 5/8] Add static and default interface methods support --- test-app/runtime/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-app/runtime/build.gradle b/test-app/runtime/build.gradle index 83d9c0041..b9ce2782f 100644 --- a/test-app/runtime/build.gradle +++ b/test-app/runtime/build.gradle @@ -75,7 +75,7 @@ android { if (onlyX86) { abiFilters 'x86' } else { - abiFilters 'x86'//, 'armeabi-v7a', 'arm64-v8a' + abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a' } } } From a742c3e3763d2dd9af6e1eb822e9cc6f22e2a773 Mon Sep 17 00:00:00 2001 From: vmutafov Date: Thu, 22 Nov 2018 11:33:17 +0200 Subject: [PATCH 6/8] Add static and default interface methods support --- .../src/src/com/telerik/metadata/Builder.java | 31 +++---------- .../telerik/metadata/parsing/ClassParser.java | 43 +++++++++++++++++++ 2 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java index 54061a7ea..1b37f0a54 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import com.telerik.metadata.TreeNode.FieldInfo; import com.telerik.metadata.TreeNode.MethodInfo; @@ -22,6 +23,7 @@ import com.telerik.metadata.desc.MethodDescriptor; import com.telerik.metadata.desc.TypeDescriptor; import com.telerik.metadata.dx.DexFile; +import com.telerik.metadata.parsing.ClassParser; public class Builder { private static class MethodNameComparator implements Comparator { @@ -250,33 +252,14 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr } private static MethodDescriptor[] getDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz, MethodDescriptor[] originalClassMethodDescriptors) { - HashSet defaultMethods = getAllDefaultMethodsFromImplementedInterfaces(clazz); - HashSet classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); - defaultMethods.removeAll(classMethods); - - return defaultMethods.toArray(new MethodDescriptor[0]); - } - - private static HashSet getAllDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz) { - return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); - } - - private static HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { - String[] implementedInterfacesNames = clazz.getInterfaceNames(); - - for (String implementedInterfaceName : implementedInterfacesNames) { - ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + ClassParser parser = ClassParser.forClassDescriptor(clazz); - for (MethodDescriptor md : interfaceClass.getMethods()) { - if (!md.isStatic() && !md.isAbstract()) { - collectedDefaultMethods.add(md); - } - } + Set defaultMethods = parser.getAllDefaultMethodsFromImplementedInterfaces(); + Set classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); - collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); - } + defaultMethods.removeAll(classMethods); - return collectedDefaultMethods; + return defaultMethods.toArray(new MethodDescriptor[0]); } private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java new file mode 100644 index 000000000..640dfed3e --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java @@ -0,0 +1,43 @@ +package com.telerik.metadata.parsing; + +import com.telerik.metadata.ClassRepo; +import com.telerik.metadata.desc.ClassDescriptor; +import com.telerik.metadata.desc.MethodDescriptor; + +import java.util.HashSet; +import java.util.Set; + +public final class ClassParser { + + private final ClassDescriptor clazz; + + private ClassParser(ClassDescriptor clazz) { + this.clazz = clazz; + } + + public static ClassParser forClassDescriptor(ClassDescriptor clazz) { + return new ClassParser(clazz); + } + + public Set getAllDefaultMethodsFromImplementedInterfaces() { + return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); + } + + private HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { + String[] implementedInterfacesNames = clazz.getInterfaceNames(); + + for (String implementedInterfaceName : implementedInterfacesNames) { + ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + + for (MethodDescriptor md : interfaceClass.getMethods()) { + if (!md.isStatic() && !md.isAbstract()) { + collectedDefaultMethods.add(md); + } + } + + collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); + } + + return collectedDefaultMethods; + } +} From 21efa7e9edee1b1e935b976912352e5ce2c6f70b Mon Sep 17 00:00:00 2001 From: vmutafov Date: Thu, 22 Nov 2018 11:33:17 +0200 Subject: [PATCH 7/8] Add static and default interface methods support --- .../android-metadata-generator/build.gradle | 2 +- .../src/src/com/telerik/metadata/Builder.java | 33 ++++---------- .../telerik/metadata/parsing/ClassParser.java | 43 +++++++++++++++++++ .../runtime/src/main/cpp/MetadataNode.cpp | 3 +- .../src/main/java/com/tns/MethodResolver.java | 24 +++++------ 5 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java diff --git a/test-app/build-tools/android-metadata-generator/build.gradle b/test-app/build-tools/android-metadata-generator/build.gradle index b884acbf6..9bcb52ff5 100644 --- a/test-app/build-tools/android-metadata-generator/build.gradle +++ b/test-app/build-tools/android-metadata-generator/build.gradle @@ -36,7 +36,7 @@ compileJava { compileJava.outputs.dir("$rootDir/dist/classes") dependencies { - compile 'org.apache.bcel:bcel:6.2' + compile 'org.apache.bcel:bcel:6.0' compile files("./src/libs/dx.jar") } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java index 54061a7ea..36fb74265 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import com.telerik.metadata.TreeNode.FieldInfo; import com.telerik.metadata.TreeNode.MethodInfo; @@ -22,6 +23,7 @@ import com.telerik.metadata.desc.MethodDescriptor; import com.telerik.metadata.desc.TypeDescriptor; import com.telerik.metadata.dx.DexFile; +import com.telerik.metadata.parsing.ClassParser; public class Builder { private static class MethodNameComparator implements Comparator { @@ -130,7 +132,7 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod MethodDescriptor[] allMethods = ClassUtil.getAllMethods(clazz); MethodDescriptor[] classImplementedMethods = clazz.getMethods(); - MethodDescriptor[] interfaceImplementedMethods = getDefaultMethodsFromImplementedInterfaces(clazz, classImplementedMethods); + MethodDescriptor[] interfaceImplementedMethods = clazz.isClass() ? getDefaultMethodsFromImplementedInterfaces(clazz, classImplementedMethods) : new MethodDescriptor[0]; MethodDescriptor[] methods = concatenate(classImplementedMethods, interfaceImplementedMethods); Arrays.sort(methods, methodNameComparator); @@ -250,33 +252,14 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr } private static MethodDescriptor[] getDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz, MethodDescriptor[] originalClassMethodDescriptors) { - HashSet defaultMethods = getAllDefaultMethodsFromImplementedInterfaces(clazz); - HashSet classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); - defaultMethods.removeAll(classMethods); - - return defaultMethods.toArray(new MethodDescriptor[0]); - } - - private static HashSet getAllDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz) { - return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); - } - - private static HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { - String[] implementedInterfacesNames = clazz.getInterfaceNames(); - - for (String implementedInterfaceName : implementedInterfacesNames) { - ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + ClassParser parser = ClassParser.forClassDescriptor(clazz); - for (MethodDescriptor md : interfaceClass.getMethods()) { - if (!md.isStatic() && !md.isAbstract()) { - collectedDefaultMethods.add(md); - } - } + Set defaultMethods = parser.getAllDefaultMethodsFromImplementedInterfaces(); + Set classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); - collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); - } + defaultMethods.removeAll(classMethods); - return collectedDefaultMethods; + return defaultMethods.toArray(new MethodDescriptor[0]); } private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java new file mode 100644 index 000000000..640dfed3e --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/ClassParser.java @@ -0,0 +1,43 @@ +package com.telerik.metadata.parsing; + +import com.telerik.metadata.ClassRepo; +import com.telerik.metadata.desc.ClassDescriptor; +import com.telerik.metadata.desc.MethodDescriptor; + +import java.util.HashSet; +import java.util.Set; + +public final class ClassParser { + + private final ClassDescriptor clazz; + + private ClassParser(ClassDescriptor clazz) { + this.clazz = clazz; + } + + public static ClassParser forClassDescriptor(ClassDescriptor clazz) { + return new ClassParser(clazz); + } + + public Set getAllDefaultMethodsFromImplementedInterfaces() { + return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); + } + + private HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { + String[] implementedInterfacesNames = clazz.getInterfaceNames(); + + for (String implementedInterfaceName : implementedInterfacesNames) { + ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + + for (MethodDescriptor md : interfaceClass.getMethods()) { + if (!md.isStatic() && !md.isAbstract()) { + collectedDefaultMethods.add(md); + } + } + + collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); + } + + return collectedDefaultMethods; + } +} diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index cabb11bc5..b29748cb7 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -968,6 +968,7 @@ void MetadataNode::MethodCallback(const v8::FunctionCallbackInfo& inf auto e = info.Data().As(); auto callbackData = reinterpret_cast(e->Value()); + auto initialCallbackData = reinterpret_cast(e->Value()); // Number of arguments the method is invoked with int argLength = info.Length(); @@ -1011,7 +1012,7 @@ void MetadataNode::MethodCallback(const v8::FunctionCallbackInfo& inf if ((argLength == 0) && (methodName == V8StringConstants::VALUE_OF)) { info.GetReturnValue().Set(thiz); } else { - bool isFromInterface = callbackData->node->IsNodeTypeInterface(); + bool isFromInterface = initialCallbackData->node->IsNodeTypeInterface(); CallbackHandlers::CallJavaMethod(thiz, *className, methodName, entry, isFromInterface, first.isStatic, isSuper, info); } } catch (NativeScriptException& e) { diff --git a/test-app/runtime/src/main/java/com/tns/MethodResolver.java b/test-app/runtime/src/main/java/com/tns/MethodResolver.java index 089c13348..85b65f815 100644 --- a/test-app/runtime/src/main/java/com/tns/MethodResolver.java +++ b/test-app/runtime/src/main/java/com/tns/MethodResolver.java @@ -114,7 +114,7 @@ static String resolveMethodOverload(Class clazz, String methodName, Object[] methodOverloadsForClass.put(c, finder); } - if(!finder.errorGettingMethods()) { + if (!finder.errorGettingMethods()) { ArrayList matchingMethods = finder.getMatchingMethods(methodName); tryFindMatches(methodName, candidates, args, argLength, matchingMethods); if (candidates.size() > iterationIndex && candidates.get(iterationIndex).y == 0) { @@ -123,7 +123,7 @@ static String resolveMethodOverload(Class clazz, String methodName, Object[] } } else { Method method = finder.getMatchingMethodWithArguments(methodName, args); - if(method != null) { + if (method != null) { candidates.add(new Tuple<>(method, 0)); break; } @@ -159,8 +159,8 @@ static void tryFindMatches(String methodName, ArrayList> for (int i = 0; i < params.length; i++) { if (args[i] != null) { Class argClass = args[i] instanceof NullObject ? - ((NullObject)args[i]).getNullObjectClass() - : args[i].getClass(); + ((NullObject) args[i]).getNullObjectClass() + : args[i].getClass(); Tuple res = isAssignableFrom(params[i], argClass); success = res.x.booleanValue(); @@ -226,8 +226,8 @@ static Constructor resolveConstructor(Class clazz, Object[] args) throws C for (int i = 0; i < args.length; i++) { if (args[i] != null) { Class argClass = args[i] instanceof NullObject ? - ((NullObject)args[i]).getNullObjectClass() - : args[i].getClass(); + ((NullObject) args[i]).getNullObjectClass() + : args[i].getClass(); Tuple res = isAssignableFrom(paramTypes[i], argClass); success = res.x.booleanValue(); @@ -514,7 +514,7 @@ public MethodFinder(Class clazz) { errorGettingMethods = true; } } - Method[] interfaceDefaultMethods = getInterfaceDefaultMethods(clazz); + Method[] interfaceDefaultMethods = (!clazz.isInterface()) ? getInterfaceDefaultMethods(clazz) : new Method[0]; declaredMethods = concatenate(declaredMethods, interfaceDefaultMethods); this.couldNotGetMethods = errorGettingMethods; } @@ -531,13 +531,13 @@ private static T[] concatenate(T[] a, T[] b) { return c; } - private Method[] getInterfaceDefaultMethods(Class clazz){ + private Method[] getInterfaceDefaultMethods(Class clazz) { List interfaceDefaultMethods = new ArrayList<>(); Class[] interfaces = clazz.getInterfaces(); - for(Class interfaze: interfaces){ - for(Method method: interfaze.getMethods()) { + for (Class interfaze : interfaces) { + for (Method method : interfaze.getMethods()) { int methodModifiers = method.getModifiers(); - if(!Modifier.isAbstract(methodModifiers) && !Modifier.isStatic(methodModifiers)){ + if (!Modifier.isAbstract(methodModifiers) && !Modifier.isStatic(methodModifiers)) { interfaceDefaultMethods.add(method); } } @@ -551,7 +551,7 @@ public boolean errorGettingMethods() { } public ArrayList getMatchingMethods(String methodName) { - if(this.errorGettingMethods()) { + if (this.errorGettingMethods()) { return null; } ArrayList matches = this.matchingMethods.get(methodName); From 3ffa4a22b4ad49d7f845946fe0676b2a77ce3c13 Mon Sep 17 00:00:00 2001 From: vmutafov Date: Mon, 26 Nov 2018 15:04:45 +0200 Subject: [PATCH 8/8] Add tests for static and default methods support --- test-app/app/build.gradle | 5 +++++ test-app/app/src/main/assets/app/mainpage.js | 2 ++ .../app/tests/testInterfaceDefaultMethods.js | 17 +++++++++++++++++ .../app/tests/testInterfaceStaticMethods.js | 9 +++++++++ .../defaultmethods/contract/CarProducer.java | 10 ++++++++++ .../defaultmethods/contract/Generation.java | 7 +++++++ .../defaultmethods/contract/Producer.java | 9 +++++++++ .../defaultmethods/impl/CarProducerImpl.java | 7 +++++++ .../defaultmethods/impl/FirstGeneration.java | 12 ++++++++++++ .../defaultmethods/impl/SecondGeneration.java | 10 ++++++++++ .../staticmethods/StaticProducer.java | 7 +++++++ 11 files changed, 95 insertions(+) create mode 100644 test-app/app/src/main/assets/app/tests/testInterfaceDefaultMethods.js create mode 100644 test-app/app/src/main/assets/app/tests/testInterfaceStaticMethods.js create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/CarProducer.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Generation.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Producer.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/CarProducerImpl.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/FirstGeneration.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/SecondGeneration.java create mode 100644 test-app/app/src/main/java/com/tns/tests/interfaces/staticmethods/StaticProducer.java diff --git a/test-app/app/build.gradle b/test-app/app/build.gradle index e8cfff2a3..2ac575c83 100644 --- a/test-app/app/build.gradle +++ b/test-app/app/build.gradle @@ -195,6 +195,11 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + sourceSets.main { jniLibs.srcDir "$projectDir/libs/jni" } diff --git a/test-app/app/src/main/assets/app/mainpage.js b/test-app/app/src/main/assets/app/mainpage.js index 1a81c9afd..624a647b1 100644 --- a/test-app/app/src/main/assets/app/mainpage.js +++ b/test-app/app/src/main/assets/app/mainpage.js @@ -20,6 +20,8 @@ shared.runRequireTests(); shared.runWeakRefTests(); shared.runRuntimeTests(); shared.runWorkerTests(); +require("./tests/testInterfaceDefaultMethods"); +require("./tests/testInterfaceStaticMethods"); require("./tests/testMetadata"); require("./tests/testAsserts"); require("./tests/testWeakRef"); diff --git a/test-app/app/src/main/assets/app/tests/testInterfaceDefaultMethods.js b/test-app/app/src/main/assets/app/tests/testInterfaceDefaultMethods.js new file mode 100644 index 000000000..7e883b58f --- /dev/null +++ b/test-app/app/src/main/assets/app/tests/testInterfaceDefaultMethods.js @@ -0,0 +1,17 @@ +describe("Tests Java 8 default methods support", function () { + + it("Test default method overrides in extending classes", function () { + var firstGen = new com.tns.tests.interfaces.defaultmethods.impl.FirstGeneration(); + expect(firstGen.grow()).toBe("first generation grow"); + + var secondGeneration = new com.tns.tests.interfaces.defaultmethods.impl.SecondGeneration(); + expect(secondGeneration.grow()).toBe("second generation grow"); + }) + + it("Test default method overrides in interfaces chain", function () { + var producer = new com.tns.tests.interfaces.defaultmethods.impl.CarProducerImpl(); + expect(producer.produce()).toBe("default produce in CarProducer"); + }) + + +}) \ No newline at end of file diff --git a/test-app/app/src/main/assets/app/tests/testInterfaceStaticMethods.js b/test-app/app/src/main/assets/app/tests/testInterfaceStaticMethods.js new file mode 100644 index 000000000..4284d53c8 --- /dev/null +++ b/test-app/app/src/main/assets/app/tests/testInterfaceStaticMethods.js @@ -0,0 +1,9 @@ +describe("Tests Java 8 static methods support", function () { + + it("Test static method in interface", function () { + var producer = com.tns.tests.interfaces.staticmethods.StaticProducer; + expect(producer.staticProduce()).toBe("static produce"); + }) + + +}) \ No newline at end of file diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/CarProducer.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/CarProducer.java new file mode 100644 index 000000000..60fd66ed3 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/CarProducer.java @@ -0,0 +1,10 @@ +package com.tns.tests.interfaces.defaultmethods.contract; + +public interface CarProducer extends Producer{ + + @Override + default String produce(){ + return "default produce in CarProducer"; + } +} + diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Generation.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Generation.java new file mode 100644 index 000000000..922d69a79 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Generation.java @@ -0,0 +1,7 @@ +package com.tns.tests.interfaces.defaultmethods.contract; + +public interface Generation{ + default String grow(){ + return "default grow"; + } +} \ No newline at end of file diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Producer.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Producer.java new file mode 100644 index 000000000..1e48e4d22 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/contract/Producer.java @@ -0,0 +1,9 @@ +package com.tns.tests.interfaces.defaultmethods.contract; + +public interface Producer{ + + default String produce(){ + return "default produce in Producer"; + } +} + diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/CarProducerImpl.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/CarProducerImpl.java new file mode 100644 index 000000000..b79c875d9 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/CarProducerImpl.java @@ -0,0 +1,7 @@ +package com.tns.tests.interfaces.defaultmethods.impl; + +import com.tns.tests.interfaces.defaultmethods.contract.CarProducer; + +public class CarProducerImpl implements CarProducer { + +} \ No newline at end of file diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/FirstGeneration.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/FirstGeneration.java new file mode 100644 index 000000000..357a83c72 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/FirstGeneration.java @@ -0,0 +1,12 @@ +package com.tns.tests.interfaces.defaultmethods.impl; + +import com.tns.tests.interfaces.defaultmethods.contract.Generation; + +public class FirstGeneration implements Generation { + + @Override + public String grow(){ + return "first generation grow"; + } + +} \ No newline at end of file diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/SecondGeneration.java b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/SecondGeneration.java new file mode 100644 index 000000000..1e94ed305 --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/defaultmethods/impl/SecondGeneration.java @@ -0,0 +1,10 @@ +package com.tns.tests.interfaces.defaultmethods.impl; + +public class SecondGeneration extends FirstGeneration{ + + @Override + public String grow(){ + return "second generation grow"; + } + +} \ No newline at end of file diff --git a/test-app/app/src/main/java/com/tns/tests/interfaces/staticmethods/StaticProducer.java b/test-app/app/src/main/java/com/tns/tests/interfaces/staticmethods/StaticProducer.java new file mode 100644 index 000000000..56a9dff1e --- /dev/null +++ b/test-app/app/src/main/java/com/tns/tests/interfaces/staticmethods/StaticProducer.java @@ -0,0 +1,7 @@ +package com.tns.tests.interfaces.staticmethods; + +public interface StaticProducer { + static String staticProduce(){ + return "static produce"; + } +}