Skip to content

Commit 94bc92d

Browse files
author
Mihail Slavchev
authored
Merge pull request #642 from NativeScript/slavchev/fix-bundlebase
workaround for issue #628
2 parents dabb834 + 1d3bbbd commit 94bc92d

File tree

18 files changed

+371
-37
lines changed

18 files changed

+371
-37
lines changed

android-metadata-generator/src/src/com/telerik/metadata/Builder.java

+39-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.telerik.metadata.TreeNode.FieldInfo;
1212
import com.telerik.metadata.TreeNode.MethodInfo;
1313
import com.telerik.metadata.bcl.JarFile;
14+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
1415
import com.telerik.metadata.desc.ClassDescriptor;
1516
import com.telerik.metadata.desc.FieldDescriptor;
1617
import com.telerik.metadata.desc.MethodDescriptor;
@@ -94,12 +95,24 @@ private static void generate(ClassDescriptor clazz, TreeNode root) throws Except
9495
if (!isClassPublic(clazz)) {
9596
return;
9697
}
97-
TreeNode node = getOrCreateNode(root, clazz);
9898

99-
setNodeMembers(clazz, node, root);
99+
MetadataInfoAnnotationDescriptor metadataInfo = clazz.getMetadataInfoAnnotation();
100+
boolean hasClassMetadataInfo = metadataInfo != null;
101+
String predefinedSuperClassname = null;
102+
if (hasClassMetadataInfo) {
103+
if (metadataInfo.skip()) {
104+
return;
105+
} else {
106+
predefinedSuperClassname = metadataInfo.getSuperClassname();
107+
}
108+
}
109+
110+
TreeNode node = getOrCreateNode(root, clazz, predefinedSuperClassname);
111+
112+
setNodeMembers(clazz, node, root, hasClassMetadataInfo);
100113
}
101114

