mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix abstract classes are considered by dependency analysis when constructed by reflection
Also fix #592
This commit is contained in:
parent
f0d805fda8
commit
7fe79a1768
|
@ -201,13 +201,22 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
|
|||
.addLocation(location)
|
||||
.getVariable(0).getClassValueNode();
|
||||
classValueNode.addConsumer(reflectedType -> {
|
||||
if (reflectedType.getName().startsWith("[")) {
|
||||
if (reflectedType.getName().startsWith("[") || reflectedType.getName().startsWith("~")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassReader cls = agent.getClassSource().get(reflectedType.getName());
|
||||
if (cls == null || cls.hasModifier(ElementModifier.ABSTRACT)
|
||||
|| cls.hasModifier(ElementModifier.INTERFACE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<MethodDescriptor> accessibleMethods = getAccessibleMethods(agent, reflectedType.getName());
|
||||
ClassReader cls = agent.getClassSource().get(reflectedType.getName());
|
||||
|
||||
for (MethodDescriptor methodDescriptor : accessibleMethods) {
|
||||
if (!methodDescriptor.getName().equals("<init>")) {
|
||||
continue;
|
||||
}
|
||||
MethodReader calledMethod = cls.getMethod(methodDescriptor);
|
||||
MethodDependency calledMethodDep = agent.linkMethod(calledMethod.getReference()).addLocation(location);
|
||||
calledMethodDep.use();
|
||||
|
@ -218,8 +227,9 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
|
|||
calledMethodDep.getVariable(0).propagate(reflectedType);
|
||||
linkClassIfNecessary(agent, calledMethod, location);
|
||||
}
|
||||
|
||||
method.getResult().propagate(reflectedType);
|
||||
});
|
||||
classValueNode.connect(method.getResult());
|
||||
}
|
||||
|
||||
private void handleInvoke(DependencyAgent agent, MethodDependency method) {
|
||||
|
@ -235,6 +245,9 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
|
|||
Set<MethodDescriptor> accessibleMethods = getAccessibleMethods(agent, reflectedType.getName());
|
||||
ClassReader cls = agent.getClassSource().get(reflectedType.getName());
|
||||
for (MethodDescriptor methodDescriptor : accessibleMethods) {
|
||||
if (methodDescriptor.getName().equals("<init>")) {
|
||||
continue;
|
||||
}
|
||||
MethodReader calledMethod = cls.getMethod(methodDescriptor);
|
||||
MethodDependency calledMethodDep = agent.linkMethod(calledMethod.getReference()).addLocation(location);
|
||||
calledMethodDep.use();
|
||||
|
|
|
@ -67,7 +67,16 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin {
|
|||
public void methodReached(DependencyAgent agent, MethodDependency method) {
|
||||
switch (method.getReference().getName()) {
|
||||
case "newEmptyInstance":
|
||||
method.getVariable(0).getClassValueNode().connect(method.getResult());
|
||||
method.getVariable(0).getClassValueNode().addConsumer(type -> {
|
||||
String className = type.getName();
|
||||
if (!className.startsWith("[") && !className.startsWith("~")) {
|
||||
ClassReader cls = agent.getClassSource().get(className);
|
||||
if (cls != null && !cls.hasModifier(ElementModifier.ABSTRACT)
|
||||
&& !cls.hasModifier(ElementModifier.INTERFACE)) {
|
||||
method.getResult().propagate(type);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "getSuperclass":
|
||||
reachGetSuperclass(agent, method);
|
||||
|
|
|
@ -108,6 +108,11 @@ public class DependencyTest {
|
|||
doTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reflectionConstructor() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
TeaVM vm = new TeaVMBuilder(new JavaScriptTarget())
|
||||
.setClassLoader(DependencyTest.class.getClassLoader())
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
package org.teavm.dependency;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DependencyTestData {
|
||||
private DependencyTestData() {
|
||||
}
|
||||
|
@ -114,6 +118,14 @@ public class DependencyTestData {
|
|||
}
|
||||
}
|
||||
|
||||
public static void reflectionConstructor() throws Exception {
|
||||
var classes = new Class<?>[] { AbstractList.class, ArrayList.class };
|
||||
for (var cls : classes) {
|
||||
var instance = cls.getConstructor().newInstance();
|
||||
MetaAssertions.assertTypes(instance, ArrayList.class);
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
Object foo();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user