diff --git a/test-app/build-tools/android-metadata-generator/build.gradle b/test-app/build-tools/android-metadata-generator/build.gradle index 2ac8c4d4e..70c3e674b 100644 --- a/test-app/build-tools/android-metadata-generator/build.gradle +++ b/test-app/build-tools/android-metadata-generator/build.gradle @@ -1,11 +1,5 @@ -/* -* Packs metadata generator in a .tgz file in ~/dist folder -* To build .tgz -* gradlew packmg -* To build jar -* gradlew jarmg -*/ -apply plugin: "java" +apply plugin: 'java' +apply plugin: 'kotlin' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -26,6 +20,9 @@ sourceSets { java { srcDir 'src/src' } + kotlin { + srcDirs += 'src/src' + } } } @@ -35,6 +32,10 @@ compileJava { compileJava.outputs.dir("$rootDir/dist/classes") +compileKotlin { + kotlinOptions.allWarningsAsErrors = true +} + repositories { google() mavenCentral() 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 9259f854c..b585e3303 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 @@ -2,22 +2,21 @@ import com.telerik.metadata.TreeNode.FieldInfo; import com.telerik.metadata.TreeNode.MethodInfo; -import com.telerik.metadata.bcl.JarFile; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.FieldDescriptor; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.PropertyDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; -import com.telerik.metadata.dx.DexFile; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.classes.impl.KotlinClassMetadataParserImpl; -import com.telerik.metadata.kotlin.functions.ClassNameAndExtensionFunctionPair; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsCollector; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsStorage; -import com.telerik.metadata.kotlin.functions.impl.ExtensionFunctionsCollectorImpl; -import com.telerik.metadata.kotlin.functions.impl.ExtensionFunctionsStorageImpl; -import com.telerik.metadata.nodes.cache.NodesCacheImpl; +import com.telerik.metadata.parsing.classes.bytecode.JarFile; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.NativeFieldDescriptor; +import com.telerik.metadata.parsing.classes.MetadataInfoAnnotationDescriptor; +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.extensions.KotlinExtensionFunctionDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.properties.KotlinPropertyDescriptor; +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.metadata.ClassMetadataParser; +import com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode.BytecodeClassMetadataParser; +import com.telerik.metadata.parsing.classes.kotlin.extensions.ClassNameAndFunctionPair; +import com.telerik.metadata.parsing.classes.kotlin.extensions.ExtensionFunctionsCollector; +import com.telerik.metadata.storage.functions.FunctionsStorage; +import com.telerik.metadata.parsing.classes.kotlin.extensions.bytecode.BytecodeExtensionFunctionsCollector; +import com.telerik.metadata.storage.functions.extensions.ExtensionFunctionsStorage; import com.telerik.metadata.parsing.ClassParser; import java.io.File; @@ -33,16 +32,16 @@ import java.util.Set; public class Builder { - private static class MethodNameComparator implements Comparator { + private static class MethodNameComparator implements Comparator { @Override - public int compare(MethodDescriptor o1, MethodDescriptor o2) { + public int compare(NativeMethodDescriptor o1, NativeMethodDescriptor o2) { return o1.getName().compareTo(o2.getName()); } } private static MethodNameComparator methodNameComparator = new MethodNameComparator(); - public static TreeNode build(List paths) throws Exception { + static TreeNode build(List paths) throws Exception { for (String path : paths) { File file = new File(path); if (file.exists()) { @@ -50,9 +49,6 @@ public static TreeNode build(List paths) throws Exception { if (path.endsWith(".jar")) { JarFile jar = JarFile.readJar(path); ClassRepo.addToCache(jar); - } else if (path.endsWith(".dex")) { - DexFile dex = DexFile.readDex(path); - ClassRepo.addToCache(dex); } } else if (file.isDirectory()) { ClassDirectory dir = ClassDirectory.readDirectory(path); @@ -67,7 +63,7 @@ public static TreeNode build(List paths) throws Exception { for (String className : classNames) { try { - ClassDescriptor clazz = ClassRepo.findClass(className); + NativeClassDescriptor clazz = ClassRepo.findClass(className); if (clazz == null) { throw new ClassNotFoundException("Class " + className + " not found in the input android libraries."); } else { @@ -90,10 +86,13 @@ public static TreeNode build(List paths) throws Exception { // our class path API 17 // Class clazz = Class.forName(className, false, loader); - ClassDescriptor clazz = ClassRepo.findClass(className); + NativeClassDescriptor clazz = ClassRepo.findClass(className); if (clazz == null) { throw new ClassNotFoundException("Class " + className + " not found in the input android libraries."); } else { + if(clazz.getClassName().contains("SomePublicClass")){ + System.out.println("asd"); + } generate(clazz, root); } } catch (Throwable e) { @@ -107,21 +106,21 @@ public static TreeNode build(List paths) throws Exception { return root; } - private static void tryCollectKotlinExtensionFunctions(ClassDescriptor classDescriptor) { - ExtensionFunctionsCollector extensionFunctionsCollector = new ExtensionFunctionsCollectorImpl(new KotlinClassMetadataParserImpl()); - Collection extensionFunctions = extensionFunctionsCollector.collectExtensionFunctions(classDescriptor); + private static void tryCollectKotlinExtensionFunctions(NativeClassDescriptor classDescriptor) { + ExtensionFunctionsCollector extensionFunctionsCollector = new BytecodeExtensionFunctionsCollector(new BytecodeClassMetadataParser()); + Collection> extensionFunctions = extensionFunctionsCollector.collectExtensionFunctions(classDescriptor); if (!extensionFunctions.isEmpty()) { - ExtensionFunctionsStorage extensionFunctionsStorage = ExtensionFunctionsStorageImpl.getInstance(); - extensionFunctionsStorage.storeExtensionFunctions(extensionFunctions); + FunctionsStorage extensionFunctionsStorage = ExtensionFunctionsStorage.getInstance(); + extensionFunctionsStorage.storeFunctions(extensionFunctions); } } - private static Boolean isClassPublic(ClassDescriptor clazz) { - Boolean isPublic = true; + private static Boolean isClassPublic(NativeClassDescriptor clazz) { + boolean isPublic = true; try { - ClassDescriptor currClass = clazz; + NativeClassDescriptor currClass = clazz; while (currClass != null) { if (!currClass.isPublic() && !currClass.isProtected()) { isPublic = false; @@ -137,7 +136,7 @@ private static Boolean isClassPublic(ClassDescriptor clazz) { return isPublic; } - private static void generate(ClassDescriptor clazz, TreeNode root) throws Exception { + private static void generate(NativeClassDescriptor clazz, TreeNode root) throws Exception { if (!isClassPublic(clazz)) { return; } @@ -159,25 +158,25 @@ private static void generate(ClassDescriptor clazz, TreeNode root) throws Except } } - private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNode root, boolean hasClassMetadataInfo) throws Exception { + private static void setNodeMembers(NativeClassDescriptor clazz, TreeNode node, TreeNode root, boolean hasClassMetadataInfo) throws Exception { node.setWentThroughSettingMembers(true); Map existingMethods = new HashMap<>(); for (MethodInfo mi : node.instanceMethods) { existingMethods.put(mi.name + mi.sig, mi); } - MethodDescriptor[] extensionFunctions = ExtensionFunctionsStorageImpl.getInstance().retrieveExtensionFunctions(clazz.getClassName()).toArray(new MethodDescriptor[0]); - MethodDescriptor[] nonExtensionFunctionMethods = ClassUtil.getAllMethods(clazz); - MethodDescriptor[] allMethods = concatenate(extensionFunctions, nonExtensionFunctionMethods); + NativeMethodDescriptor[] extensionFunctions = ExtensionFunctionsStorage.getInstance().retrieveFunctions(clazz.getClassName()).toArray(new NativeMethodDescriptor[0]); + NativeMethodDescriptor[] nonExtensionFunctionMethods = ClassUtil.getAllMethods(clazz); + NativeMethodDescriptor[] allMethods = concatenate(extensionFunctions, nonExtensionFunctionMethods); - MethodDescriptor[] classImplementedMethods = clazz.getMethods(); - MethodDescriptor[] interfaceImplementedMethods = clazz.isClass() ? getDefaultMethodsFromImplementedInterfaces(clazz, classImplementedMethods) : new MethodDescriptor[0]; - MethodDescriptor[] methods = concatenate(classImplementedMethods, interfaceImplementedMethods, extensionFunctions); + NativeMethodDescriptor[] classImplementedMethods = clazz.getMethods(); + NativeMethodDescriptor[] interfaceImplementedMethods = clazz.isClass() ? getDefaultMethodsFromImplementedInterfaces(clazz, classImplementedMethods) : new NativeMethodDescriptor[0]; + NativeMethodDescriptor[] methods = concatenate(classImplementedMethods, interfaceImplementedMethods, extensionFunctions); Arrays.sort(methods, methodNameComparator); setMethodsInfo(root, node, clazz, methods, allMethods, existingMethods, hasClassMetadataInfo); - FieldDescriptor[] fields = clazz.getFields(); + NativeFieldDescriptor[] fields = clazz.getFields(); setFieldInfo(clazz, node, root, fields, null); @@ -187,10 +186,10 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod getFieldsFromImplementedInterfaces(clazz, node, root, fields); } - private static void setMethodsInfo(TreeNode root, TreeNode node, ClassDescriptor clazz, MethodDescriptor[] ownMethodDescriptors, MethodDescriptor[] ownAndParentMethodDescriptors, Map existingNodeMethods, boolean hasClassMetadataInfo) throws Exception { + private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDescriptor clazz, NativeMethodDescriptor[] ownMethodDescriptors, NativeMethodDescriptor[] ownAndParentMethodDescriptors, Map existingNodeMethods, boolean hasClassMetadataInfo) throws Exception { - for (MethodDescriptor m : ownMethodDescriptors) { + for (NativeMethodDescriptor m : ownMethodDescriptors) { if (m.isSynthetic()) { continue; } @@ -207,7 +206,7 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, ClassDescriptor MethodInfo mi = new MethodInfo(m); int countUnique = 0; - for (MethodDescriptor m1 : ownAndParentMethodDescriptors) { + for (NativeMethodDescriptor m1 : ownAndParentMethodDescriptors) { boolean m1IsStatic = m1.isStatic(); if (!m1.isSynthetic() && (m1.isPublic() || m1.isProtected()) @@ -223,7 +222,7 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, ClassDescriptor mi.isResolved = countUnique == 1; - TypeDescriptor[] params = m.getArgumentTypes(); + NativeTypeDescriptor[] params = m.getArgumentTypes(); mi.signature = getMethodSignature(root, m.getReturnType(), params); @@ -253,12 +252,12 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, ClassDescriptor } - private static void setPropertiesInfo(TreeNode root, TreeNode node, PropertyDescriptor[] propertyDescriptors) throws Exception { - for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + private static void setPropertiesInfo(TreeNode root, TreeNode node, KotlinPropertyDescriptor[] propertyDescriptors) throws Exception { + for (KotlinPropertyDescriptor propertyDescriptor : propertyDescriptors) { String propertyName = propertyDescriptor.getName(); - MethodDescriptor getterMethod = propertyDescriptor.getGetterMethod(); - MethodDescriptor setterMethod = propertyDescriptor.getSetterMethod(); + NativeMethodDescriptor getterMethod = propertyDescriptor.getGetterMethod(); + NativeMethodDescriptor setterMethod = propertyDescriptor.getSetterMethod(); MethodInfo getterMethodInfo = null; if (getterMethod != null) { @@ -281,12 +280,12 @@ private static void setPropertiesInfo(TreeNode root, TreeNode node, PropertyDesc } - private static void setFieldInfo(ClassDescriptor clazz, TreeNode node, TreeNode root, FieldDescriptor[] fields, ClassDescriptor interfaceClass) throws Exception { - for (FieldDescriptor f : fields) { + private static void setFieldInfo(NativeClassDescriptor clazz, TreeNode node, TreeNode root, NativeFieldDescriptor[] fields, NativeClassDescriptor interfaceClass) throws Exception { + for (NativeFieldDescriptor f : fields) { if (f.isPublic() || f.isProtected()) { FieldInfo fi = new FieldInfo(f.getName()); - TypeDescriptor t = f.getType(); + NativeTypeDescriptor t = f.getType(); boolean isPrimitive = ClassUtil.isPrimitive(t); fi.valueType = isPrimitive ? TreeNode.getPrimitive(t) : getOrCreateNode(root, t); @@ -307,11 +306,11 @@ private static void setFieldInfo(ClassDescriptor clazz, TreeNode node, TreeNode } } - private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, TreeNode node, TreeNode root, FieldDescriptor[] classFields) throws Exception { - FieldDescriptor[] fields = null; - List originalClassFields = Arrays.asList(classFields); + private static void getFieldsFromImplementedInterfaces(NativeClassDescriptor clazz, TreeNode node, TreeNode root, NativeFieldDescriptor[] classFields) throws Exception { + NativeFieldDescriptor[] fields; + List originalClassFields = Arrays.asList(classFields); - ClassDescriptor interfaceClass = null; + NativeClassDescriptor interfaceClass; String[] implementedInterfacesNames = clazz.getInterfaceNames(); if (implementedInterfacesNames.length > 0) { for (String currInterface : implementedInterfacesNames) { @@ -324,7 +323,7 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr //if interface and implementing class declare the same static field name the class take precedence if (originalClassFields.size() > 0) { - for (FieldDescriptor f : fields) { + for (NativeFieldDescriptor f : fields) { if (originalClassFields.contains(f)) { return; } @@ -336,18 +335,18 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr } } - private static MethodDescriptor[] getDefaultMethodsFromImplementedInterfaces(ClassDescriptor clazz, MethodDescriptor[] originalClassMethodDescriptors) { + private static NativeMethodDescriptor[] getDefaultMethodsFromImplementedInterfaces(NativeClassDescriptor clazz, NativeMethodDescriptor[] originalClassMethodDescriptors) { ClassParser parser = ClassParser.forClassDescriptor(clazz); - Set defaultMethods = parser.getAllDefaultMethodsFromImplementedInterfaces(); - Set classMethods = new HashSet(Arrays.asList(originalClassMethodDescriptors)); + Set defaultMethods = parser.getAllDefaultMethodsFromImplementedInterfaces(); + Set classMethods = new HashSet<>(Arrays.asList(originalClassMethodDescriptors)); defaultMethods.removeAll(classMethods); - return defaultMethods.toArray(new MethodDescriptor[0]); + return defaultMethods.toArray(new NativeMethodDescriptor[0]); } - private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) + private static TreeNode getOrCreateNode(TreeNode root, NativeTypeDescriptor type) throws Exception { TreeNode node; @@ -357,7 +356,7 @@ private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) node = createArrayNode(root, typeName); } else { String name = ClassUtil.getCanonicalName(type.getSignature()); - ClassDescriptor clazz = ClassRepo.findClass(name); + NativeClassDescriptor clazz = ClassRepo.findClass(name); // if clazz is not found in the ClassRepo, the method/field being analyzed will be skipped if (clazz == null) { @@ -370,7 +369,7 @@ private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type) return node; } - private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, String predefinedSuperClassname) throws Exception { + private static TreeNode getOrCreateNode(TreeNode root, NativeClassDescriptor clazz, String predefinedSuperClassname) throws Exception { if (ClassUtil.isPrimitive(clazz)) { return TreeNode.getPrimitive(clazz); @@ -395,10 +394,10 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St node = child; } - ClassDescriptor outer = ClassUtil.getEnclosingClass(clazz); + NativeClassDescriptor outer = ClassUtil.getEnclosingClass(clazz); - ArrayList outerClasses = new ArrayList(); + ArrayList outerClasses = new ArrayList<>(); while (outer != null) { if (!outer.isPublic()) { return null; @@ -445,7 +444,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St } node = child; if (node.baseClassNode == null) { - ClassDescriptor baseClass = null; + NativeClassDescriptor baseClass = null; if (predefinedSuperClassname != null) { baseClass = ClassUtil.getClassByName(predefinedSuperClassname); } else { @@ -463,16 +462,15 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St } } - NodesCacheImpl.getInstance().addNode(clazz.getClassName(), node); return node; } - private static boolean isNestedClassKotlinCompanionObject(ClassDescriptor outerClass, ClassDescriptor nestedClass) { + private static boolean isNestedClassKotlinCompanionObject(NativeClassDescriptor outerClass, NativeClassDescriptor nestedClass) { if (outerClass == null || nestedClass == null) { return false; } - KotlinClassMetadataParser kotlinClassMetadataParser = new KotlinClassMetadataParserImpl(); + ClassMetadataParser kotlinClassMetadataParser = new BytecodeClassMetadataParser(); return kotlinClassMetadataParser.wasKotlinCompanionObject(outerClass, nestedClass); } @@ -502,7 +500,7 @@ private static TreeNode createArrayNode(TreeNode root, String className) child.nodeType = node.nodeType; child.arrayElement = node; } else { - ClassDescriptor clazz = ClassRepo.findClass(name); + NativeClassDescriptor clazz = ClassRepo.findClass(name); child.nodeType = clazz.isInterface() ? TreeNode.Interface : TreeNode.Class; if (clazz.isStatic()) { @@ -516,9 +514,9 @@ private static TreeNode createArrayNode(TreeNode root, String className) } private static ArrayList getMethodSignature(TreeNode root, - TypeDescriptor retType, TypeDescriptor[] params) throws Exception { - ArrayList sig = new ArrayList(); - boolean isVoid = retType.equals(TypeDescriptor.VOID); + NativeTypeDescriptor retType, NativeTypeDescriptor[] params) throws Exception { + ArrayList sig = new ArrayList<>(); + boolean isVoid = retType.equals(NativeTypeDescriptor.Companion.getVOID()); TreeNode node = null; if (!isVoid) { @@ -528,7 +526,7 @@ private static ArrayList getMethodSignature(TreeNode root, } sig.add(node); - for (TypeDescriptor param : params) { + for (NativeTypeDescriptor param : params) { boolean isPrimitive = ClassUtil.isPrimitive(param); node = isPrimitive ? TreeNode.getPrimitive(param) : getOrCreateNode(root, param); 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 b6991624e..dce40818b 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 @@ -2,9 +2,10 @@ import com.telerik.metadata.analytics.AnalyticsCollector; import com.telerik.metadata.analytics.AnalyticsCollectorProvider; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.classes.impl.KotlinClassMetadataParserImpl; +import com.telerik.metadata.parsing.classes.bytecode.NativeClassBytecodeDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.metadata.ClassMetadataParser; +import com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode.BytecodeClassMetadataParser; import org.apache.bcel.classfile.ClassParser; @@ -17,18 +18,18 @@ public class ClassDirectory implements ClassMapProvider { private final String path; - private final Map classMap; - private static final KotlinClassMetadataParser kotlinClassMetadataParser = new KotlinClassMetadataParserImpl(); + private final Map classMap; + private static final ClassMetadataParser kotlinClassMetadataParser = new BytecodeClassMetadataParser(); private static final AnalyticsCollector analyticsCollector = AnalyticsCollectorProvider.getInstance().provideAnalyticsCollector(); private static final String CLASS_EXT = ".class"; private static final String DEX_EXT = ".dex"; private ClassDirectory(String path) { this.path = path; - this.classMap = new HashMap(); + this.classMap = new HashMap(); } - public Map getClassMap() { + public Map getClassMap() { return classMap; } @@ -50,7 +51,7 @@ private static void readDirectory(ClassDirectory dir, String path) if (file.isFile()) { String name = file.getName(); if (name.endsWith(CLASS_EXT)) { - ClassDescriptor clazz = getClassDescriptor(name, file); + NativeClassDescriptor clazz = getClassDescriptor(name, file); dir.classMap.put(clazz.getClassName(), clazz); } } else if (file.isDirectory()) { @@ -62,11 +63,11 @@ private static void readDirectory(ClassDirectory dir, String path) } } - private static ClassDescriptor getClassDescriptor(String name, File file) throws IOException { - ClassDescriptor clazz = null; + private static NativeClassDescriptor getClassDescriptor(String name, File file) throws IOException { + NativeClassDescriptor clazz = null; if (name.endsWith(CLASS_EXT)) { ClassParser cp = new ClassParser(file.getAbsolutePath()); - clazz = new com.telerik.metadata.bcl.ClassInfo(cp.parse()); + clazz = new NativeClassBytecodeDescriptor(cp.parse()); markIfKotlinClass(clazz); } else if (name.endsWith(DEX_EXT)) { // TODO: @@ -75,7 +76,7 @@ private static ClassDescriptor getClassDescriptor(String name, File file) throws return clazz; } - private static void markIfKotlinClass(ClassDescriptor classDescriptor) { + private static void markIfKotlinClass(NativeClassDescriptor classDescriptor) { if (kotlinClassMetadataParser.wasKotlinClass(classDescriptor)) { analyticsCollector.markHasKotlinRuntimeClassesIfNotMarkedAlready(); } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassMapProvider.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassMapProvider.java index fdd602b66..4923468c1 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassMapProvider.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassMapProvider.java @@ -1,11 +1,11 @@ package com.telerik.metadata; -import com.telerik.metadata.desc.ClassDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; import java.util.Map; public interface ClassMapProvider { - Map getClassMap(); + Map getClassMap(); String getPath(); } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassRepo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassRepo.java index d4c98efbf..31db7f6c3 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassRepo.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassRepo.java @@ -1,6 +1,6 @@ package com.telerik.metadata; -import com.telerik.metadata.desc.ClassDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; import java.util.ArrayList; import java.util.Arrays; @@ -15,8 +15,8 @@ public static void addToCache(ClassMapProvider classMapProvider) { cachedProviders.add(classMapProvider); } - public static ClassDescriptor findClass(String className) { - ClassDescriptor clazz = null; + public static NativeClassDescriptor findClass(String className) { + NativeClassDescriptor clazz = null; for (ClassMapProvider classMapProvider : cachedProviders) { clazz = classMapProvider.getClassMap().get(className); if (clazz != null) { diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassUtil.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassUtil.java index 930b97c76..e0933dd83 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassUtil.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/ClassUtil.java @@ -1,29 +1,27 @@ package com.telerik.metadata; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor; +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor; import java.util.ArrayList; -import org.apache.bcel.generic.Type; - public class ClassUtil { private ClassUtil() { } - public static boolean isPrimitive(ClassDescriptor clazz) { + public static boolean isPrimitive(NativeClassDescriptor clazz) { boolean isPrimitive = !clazz.isClass() && !clazz.isEnum() && !clazz.isInterface(); return isPrimitive; } - public static boolean isPrimitive(TypeDescriptor type) { - boolean isPrimitive = type.equals(TypeDescriptor.BOOLEAN) - || type.equals(TypeDescriptor.CHAR) || type.equals(TypeDescriptor.BYTE) - || type.equals(TypeDescriptor.SHORT) || type.equals(TypeDescriptor.INT) - || type.equals(TypeDescriptor.LONG) || type.equals(TypeDescriptor.FLOAT) - || type.equals(TypeDescriptor.DOUBLE) || type.equals(TypeDescriptor.VOID); + public static boolean isPrimitive(NativeTypeDescriptor type) { + boolean isPrimitive = type.equals(NativeTypeDescriptor.Companion.getBOOLEAN()) + || type.equals(NativeTypeDescriptor.Companion.getCHAR()) || type.equals(NativeTypeDescriptor.Companion.getBYTE()) + || type.equals(NativeTypeDescriptor.Companion.getSHORT()) || type.equals(NativeTypeDescriptor.Companion.getINT()) + || type.equals(NativeTypeDescriptor.Companion.getLONG()) || type.equals(NativeTypeDescriptor.Companion.getFLOAT()) + || type.equals(NativeTypeDescriptor.Companion.getDOUBLE()) || type.equals(NativeTypeDescriptor.Companion.getVOID()); return isPrimitive; } @@ -36,7 +34,7 @@ public static boolean isPrimitive(String name) { return isPrimitive; } - public static boolean isArray(ClassDescriptor clazz) { + public static boolean isArray(NativeClassDescriptor clazz) { boolean isArray = isArray(clazz.getClassName()); return isArray; } @@ -46,8 +44,8 @@ public static boolean isArray(String className) { return isArray; } - public static ClassDescriptor getEnclosingClass(ClassDescriptor clazz) { - ClassDescriptor enclosingClass = null; + public static NativeClassDescriptor getEnclosingClass(NativeClassDescriptor clazz) { + NativeClassDescriptor enclosingClass = null; String className = clazz.getClassName(); int idx = className.lastIndexOf("$"); @@ -59,7 +57,7 @@ public static ClassDescriptor getEnclosingClass(ClassDescriptor clazz) { return enclosingClass; } - public static String getSimpleName(ClassDescriptor clazz) { + public static String getSimpleName(NativeClassDescriptor clazz) { String className = clazz.getClassName(); int idx = className.lastIndexOf("$"); if (idx < 0) { @@ -69,19 +67,19 @@ public static String getSimpleName(ClassDescriptor clazz) { return simpleName; } - public static MethodDescriptor[] getAllMethods(ClassDescriptor clazz) { - ArrayList methods = new ArrayList(); - ClassDescriptor currentClass = clazz; + public static NativeMethodDescriptor[] getAllMethods(NativeClassDescriptor clazz) { + ArrayList methods = new ArrayList(); + NativeClassDescriptor currentClass = clazz; while (currentClass != null) { - MethodDescriptor[] currentClassMethods = currentClass.getMethods(); - for (MethodDescriptor m : currentClassMethods) { + NativeMethodDescriptor[] currentClassMethods = currentClass.getMethods(); + for (NativeMethodDescriptor m : currentClassMethods) { if ((m.isPublic() || m.isProtected()) && !m.isSynthetic()) { methods.add(m); } } currentClass = getSuperclass(currentClass); } - return methods.toArray(new MethodDescriptor[0]); + return methods.toArray(new NativeMethodDescriptor[0]); } public static String getCanonicalName(String className) { @@ -95,8 +93,8 @@ public static String getCanonicalName(String className) { return canonicalName; } - public static ClassDescriptor getSuperclass(ClassDescriptor clazz) { - ClassDescriptor superClass = null; + public static NativeClassDescriptor getSuperclass(NativeClassDescriptor clazz) { + NativeClassDescriptor superClass = null; if (!clazz.getClassName().equals("java.lang.Object")) { String superClassName = clazz.getSuperclassName(); superClass = ClassRepo.findClass(superClassName); @@ -104,8 +102,8 @@ public static ClassDescriptor getSuperclass(ClassDescriptor clazz) { return superClass; } - public static ClassDescriptor getClassByName(String className) { - ClassDescriptor clazz = ClassRepo.findClass(className); + public static NativeClassDescriptor getClassByName(String className) { + NativeClassDescriptor clazz = ClassRepo.findClass(className); return clazz; } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/TreeNode.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/TreeNode.java index 72ab9c1cb..a19ac2224 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/TreeNode.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/TreeNode.java @@ -1,9 +1,9 @@ package com.telerik.metadata; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.ExtensionFunctionDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.extensions.KotlinExtensionFunctionDescriptor; +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor; +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor; import java.util.ArrayList; import java.util.List; @@ -11,11 +11,11 @@ public class TreeNode { public static class MethodInfo { - public MethodInfo(MethodDescriptor m) { + public MethodInfo(NativeMethodDescriptor m) { this.name = m.getName(); this.sig = m.getSignature(); this.isResolved = false; - this.isExtensionFunction = m instanceof ExtensionFunctionDescriptor; + this.isExtensionFunction = m instanceof KotlinExtensionFunctionDescriptor; signature = new ArrayList<>(); } @@ -109,35 +109,35 @@ public TreeNode() { public static final TreeNode BOOLEAN = getPrimitive("Z", (byte) 7); public static final TreeNode CHAR = getPrimitive("C", (byte) 8); - public static TreeNode getPrimitive(TypeDescriptor type) throws Exception { + public static TreeNode getPrimitive(NativeTypeDescriptor type) throws Exception { if (!ClassUtil.isPrimitive(type)) { throw new Exception("type must be primitive"); } - if (type.equals(TypeDescriptor.BYTE)) { + if (type.equals(NativeTypeDescriptor.Companion.getBYTE())) { return TreeNode.BYTE; - } else if (type.equals(TypeDescriptor.SHORT)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getSHORT())) { return TreeNode.SHORT; - } else if (type.equals(TypeDescriptor.INT)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getINT())) { return TreeNode.INTEGER; - } else if (type.equals(TypeDescriptor.LONG)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getLONG())) { return TreeNode.LONG; - } else if (type.equals(TypeDescriptor.FLOAT)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getFLOAT())) { return TreeNode.FLOAT; - } else if (type.equals(TypeDescriptor.DOUBLE)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getDOUBLE())) { return TreeNode.DOUBLE; - } else if (type.equals(TypeDescriptor.BOOLEAN)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getBOOLEAN())) { return TreeNode.BOOLEAN; - } else if (type.equals(TypeDescriptor.CHAR)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getCHAR())) { return TreeNode.CHAR; - } else if (type.equals(TypeDescriptor.VOID)) { + } else if (type.equals(NativeTypeDescriptor.Companion.getVOID())) { return null; } else { throw new Exception("unknown type=" + type.toString()); } } - public static TreeNode getPrimitive(ClassDescriptor clazz) throws Exception { + public static TreeNode getPrimitive(NativeClassDescriptor clazz) throws Exception { if (!ClassUtil.isPrimitive(clazz)) { throw new Exception("clazz must be primitive"); } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/AnalyticsCollectorProvider.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/AnalyticsCollectorProvider.java index b86f04477..4bfd23331 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/AnalyticsCollectorProvider.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/AnalyticsCollectorProvider.java @@ -1,7 +1,7 @@ package com.telerik.metadata.analytics; -import com.telerik.metadata.analytics.impl.EnabledAnalyticsCollectorImpl; -import com.telerik.metadata.analytics.impl.NoOpAnalyticsCollector; +import com.telerik.metadata.analytics.enabled.DefaultAnalyticsCollector; +import com.telerik.metadata.analytics.disabled.NoOpAnalyticsCollector; public class AnalyticsCollectorProvider { private static final AnalyticsCollectorProvider ourInstance = new AnalyticsCollectorProvider(); @@ -16,7 +16,7 @@ private AnalyticsCollectorProvider() { public AnalyticsCollector provideAnalyticsCollector() { if (AnalyticsConfiguration.areAnalyticsEnabled()) { String analyticsFilePath = AnalyticsConfiguration.getAnalyticsFilePath(); - return new EnabledAnalyticsCollectorImpl(analyticsFilePath); + return new DefaultAnalyticsCollector(analyticsFilePath); } else { return new NoOpAnalyticsCollector(); } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/NoOpAnalyticsCollector.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/disabled/NoOpAnalyticsCollector.java similarity index 84% rename from test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/NoOpAnalyticsCollector.java rename to test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/disabled/NoOpAnalyticsCollector.java index fa7d28e3a..b87b0ecd6 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/NoOpAnalyticsCollector.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/disabled/NoOpAnalyticsCollector.java @@ -1,4 +1,4 @@ -package com.telerik.metadata.analytics.impl; +package com.telerik.metadata.analytics.disabled; import com.telerik.metadata.analytics.AnalyticsCollector; diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/EnabledAnalyticsCollectorImpl.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/enabled/DefaultAnalyticsCollector.java similarity index 90% rename from test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/EnabledAnalyticsCollectorImpl.java rename to test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/enabled/DefaultAnalyticsCollector.java index c06bb6645..7d9f7fb80 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/impl/EnabledAnalyticsCollectorImpl.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/analytics/enabled/DefaultAnalyticsCollector.java @@ -1,4 +1,4 @@ -package com.telerik.metadata.analytics.impl; +package com.telerik.metadata.analytics.enabled; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -11,7 +11,7 @@ import java.nio.file.Path; import java.nio.file.Paths; -public final class EnabledAnalyticsCollectorImpl implements AnalyticsCollector { +public final class DefaultAnalyticsCollector implements AnalyticsCollector { private static final String HAS_KOTLIN_RUNTIME_CLASSES_JSON_PROPERTY_NAME = "hasKotlinRuntimeClasses"; private static final String HAS_USE_KOTLIN_PROPERTY_IN_APP_JSON_PROPERTY_NAME = "hasUseKotlinPropertyInApp"; @@ -23,11 +23,11 @@ public final class EnabledAnalyticsCollectorImpl implements AnalyticsCollector { private boolean hasMarked; public static void main(String... args) { - EnabledAnalyticsCollectorImpl a = new EnabledAnalyticsCollectorImpl("/Users/vmutafov/work/android_runtime_release/android-runtime/test-app/analytics/build-statistics.json"); + DefaultAnalyticsCollector a = new DefaultAnalyticsCollector("/Users/vmutafov/work/android_runtime_release/android-runtime/test-app/analytics/build-statistics.json"); a.markHasKotlinRuntimeClassesIfNotMarkedAlready(); } - public EnabledAnalyticsCollectorImpl(String analyticsFilePath) { + public DefaultAnalyticsCollector(String analyticsFilePath) { this.analyticsFilePath = analyticsFilePath; this.gson = new GsonBuilder().setPrettyPrinting().create(); this.hasMarked = false; diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ClassInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ClassInfo.java deleted file mode 100644 index d20af7378..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ClassInfo.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.telerik.metadata.bcl; - -import com.telerik.metadata.ClassUtil; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.FieldDescriptor; -import com.telerik.metadata.desc.KotlinClassMetadataAnnotation; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.PropertyDescriptor; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.classes.impl.KotlinClassMetadataParserImpl; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsCollector; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsStorage; -import com.telerik.metadata.kotlin.functions.impl.ExtensionFunctionsCollectorImpl; -import com.telerik.metadata.kotlin.functions.impl.ExtensionFunctionsStorageImpl; - -import org.apache.bcel.classfile.AnnotationEntry; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.ConstantClass; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantUtf8; -import org.apache.bcel.classfile.Field; -import org.apache.bcel.classfile.InnerClass; -import org.apache.bcel.classfile.InnerClasses; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.classfile.Method; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.KmProperty; -import kotlinx.metadata.jvm.JvmExtensionsKt; -import kotlinx.metadata.jvm.JvmMethodSignature; - -public class ClassInfo implements ClassDescriptor { - private final JavaClass clazz; - private final ExtensionFunctionsStorage extensionFunctionsStorage; - - public ClassInfo(JavaClass clazz) { - this.clazz = clazz; - this.extensionFunctionsStorage = ExtensionFunctionsStorageImpl.getInstance(); - init(); - } - - private void init() { - if (clazz.getClassName().contains("$")) { - String name = ClassUtil.getSimpleName(this); - boolean isAnonymousClass; - try { - Integer.parseInt(name); - isAnonymousClass = true; - } catch (Exception e) { - isAnonymousClass = false; - } - if (isAnonymousClass) { - return; - } - boolean found = false; - String fullClassName = getClassName(clazz.getClassNameIndex()); - if (fullClassName == null) { - return; - } - - for (Attribute a : clazz.getAttributes()) { - if (a instanceof InnerClasses) { - InnerClass[] i = ((InnerClasses) a).getInnerClasses(); - for (InnerClass ic : i) { - String innerClassName = getClassName(ic.getInnerClassIndex()); - - if (fullClassName.equals(innerClassName)) { - int flags = ic.getInnerAccessFlags(); - clazz.setAccessFlags(flags); - found = true; - break; - } - } - } - if (found) { - break; - } - } - } - } - - private String getClassName(int classIndex) { - ConstantPool constantPool = clazz.getConstantPool(); - ConstantClass innerClassNameIndex = (ConstantClass) constantPool.getConstant(classIndex); - if (innerClassNameIndex == null) { - return null; - } - ConstantUtf8 className = (ConstantUtf8) constantPool.getConstant(innerClassNameIndex.getNameIndex()); - if (className == null) { - return null; - } - return className.getBytes(); - } - - @Override - public boolean isClass() { - return clazz.isClass(); - } - - @Override - public boolean isInterface() { - return clazz.isInterface(); - } - - @Override - public boolean isEnum() { - return clazz.isEnum(); - } - - @Override - public boolean isStatic() { - return clazz.isStatic(); - } - - @Override - public boolean isPublic() { - return clazz.isPublic(); - } - - @Override - public boolean isProtected() { - return clazz.isProtected(); - } - - @Override - public MethodDescriptor[] getMethods() { - Method[] ms = clazz.getMethods(); - MethodDescriptor[] methods = new MethodDescriptor[ms.length]; - for (int i = 0; i < methods.length; i++) { - methods[i] = new MethodInfo(ms[i], this); - } - return methods; - } - - @Override - public PropertyDescriptor[] getProperties() { - List propertyDescriptors = new ArrayList(); - KotlinClassMetadataParser kotlinClassMetadataParser = new KotlinClassMetadataParserImpl(); - List kotlinProperties = kotlinClassMetadataParser.getKotlinProperties(this); - for (KmProperty kmProperty : kotlinProperties) { - String propertyName = kmProperty.getName(); - - MethodDescriptor getter = null; - JvmMethodSignature getterSignature = JvmExtensionsKt.getGetterSignature(kmProperty); - if (getterSignature != null) { - getter = getMethodDescriptorWithSignature(getterSignature.getName(), getterSignature.getDesc()); - } - - MethodDescriptor setter = null; - JvmMethodSignature setterSignature = JvmExtensionsKt.getSetterSignature(kmProperty); - if (setterSignature != null) { - setter = getMethodDescriptorWithSignature(setterSignature.getName(), setterSignature.getDesc()); - } - - propertyDescriptors.add(new PropertyInfo(propertyName, getter, setter)); - - } - - return propertyDescriptors.toArray(new PropertyDescriptor[0]); - } - - private MethodDescriptor getMethodDescriptorWithSignature(String name, String signature) { - for (Method method : clazz.getMethods()) { - String methodSignature = method.getSignature(); - String methodName = method.getName(); - - if (methodSignature.equals(signature) && methodName.equals(name)) { - return new MethodInfo(method, this); - } - } - - return null; - } - - @Override - public FieldDescriptor[] getFields() { - Field[] fs = clazz.getFields(); - FieldDescriptor[] fields = new FieldDescriptor[fs.length]; - for (int i = 0; i < fields.length; i++) { - fields[i] = new FieldInfo(fs[i]); - } - return fields; - } - - @Override - public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { - return null; - } - - @Override - public Optional getKotlinClassMetadataAnnotation() { - AnnotationEntry[] annotationEntries = clazz.getAnnotationEntries(); - if (annotationEntries != null) { - for (AnnotationEntry annotationEntry : annotationEntries) { - String annotationType = annotationEntry.getAnnotationType(); - if ("Lkotlin/Metadata;".equals(annotationType)) { - KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation = new KotlinBytecodeClassMetadataAnnotation(annotationEntry); - return Optional.of(kotlinClassMetadataAnnotation); - } - } - } - - return Optional.empty(); - } - - @Override - public String[] getInterfaceNames() { - return clazz.getInterfaceNames(); - } - - @Override - public String getPackageName() { - return clazz.getPackageName(); - } - - @Override - public String getClassName() { - return clazz.getClassName(); - } - - @Override - public String getSuperclassName() { - return clazz.getSuperclassName(); - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ExtensionFunctionInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ExtensionFunctionInfo.java deleted file mode 100644 index 1b74fef76..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/ExtensionFunctionInfo.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.telerik.metadata.bcl; - -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.ExtensionFunctionDescriptor; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; - -public class ExtensionFunctionInfo implements ExtensionFunctionDescriptor { - private final MethodDescriptor m; - - public ExtensionFunctionInfo(MethodDescriptor m) { - this.m = m; - } - - @Override - public boolean isPublic() { - return m.isPublic(); - } - - @Override - public boolean isProtected() { - return m.isProtected(); - } - - @Override - public boolean isSynthetic() { - return m.isSynthetic(); - } - - @Override - public boolean isStatic() { - return m.isStatic(); - } - - @Override - public boolean isAbstract() { - return m.isAbstract(); - } - - @Override - public ClassDescriptor getDeclaringClass() { - return m.getDeclaringClass(); - } - - @Override - public String getName() { - return m.getName(); - } - - @Override - public String getSignature() { - return m.getSignature(); - } - - @Override - public TypeDescriptor[] getArgumentTypes() { - return m.getArgumentTypes(); - } - - @Override - public TypeDescriptor getReturnType() { - return m.getReturnType(); - } - - @Override - public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ExtensionFunctionInfo that = (ExtensionFunctionInfo) 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/bcl/FieldInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/FieldInfo.java deleted file mode 100644 index 81463d762..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/FieldInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.telerik.metadata.bcl; - -import com.telerik.metadata.desc.FieldDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; - -import org.apache.bcel.classfile.Field; - -public class FieldInfo implements FieldDescriptor { - private final Field f; - - public FieldInfo(Field f) { - this.f = f; - } - - @Override - public boolean isPublic() { - return f.isPublic(); - } - - @Override - public boolean isProtected() { - return f.isProtected(); - } - - @Override - public boolean isFinal() { - return f.isFinal(); - } - - @Override - public boolean isStatic() { - return f.isStatic(); - } - - @Override - public String getName() { - return f.getName(); - } - - @Override - public TypeDescriptor getType() { - return new TypeInfo(f.getType()); - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/KotlinBytecodeClassMetadataAnnotation.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/KotlinBytecodeClassMetadataAnnotation.java deleted file mode 100644 index 11b43c51c..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/KotlinBytecodeClassMetadataAnnotation.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.telerik.metadata.bcl; - -import com.telerik.metadata.desc.KotlinClassMetadataAnnotation; - -import org.apache.bcel.classfile.AnnotationEntry; -import org.apache.bcel.classfile.ArrayElementValue; -import org.apache.bcel.classfile.ElementValue; -import org.apache.bcel.classfile.ElementValuePair; -import org.apache.bcel.classfile.SimpleElementValue; - -public class KotlinBytecodeClassMetadataAnnotation implements KotlinClassMetadataAnnotation { - - private Integer kind = null; - private int[] metadataVersion = null; - private int[] bytecodeVersion = null; - private String[] data1 = null; - private String[] data2 = null; - private String extraString = null; - private String packageName = null; - private Integer extraInt = null; - - KotlinBytecodeClassMetadataAnnotation(AnnotationEntry annotationEntry) { - if (annotationEntry != null) { - parseKotlinMetadataAnnotation(annotationEntry); - } - } - - private void parseKotlinMetadataAnnotation(AnnotationEntry annotationEntry) { - ElementValuePair[] elementValuePairs = annotationEntry.getElementValuePairs(); - if (elementValuePairs != null) { - for (ElementValuePair elementValuePair : annotationEntry.getElementValuePairs()) { - - String elementName = elementValuePair.getNameString(); - ElementValue elementValue = elementValuePair.getValue(); - - if ("k".equals(elementName)) { - parseKind(elementValue); - } else if ("mv".equals(elementName)) { - parseMetadataVersion(elementValue); - } else if ("bv".equals(elementName)) { - parseBytecodeVersion(elementValue); - } else if ("d1".equals(elementName)) { - parseData1(elementValue); - } else if ("d2".equals(elementName)) { - parseData2(elementValue); - } else if ("xs".equals(elementName)) { - parseExtraString(elementValue); - } else if ("pn".equals(elementName)) { - parsePackageName(elementValue); - } else if ("xi".equals(elementName)) { - parseExtraInt(elementValue); - } - } - } - } - - private void parseKind(ElementValue elementValue) { - SimpleElementValue simpleElementValue = (SimpleElementValue) elementValue; - kind = simpleElementValue.getValueInt(); - } - - private void parseMetadataVersion(ElementValue elementValue) { - ArrayElementValue arrayElement = (ArrayElementValue) elementValue; - - int metadataVersionArraySize = arrayElement.getElementValuesArraySize(); - metadataVersion = new int[metadataVersionArraySize]; - - ElementValue[] arrayElementValues = arrayElement.getElementValuesArray(); - - for (int i = 0; i < metadataVersionArraySize; i++) { - SimpleElementValue simpleElementValue = (SimpleElementValue) arrayElementValues[i]; - metadataVersion[i] = simpleElementValue.getValueInt(); - } - } - - private void parseBytecodeVersion(ElementValue elementValue) { - ArrayElementValue arrayElement = (ArrayElementValue) elementValue; - - int bytecodeVersionArraySize = arrayElement.getElementValuesArraySize(); - bytecodeVersion = new int[bytecodeVersionArraySize]; - - ElementValue[] arrayElementValues = arrayElement.getElementValuesArray(); - - for (int i = 0; i < bytecodeVersionArraySize; i++) { - SimpleElementValue simpleElementValue = (SimpleElementValue) arrayElementValues[i]; - bytecodeVersion[i] = simpleElementValue.getValueInt(); - } - } - - private void parseData1(ElementValue elementValue) { - ArrayElementValue arrayElement = (ArrayElementValue) elementValue; - - int data1ArraySize = arrayElement.getElementValuesArraySize(); - data1 = new String[data1ArraySize]; - - ElementValue[] arrayElementValues = arrayElement.getElementValuesArray(); - - for (int i = 0; i < data1ArraySize; i++) { - SimpleElementValue simpleElementValue = (SimpleElementValue) arrayElementValues[i]; - data1[i] = simpleElementValue.getValueString(); - } - } - - private void parseData2(ElementValue elementValue) { - ArrayElementValue arrayElement = (ArrayElementValue) elementValue; - - int data2ArraySize = arrayElement.getElementValuesArraySize(); - data2 = new String[data2ArraySize]; - - ElementValue[] arrayElementValues = arrayElement.getElementValuesArray(); - - for (int i = 0; i < data2ArraySize; i++) { - SimpleElementValue simpleElementValue = (SimpleElementValue) arrayElementValues[i]; - data2[i] = simpleElementValue.getValueString(); - } - } - - private void parseExtraString(ElementValue elementValue) { - SimpleElementValue simpleElementValue = (SimpleElementValue) elementValue; - extraString = simpleElementValue.getValueString(); - } - - private void parsePackageName(ElementValue elementValue) { - SimpleElementValue simpleElementValue = (SimpleElementValue) elementValue; - packageName = simpleElementValue.getValueString(); - } - - private void parseExtraInt(ElementValue elementValue) { - SimpleElementValue simpleElementValue = (SimpleElementValue) elementValue; - extraInt = simpleElementValue.getValueInt(); - } - - @Override - public Integer getKind() { - return kind; - } - - @Override - public int[] getMetadataVersion() { - return metadataVersion; - } - - @Override - public int[] getBytecodeVersion() { - return bytecodeVersion; - } - - @Override - public String[] getData1() { - return data1; - } - - @Override - public String[] getData2() { - return data2; - } - - @Override - public String getExtraString() { - return extraString; - } - - @Override - public String getPackageName() { - return packageName; - } - - @Override - public Integer getExtraInt() { - return extraInt; - } -} 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 deleted file mode 100644 index 975177083..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.telerik.metadata.bcl; - -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.generic.Type; - -public class MethodInfo implements MethodDescriptor { - - private final Method m; - private final ClassDescriptor classDescriptor; - - public MethodInfo(Method m, ClassDescriptor classDescriptor) { - this.m = m; - this.classDescriptor = classDescriptor; - } - - @Override - public boolean isPublic() { - return m.isPublic(); - } - - @Override - public boolean isProtected() { - return m.isProtected(); - } - - @Override - public boolean isSynthetic() { - return m.isSynthetic(); - } - - @Override - public boolean isStatic() { - return m.isStatic(); - } - - @Override - public boolean isAbstract() { - return m.isAbstract(); - } - - @Override - public ClassDescriptor getDeclaringClass() { - return classDescriptor; - } - - @Override - public String getName() { - return m.getName(); - } - - @Override - public String getSignature() { - return m.getSignature(); - } - - @Override - public TypeDescriptor[] getArgumentTypes() { - Type[] ts = m.getArgumentTypes(); - TypeDescriptor[] argTypes = new TypeDescriptor[ts.length]; - for (int i=0; i getKotlinClassMetadataAnnotation(); - - String[] getInterfaceNames(); - - String getPackageName(); - - String getClassName(); - - String getSuperclassName(); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/ExtensionFunctionDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/ExtensionFunctionDescriptor.java deleted file mode 100644 index d96a57c39..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/ExtensionFunctionDescriptor.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.telerik.metadata.desc; - -public interface ExtensionFunctionDescriptor extends MethodDescriptor { -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/FieldDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/FieldDescriptor.java deleted file mode 100644 index 94c00b4f4..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/FieldDescriptor.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.telerik.metadata.desc; - -public interface FieldDescriptor { - boolean isPublic(); - boolean isProtected(); - boolean isFinal(); - boolean isStatic(); - String getName(); - TypeDescriptor getType(); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/KotlinClassMetadataAnnotation.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/KotlinClassMetadataAnnotation.java deleted file mode 100644 index c4a8a44c7..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/KotlinClassMetadataAnnotation.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.telerik.metadata.desc; - -public interface KotlinClassMetadataAnnotation { - - Integer getKind(); // k - - int[] getMetadataVersion(); // mv - - int[] getBytecodeVersion(); // bv - - String[] getData1(); // d1 - - String[] getData2(); // d2 - - String getExtraString(); // xs - - String getPackageName(); // pn - - Integer getExtraInt(); // xi -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MetadataInfoAnnotationDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MetadataInfoAnnotationDescriptor.java deleted file mode 100644 index 5acbda4ba..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MetadataInfoAnnotationDescriptor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.telerik.metadata.desc; - -public interface MetadataInfoAnnotationDescriptor { - boolean skip(); - String getSuperClassname(); -} 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 deleted file mode 100644 index b4038a55f..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.telerik.metadata.desc; - -public interface MethodDescriptor { - boolean isPublic(); - boolean isProtected(); - boolean isSynthetic(); - boolean isStatic(); - boolean isAbstract(); - - ClassDescriptor getDeclaringClass(); - - String getName(); - String getSignature(); - - TypeDescriptor[] getArgumentTypes(); - TypeDescriptor getReturnType(); - - MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation(); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/PropertyDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/PropertyDescriptor.java deleted file mode 100644 index eccb001a1..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/PropertyDescriptor.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.telerik.metadata.desc; - -public interface PropertyDescriptor { - String getName(); - MethodDescriptor getGetterMethod(); - MethodDescriptor getSetterMethod(); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/TypeDescriptor.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/TypeDescriptor.java deleted file mode 100644 index 4957f77b5..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/desc/TypeDescriptor.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.telerik.metadata.desc; - -public interface TypeDescriptor { - String getSignature(); - - TypeDescriptor VOID = new PrimitiveType("V"); - TypeDescriptor CHAR = new PrimitiveType("C"); - TypeDescriptor BOOLEAN = new PrimitiveType("Z"); - TypeDescriptor BYTE = new PrimitiveType("B"); - TypeDescriptor SHORT = new PrimitiveType("S"); - TypeDescriptor INT = new PrimitiveType("I"); - TypeDescriptor LONG = new PrimitiveType("J"); - TypeDescriptor FLOAT = new PrimitiveType("F"); - TypeDescriptor DOUBLE = new PrimitiveType("D"); - - class PrimitiveType implements TypeDescriptor { - private final String signature; - - private PrimitiveType(String signature) { - this.signature = signature; - } - - @Override - public String getSignature() { - return signature; - } - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/ClassInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/ClassInfo.java deleted file mode 100644 index 6872948bb..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/ClassInfo.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.Annotation; -import com.android.dex.ClassData; -import com.android.dex.ClassDef; -import com.android.dex.Dex; -import com.android.dx.rop.code.AccessFlags; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.type.Type; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.FieldDescriptor; -import com.telerik.metadata.desc.KotlinClassMetadataAnnotation; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.PropertyDescriptor; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.classes.impl.KotlinClassMetadataParserImpl; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; - -import kotlinx.metadata.KmProperty; -import kotlinx.metadata.jvm.JvmExtensionsKt; -import kotlinx.metadata.jvm.JvmMethodSignature; - -public class ClassInfo implements ClassDescriptor { - private final DexFile dexFile; - private final ClassDef classDef; - - private final Comparator METHOD_NAME_COMPARATOR = new Comparator() { - @Override - public int compare(MethodDescriptor m1, MethodDescriptor m2) { - return m1.getName().compareTo(m2.getName()); - } - }; - - public ClassInfo(DexFile dexFile, ClassDef classDef) { - this.dexFile = dexFile; - this.classDef = classDef; - } - - @Override - public boolean isClass() { - return !isInterface() && !isEnum(); - } - - @Override - public boolean isInterface() { - return AccessFlags.isInterface(classDef.getAccessFlags()); - } - - @Override - public boolean isEnum() { - return AccessFlags.isEnum(classDef.getAccessFlags()); - } - - @Override - public boolean isStatic() { - return AccessFlags.isStatic(classDef.getAccessFlags()); - } - - @Override - public boolean isPublic() { - return AccessFlags.isPublic(classDef.getAccessFlags()); - } - - @Override - public boolean isProtected() { - return AccessFlags.isProtected(classDef.getAccessFlags()); - } - - @Override - public MethodDescriptor[] getMethods() { - MethodDescriptor[] methods; - Dex dex = dexFile.getDex(); - int off = classDef.getClassDataOffset(); - if (off != 0) { - ClassData data = dex.readClassData(classDef); - ClassData.Method[] allMethods = data.allMethods(); - methods = new MethodDescriptor[allMethods.length]; - for (int i = 0; i < allMethods.length; i++) { - methods[i] = new MethodInfo(dexFile, allMethods[i]); - } - } else { - methods = new MethodDescriptor[0]; - } - Arrays.sort(methods, METHOD_NAME_COMPARATOR); - - return methods; - } - - @Override - public PropertyDescriptor[] getProperties() { - List propertyDescriptors = new ArrayList(); - KotlinClassMetadataParser kotlinClassMetadataParser = new KotlinClassMetadataParserImpl(); - List kotlinProperties = kotlinClassMetadataParser.getKotlinProperties(this); - for (KmProperty kmProperty : kotlinProperties) { - String propertyName = kmProperty.getName(); - - MethodDescriptor getter = null; - JvmMethodSignature getterSignature = JvmExtensionsKt.getGetterSignature(kmProperty); - if (getterSignature != null) { - getter = getMethodDescriptorWithSignature(getterSignature.getName(), getterSignature.getDesc()); - } - - MethodDescriptor setter = null; - JvmMethodSignature setterSignature = JvmExtensionsKt.getSetterSignature(kmProperty); - if (setterSignature != null) { - setter = getMethodDescriptorWithSignature(setterSignature.getName(), setterSignature.getDesc()); - } - - propertyDescriptors.add(new PropertyInfo(propertyName, getter, setter)); - - } - - return propertyDescriptors.toArray(new PropertyDescriptor[0]); - - } - - private MethodDescriptor getMethodDescriptorWithSignature(String name, String signature) { - Optional method = Arrays - .stream(getMethods()) - .filter(m -> m.getName().equals(name) - && m.getSignature().equals(signature)) - .findFirst(); - - return method.orElse(null); - } - - @Override - public FieldDescriptor[] getFields() { - FieldDescriptor[] fields; - Dex dex = dexFile.getDex(); - int off = classDef.getClassDataOffset(); - if (off != 0) { - ClassData data = dex.readClassData(classDef); - ClassData.Field[] allFields = data.allFields(); - fields = new FieldDescriptor[allFields.length]; - for (int i = 0; i < fields.length; i++) { - fields[i] = new FieldInfo(dexFile, allFields[i]); - } - } else { - fields = new FieldDescriptor[0]; - } - - return fields; - } - - @Override - public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { - - Optional metadataInfoAnnotation = getJavaAnnotationWithName("Lcom/telerik/metadata/MetadataInfo;"); - if (metadataInfoAnnotation.isPresent()) { - return new MetadataInfoAnnotationInfo(dexFile, metadataInfoAnnotation.get()); - } - return null; - } - - private Optional getJavaAnnotationWithName(String name) { - int annotationsOffset = classDef.getAnnotationsOffset(); - if (annotationsOffset == 0) { - return Optional.empty(); - } - - Dex dex = dexFile.getDex(); - - int classDefIndex = dex.findClassDefIndexFromTypeIndex(classDef.getTypeIndex()); - int dexAnnotationDirectoryOffset = dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex); - if (dexAnnotationDirectoryOffset == 0) { - return Optional.empty(); - } - Dex.Section dirSection = dex.open(dexAnnotationDirectoryOffset); - int classSetOffset = dirSection.readInt(); - - int annotationSetOffset = classSetOffset; - - if (annotationSetOffset == 0) { - return Optional.empty(); - } - - Dex.Section annSetSection = dex.open(annotationSetOffset); - int size = annSetSection.readInt(); - for (int i = 0; i < size; i++) { - int annotationOffset = annSetSection.readInt(); - Dex.Section annSection = dex.open(annotationOffset); - Annotation annotation = annSection.readAnnotation(); - String annotationName = dex.strings().get(dex.typeIds().get(annotation.getTypeIndex())); - if (annotationName.equals(name)) { - return Optional.of(annotation); - } - } - - return Optional.empty(); - } - - @Override - public Optional getKotlinClassMetadataAnnotation() { - Optional kotlinMetadataAnnotation = getJavaAnnotationWithName("Lkotlin/Metadata;"); - if (kotlinMetadataAnnotation.isPresent()) { - KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation = new KotlinDexClassMetadataAnnotation(kotlinMetadataAnnotation.get(), dexFile); - return Optional.of(kotlinClassMetadataAnnotation); - } - return Optional.empty(); - } - - @Override - public String[] getInterfaceNames() { - ArrayList names = new ArrayList(); - short[] ifaceIndexes = classDef.getInterfaces(); - if ((ifaceIndexes != null) && (ifaceIndexes.length > 0)) { - List typeNames = dexFile.getDex().typeNames(); - for (short idx : ifaceIndexes) { - String interfaceName = typeNames.get(idx); - names.add(interfaceName); - } - } - return names.toArray(new String[names.size()]); - } - - @Override - public String getPackageName() { - String className = getClassName(); - String name = className.replace('.', '/'); - Type t = Type.internClassName(name); - CstType c = CstType.intern(t); - String packageName = c.getPackageName(); - return packageName; - } - - @Override - public String getClassName() { - List typeNames = dexFile.getDex().typeNames(); - int cdIdx = classDef.getTypeIndex(); - String typeName = typeNames.get(cdIdx); - String name = typeName.substring(1, typeName.length() - 1).replace('/', '.'); - return name; - } - - @Override - public String getSuperclassName() { - List typeNames = dexFile.getDex().typeNames(); - int idx = classDef.getSupertypeIndex(); - String superClassname = typeNames.get(idx); - String name = superClassname.substring(1, superClassname.length() - 1).replace('/', '.'); - return name; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/DexFile.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/DexFile.java deleted file mode 100644 index 6fdd7e11d..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/DexFile.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.ClassDef; -import com.android.dex.Dex; -import com.telerik.metadata.ClassMapProvider; -import com.telerik.metadata.desc.ClassDescriptor; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class DexFile implements ClassMapProvider { - private final Dex dex; - private final String path; - private final Map classMap; - private static final String CLASS_EXT = ".dex"; - - private DexFile(Dex dex, String path) { - this.dex = dex; - this.path = path; - this.classMap = new HashMap(); - } - - @Override - public Map getClassMap() { - return classMap; - } - - @Override - public String getPath() { - return path; - } - - public Dex getDex() { - return dex; - } - - public static DexFile readDex(String path) throws IOException { - Dex dex = new Dex(new File(path)); - DexFile dexFile = new DexFile(dex, path); - - List typeNames = dex.typeNames(); - - for (ClassDef classDef : dex.classDefs()) { - int cdIdx = classDef.getTypeIndex(); - String typeName = typeNames.get(cdIdx); - String name = typeName.substring(1, typeName.length()-1).replace('/', '.'); - dexFile.classMap.put(name, new ClassInfo(dexFile, classDef)); - } - - return dexFile; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/FieldInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/FieldInfo.java deleted file mode 100644 index 679b100a8..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/FieldInfo.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.ClassData; -import com.android.dex.Dex; -import com.android.dex.FieldId; -import com.android.dx.rop.code.AccessFlags; -import com.telerik.metadata.desc.FieldDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; - -import java.util.List; - -public class FieldInfo implements FieldDescriptor { - private final DexFile dexFile; - private final ClassData.Field field; - - public FieldInfo(DexFile dexFile, ClassData.Field field) { - this.dexFile = dexFile; - this.field = field; - } - - @Override - public boolean isPublic() { - return AccessFlags.isPublic(field.getAccessFlags()); - } - - @Override - public boolean isProtected() { - return AccessFlags.isProtected(field.getAccessFlags()); - } - - @Override - public boolean isFinal() { - boolean isFinal = (field.getAccessFlags() & AccessFlags.ACC_FINAL) == AccessFlags.ACC_FINAL; - return isFinal; - } - - @Override - public boolean isStatic() { - return AccessFlags.isStatic(field.getAccessFlags()); - } - - @Override - public String getName() { - Dex dex = dexFile.getDex(); - List strings = dex.strings(); - int idx = dex.nameIndexFromFieldIndex(field.getFieldIndex()); - String fieldName = strings.get(idx); - return fieldName; - } - - @Override - public TypeDescriptor getType() { - Dex dex = dexFile.getDex(); - List typeNames = dex.typeNames(); - FieldId fieldId = dex.fieldIds().get(field.getFieldIndex()); - int typeIdx = fieldId.getTypeIndex(); - String retTypeName = typeNames.get(typeIdx); - return new TypeInfo(retTypeName); - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/KotlinDexClassMetadataAnnotation.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/KotlinDexClassMetadataAnnotation.java deleted file mode 100644 index 4c3f57277..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/KotlinDexClassMetadataAnnotation.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.Annotation; -import com.android.dex.EncodedValueReader; -import com.telerik.metadata.desc.KotlinClassMetadataAnnotation; - -import java.util.List; - -public class KotlinDexClassMetadataAnnotation implements KotlinClassMetadataAnnotation { - - private Integer kind = null; - private int[] metadataVersion = null; - private int[] bytecodeVersion = null; - private String[] data1 = null; - private String[] data2 = null; - private String extraString = null; - private String packageName = null; - private Integer extraInt = null; - - KotlinDexClassMetadataAnnotation(Annotation annotation, DexFile dexFile) { - if (annotation != null) { - parseKotlinMetadataAnnotation(annotation, dexFile); - } - } - - private void parseKotlinMetadataAnnotation(Annotation annotation, DexFile dexFile) { - List strings = dexFile.getDex().strings(); - EncodedValueReader reader = annotation.getReader(); - int count = reader.readAnnotation(); - for (int i = 0; i < count; i++) { - String annotationFieldName = strings.get(reader.readAnnotationName()); - if (annotationFieldName.equals("k")) { - kind = reader.readInt(); - } else if (annotationFieldName.equals("mv")) { - metadataVersion = readIntArray(reader); - } else if (annotationFieldName.equals("bv")) { - bytecodeVersion = readIntArray(reader); - } else if (annotationFieldName.equals("d1")) { - data1 = readStringArray(reader, strings); - } else if (annotationFieldName.equals("d2")) { - data2 = readStringArray(reader, strings); - } else if (annotationFieldName.equals("xs")) { - extraString = strings.get(reader.readString()); - } else if (annotationFieldName.equals("pn")) { - packageName = strings.get(reader.readString()); - } else if (annotationFieldName.equals("xi")) { - extraInt = reader.readInt(); - } - } - } - - private int[] readIntArray(EncodedValueReader reader) { - int size = reader.readArray(); - int[] intArray = new int[size]; - - for (int i = 0; i < size; i++) { - intArray[i] = reader.readInt(); - } - - return intArray; - } - - private String[] readStringArray(EncodedValueReader reader, List strings) { - int size = reader.readArray(); - String[] stringArray = new String[size]; - - for (int a = 0; a < size; a++) { - stringArray[a] = strings.get(reader.readString()); - } - - return stringArray; - } - - @Override - public Integer getKind() { - return kind; - } - - @Override - public int[] getMetadataVersion() { - return metadataVersion; - } - - @Override - public int[] getBytecodeVersion() { - return bytecodeVersion; - } - - @Override - public String[] getData1() { - return data1; - } - - @Override - public String[] getData2() { - return data2; - } - - @Override - public String getExtraString() { - return extraString; - } - - @Override - public String getPackageName() { - return packageName; - } - - @Override - public Integer getExtraInt() { - return extraInt; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MetadataInfoAnnotationInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MetadataInfoAnnotationInfo.java deleted file mode 100644 index e5f0fd58b..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MetadataInfoAnnotationInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.Annotation; -import com.android.dex.EncodedValueReader; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; - -import java.util.List; - -public class MetadataInfoAnnotationInfo implements MetadataInfoAnnotationDescriptor { - private final DexFile dexFile; - private final Annotation annotation; - - public MetadataInfoAnnotationInfo(DexFile dexFile, Annotation annotation) { - this.dexFile = dexFile; - this.annotation = annotation; - } - - @Override - public boolean skip() { - List strings = dexFile.getDex().strings(); - EncodedValueReader reader = annotation.getReader(); - int count = reader.readAnnotation(); - for (int i = 0; i < count; i++) { - String annName = strings.get(reader.readAnnotationName()); - if (annName.equals("skip")) { - return reader.readBoolean(); - } - } - return false; - } - - @Override - public String getSuperClassname() { - List strings = dexFile.getDex().strings(); - EncodedValueReader reader = annotation.getReader(); - int count = reader.readAnnotation(); - for (int i = 0; i < count; i++) { - String annName = strings.get(reader.readAnnotationName()); - if (annName.equals("superClassname")) { - return strings.get(reader.readString()); - } - } - return null; - } -} 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 deleted file mode 100644 index 9815e7024..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.telerik.metadata.dx; - -import com.android.dex.Annotation; -import com.android.dex.ClassData; -import com.android.dex.ClassDef; -import com.android.dex.Dex; -import com.android.dex.MethodId; -import com.android.dex.ProtoId; -import com.android.dx.rop.code.AccessFlags; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; - -import java.util.List; - -public class MethodInfo implements MethodDescriptor { - private final DexFile dexFile; - private final ClassData.Method method; - - public MethodInfo(DexFile dexFile, ClassData.Method method) { - this.dexFile = dexFile; - this.method = method; - } - - @Override - public boolean isPublic() { - return AccessFlags.isPublic(method.getAccessFlags()); - } - - @Override - public boolean isProtected() { - return AccessFlags.isProtected(method.getAccessFlags()); - } - - @Override - public boolean isSynthetic() { - boolean isSynthetic = (method.getAccessFlags() & AccessFlags.ACC_SYNTHETIC) == AccessFlags.ACC_SYNTHETIC; - return isSynthetic; - } - - @Override - public boolean isStatic() { - return AccessFlags.isStatic(method.getAccessFlags()); - } - - @Override - public boolean isAbstract() { - return AccessFlags.isAbstract(method.getAccessFlags()); - } - - @Override - public ClassDescriptor getDeclaringClass() { - return null; - } - - @Override - public String getName() { - Dex dex = dexFile.getDex(); - List strings = dex.strings(); - int idx = dex.nameIndexFromMethodIndex(method.getMethodIndex()); - String methodName = strings.get(idx); - return methodName; - } - - @Override - public String getSignature() { - Dex dex = dexFile.getDex(); - List typeNames = dex.typeNames(); - MethodId methodId = dex.methodIds().get(method.getMethodIndex()); - ProtoId methodProtoId = dex.protoIds().get(methodId.getProtoIndex()); - short[] parameterTypes = dex.readTypeList(methodProtoId.getParametersOffset()).getTypes(); - StringBuilder signature = new StringBuilder("("); - for (short paramId: parameterTypes) { - signature.append(typeNames.get(paramId)); - } - signature.append(")").append(getReturnType().getSignature()); - return signature.toString(); - } - - @Override - public TypeDescriptor[] getArgumentTypes() { - Dex dex = dexFile.getDex(); - List typeNames = dex.typeNames(); - MethodId methodId = dex.methodIds().get(method.getMethodIndex()); - ProtoId methodProtoId = dex.protoIds().get(methodId.getProtoIndex()); - short[] parameterTypes = dex.readTypeList(methodProtoId.getParametersOffset()).getTypes(); - TypeDescriptor[] argTypes = new TypeDescriptor[parameterTypes.length]; - - for (int i=0; i typeNames = dex.typeNames(); - MethodId methodId = dex.methodIds().get(method.getMethodIndex()); - ProtoId methodProtoId = dex.protoIds().get(methodId.getProtoIndex()); - int retTypeIdx = methodProtoId.getReturnTypeIndex(); - String retTypeName = typeNames.get(retTypeIdx); - return new TypeInfo(retTypeName); - } - - @Override - public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() { - Dex dex = dexFile.getDex(); - - MethodId methodId = dex.methodIds().get(method.getMethodIndex()); - int cdIdx = methodId.getDeclaringClassIndex(); - - ClassDef classDef = null; - for (ClassDef currClassDef : dex.classDefs()) { - if (cdIdx == currClassDef.getTypeIndex()) { - classDef = currClassDef; - break; - } - } - - int classDefIndex = dex.findClassDefIndexFromTypeIndex(classDef.getTypeIndex()); - int directoryOffset = dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex); - if (directoryOffset == 0) { - return null; - } - Dex.Section directoryIn = dex.open(directoryOffset); - int classSetOffset = directoryIn.readInt(); - int fieldCount = directoryIn.readInt(); - int methodsCount = directoryIn.readInt(); - directoryIn.readInt(); - - for (int i = 0; i < fieldCount; i++) { - directoryIn.readInt(); - directoryIn.readInt(); - } - - int methodIdx = method.getMethodIndex(); - - int annotationSetOffset = 0; - for (int i = 0; i < methodsCount; i++) { - int candidateMethodIndex = directoryIn.readInt(); - int currAnnotationSetOffset = directoryIn.readInt(); - if (candidateMethodIndex == methodIdx) { - annotationSetOffset = currAnnotationSetOffset; - } - } - - if (annotationSetOffset == 0) { - return null; - } - - Dex.Section annSetSection = dex.open(annotationSetOffset); - int size = annSetSection.readInt(); - for (int i = 0; i < size; i++) { - int annotationOffset = annSetSection.readInt(); - Dex.Section annSection = dex.open(annotationOffset); - Annotation annotation = annSection.readAnnotation(); - String annotationName = dex.strings().get(dex.typeIds().get(annotation.getTypeIndex())); - if (annotationName.equals("Lcom/telerik/metadata/MetadataInfo;")) { - return new MetadataInfoAnnotationInfo(dexFile, annotation); - } - } - - 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/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/PropertyInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/PropertyInfo.java deleted file mode 100644 index 616d2bc26..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/PropertyInfo.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.telerik.metadata.dx; - -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.PropertyDescriptor; - -public class PropertyInfo implements PropertyDescriptor { - - private final String name; - private final MethodDescriptor getter; - private final MethodDescriptor setter; - - PropertyInfo(String name, MethodDescriptor getter, MethodDescriptor setter) { - this.name = name; - this.getter = getter; - this.setter = setter; - } - - @Override - public String getName() { - return name; - } - - @Override - public MethodDescriptor getGetterMethod() { - return getter; - } - - @Override - public MethodDescriptor getSetterMethod() { - return setter; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/TypeInfo.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/TypeInfo.java deleted file mode 100644 index 64bd0305a..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/dx/TypeInfo.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.telerik.metadata.dx; - -import com.telerik.metadata.desc.TypeDescriptor; - -public class TypeInfo implements TypeDescriptor { - private final String signature; - - public TypeInfo(String signature) { - this.signature = signature; - } - - @Override - public String getSignature() { - return signature; - } - - @Override - public int hashCode() { - return getSignature().hashCode(); - } - - @Override - public boolean equals(Object other) { - if ((other != null) && (other instanceof TypeDescriptor)) { - TypeDescriptor otherTypeDesc = (TypeDescriptor)other; - return this.getSignature().equals(otherTypeDesc.getSignature()); - } - return false; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/KotlinClassMetadataParser.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/KotlinClassMetadataParser.java deleted file mode 100644 index 858f478a4..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/KotlinClassMetadataParser.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.telerik.metadata.kotlin.classes; - -import com.telerik.metadata.desc.ClassDescriptor; - -import java.util.List; - -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.KmProperty; - -public interface KotlinClassMetadataParser { - boolean wasKotlinClass(ClassDescriptor clazz); - boolean wasKotlinCompanionObject(ClassDescriptor clazz, ClassDescriptor possibleCompanion); - List getKotlinProperties(ClassDescriptor clazz); - List getKotlinExtensionFunctions(ClassDescriptor clazz); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/impl/KotlinClassMetadataParserImpl.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/impl/KotlinClassMetadataParserImpl.java deleted file mode 100644 index 8e296d556..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/classes/impl/KotlinClassMetadataParserImpl.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.telerik.metadata.kotlin.classes.impl; - -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.KotlinClassMetadataAnnotation; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Modifier; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import kotlinx.metadata.Flag; -import kotlinx.metadata.KmClass; -import kotlinx.metadata.KmExtensionType; -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.KmFunctionExtensionVisitor; -import kotlinx.metadata.KmFunctionVisitor; -import kotlinx.metadata.KmPackage; -import kotlinx.metadata.KmProperty; -import kotlinx.metadata.jvm.KotlinClassHeader; -import kotlinx.metadata.jvm.KotlinClassMetadata; - -public class KotlinClassMetadataParserImpl implements KotlinClassMetadataParser { - - @Override - public boolean wasKotlinClass(ClassDescriptor clazz) { - return clazz.getKotlinClassMetadataAnnotation().isPresent(); - } - - @Override - public boolean wasKotlinCompanionObject(ClassDescriptor clazz, ClassDescriptor possibleCompanion) { - Optional kotlinClassMetadataAnnotationOptional = clazz.getKotlinClassMetadataAnnotation(); - if (!kotlinClassMetadataAnnotationOptional.isPresent()) { - return false; - } - - KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get(); - KotlinClassMetadata kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation); - - if (kotlinClassMetadata instanceof KotlinClassMetadata.Class) { - KotlinClassMetadata.Class regularKotlinClassMetadata = (KotlinClassMetadata.Class) kotlinClassMetadata; - KmClass kmClass = regularKotlinClassMetadata.toKmClass(); - String companion = kmClass.getCompanionObject(); - String fullCompanionName = clazz.getClassName() + "$" + companion; - return possibleCompanion.getClassName().equals(fullCompanionName); - } - - return false; - } - - private KotlinClassMetadata buildKotlinClassMetadata(KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation) { - KotlinClassHeader kotlinClassHeader = new KotlinClassHeader( - kotlinClassMetadataAnnotation.getKind(), - kotlinClassMetadataAnnotation.getMetadataVersion(), - kotlinClassMetadataAnnotation.getBytecodeVersion(), - kotlinClassMetadataAnnotation.getData1(), - kotlinClassMetadataAnnotation.getData2(), - kotlinClassMetadataAnnotation.getExtraString(), - kotlinClassMetadataAnnotation.getPackageName(), - kotlinClassMetadataAnnotation.getExtraInt()); - - return KotlinClassMetadata.read(kotlinClassHeader); - } - - @Override - public List getKotlinProperties(ClassDescriptor clazz) { - Optional kotlinClassMetadataAnnotationOptional = clazz.getKotlinClassMetadataAnnotation(); - if (!kotlinClassMetadataAnnotationOptional.isPresent()) { - return Collections.emptyList(); - } - - KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get(); - KotlinClassMetadata kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation); - - if (kotlinClassMetadata instanceof KotlinClassMetadata.Class) { - KotlinClassMetadata.Class regularKotlinClassMetadata = (KotlinClassMetadata.Class) kotlinClassMetadata; - KmClass kmClass = regularKotlinClassMetadata.toKmClass(); - return kmClass.getProperties() - .stream() - .filter(p -> (Modifier.isPublic(p.getGetterFlags()) || Modifier.isProtected(p.getGetterFlags())) - && (Modifier.isPublic(p.getSetterFlags()) || Modifier.isProtected(p.getSetterFlags())) - && !p.getName().startsWith("is")) - .collect(Collectors.toList()); - } - - return Collections.emptyList(); - } - - @Override - public List getKotlinExtensionFunctions(ClassDescriptor clazz) { - Optional kotlinClassMetadataAnnotationOptional = clazz.getKotlinClassMetadataAnnotation(); - if (!kotlinClassMetadataAnnotationOptional.isPresent()) { - return Collections.emptyList(); - } - - KotlinClassMetadataAnnotation kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get(); - KotlinClassMetadata kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation); - - if (kotlinClassMetadata instanceof KotlinClassMetadata.Class) { - KotlinClassMetadata.Class regularKotlinClassMetadata = (KotlinClassMetadata.Class) kotlinClassMetadata; - KmClass kmClass = regularKotlinClassMetadata.toKmClass(); - - return kmClass.getFunctions() - .stream() - .filter(KotlinClassMetadataParserImpl::isVisibleExtensionFunction) - .collect(Collectors.toList()); - } else if (kotlinClassMetadata instanceof KotlinClassMetadata.FileFacade) { - KotlinClassMetadata.FileFacade fileFacadeMetadata = (KotlinClassMetadata.FileFacade) kotlinClassMetadata; - KmPackage kmClass = fileFacadeMetadata.toKmPackage(); - - return kmClass.getFunctions() - .stream() - .filter(KotlinClassMetadataParserImpl::isVisibleExtensionFunction) - .collect(Collectors.toList()); - } - - return Collections.emptyList(); - } - - class KotlinClassVisitor extends KmFunctionVisitor{ - @Nullable - @Override - public KmFunctionExtensionVisitor visitExtensions(@NotNull KmExtensionType type) { - return super.visitExtensions(type); - } - } - - private static boolean isVisibleExtensionFunction(KmFunction function) { - return function.getReceiverParameterType() != null; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ClassNameAndExtensionFunctionPair.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ClassNameAndExtensionFunctionPair.java deleted file mode 100644 index 2b50b97c6..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ClassNameAndExtensionFunctionPair.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.telerik.metadata.kotlin.functions; - -import com.telerik.metadata.desc.ExtensionFunctionDescriptor; - -public final class ClassNameAndExtensionFunctionPair { - private final String className; - private final ExtensionFunctionDescriptor extensionFunction; - - public ClassNameAndExtensionFunctionPair(String className, ExtensionFunctionDescriptor extensionFunction) { - this.className = className; - this.extensionFunction = extensionFunction; - } - - public String getClassName() { - return className; - } - - public ExtensionFunctionDescriptor getExtensionFunction() { - return extensionFunction; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsCollector.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsCollector.java deleted file mode 100644 index 4332ddc06..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsCollector.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.telerik.metadata.kotlin.functions; - -import com.telerik.metadata.desc.ClassDescriptor; -import java.util.Collection; - -public interface ExtensionFunctionsCollector { - Collection collectExtensionFunctions(ClassDescriptor classDescriptor); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsStorage.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsStorage.java deleted file mode 100644 index 25f8dc5f2..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/ExtensionFunctionsStorage.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.telerik.metadata.kotlin.functions; - -import com.telerik.metadata.desc.ExtensionFunctionDescriptor; - -import java.util.Collection; - -public interface ExtensionFunctionsStorage { - void storeExtensionFunctions(Collection extensionFunctions); - - Collection retrieveExtensionFunctions(String className); -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsCollectorImpl.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsCollectorImpl.java deleted file mode 100644 index 2474c6a21..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsCollectorImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.telerik.metadata.kotlin.functions.impl; - -import com.telerik.metadata.ClassUtil; -import com.telerik.metadata.bcl.ExtensionFunctionInfo; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; -import com.telerik.metadata.desc.TypeDescriptor; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.functions.ClassNameAndExtensionFunctionPair; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsCollector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.jvm.JvmExtensionsKt; -import kotlinx.metadata.jvm.JvmMethodSignature; - -public class ExtensionFunctionsCollectorImpl implements ExtensionFunctionsCollector { - - private final KotlinClassMetadataParser kotlinClassMetadataParser; - - public ExtensionFunctionsCollectorImpl(KotlinClassMetadataParser kotlinClassMetadataParser) { - this.kotlinClassMetadataParser = kotlinClassMetadataParser; - } - - @Override - public Collection collectExtensionFunctions(ClassDescriptor classDescriptor) { - Collection extensionFunctionsDescriptors = new ArrayList<>(); - - List extensionFunctions = kotlinClassMetadataParser.getKotlinExtensionFunctions(classDescriptor); - - for (KmFunction extensionFunction : extensionFunctions) { - JvmMethodSignature signature = JvmExtensionsKt.getSignature(extensionFunction); - - String functionName = signature.getName(); - String functionSignature = signature.getDesc(); - - MethodDescriptor extensionFunctionDescriptor = Arrays - .stream(classDescriptor.getMethods()) - .filter(x -> x.getName().equals(functionName) && x.getSignature().equals(functionSignature)) - .findFirst() - .get(); - - if (extensionFunctionDescriptor.isStatic()) { - TypeDescriptor receiverType = extensionFunctionDescriptor.getArgumentTypes()[0]; // kotlin extension functions' first argument is the receiver type - String receiverClassName = ClassUtil.getCanonicalName(receiverType.getSignature()); - extensionFunctionsDescriptors.add(new ClassNameAndExtensionFunctionPair(receiverClassName, new ExtensionFunctionInfo(extensionFunctionDescriptor))); - } - } - - return extensionFunctionsDescriptors; - } -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsStorageImpl.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsStorageImpl.java deleted file mode 100644 index b2f09a64d..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/kotlin/functions/impl/ExtensionFunctionsStorageImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.telerik.metadata.kotlin.functions.impl; - -import com.telerik.metadata.desc.ExtensionFunctionDescriptor; -import com.telerik.metadata.kotlin.functions.ClassNameAndExtensionFunctionPair; -import com.telerik.metadata.kotlin.functions.ExtensionFunctionsStorage; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class ExtensionFunctionsStorageImpl implements ExtensionFunctionsStorage { - - private static final ExtensionFunctionsStorageImpl ourInstance = new ExtensionFunctionsStorageImpl(); - - public static ExtensionFunctionsStorage getInstance() { - return ourInstance; - } - - private final Map> extensionFunctions; - - private ExtensionFunctionsStorageImpl() { - this.extensionFunctions = new HashMap<>(); - } - - @Override - public void storeExtensionFunctions(Collection extensionFunctions) { - Map> classConcreteExtensionFunctions = extensionFunctions - .stream() - .collect(Collectors - .groupingBy(ClassNameAndExtensionFunctionPair::getClassName, - Collectors.mapping(ClassNameAndExtensionFunctionPair::getExtensionFunction, - Collectors.toList()))); - - for (Map.Entry> classConcreteExtensionFunction : classConcreteExtensionFunctions.entrySet()) { - String className = classConcreteExtensionFunction.getKey(); - - if (this.extensionFunctions.containsKey(className)) { - Collection existingExtensionFunctions = this.extensionFunctions.get(className); - existingExtensionFunctions.addAll(classConcreteExtensionFunction.getValue()); - } else { - this.extensionFunctions.put(className, classConcreteExtensionFunction.getValue()); - } - } - } - - @Override - public Collection retrieveExtensionFunctions(String className) { - Collection classConcreteExtensionFunctions = extensionFunctions.get(className); - - if (classConcreteExtensionFunctions != null) { - return classConcreteExtensionFunctions; - } - - return Collections.emptyList(); - } - -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCache.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCache.java deleted file mode 100644 index f8223c83f..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCache.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.telerik.metadata.nodes.cache; - -import com.telerik.metadata.TreeNode; - -public interface NodesCache { - - public void addNode(String className, TreeNode node); - - public TreeNode getNode(String className); - -} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCacheImpl.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCacheImpl.java deleted file mode 100644 index 2f30b5e8b..000000000 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/nodes/cache/NodesCacheImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.telerik.metadata.nodes.cache; - -import com.telerik.metadata.TreeNode; - -import java.util.HashMap; -import java.util.Map; - -public class NodesCacheImpl implements NodesCache { - private static final NodesCacheImpl ourInstance = new NodesCacheImpl(); - - private final Map nodesCache; - - public static NodesCache getInstance() { - return ourInstance; - } - - private NodesCacheImpl() { - this.nodesCache = new HashMap<>(); - } - - public void addNode(String className, TreeNode node) { - nodesCache.put(className, node); - } - - public TreeNode getNode(String className) { - return nodesCache.get(className); - } -} 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 index 044b8bc08..7bc857e27 100644 --- 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 @@ -1,46 +1,46 @@ package com.telerik.metadata.parsing; import com.telerik.metadata.ClassRepo; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.desc.MethodDescriptor; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor; import java.util.HashSet; import java.util.Set; public final class ClassParser { - private final ClassDescriptor clazz; + private final NativeClassDescriptor clazz; - private ClassParser(ClassDescriptor clazz) { + private ClassParser(NativeClassDescriptor clazz) { this.clazz = clazz; } - public static ClassParser forClassDescriptor(ClassDescriptor clazz) { + public static ClassParser forClassDescriptor(NativeClassDescriptor clazz) { return new ClassParser(clazz); } - public Set getAllDefaultMethodsFromImplementedInterfaces() { - return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); + public Set getAllDefaultMethodsFromImplementedInterfaces() { + return getAllDefaultMethodsFromImplementedInterfacesRecursively(clazz, new HashSet()); } - private HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(ClassDescriptor clazz, HashSet collectedDefaultMethods) { + private HashSet getAllDefaultMethodsFromImplementedInterfacesRecursively(NativeClassDescriptor clazz, HashSet collectedDefaultMethods) { String[] implementedInterfacesNames = clazz.getInterfaceNames(); for (String implementedInterfaceName : implementedInterfacesNames) { - ClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); + NativeClassDescriptor interfaceClass = ClassRepo.findClass(implementedInterfaceName); if (interfaceClass == null) { System.out.println(String.format("WARNING: Skipping interface %s implemented in %s as it cannot be resolved", implementedInterfaceName, clazz.getClassName())); continue; } - for (MethodDescriptor md : interfaceClass.getMethods()) { + for (NativeMethodDescriptor md : interfaceClass.getMethods()) { if (!md.isStatic() && !md.isAbstract()) { collectedDefaultMethods.add(md); } } - collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); + collectedDefaultMethods.addAll(getAllDefaultMethodsFromImplementedInterfacesRecursively(interfaceClass, new HashSet())); } return collectedDefaultMethods; diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/MetadataInfoAnnotationDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/MetadataInfoAnnotationDescriptor.kt new file mode 100644 index 000000000..d794eed44 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/MetadataInfoAnnotationDescriptor.kt @@ -0,0 +1,6 @@ +package com.telerik.metadata.parsing.classes + +interface MetadataInfoAnnotationDescriptor { + val superClassname: String + fun skip(): Boolean +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeClassDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeClassDescriptor.kt new file mode 100644 index 000000000..d3260614c --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeClassDescriptor.kt @@ -0,0 +1,41 @@ +package com.telerik.metadata.parsing.classes + +import com.telerik.metadata.parsing.classes.kotlin.metadata.MetadataAnnotation +import com.telerik.metadata.parsing.classes.kotlin.properties.KotlinPropertyDescriptor + +import java.util.Optional + +/** + * Describes the properties of a native class + */ +interface NativeClassDescriptor { + val isClass: Boolean + + val isInterface: Boolean + + val isEnum: Boolean + + val isStatic: Boolean + + val isPublic: Boolean + + val isProtected: Boolean + + val methods: Array + + val properties: Array + + val fields: Array + + val metadataInfoAnnotation: MetadataInfoAnnotationDescriptor? + + val kotlinClassMetadataAnnotation: Optional + + val interfaceNames: Array + + val packageName: String + + val className: String + + val superclassName: String +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeFieldDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeFieldDescriptor.kt new file mode 100644 index 000000000..3ddc343ef --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeFieldDescriptor.kt @@ -0,0 +1,13 @@ +package com.telerik.metadata.parsing.classes + +/** + * Describes the properties of a native field + */ +interface NativeFieldDescriptor { + val isPublic: Boolean + val isProtected: Boolean + val isFinal: Boolean + val isStatic: Boolean + val name: String + val type: NativeTypeDescriptor +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeMethodDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeMethodDescriptor.kt new file mode 100644 index 000000000..7c27ca5c4 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeMethodDescriptor.kt @@ -0,0 +1,22 @@ +package com.telerik.metadata.parsing.classes + +/** + * Describes the properties of a native method + */ +interface NativeMethodDescriptor { + val isPublic: Boolean + val isProtected: Boolean + val isSynthetic: Boolean + val isStatic: Boolean + val isAbstract: Boolean + + val declaringClass: NativeClassDescriptor + + val name: String + val signature: String + + val argumentTypes: Array + val returnType: NativeTypeDescriptor + + val metadataInfoAnnotation: MetadataInfoAnnotationDescriptor? +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeTypeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeTypeDescriptor.kt new file mode 100644 index 000000000..269925122 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/NativeTypeDescriptor.kt @@ -0,0 +1,22 @@ +package com.telerik.metadata.parsing.classes + +/** + * Describes the signature of a native type + */ +interface NativeTypeDescriptor { + val signature: String + + class PrimitiveType constructor(override val signature: String) : NativeTypeDescriptor + + companion object { + val VOID: NativeTypeDescriptor = PrimitiveType("V") + val CHAR: NativeTypeDescriptor = PrimitiveType("C") + val BOOLEAN: NativeTypeDescriptor = PrimitiveType("Z") + val BYTE: NativeTypeDescriptor = PrimitiveType("B") + val SHORT: NativeTypeDescriptor = PrimitiveType("S") + val INT: NativeTypeDescriptor = PrimitiveType("I") + val LONG: NativeTypeDescriptor = PrimitiveType("J") + val FLOAT: NativeTypeDescriptor = PrimitiveType("F") + val DOUBLE: NativeTypeDescriptor = PrimitiveType("D") + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/JarFile.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/JarFile.java similarity index 74% rename from test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/JarFile.java rename to test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/JarFile.java index fff1d8c1a..0504d67e3 100644 --- a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/bcl/JarFile.java +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/JarFile.java @@ -1,11 +1,11 @@ -package com.telerik.metadata.bcl; +package com.telerik.metadata.parsing.classes.bytecode; import com.telerik.metadata.ClassMapProvider; import com.telerik.metadata.analytics.AnalyticsCollector; import com.telerik.metadata.analytics.AnalyticsCollectorProvider; -import com.telerik.metadata.desc.ClassDescriptor; -import com.telerik.metadata.kotlin.classes.KotlinClassMetadataParser; -import com.telerik.metadata.kotlin.classes.impl.KotlinClassMetadataParserImpl; +import com.telerik.metadata.parsing.classes.NativeClassDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.metadata.ClassMetadataParser; +import com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode.BytecodeClassMetadataParser; import org.apache.bcel.classfile.ClassFormatException; import org.apache.bcel.classfile.ClassParser; @@ -19,8 +19,8 @@ public class JarFile implements ClassMapProvider { private final String path; - private final Map classMap; - private static final KotlinClassMetadataParser kotlinClassMetadataParser = new KotlinClassMetadataParserImpl(); + private final Map classMap; + private static final ClassMetadataParser kotlinClassMetadataParser = new BytecodeClassMetadataParser(); private static final AnalyticsCollector analyticsCollector = AnalyticsCollectorProvider.getInstance().provideAnalyticsCollector(); private static final String CLASS_EXT = ".class"; @@ -33,7 +33,7 @@ public String getPath() { return path; } - public Map getClassMap() { + public Map getClassMap() { return classMap; } @@ -54,7 +54,7 @@ public static JarFile readJar(String path) throws ClassFormatException, .substring(0, name.length() - CLASS_EXT.length()) .replace('/', '.'); ClassParser cp = new ClassParser(jis, name); - ClassDescriptor clazz = new ClassInfo(cp.parse()); + NativeClassDescriptor clazz = new NativeClassBytecodeDescriptor(cp.parse()); markIfKotlinClass(clazz); jar.classMap.put(name, clazz); } @@ -67,7 +67,7 @@ public static JarFile readJar(String path) throws ClassFormatException, return jar; } - private static void markIfKotlinClass(ClassDescriptor classDescriptor) { + private static void markIfKotlinClass(NativeClassDescriptor classDescriptor) { if (kotlinClassMetadataParser.wasKotlinClass(classDescriptor)) { analyticsCollector.markHasKotlinRuntimeClassesIfNotMarkedAlready(); } diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeClassBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeClassBytecodeDescriptor.kt new file mode 100644 index 000000000..b26f289cd --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeClassBytecodeDescriptor.kt @@ -0,0 +1,165 @@ +package com.telerik.metadata.parsing.classes.bytecode + +import com.telerik.metadata.ClassUtil +import com.telerik.metadata.parsing.classes.MetadataInfoAnnotationDescriptor +import com.telerik.metadata.parsing.classes.NativeClassDescriptor +import com.telerik.metadata.parsing.classes.NativeFieldDescriptor +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor +import com.telerik.metadata.parsing.classes.kotlin.metadata.MetadataAnnotation +import com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode.BytecodeClassMetadataParser +import com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode.BytecodeMetadataAnnotation +import com.telerik.metadata.parsing.classes.kotlin.properties.KotlinPropertyDescriptor +import com.telerik.metadata.parsing.classes.kotlin.properties.bytecode.KotlinPropertyBytecodeDescriptor +import kotlinx.metadata.jvm.getterSignature +import kotlinx.metadata.jvm.setterSignature +import org.apache.bcel.classfile.ConstantClass +import org.apache.bcel.classfile.ConstantUtf8 +import org.apache.bcel.classfile.InnerClasses +import org.apache.bcel.classfile.JavaClass +import java.util.* + +class NativeClassBytecodeDescriptor(private val clazz: JavaClass) : NativeClassDescriptor { + + override val isClass = clazz.isClass + + override val isInterface = clazz.isInterface + + override val isEnum = clazz.isEnum + + override val isStatic = clazz.isStatic + + override val isPublic = clazz.isPublic + + override val isProtected = clazz.isProtected + + override val methods: Array + get() { + val ms = clazz.methods + return Array(ms.size) { + NativeMethodBytecodeDescriptor(ms[it], this) + } + } + + override val properties: Array + get() { + val propertyDescriptors = ArrayList() + val kotlinClassMetadataParser = BytecodeClassMetadataParser() + val kotlinProperties = kotlinClassMetadataParser.getKotlinProperties(this) + for (kmProperty in kotlinProperties) { + val propertyName = kmProperty.name + + var getter: NativeMethodDescriptor? = null + val getterSignature = kmProperty.getterSignature + if (getterSignature != null) { + getter = getMethodDescriptorWithSignature(getterSignature.name, getterSignature.desc) + } + + var setter: NativeMethodDescriptor? = null + val setterSignature = kmProperty.setterSignature + if (setterSignature != null) { + setter = getMethodDescriptorWithSignature(setterSignature.name, setterSignature.desc) + } + + propertyDescriptors.add(KotlinPropertyBytecodeDescriptor(propertyName, getter, setter)) + + } + + return propertyDescriptors.toTypedArray() + } + + override val fields: Array + get() { + val fs = clazz.fields + return Array(fs.size) { + NativeFieldBytecodeDescriptor(fs[it]) + } + } + + override val metadataInfoAnnotation: MetadataInfoAnnotationDescriptor? = null + + override val kotlinClassMetadataAnnotation: Optional + get() { + val annotationEntries = clazz.annotationEntries + if (annotationEntries != null) { + for (annotationEntry in annotationEntries) { + val annotationType = annotationEntry.annotationType + if ("Lkotlin/Metadata;" == annotationType) { + val kotlinClassMetadataAnnotation = BytecodeMetadataAnnotation(annotationEntry) + return Optional.of(kotlinClassMetadataAnnotation) + } + } + } + + return Optional.empty() + } + + override val interfaceNames: Array = clazz.interfaceNames + + override val packageName: String = clazz.packageName + + override val className: String = clazz.className + + override val superclassName: String = clazz.superclassName + + init { + init() + } + + private fun init() { + if (clazz.className.contains("$")) { + val name = ClassUtil.getSimpleName(this) + var isAnonymousClass: Boolean + try { + Integer.parseInt(name) + isAnonymousClass = true + } catch (e: Exception) { + isAnonymousClass = false + } + + if (isAnonymousClass) { + return + } + var found = false + val fullClassName = getClassName(clazz.classNameIndex) ?: return + + for (a in clazz.attributes) { + if (a is InnerClasses) { + val i = a.innerClasses + for (ic in i) { + val innerClassName = getClassName(ic.innerClassIndex) + + if (fullClassName == innerClassName) { + val flags = ic.innerAccessFlags + clazz.accessFlags = flags + found = true + break + } + } + } + if (found) { + break + } + } + } + } + + private fun getClassName(classIndex: Int): String? { + val constantPool = clazz.constantPool + val innerClassNameIndex = constantPool.getConstant(classIndex) as ConstantClass + val className = constantPool.getConstant(innerClassNameIndex.nameIndex) as ConstantUtf8 + return className.bytes + } + + private fun getMethodDescriptorWithSignature(name: String, signature: String): NativeMethodDescriptor? { + for (method in clazz.methods) { + val methodSignature = method.signature + val methodName = method.name + + if (methodSignature == signature && methodName == name) { + return NativeMethodBytecodeDescriptor(method, this) + } + } + + return null + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeFieldBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeFieldBytecodeDescriptor.kt new file mode 100644 index 000000000..2b18c66c9 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeFieldBytecodeDescriptor.kt @@ -0,0 +1,21 @@ +package com.telerik.metadata.parsing.classes.bytecode + +import com.telerik.metadata.parsing.classes.NativeFieldDescriptor +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor + +import org.apache.bcel.classfile.Field + +class NativeFieldBytecodeDescriptor(f: Field) : NativeFieldDescriptor { + + override val isPublic = f.isPublic + + override val isProtected = f.isProtected + + override val isFinal = f.isFinal + + override val isStatic = f.isStatic + + override val name: String = f.name + + override val type = NativeTypeBytecodeDescriptor(f.type) +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeMethodBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeMethodBytecodeDescriptor.kt new file mode 100644 index 000000000..6ffb1b6c4 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeMethodBytecodeDescriptor.kt @@ -0,0 +1,47 @@ +package com.telerik.metadata.parsing.classes.bytecode + +import com.telerik.metadata.parsing.classes.MetadataInfoAnnotationDescriptor +import com.telerik.metadata.parsing.classes.NativeClassDescriptor +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor +import org.apache.bcel.classfile.Method + +class NativeMethodBytecodeDescriptor(private val m: Method, override val declaringClass: NativeClassDescriptor) : NativeMethodDescriptor { + + override val isPublic = m.isPublic + + override val isProtected = m.isProtected + + override val isSynthetic = m.isSynthetic + + override val isStatic = m.isStatic + + override val isAbstract = m.isAbstract + + override val name: String = m.name + + override val signature: String = m.signature + + override val argumentTypes: Array + get() { + val ts = m.argumentTypes + return Array(ts.size) { + NativeTypeBytecodeDescriptor(ts[it]) + } + } + + override val returnType = NativeTypeBytecodeDescriptor(m.returnType) + + override val metadataInfoAnnotation: MetadataInfoAnnotationDescriptor? = null + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + + return other is NativeMethodBytecodeDescriptor && m == other.m + } + + override fun hashCode(): Int { + return m.hashCode() + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeTypeBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeTypeBytecodeDescriptor.kt new file mode 100644 index 000000000..40e77297f --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/bytecode/NativeTypeBytecodeDescriptor.kt @@ -0,0 +1,14 @@ +package com.telerik.metadata.parsing.classes.bytecode + +import com.telerik.metadata.parsing.classes.NativeTypeDescriptor + +import org.apache.bcel.generic.Type + +class NativeTypeBytecodeDescriptor(t: Type) : NativeTypeDescriptor { + + override val signature: String = t.signature + + override fun hashCode() = signature.hashCode() + + override fun equals(other: Any?) = other is NativeTypeDescriptor && this.signature == other.signature +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ClassNameAndFunctionPair.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ClassNameAndFunctionPair.kt new file mode 100644 index 000000000..15024cae3 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ClassNameAndFunctionPair.kt @@ -0,0 +1,5 @@ +package com.telerik.metadata.parsing.classes.kotlin.extensions + +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor + +class ClassNameAndFunctionPair(val className: String, val function: T) diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ExtensionFunctionsCollector.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ExtensionFunctionsCollector.kt new file mode 100644 index 000000000..30bf74381 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/ExtensionFunctionsCollector.kt @@ -0,0 +1,16 @@ +package com.telerik.metadata.parsing.classes.kotlin.extensions + +import com.telerik.metadata.parsing.classes.NativeClassDescriptor + +/** + * Handles collection of Kotlin extension functions + */ +interface ExtensionFunctionsCollector { + /** + * Collects Kotlin extension functions for a given native class descriptor + * + * @param classDescriptor class descriptor to use + * @return collection of pairs consisting of class name and extension function + */ + fun collectExtensionFunctions(classDescriptor: NativeClassDescriptor): Collection> +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/KotlinExtensionFunctionDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/KotlinExtensionFunctionDescriptor.kt new file mode 100644 index 000000000..5782b89f6 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/KotlinExtensionFunctionDescriptor.kt @@ -0,0 +1,8 @@ +package com.telerik.metadata.parsing.classes.kotlin.extensions + +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor + +/** + * Describes the properties of a Kotlin extension function + */ +interface KotlinExtensionFunctionDescriptor : NativeMethodDescriptor diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/BytecodeExtensionFunctionsCollector.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/BytecodeExtensionFunctionsCollector.kt new file mode 100644 index 000000000..5f53bf933 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/BytecodeExtensionFunctionsCollector.kt @@ -0,0 +1,43 @@ +package com.telerik.metadata.parsing.classes.kotlin.extensions.bytecode + +import com.telerik.metadata.ClassUtil +import com.telerik.metadata.parsing.classes.NativeClassDescriptor +import com.telerik.metadata.parsing.classes.kotlin.extensions.ClassNameAndFunctionPair +import com.telerik.metadata.parsing.classes.kotlin.extensions.KotlinExtensionFunctionDescriptor +import com.telerik.metadata.parsing.classes.kotlin.extensions.ExtensionFunctionsCollector +import com.telerik.metadata.parsing.classes.kotlin.metadata.ClassMetadataParser +import kotlinx.metadata.jvm.signature +import java.util.* + +class BytecodeExtensionFunctionsCollector(private val kotlinClassMetadataParser: ClassMetadataParser) : ExtensionFunctionsCollector { + + override fun collectExtensionFunctions(classDescriptor: NativeClassDescriptor): Collection> { + val extensionFunctionsDescriptors = ArrayList>() + + val extensionFunctions = kotlinClassMetadataParser.getKotlinExtensionFunctions(classDescriptor) + + for (extensionFunction in extensionFunctions) { + val signature = extensionFunction.signature + + if (signature != null) { + val functionName = signature.name + val functionSignature = signature.desc + + val extensionFunctionDescriptor = Arrays + .stream(classDescriptor.methods) + .filter { x -> x.name == functionName && x.signature == functionSignature } + .findFirst() + .get() + + if (extensionFunctionDescriptor.isStatic) { + val receiverType = extensionFunctionDescriptor.argumentTypes[0] // kotlin extension functions' first argument is the receiver type + val receiverClassName = ClassUtil.getCanonicalName(receiverType.signature) + val classNameAndFunctionPair: ClassNameAndFunctionPair = ClassNameAndFunctionPair(receiverClassName, KotlinExtensionFunctionBytecodeDescriptor(extensionFunctionDescriptor)) + extensionFunctionsDescriptors.add(classNameAndFunctionPair) + } + } + } + + return extensionFunctionsDescriptors + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/KotlinExtensionFunctionBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/KotlinExtensionFunctionBytecodeDescriptor.kt new file mode 100644 index 000000000..af3fafcb0 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/extensions/bytecode/KotlinExtensionFunctionBytecodeDescriptor.kt @@ -0,0 +1,43 @@ +package com.telerik.metadata.parsing.classes.kotlin.extensions.bytecode + +import com.telerik.metadata.parsing.classes.MetadataInfoAnnotationDescriptor +import com.telerik.metadata.parsing.classes.kotlin.extensions.KotlinExtensionFunctionDescriptor +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor + +class KotlinExtensionFunctionBytecodeDescriptor(private val m: NativeMethodDescriptor) : KotlinExtensionFunctionDescriptor { + + override val isPublic = m.isPublic + + override val isProtected = m.isProtected + + override val isSynthetic = m.isSynthetic + + override val isStatic = m.isStatic + + override val isAbstract = m.isAbstract + + override val declaringClass = m.declaringClass + + override val name = m.name + + override val signature = m.signature + + override val argumentTypes = m.argumentTypes + + override val returnType = m.returnType + + override val metadataInfoAnnotation: MetadataInfoAnnotationDescriptor? = null + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + + val that = other as KotlinExtensionFunctionBytecodeDescriptor? + + return m == that!!.m + } + + override fun hashCode(): Int { + return m.hashCode() + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/ClassMetadataParser.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/ClassMetadataParser.kt new file mode 100644 index 000000000..b8a6ecba9 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/ClassMetadataParser.kt @@ -0,0 +1,13 @@ +package com.telerik.metadata.parsing.classes.kotlin.metadata + +import com.telerik.metadata.parsing.classes.NativeClassDescriptor + +import kotlinx.metadata.KmFunction +import kotlinx.metadata.KmProperty + +interface ClassMetadataParser { + fun wasKotlinClass(clazz: NativeClassDescriptor): Boolean + fun wasKotlinCompanionObject(clazz: NativeClassDescriptor, possibleCompanion: NativeClassDescriptor): Boolean + fun getKotlinProperties(clazz: NativeClassDescriptor): List + fun getKotlinExtensionFunctions(clazz: NativeClassDescriptor): List +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/MetadataAnnotation.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/MetadataAnnotation.kt new file mode 100644 index 000000000..c2eff1e8a --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/MetadataAnnotation.kt @@ -0,0 +1,20 @@ +package com.telerik.metadata.parsing.classes.kotlin.metadata + +interface MetadataAnnotation { + + val kind: Int // k + + val metadataVersion: IntArray // mv + + val bytecodeVersion: IntArray // bv + + val data1: Array // d1 + + val data2: Array // d2 + + val extraString: String // xs + + val packageName: String // pn + + val extraInt: Int // xi +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeClassMetadataParser.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeClassMetadataParser.kt new file mode 100644 index 000000000..f3aa31666 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeClassMetadataParser.kt @@ -0,0 +1,107 @@ +package com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode + +import com.telerik.metadata.parsing.classes.NativeClassDescriptor +import com.telerik.metadata.parsing.classes.kotlin.metadata.ClassMetadataParser +import com.telerik.metadata.parsing.classes.kotlin.metadata.MetadataAnnotation +import kotlinx.metadata.KmFunction +import kotlinx.metadata.KmProperty +import kotlinx.metadata.jvm.KotlinClassHeader +import kotlinx.metadata.jvm.KotlinClassMetadata +import java.lang.reflect.Modifier +import java.util.stream.Collectors + +class BytecodeClassMetadataParser : ClassMetadataParser { + + override fun wasKotlinClass(clazz: NativeClassDescriptor): Boolean { + return clazz.kotlinClassMetadataAnnotation.isPresent + } + + override fun wasKotlinCompanionObject(clazz: NativeClassDescriptor, possibleCompanion: NativeClassDescriptor): Boolean { + val kotlinClassMetadataAnnotationOptional = clazz.kotlinClassMetadataAnnotation + if (!kotlinClassMetadataAnnotationOptional.isPresent) { + return false + } + + val kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get() + val kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation) + + if (kotlinClassMetadata is KotlinClassMetadata.Class) { + val kmClass = kotlinClassMetadata.toKmClass() + val companion = kmClass.companionObject + val fullCompanionName = clazz.className + "$" + companion + return possibleCompanion.className == fullCompanionName + } + + return false + } + + private fun buildKotlinClassMetadata(kotlinClassMetadataAnnotation: MetadataAnnotation): KotlinClassMetadata? { + val kotlinClassHeader = KotlinClassHeader( + kotlinClassMetadataAnnotation.kind, + kotlinClassMetadataAnnotation.metadataVersion, + kotlinClassMetadataAnnotation.bytecodeVersion, + kotlinClassMetadataAnnotation.data1, + kotlinClassMetadataAnnotation.data2, + kotlinClassMetadataAnnotation.extraString, + kotlinClassMetadataAnnotation.packageName, + kotlinClassMetadataAnnotation.extraInt) + + return KotlinClassMetadata.read(kotlinClassHeader) + } + + override fun getKotlinProperties(clazz: NativeClassDescriptor): List { + val kotlinClassMetadataAnnotationOptional = clazz.kotlinClassMetadataAnnotation + if (!kotlinClassMetadataAnnotationOptional.isPresent) { + return emptyList() + } + + val kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get() + val kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation) + + if (kotlinClassMetadata is KotlinClassMetadata.Class) { + val kmClass = kotlinClassMetadata.toKmClass() + return kmClass.properties + .stream() + .filter { p -> + ((Modifier.isPublic(p.getterFlags) || Modifier.isProtected(p.getterFlags)) + && (Modifier.isPublic(p.setterFlags) || Modifier.isProtected(p.setterFlags)) + && !p.name.startsWith("is")) + } + .collect(Collectors.toList()) + } + + return emptyList() + } + + override fun getKotlinExtensionFunctions(clazz: NativeClassDescriptor): List { + val kotlinClassMetadataAnnotationOptional = clazz.kotlinClassMetadataAnnotation + if (!kotlinClassMetadataAnnotationOptional.isPresent) { + return emptyList() + } + + val kotlinClassMetadataAnnotation = kotlinClassMetadataAnnotationOptional.get() + val kotlinClassMetadata = buildKotlinClassMetadata(kotlinClassMetadataAnnotation) + + if (kotlinClassMetadata is KotlinClassMetadata.Class) { + val kmClass = kotlinClassMetadata.toKmClass() + + return kmClass.functions + .stream() + .filter { isVisibleExtensionFunction(it) } + .collect(Collectors.toList()) + } else if (kotlinClassMetadata is KotlinClassMetadata.FileFacade) { + val kmClass = kotlinClassMetadata.toKmPackage() + + return kmClass.functions + .stream() + .filter { isVisibleExtensionFunction(it) } + .collect(Collectors.toList()) + } + + return emptyList() + } + + private fun isVisibleExtensionFunction(function: KmFunction): Boolean { + return function.receiverParameterType != null + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeMetadataAnnotation.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeMetadataAnnotation.kt new file mode 100644 index 000000000..b00828b84 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/metadata/bytecode/BytecodeMetadataAnnotation.kt @@ -0,0 +1,146 @@ +package com.telerik.metadata.parsing.classes.kotlin.metadata.bytecode + +import com.telerik.metadata.parsing.classes.kotlin.metadata.MetadataAnnotation +import org.apache.bcel.classfile.AnnotationEntry +import org.apache.bcel.classfile.ArrayElementValue +import org.apache.bcel.classfile.ElementValue +import org.apache.bcel.classfile.SimpleElementValue + +class BytecodeMetadataAnnotation(annotationEntry: AnnotationEntry?) : MetadataAnnotation { + + override var kind: Int = 1 // 1 comes from the source of the kotlin.Metadata + private set(value) { + field = value + } + + override var metadataVersion: IntArray = intArrayOf() + private set(value) { + field = value + } + + override var bytecodeVersion: IntArray = intArrayOf() + private set(value) { + field = value + } + + override var data1: Array = emptyArray() + private set(value) { + field = value + } + + override var data2: Array = emptyArray() + private set(value) { + field = value + } + + override var extraString: String = "" + private set(value) { + field = value + } + + override var packageName: String = "" + private set(value) { + field = value + } + + override var extraInt: Int = 0 // 0 comes from the source of the kotlin.Metadata + private set(value) { + field = value + } + + init { + if (annotationEntry != null) { + parseKotlinMetadataAnnotation(annotationEntry) + } + } + + private fun parseKotlinMetadataAnnotation(annotationEntry: AnnotationEntry) { + val elementValuePairs = annotationEntry.elementValuePairs + if (elementValuePairs != null) { + for (elementValuePair in annotationEntry.elementValuePairs) { + + val elementName = elementValuePair.nameString + val elementValue = elementValuePair.value + + when (elementName) { + "k" -> parseKind(elementValue) + "mv" -> parseMetadataVersion(elementValue) + "bv" -> parseBytecodeVersion(elementValue) + "d1" -> parseData1(elementValue) + "d2" -> parseData2(elementValue) + "xs" -> parseExtraString(elementValue) + "pn" -> parsePackageName(elementValue) + "xi" -> parseExtraInt(elementValue) + } + } + } + } + + private fun parseKind(elementValue: ElementValue) { + val simpleElementValue = elementValue as SimpleElementValue + kind = simpleElementValue.valueInt + } + + private fun parseMetadataVersion(elementValue: ElementValue) { + val arrayElement = elementValue as ArrayElementValue + + val metadataVersionArraySize = arrayElement.elementValuesArraySize + val arrayElementValues = arrayElement.elementValuesArray + + metadataVersion = IntArray(metadataVersionArraySize) { + val simpleElementValue = arrayElementValues[it] as SimpleElementValue + simpleElementValue.valueInt + } + } + + private fun parseBytecodeVersion(elementValue: ElementValue) { + val arrayElement = elementValue as ArrayElementValue + + val bytecodeVersionArraySize = arrayElement.elementValuesArraySize + val arrayElementValues = arrayElement.elementValuesArray + + bytecodeVersion = IntArray(bytecodeVersionArraySize) { + val simpleElementValue = arrayElementValues[it] as SimpleElementValue + simpleElementValue.valueInt + } + } + + private fun parseData1(elementValue: ElementValue) { + val arrayElement = elementValue as ArrayElementValue + + val data1ArraySize = arrayElement.elementValuesArraySize + val arrayElementValues = arrayElement.elementValuesArray + + data1 = Array(data1ArraySize) { + val simpleElementValue = arrayElementValues[it] as SimpleElementValue + simpleElementValue.valueString + } + } + + private fun parseData2(elementValue: ElementValue) { + val arrayElement = elementValue as ArrayElementValue + + val data2ArraySize = arrayElement.elementValuesArraySize + val arrayElementValues = arrayElement.elementValuesArray + + data2 = Array(data2ArraySize) { i -> + val simpleElementValue = arrayElementValues[i] as SimpleElementValue + simpleElementValue.valueString + } + } + + private fun parseExtraString(elementValue: ElementValue) { + val simpleElementValue = elementValue as SimpleElementValue + extraString = simpleElementValue.valueString + } + + private fun parsePackageName(elementValue: ElementValue) { + val simpleElementValue = elementValue as SimpleElementValue + packageName = simpleElementValue.valueString + } + + private fun parseExtraInt(elementValue: ElementValue) { + val simpleElementValue = elementValue as SimpleElementValue + extraInt = simpleElementValue.valueInt + } +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/KotlinPropertyDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/KotlinPropertyDescriptor.kt new file mode 100644 index 000000000..307375c84 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/KotlinPropertyDescriptor.kt @@ -0,0 +1,12 @@ +package com.telerik.metadata.parsing.classes.kotlin.properties + +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor + +/** + * Describes the properties of a Kotlin property + */ +interface KotlinPropertyDescriptor { + val name: String + val getterMethod: NativeMethodDescriptor? + val setterMethod: NativeMethodDescriptor? +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/bytecode/KotlinPropertyBytecodeDescriptor.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/bytecode/KotlinPropertyBytecodeDescriptor.kt new file mode 100644 index 000000000..d11e00dad --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/parsing/classes/kotlin/properties/bytecode/KotlinPropertyBytecodeDescriptor.kt @@ -0,0 +1,8 @@ +package com.telerik.metadata.parsing.classes.kotlin.properties.bytecode + +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor +import com.telerik.metadata.parsing.classes.kotlin.properties.KotlinPropertyDescriptor + +class KotlinPropertyBytecodeDescriptor(override val name: String, + override val getterMethod: NativeMethodDescriptor?, + override val setterMethod: NativeMethodDescriptor?) : KotlinPropertyDescriptor diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/FunctionsStorage.kt b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/FunctionsStorage.kt new file mode 100644 index 000000000..eac8a9d69 --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/FunctionsStorage.kt @@ -0,0 +1,9 @@ +package com.telerik.metadata.storage.functions + +import com.telerik.metadata.parsing.classes.NativeMethodDescriptor +import com.telerik.metadata.parsing.classes.kotlin.extensions.ClassNameAndFunctionPair + +interface FunctionsStorage { + fun storeFunctions(extensionFunctions: Collection>) + fun retrieveFunctions(className: String): Collection +} diff --git a/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/extensions/ExtensionFunctionsStorage.java b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/extensions/ExtensionFunctionsStorage.java new file mode 100644 index 000000000..0e3b59b2a --- /dev/null +++ b/test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/storage/functions/extensions/ExtensionFunctionsStorage.java @@ -0,0 +1,63 @@ +package com.telerik.metadata.storage.functions.extensions; + +import com.telerik.metadata.parsing.classes.kotlin.extensions.KotlinExtensionFunctionDescriptor; +import com.telerik.metadata.parsing.classes.kotlin.extensions.ClassNameAndFunctionPair; +import com.telerik.metadata.storage.functions.FunctionsStorage; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ExtensionFunctionsStorage implements FunctionsStorage { + + private static final ExtensionFunctionsStorage ourInstance = new ExtensionFunctionsStorage(); + + public static FunctionsStorage getInstance() { + return ourInstance; + } + + private final Map> extensionFunctions; + + private ExtensionFunctionsStorage() { + this.extensionFunctions = new HashMap<>(); + } + + @Override + public void storeFunctions(Collection> extensionFunctions) { + Map> classConcreteExtensionFunctions = extensionFunctions + .stream() + .collect(Collectors + .groupingBy(ClassNameAndFunctionPair::getClassName, + Collectors.mapping(ClassNameAndFunctionPair::getFunction, + Collectors.toList()))); + + for (Map.Entry> classConcreteExtensionFunction : classConcreteExtensionFunctions.entrySet()) { + String className = classConcreteExtensionFunction.getKey(); + + if (this.extensionFunctions.containsKey(className)) { + Collection existingExtensionFunctions = this.extensionFunctions.get(className); + existingExtensionFunctions.addAll(classConcreteExtensionFunction.getValue()); + } else { + this.extensionFunctions.put(className, classConcreteExtensionFunction.getValue()); + } + } + } + + @NotNull + @Override + public Collection retrieveFunctions(@NotNull String className) { + Collection classConcreteExtensionFunctions = extensionFunctions.get(className); + + if (classConcreteExtensionFunctions != null) { + return classConcreteExtensionFunctions; + } + + return Collections.emptyList(); + } + +}