102-
private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNode root) throws Exception {
115+
private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNode root, boolean hasClassMetadataInfo) throws Exception {
103116
Map<String, MethodInfo> existingMethods = new HashMap<String, MethodInfo>();
104117
for (MethodInfo mi : node.instanceMethods) {
105118
existingMethods.put(mi.name + mi.sig, mi);
@@ -114,6 +127,13 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod
114127
if (m.isSynthetic())
115128
continue;
116129

130+
if (hasClassMetadataInfo && !m.getName().equals("<init>")) {
131+
MetadataInfoAnnotationDescriptor metadataInfo = m.getMetadataInfoAnnotation();
132+
if ((metadataInfo != null) && metadataInfo.skip()) {
133+
continue;
134+
}
135+
}
136+
117137
if (m.isPublic() || m.isProtected()) {
118138
boolean isStatic = m.isStatic();
119139

@@ -139,7 +159,7 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod
139159

140160
if (mi.signature != null) {
141161
if (isStatic) {
142-
mi.declaringType = getOrCreateNode(root, clazz);
162+
mi.declaringType = getOrCreateNode(root, clazz, null);
143163
node.staticMethods.add(mi);
144164
} else {
145165
String sig = m.getName() + m.getSignature();
@@ -174,10 +194,10 @@ private static void setFieldInfo(ClassDescriptor clazz, TreeNode node, TreeNode
174194
if (f.isStatic()) {
175195
if(interfaceClass != null) {
176196
// changes declaring type of static fields from implementing class to interface
177-
fi.declaringType = getOrCreateNode(root, interfaceClass);
197+
fi.declaringType = getOrCreateNode(root, interfaceClass, null);
178198
}
179199
else {
180-
fi.declaringType = getOrCreateNode(root, clazz);
200+
fi.declaringType = getOrCreateNode(root, clazz, null);
181201
}
182202
node.staticFields.add(fi);
183203
} else {
@@ -224,13 +244,13 @@ private static TreeNode getOrCreateNode(TreeNode root, TypeDescriptor type)
224244
} else {
225245
String name = ClassUtil.getCanonicalName(type.getSignature());
226246
ClassDescriptor clazz = ClassRepo.findClass(name);
227-
node = getOrCreateNode(root, clazz);
247+
node = getOrCreateNode(root, clazz, null);
228248
}
229249

230250
return node;
231251
}
232252

233-
private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz) throws Exception {
253+
private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, String predefinedSuperClassname) throws Exception {
234254
if (ClassUtil.isPrimitive(clazz)) {
235255
return TreeNode.getPrimitive(clazz);
236256
}
@@ -297,11 +317,16 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz) th
297317
}
298318
node = child;
299319
if (node.baseClassNode == null) {
300-
ClassDescriptor baseClass = clazz.isInterface() ? ClassUtil
301-
.getClassByName("java.lang.Object") : ClassUtil
302-
.getSuperclass(clazz);
320+
ClassDescriptor baseClass = null;
321+
if (predefinedSuperClassname != null) {
322+
baseClass = ClassUtil.getClassByName(predefinedSuperClassname);
323+
} else {
324+
baseClass = clazz.isInterface()
325+
? ClassUtil.getClassByName("java.lang.Object")
326+
: ClassUtil.getSuperclass(clazz);
327+
}
303328
if (baseClass != null) {
304-
node.baseClassNode = getOrCreateNode(root, baseClass);
329+
node.baseClassNode = getOrCreateNode(root, baseClass, null);
305330
copyBasePublicApi(baseClass, node, root);
306331
}
307332
}
@@ -312,7 +337,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz) th
312337
private static void copyBasePublicApi(ClassDescriptor baseClass, TreeNode node,
313338
TreeNode root) throws Exception {
314339
while ((baseClass != null) && !baseClass.isPublic()) {
315-
setNodeMembers(baseClass, node, root);
340+
setNodeMembers(baseClass, node, root, false);
316341
baseClass = ClassUtil.getSuperclass(baseClass);
317342
}
318343
}
@@ -349,7 +374,7 @@ private static TreeNode createArrayNode(TreeNode root, String className)
349374
if (clazz.isStatic()) {
350375
child.nodeType |= TreeNode.Static;
351376
}
352-
child.arrayElement = getOrCreateNode(root, clazz);
377+
child.arrayElement = getOrCreateNode(root, clazz, null);
353378
}
354379
}
355380

android-metadata-generator/src/src/com/telerik/metadata/bcl/ClassInfo.java

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.telerik.metadata.bcl;
22

33
import com.telerik.metadata.ClassUtil;
4+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
45
import com.telerik.metadata.desc.ClassDescriptor;
56
import com.telerik.metadata.desc.FieldDescriptor;
67
import com.telerik.metadata.desc.MethodDescriptor;
@@ -111,6 +112,11 @@ public FieldDescriptor[] getFields() {
111112
return fields;
112113
}
113114

