Skip to content

Commit c2d02b4

Browse files
committed
(sbg): don't include abstract super class's methods to avoid compilation issues when identical signatures are used
1 parent 935da6c commit c2d02b4

File tree

5 files changed

+84
-31
lines changed

5 files changed

+84
-31
lines changed

android-static-binding-generator/project/staticbindinggenerator/src/main/java/org/nativescript/staticbindinggenerator/Generator.java

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -191,37 +191,47 @@ private String getNormalizedName(String filename) {
191191
private Map<String, List<Method>> getPublicApi(JavaClass clazz) {
192192
Map<String, List<Method>> api = new HashMap<String, List<Method>>();
193193
JavaClass currentClass = clazz;
194+
String clazzName = clazz.getClassName();
194195
while (true) {
195196
String currentClassname = currentClass.getClassName();
196-
List<Method> methods = new ArrayList<Method>();
197-
for (Method m : currentClass.getMethods()) {
198-
methods.add(m);
199-
}
200197

201-
// System.out.println("SBG: getPublicApi:collectInterfaceMethods classname: " + currentClassname);
198+
boolean shouldCollectMethods = !(!clazzName.equals(currentClassname) && currentClass.isAbstract());
199+
200+
if (shouldCollectMethods || currentClass.isInterface()) {
201+
// Don't include abstract parent class's methods to avoid compilation issues
202+
// where a child class has 2 methods, of the same type, with just a
203+
// return type/parameter type that differs by being of a superclass of the class being extended.
204+
// see Test testCanCompileBindingClassExtendingAnExtendedClassWithMethodsWithTheSameSignature
205+
List<Method> methods = new ArrayList<Method>();
206+
for (Method m : currentClass.getMethods()) {
207+
methods.add(m);
208+
}
209+
210+
// System.out.println("SBG: getPublicApi:collectInterfaceMethods classname: " + currentClassname);
202211

203-
collectInterfaceMethods(clazz, methods);
204-
for (Method m : methods) {
205-
if (!m.isSynthetic() && (m.isPublic() || m.isProtected()) && !m.isStatic()) {
206-
String name = m.getName();
212+
collectInterfaceMethods(clazz, methods);
213+
for (Method m : methods) {
214+
if (!m.isSynthetic() && (m.isPublic() || m.isProtected()) && !m.isStatic()) {
215+
String name = m.getName();
207216

208-
List<Method> methodGroup;
209-
if (api.containsKey(name)) {
210-
methodGroup = api.get(name);
211-
} else {
212-
methodGroup = new ArrayList<Method>();
213-
api.put(name, methodGroup);
214-
}
215-
boolean found = false;
216-
String methodSig = m.getSignature();
217-
for (Method m1 : methodGroup) {
218-
found = methodSig.equals(m1.getSignature());
219-
if (found) {
220-
break;
217+
List<Method> methodGroup;
218+
if (api.containsKey(name)) {
219+
methodGroup = api.get(name);
220+
} else {
221+
methodGroup = new ArrayList<Method>();
222+
api.put(name, methodGroup);
223+
}
224+
boolean found = false;
225+
String methodSig = m.getSignature();
226+
for (Method m1 : methodGroup) {
227+
found = methodSig.equals(m1.getSignature());
228+
if (found) {
229+
break;
230+
}
231+
}
232+
if (!found) {
233+
methodGroup.add(m);
221234
}
222-
}
223-
if (!found) {
224-
methodGroup.add(m);
225235
}
226236
}
227237
}
@@ -650,12 +660,6 @@ private void collectInterfaceMethods(JavaClass clazz, List<Method> methods) {
650660
JavaClass currentClass = clazz;
651661

652662
while (true) {
653-
if (currentClass == null) {
654-
System.out.println("Contains android.support.v7.widget.RecyclerView$Adapter: " + classes.keySet().contains("android.support.v7.widget.RecyclerView$Adapter"));
655-
656-
System.out.println("Contains android.support.v7.widget.RecyclerView.Adapter: " + classes.keySet().contains("android.support.v7.widget.RecyclerView.Adapter"));
657-
}
658-
659663
String currentClassname = currentClass.getClassName();
660664

661665
Queue<String> queue = new ArrayDeque<String>();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example;
2+
3+
/**
4+
* Created by pkanev on 4/27/2017.
5+
*/
6+
7+
public class ListView extends View {
8+
public ListView createView() {
9+
return new ListView();
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example;
2+
3+
/**
4+
* Created by pkanev on 4/27/2017.
5+
*/
6+
7+
public abstract class View {
8+
public View createView() {
9+
return null;
10+
}
11+
}

android-static-binding-generator/project/staticbindinggenerator/src/test/java/org/nativescript/staticbindinggenerator/test/GeneratorTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.nativescript.staticbindinggenerator.test;
22

3+
import com.example.ListView;
34
import com.example.MyInterface;
45

56
import org.apache.commons.io.IOUtils;
@@ -103,4 +104,29 @@ public void testCanCompileBindingClassImplementingMultipleInterfaces() throws Ex
103104
Assert.assertNotNull(ComplexClass);
104105
Assert.assertEquals(5, ComplexClass.getInterfaces().length); // 4 + 1 (hashcodeprovider)
105106
}
107+
108+
@Test
109+
public void testCanCompileBindingClassExtendingAnExtendedClassWithMethodsWithTheSameSignature() throws Exception {
110+
URL u = ListView.class.getResource('/' + ListView.class.getName().replace('.', '/') + ".class");
111+
File f = new File(u.toURI()).getParentFile().getParentFile().getParentFile();
112+
113+
String dataRowString = "com.example.ListView*_fapp_l9_c29__*createView*com.example.MyListView**";
114+
DataRow dataRow = new DataRow(dataRowString);
115+
116+
System.out.println(dataRowString);
117+
118+
String outputDir = null;
119+
String[] libs = {runtimePath, f.getAbsolutePath()};
120+
Generator generator = new Generator(outputDir, libs);
121+
Binding binding = generator.generateBinding(dataRow);
122+
123+
StringBuffer sourceCode = new StringBuffer();
124+
sourceCode.append(binding.getContent());
125+
126+
Iterable<String> options = new ArrayList<String>(Arrays.asList("-cp", dependenciesDir));
127+
Class<?> ComplexClass = InMemoryJavaCompiler.compile(binding.getClassname(), sourceCode.toString(), options);
128+
129+
Assert.assertNotNull(ComplexClass);
130+
Assert.assertEquals(4, ComplexClass.getDeclaredMethods().length); // 1 + constructor + (equals + hashcode)
131+
}
106132
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"com.example.ListView*_fapp_l9_c29__*createView*com.example.MyListView**"

0 commit comments

Comments
 (0)