Skip to content

Commit

Permalink
Merge pull request #754 from NativeScript/pete/fix-sbg
Browse files Browse the repository at this point in the history
Fix SBG (#753) and string replacement
  • Loading branch information
petekanev authored Apr 28, 2017
2 parents df627ec + c2d02b4 commit ce5d00f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.PrintStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -141,6 +142,9 @@ private Binding[] processRows(List<DataRow> rows) throws IOException {
String classname = dataRow.getBaseClassname();
boolean isJavaExtend = classes.containsKey(classname);
if (isJavaExtend) {

// System.out.println("SBG: DataRow: baseClassName: " + classname + ", suffix: " + dataRow.getSuffix() + ", interfaces: " + String.join(", ", Arrays.asList(dataRow.getInterfaces())) + ", jsFileName: " + dataRow.getJsFilename());

Binding binding = generateBinding(dataRow, interfaceNames);

if (binding != null) {
Expand Down Expand Up @@ -187,42 +191,56 @@ private String getNormalizedName(String filename) {
private Map<String, List<Method>> getPublicApi(JavaClass clazz) {
Map<String, List<Method>> api = new HashMap<String, List<Method>>();
JavaClass currentClass = clazz;
String clazzName = clazz.getClassName();
while (true) {
String currentClassname = currentClass.getClassName();
List<Method> methods = new ArrayList<Method>();
for (Method m : currentClass.getMethods()) {
methods.add(m);
}
collectInterfaceMethods(clazz, methods);
for (Method m : methods) {
if (!m.isSynthetic() && (m.isPublic() || m.isProtected()) && !m.isStatic()) {
String name = m.getName();

List<Method> methodGroup;
if (api.containsKey(name)) {
methodGroup = api.get(name);
} else {
methodGroup = new ArrayList<Method>();
api.put(name, methodGroup);
}
boolean found = false;
String methodSig = m.getSignature();
for (Method m1 : methodGroup) {
found = methodSig.equals(m1.getSignature());
if (found) {
break;

boolean shouldCollectMethods = !(!clazzName.equals(currentClassname) && currentClass.isAbstract());

if (shouldCollectMethods || currentClass.isInterface()) {
// Don't include abstract parent class's methods to avoid compilation issues
// where a child class has 2 methods, of the same type, with just a
// return type/parameter type that differs by being of a superclass of the class being extended.
// see Test testCanCompileBindingClassExtendingAnExtendedClassWithMethodsWithTheSameSignature
List<Method> methods = new ArrayList<Method>();
for (Method m : currentClass.getMethods()) {
methods.add(m);
}

// System.out.println("SBG: getPublicApi:collectInterfaceMethods classname: " + currentClassname);

collectInterfaceMethods(clazz, methods);
for (Method m : methods) {
if (!m.isSynthetic() && (m.isPublic() || m.isProtected()) && !m.isStatic()) {
String name = m.getName();

List<Method> methodGroup;
if (api.containsKey(name)) {
methodGroup = api.get(name);
} else {
methodGroup = new ArrayList<Method>();
api.put(name, methodGroup);
}
boolean found = false;
String methodSig = m.getSignature();
for (Method m1 : methodGroup) {
found = methodSig.equals(m1.getSignature());
if (found) {
break;
}
}
if (!found) {
methodGroup.add(m);
}
}
if (!found) {
methodGroup.add(m);
}
}
}

if (currentClassname.equals("java.lang.Object")) {
break;
} else {
currentClass = classes.get(currentClass.getSuperclassName());
String superClassName = currentClass.getSuperclassName();
currentClass = classes.get(superClassName.replace('$', '.'));
}
}
return api;
Expand Down Expand Up @@ -640,6 +658,7 @@ private void writeType(Type t, Writer w) {

private void collectInterfaceMethods(JavaClass clazz, List<Method> methods) {
JavaClass currentClass = clazz;

while (true) {
String currentClassname = currentClass.getClassName();

Expand All @@ -663,7 +682,8 @@ private void collectInterfaceMethods(JavaClass clazz, List<Method> methods) {
if (currentClassname.equals("java.lang.Object")) {
break;
} else {
currentClass = classes.get(currentClass.getSuperclassName());
String superClassName = currentClass.getSuperclassName();
currentClass = classes.get(superClassName.replace('$', '.'));
}
}
}
Expand All @@ -686,7 +706,8 @@ private boolean isApplicationClass(JavaClass clazz, Map<String, JavaClass> class
break;
}

currentClass = classes.get(currentClass.getSuperclassName());
String superClassName = currentClass.getSuperclassName();
currentClass = classes.get(superClassName.replace('$', '.'));
}

return isApplicationClass;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example;

/**
* Created by pkanev on 4/27/2017.
*/

public class ListView extends View {
public ListView createView() {
return new ListView();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example;

/**
* Created by pkanev on 4/27/2017.
*/

public abstract class View {
public View createView() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.nativescript.staticbindinggenerator.test;

import com.example.ListView;
import com.example.MyInterface;

import org.apache.commons.io.IOUtils;
Expand Down Expand Up @@ -103,4 +104,29 @@ public void testCanCompileBindingClassImplementingMultipleInterfaces() throws Ex
Assert.assertNotNull(ComplexClass);
Assert.assertEquals(5, ComplexClass.getInterfaces().length); // 4 + 1 (hashcodeprovider)
}

@Test
public void testCanCompileBindingClassExtendingAnExtendedClassWithMethodsWithTheSameSignature() throws Exception {
URL u = ListView.class.getResource('/' + ListView.class.getName().replace('.', '/') + ".class");
File f = new File(u.toURI()).getParentFile().getParentFile().getParentFile();

String dataRowString = "com.example.ListView*_fapp_l9_c29__*createView*com.example.MyListView**";
DataRow dataRow = new DataRow(dataRowString);

System.out.println(dataRowString);

String outputDir = null;
String[] libs = {runtimePath, f.getAbsolutePath()};
Generator generator = new Generator(outputDir, libs);
Binding binding = generator.generateBinding(dataRow);

StringBuffer sourceCode = new StringBuffer();
sourceCode.append(binding.getContent());

Iterable<String> options = new ArrayList<String>(Arrays.asList("-cp", dependenciesDir));
Class<?> ComplexClass = InMemoryJavaCompiler.compile(binding.getClassname(), sourceCode.toString(), options);

Assert.assertNotNull(ComplexClass);
Assert.assertEquals(4, ComplexClass.getDeclaredMethods().length); // 1 + constructor + (equals + hashcode)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"com.example.ListView*_fapp_l9_c29__*createView*com.example.MyListView**"

0 comments on commit ce5d00f

Please sign in to comment.