Skip to content

Commit c788804

Browse files
committed
fix: cannot detect interfaces' methods
1 parent b2080e5 commit c788804

2 files changed

Lines changed: 71 additions & 5 deletions

File tree

java/src/main/java/org/eu/smileyik/luajava/reflect/ReflectUtil.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,16 @@ public static boolean existsMethodByName(
265265
return result;
266266
}
267267

268-
while (clazz != null) {
268+
Set<Class<?>> checkedClasses = new HashSet<>();
269+
LinkedList<Class<?>> queue = new LinkedList<>();
270+
queue.add(clazz);
271+
while (!queue.isEmpty()) {
272+
clazz = queue.removeFirst();
273+
if (!checkedClasses.add(clazz)) {
274+
continue;
275+
}
276+
findSuperclasses(queue, clazz);
277+
269278
for (Method method : clazz.getDeclaredMethods()) {
270279
if (method.getName().equals(name)) {
271280
if (!checkExecutableModifiers(method, ignoreNotPublic, ignoreStatic, ignoreNotStatic)) {
@@ -274,7 +283,6 @@ public static boolean existsMethodByName(
274283
}
275284
}
276285
}
277-
clazz = clazz.getSuperclass();
278286
}
279287
CACHED_EXISTS_METHOD.putIfAbsent(cacheKey, false);
280288
return false;
@@ -313,9 +321,17 @@ public static LinkedList<LuaInvokedMethod<Method>> findMethodByParams(
313321
Set<ReflectExecutableCacheKey> checkedMethods = new HashSet<>();
314322

315323
// find methods
316-
Class<?> c = clazz;
324+
Set<Class<?>> checkedClasses = new HashSet<>();
325+
LinkedList<Class<?>> queue = new LinkedList<>();
326+
queue.add(clazz);
317327
int paramsCount = params.length;
318-
while (c != null) {
328+
while (!queue.isEmpty()) {
329+
Class<?> c = queue.removeFirst();
330+
if (!checkedClasses.add(c)) {
331+
continue;
332+
}
333+
findSuperclasses(queue, c);
334+
319335
for (Method method : c.getDeclaredMethods()) {
320336
// filters
321337
if (!method.getName().equals(methodName) ||
@@ -336,7 +352,6 @@ public static LinkedList<LuaInvokedMethod<Method>> findMethodByParams(
336352
if (currentPriority == FULL_MATCH) break;
337353
}
338354
}
339-
c = c.getSuperclass();
340355
}
341356
if (cacheKey != null) {
342357
CACHED_METHODS.get(cacheKey)
@@ -350,6 +365,18 @@ public static LinkedList<LuaInvokedMethod<Method>> findMethodByParams(
350365
return matchedList;
351366
}
352367

368+
private static void findSuperclasses(LinkedList<Class<?>> queue, Class<?> clazz) {
369+
if (clazz.getSuperclass() != null) {
370+
queue.addLast(clazz.getSuperclass());
371+
}
372+
Class<?>[] interfaces = clazz.getInterfaces();
373+
for (Class<?> i : interfaces) {
374+
if (i != null) {
375+
queue.addLast(i);
376+
}
377+
}
378+
}
379+
353380
/**
354381
* return true means need skip check this method.
355382
*/
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.eu.smileyik.luajava.javaapi;
2+
3+
import org.eu.smileyik.luajava.BaseTest;
4+
import org.eu.smileyik.luajava.LuaStateFacade;
5+
import org.junit.jupiter.api.Test;
6+
7+
public class InterfaceDefaultMethodTest extends BaseTest {
8+
9+
@Test
10+
public void test() throws Exception {
11+
LuaStateFacade luaStateFacade = newLuaState();
12+
luaStateFacade.setGlobal("a", new A());
13+
luaStateFacade.evalString("a:a()").justThrow();
14+
luaStateFacade.evalString("a:superA()").justThrow();
15+
luaStateFacade.evalString("a:b()").justThrow();
16+
}
17+
18+
public static interface ISuperA {
19+
public default void superA() {
20+
System.out.println("superA");
21+
}
22+
}
23+
24+
public static interface IA extends ISuperA {
25+
public default void a() {
26+
System.out.println("a");
27+
}
28+
29+
public void b();
30+
}
31+
32+
public static class A implements IA {
33+
34+
@Override
35+
public void b() {
36+
System.out.println("b");
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)