115+
@Override
116+
public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() {
117+
return null;
118+
}
119+
114120
@Override
115121
public String[] getInterfaceNames() {
116122
return clazz.getInterfaceNames();

android-metadata-generator/src/src/com/telerik/metadata/bcl/MethodInfo.java

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.telerik.metadata.bcl;
22

3+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
34
import com.telerik.metadata.desc.MethodDescriptor;
45
import com.telerik.metadata.desc.TypeDescriptor;
56
import org.apache.bcel.classfile.Method;
@@ -56,4 +57,9 @@ public TypeDescriptor[] getArgumentTypes() {
5657
public TypeDescriptor getReturnType() {
5758
return new TypeInfo(m.getReturnType());
5859
}
60+
61+
@Override
62+
public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() {
63+
return null;
64+
}
5965
}

android-metadata-generator/src/src/com/telerik/metadata/desc/ClassDescriptor.java

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public interface ClassDescriptor {
1313

1414
FieldDescriptor[] getFields();
1515

16+
MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation();
17+
1618
String[] getInterfaceNames();
1719

1820
String getPackageName();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.telerik.metadata.desc;
2+
3+
public interface MetadataInfoAnnotationDescriptor {
4+
boolean skip();
5+
String getSuperClassname();
6+
}

android-metadata-generator/src/src/com/telerik/metadata/desc/MethodDescriptor.java

+2
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ public interface MethodDescriptor {
1111

1212
TypeDescriptor[] getArgumentTypes();
1313
TypeDescriptor getReturnType();
14+
15+
MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation();
1416
}

android-metadata-generator/src/src/com/telerik/metadata/dx/ClassInfo.java

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.telerik.metadata.dx;
22

3+
import com.android.dex.Annotation;
34
import com.android.dex.ClassData;
45
import com.android.dex.ClassDef;
56
import com.android.dex.Dex;
6-
import com.android.dex.MethodId;
7-
import com.android.dex.ProtoId;
87
import com.android.dx.rop.code.AccessFlags;
98
import com.android.dx.rop.cst.CstType;
109
import com.android.dx.rop.type.Type;
10+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
1111
import com.telerik.metadata.desc.ClassDescriptor;
1212
import com.telerik.metadata.desc.FieldDescriptor;
1313
import com.telerik.metadata.desc.MethodDescriptor;
@@ -102,6 +102,43 @@ public FieldDescriptor[] getFields() {
102102
return fields;
103103
}
104104

105+
@Override
106+
public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() {
107+
int annotationsOffset = classDef.getAnnotationsOffset();
108+
if (annotationsOffset == 0) {
109+
return null;
110+
}
111+
112+
Dex dex = dexFile.getDex();
113+
114+
int classDefIndex = dex.findClassDefIndexFromTypeIndex(classDef.getTypeIndex());
115+
int dexAnnotationDirectoryOffset = dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex);
116+
if (dexAnnotationDirectoryOffset == 0) {
117+
return null;
118+
}
119+
Dex.Section dirSection = dex.open(dexAnnotationDirectoryOffset);
120+
int classSetOffset = dirSection.readInt();
121+
122+
int annotationSetOffset = classSetOffset;
123+
124+
if (annotationSetOffset == 0) {
125+
return null;
126+
}
127+
128+
Dex.Section annSetSection = dex.open(annotationSetOffset);
129+
int size = annSetSection.readInt();
130+
for (int i = 0; i < size; i++) {
131+
int annotationOffset = annSetSection.readInt();
132+
Dex.Section annSection = dex.open(annotationOffset);
133+
Annotation annotation = annSection.readAnnotation();
134+
String annotationName = dex.strings().get(dex.typeIds().get(annotation.getTypeIndex()));
135+
if (annotationName.equals("Lcom/telerik/metadata/MetadataInfo;")) {
136+
return new MetadataInfoAnnotationInfo(dexFile, annotation);
137+
}
138+
}
139+
return null;
140+
}
141+
105142
@Override
106143
public String[] getInterfaceNames() {
107144
ArrayList<String> names = new ArrayList<String>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.telerik.metadata.dx;
2+
3+
import com.android.dex.Annotation;
4+
import com.android.dex.EncodedValueReader;
5+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
6+
7+
import java.util.List;
8+
9+
public class MetadataInfoAnnotationInfo implements MetadataInfoAnnotationDescriptor {
10+
private final DexFile dexFile;
11+
private final Annotation annotation;
12+
13+
public MetadataInfoAnnotationInfo(DexFile dexFile, Annotation annotation) {
14+
this.dexFile = dexFile;
15+
this.annotation = annotation;
16+
}
17+
18+
@Override
19+
public boolean skip() {
20+
List<String> strings = dexFile.getDex().strings();
21+
EncodedValueReader reader = annotation.getReader();
22+
int count = reader.readAnnotation();
23+
for (int i=0; i<count; i++) {
24+
String annName = strings.get(reader.readAnnotationName());
25+
if (annName.equals("skip")) {
26+
return reader.readBoolean();
27+
}
28+
}
29+
return false;
30+
}
31+
32+
@Override
33+
public String getSuperClassname() {
34+
List<String> strings = dexFile.getDex().strings();
35+
EncodedValueReader reader = annotation.getReader();
36+
int count = reader.readAnnotation();
37+
for (int i=0; i<count; i++) {
38+
String annName = strings.get(reader.readAnnotationName());
39+
if (annName.equals("superClassname")) {
40+
return strings.get(reader.readString());
41+
}
42+
}
43+
return null;
44+
}
45+
}

android-metadata-generator/src/src/com/telerik/metadata/dx/MethodInfo.java

+64
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.telerik.metadata.dx;
22

3+
import com.android.dex.Annotation;
34
import com.android.dex.ClassData;
5+
import com.android.dex.ClassDef;
46
import com.android.dex.Dex;
57
import com.android.dex.MethodId;
68
import com.android.dex.ProtoId;
79
import com.android.dx.rop.code.AccessFlags;
10+
import com.telerik.metadata.desc.MetadataInfoAnnotationDescriptor;
811
import com.telerik.metadata.desc.MethodDescriptor;
912
import com.telerik.metadata.desc.TypeDescriptor;
1013

@@ -92,4 +95,65 @@ public TypeDescriptor getReturnType() {
9295
String retTypeName = typeNames.get(retTypeIdx);
9396
return new TypeInfo(retTypeName);
9497
}
98+
99+
@Override
100+
public MetadataInfoAnnotationDescriptor getMetadataInfoAnnotation() {
101+
Dex dex = dexFile.getDex();
102+
103+
MethodId methodId = dex.methodIds().get(method.getMethodIndex());
104+
int cdIdx = methodId.getDeclaringClassIndex();
105+
106+
ClassDef classDef = null;
107+
for (ClassDef currClassDef : dex.classDefs()) {
108+
if (cdIdx == currClassDef.getTypeIndex()) {
109+
classDef = currClassDef;
110+
break;
111+
}
112+
}
113+
114+
int classDefIndex = dex.findClassDefIndexFromTypeIndex(classDef.getTypeIndex());
115+
int directoryOffset = dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex);
116+
if (directoryOffset == 0) {
117+
return null;
118+
}
119+
Dex.Section directoryIn = dex.open(directoryOffset);
120+
int classSetOffset = directoryIn.readInt();
121+
int fieldCount = directoryIn.readInt();
122+
int methodsCount = directoryIn.readInt();
123+
directoryIn.readInt();
124+
125+
for (int i = 0; i < fieldCount; i++) {
126+
directoryIn.readInt();
127+
directoryIn.readInt();
128+
}
129+
130+
int methodIdx = method.getMethodIndex();
131+
132+
int annotationSetOffset = 0;
133+
for (int i = 0; i < methodsCount; i++) {
134+
int candidateMethodIndex = directoryIn.readInt();
135+
int currAnnotationSetOffset = directoryIn.readInt();
136+
if (candidateMethodIndex == methodIdx) {
137+
annotationSetOffset = currAnnotationSetOffset;
138+
}
139+
}
140+
141+
if (annotationSetOffset == 0) {
142+
return null;
143+
}
144+
145+
Dex.Section annSetSection = dex.open(annotationSetOffset);
146+
int size = annSetSection.readInt();
147+
for (int i = 0; i < size; i++) {
148+
int annotationOffset = annSetSection.readInt();
149+
Dex.Section annSection = dex.open(annotationOffset);
150+
Annotation annotation = annSection.readAnnotation();
151+
String annotationName = dex.strings().get(dex.typeIds().get(annotation.getTypeIndex()));
152+
if (annotationName.equals("Lcom/telerik/metadata/MetadataInfo;")) {
153+
return new MetadataInfoAnnotationInfo(dexFile, annotation);
154+
}
155+
}
156+
157+
return null;
158+
}
95159
}

0 commit comments

Comments
 (0)