Skip to content

Commit 9aa5095

Browse files
author
Mihail Slavchev
committed
fix for #502
1 parent 03e28dc commit 9aa5095

7 files changed

Lines changed: 92 additions & 89 deletions

File tree

binding-generator/src/main/java/com/tns/bindings/Dump.java

Lines changed: 32 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public void generateProxy(ApplicationWriter aw, String proxyName, Class<?> class
363363
ClassVisitor cv = generateClass(aw, classTo, classSignature, tnsClassSignature);
364364
Method[] methods = getSupportedMethods(classTo, methodOverrides);
365365

366-
methods = groupMethodsByName(methods);
366+
methods = groupMethodsByNameAndSignature(methods);
367367

368368
generateFields(cv);
369369

@@ -376,7 +376,7 @@ public void generateProxy(ApplicationWriter aw, String proxyName, Class<?> class
376376
cv.visitEnd();
377377
}
378378

379-
private Method[] groupMethodsByName(Method[] methods)
379+
private Method[] groupMethodsByNameAndSignature(Method[] methods)
380380
{
381381
HashMap<String, Method> result = new HashMap<String, Method>();
382382
for (int i = 0; i < methods.length; i++)
@@ -404,50 +404,29 @@ private String getMethodSignature(Method m)
404404
return m.getName() + sig.substring(nameIdx, endSigIdx);
405405
}
406406

407-
private Method[] getSupportedMethods(Class<?> clazz, HashSet<String> methodOverrides)
408-
{
409-
ArrayList<Method> result = new ArrayList<Method>();
410-
411-
if (clazz.isInterface())
407+
private void collectInterfaceMethods(Class<?> clazz, HashSet<String> methodOverrides, List<Method> result) {
408+
Set<String> objectMethods = new HashSet<String>();
409+
for (Method objMethod: java.lang.Object.class.getDeclaredMethods())
412410
{
413-
Set<String> objectMethods = new HashSet<String>();
414-
for (Method objMethod: java.lang.Object.class.getDeclaredMethods())
411+
if (!Modifier.isStatic(objMethod.getModifiers()))
415412
{
416-
if (!Modifier.isStatic(objMethod.getModifiers()))
417-
{
418-
String sig = getMethodSignature(objMethod);
419-
objectMethods.add(sig);
420-
}
413+
String sig = getMethodSignature(objMethod);
414+
objectMethods.add(sig);
421415
}
416+
}
422417

423-
Set<Method> notImplementedObjectMethods = new HashSet<Method>();
424-
425-
Class[] extendedInterfaces = clazz.getInterfaces();
418+
Deque<Class<?>> extendedInterfaces = new ArrayDeque<Class<?>>();
419+
if (clazz.isInterface()) {
420+
extendedInterfaces.add(clazz);
421+
} else {
422+
extendedInterfaces.addAll(Arrays.asList(clazz.getInterfaces()));
423+
}
426424

427-
for(Class extendedInterface : extendedInterfaces) {
428-
Method[] ifaceMethods = extendedInterface.getDeclaredMethods();
429-
for (Method ifaceMethod: ifaceMethods)
430-
{
431-
if (!Modifier.isStatic(ifaceMethod.getModifiers()))
432-
{
433-
String sig = getMethodSignature(ifaceMethod);
434-
if (objectMethods.contains(sig) && !methodOverrides.contains(ifaceMethod.getName()))
435-
{
436-
notImplementedObjectMethods.add(ifaceMethod);
437-
}
438-
}
439-
}
425+
Set<Method> notImplementedObjectMethods = new HashSet<Method>();
440426

441-
for (Method ifaceMethod: ifaceMethods)
442-
{
443-
if (!notImplementedObjectMethods.contains(ifaceMethod))
444-
{
445-
result.add(ifaceMethod);
446-
}
447-
}
448-
}
449-
450-
Method[] ifaceMethods = clazz.getDeclaredMethods();
427+
while (!extendedInterfaces.isEmpty()) {
428+
Class<?> currentInterface = extendedInterfaces.pollFirst();
429+
Method[] ifaceMethods = currentInterface.getDeclaredMethods();
451430
for (Method ifaceMethod: ifaceMethods)
452431
{
453432
if (!Modifier.isStatic(ifaceMethod.getModifiers()))
@@ -467,11 +446,22 @@ private Method[] getSupportedMethods(Class<?> clazz, HashSet<String> methodOverr
467446
result.add(ifaceMethod);
468447
}
469448
}
449+
450+
for (Class<?> iface: currentInterface.getInterfaces()) {
451+
extendedInterfaces.add(iface);
452+
}
470453
}
471-
else
454+
}
455+
456+
private Method[] getSupportedMethods(Class<?> clazz, HashSet<String> methodOverrides)
457+
{
458+
ArrayList<Method> result = new ArrayList<Method>();
459+
460+
collectInterfaceMethods(clazz, methodOverrides, result);
461+
462+
if (!clazz.isInterface())
472463
{
473464
HashMap<String, Method> finalMethods = new HashMap<String, Method>();
474-
ArrayList<Class<?>> implementedInterfaces = new ArrayList<Class<?>>();
475465
while (clazz != null)
476466
{
477467
Method[] methods = clazz.getDeclaredMethods();
@@ -489,12 +479,6 @@ private Method[] getSupportedMethods(Class<?> clazz, HashSet<String> methodOverr
489479
methodz.add(methods[i]);
490480
}
491481

492-
Class<?>[] interfaces = clazz.getInterfaces();
493-
for (int i = 0; i < interfaces.length; i++)
494-
{
495-
implementedInterfaces.add(interfaces[i]);
496-
}
497-
498482
for (int i = 0; i < methodz.size(); i++)
499483
{
500484
Method method = methodz.get(i);
@@ -507,47 +491,6 @@ private Method[] getSupportedMethods(Class<?> clazz, HashSet<String> methodOverr
507491

508492
clazz = clazz.getSuperclass();
509493
}
510-
511-
for (int i = 0; i < implementedInterfaces.size(); i++)
512-
{
513-
Class<?> implementedInterface = implementedInterfaces.get(i);
514-
515-
Class[] extendedInterfaces = implementedInterface.getInterfaces();
516-
517-
for(Class extendedInterface : extendedInterfaces) {
518-
Method[] interfaceMethods = extendedInterface.getMethods();
519-
for (int j = 0; j < interfaceMethods.length; j++)
520-
{
521-
Method method = interfaceMethods[j];
522-
523-
if (methodOverrides != null && !methodOverrides.contains(method.getName()))
524-
{
525-
continue;
526-
}
527-
528-
if (!isMethodMarkedAsFinalInClassHierarchy(method, finalMethods))
529-
{
530-
result.add(method);
531-
}
532-
}
533-
}
534-
535-
Method[] interfaceMethods = implementedInterface.getMethods();
536-
for (int j = 0; j < interfaceMethods.length; j++)
537-
{
538-
Method method = interfaceMethods[j];
539-
540-
if (methodOverrides != null && !methodOverrides.contains(method.getName()))
541-
{
542-
continue;
543-
}
544-
545-
if (!isMethodMarkedAsFinalInClassHierarchy(method, finalMethods))
546-
{
547-
result.add(method);
548-
}
549-
}
550-
}
551494
}
552495

553496
return result.toArray(new Method[result.size()]);

test-app/app/src/main/assets/app/mainpage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ require("./tests/java-array-test");
4444
require("./tests/field-access-test");
4545
require("./tests/byte-buffer-test");
4646
require("./tests/dex-interface-implementation");
47+
require("./tests/testInterfaceImplementation");
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
describe("Tests Java interfaces are implemented correctly", function () {
2+
3+
it("should implement all methods when an interface extends other interfaces", function () {
4+
var callF = false;
5+
var callG = false;
6+
7+
var i3 = new com.tns.tests.ImplementInterfaceTest.I3({
8+
f: function() { callF = true; },
9+
g: function() { callG = true; }
10+
})
11+
12+
com.tns.tests.ImplementInterfaceTest.triggerF(i3);
13+
com.tns.tests.ImplementInterfaceTest.triggerG(i3);
14+
15+
expect(callF).toBe(true);
16+
expect(callG).toBe(true);
17+
});
18+
19+
it("should call overridden interface method", function () {
20+
var callClose = false;
21+
22+
var c = new java.io.Closeable({
23+
close: function() { callClose = true; }
24+
})
25+
26+
com.tns.tests.ImplementInterfaceTest.triggerClose(c);
27+
28+
expect(callClose).toBe(true);
29+
});
30+
});
-8.98 KB
Binary file not shown.
-73.9 KB
Binary file not shown.
-110 KB
Binary file not shown.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.tns.tests;
2+
3+
import java.io.IOException;
4+
5+
public class ImplementInterfaceTest {
6+
public interface I1 {
7+
void f();
8+
}
9+
10+
public interface I2 extends I1 {
11+
void g();
12+
}
13+
14+
public interface I3 extends I2 {
15+
}
16+
17+
public static void triggerF(I3 i3) {
18+
i3.f();
19+
}
20+
21+
public static void triggerG(I3 i3) {
22+
i3.g();
23+
}
24+
25+
public static void triggerClose(java.io.Closeable c) throws IOException {
26+
c.close();
27+
}
28+
29+
}

0 commit comments

Comments
 (0)