mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix virtual method resolution in code server mode
This commit is contained in:
parent
05ac4b62bf
commit
2d2ef642a3
|
@ -27,7 +27,6 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.teavm.ast.AsyncMethodNode;
|
import org.teavm.ast.AsyncMethodNode;
|
||||||
import org.teavm.ast.AsyncMethodPart;
|
import org.teavm.ast.AsyncMethodPart;
|
||||||
import org.teavm.ast.MethodNode;
|
import org.teavm.ast.MethodNode;
|
||||||
|
@ -46,6 +45,7 @@ import org.teavm.debugging.information.DebugInformationEmitter;
|
||||||
import org.teavm.debugging.information.DummyDebugInformationEmitter;
|
import org.teavm.debugging.information.DummyDebugInformationEmitter;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
import org.teavm.model.AccessLevel;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
|
@ -577,7 +577,8 @@ public class Renderer implements RenderingManager {
|
||||||
|
|
||||||
List<MethodReference> virtualMethods = new ArrayList<>();
|
List<MethodReference> virtualMethods = new ArrayList<>();
|
||||||
for (PreparedMethod method : cls.getMethods()) {
|
for (PreparedMethod method : cls.getMethods()) {
|
||||||
if (!method.methodHolder.getModifiers().contains(ElementModifier.STATIC)) {
|
if (!method.methodHolder.getModifiers().contains(ElementModifier.STATIC)
|
||||||
|
&& method.methodHolder.getLevel() != AccessLevel.PRIVATE) {
|
||||||
virtualMethods.add(method.reference);
|
virtualMethods.add(method.reference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,8 +658,17 @@ public class Renderer implements RenderingManager {
|
||||||
|
|
||||||
private void collectMethodsToCopyFromInterfaces(ClassReader cls, List<MethodReference> targetList) {
|
private void collectMethodsToCopyFromInterfaces(ClassReader cls, List<MethodReference> targetList) {
|
||||||
Set<MethodDescriptor> implementedMethods = new HashSet<>();
|
Set<MethodDescriptor> implementedMethods = new HashSet<>();
|
||||||
implementedMethods.addAll(targetList.stream().map(method -> method.getDescriptor())
|
ClassReader superclass = cls;
|
||||||
.collect(Collectors.toList()));
|
while (superclass != null) {
|
||||||
|
for (MethodReader method : superclass.getMethods()) {
|
||||||
|
if (method.getLevel() != AccessLevel.PRIVATE && !method.hasModifier(ElementModifier.STATIC)
|
||||||
|
&& !method.hasModifier(ElementModifier.ABSTRACT)
|
||||||
|
&& !method.getName().equals("<init>")) {
|
||||||
|
implementedMethods.add(method.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
superclass = superclass.getParent() != null ? classSource.get(superclass.getParent()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
Set<String> visitedClasses = new HashSet<>();
|
Set<String> visitedClasses = new HashSet<>();
|
||||||
for (String ifaceName : cls.getInterfaces()) {
|
for (String ifaceName : cls.getInterfaces()) {
|
||||||
|
|
|
@ -313,6 +313,40 @@ public class VMTest {
|
||||||
assertEquals(23, ReadingStateInClinit.state);
|
assertEquals(23, ReadingStateInClinit.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void implementInBaseMethodWithDefault() {
|
||||||
|
SubclassWithInheritedImplementation o = new SubclassWithInheritedImplementation();
|
||||||
|
assertEquals(1, o.x);
|
||||||
|
assertEquals(2, new SubclassWithInheritedDefaultImplementation().foo());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class BaseClassWithImplementation {
|
||||||
|
public int foo() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseInterfaceWithDefault {
|
||||||
|
default int foo() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class IntermediateClassInheritingImplementation extends BaseClassWithImplementation {
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SubclassWithInheritedImplementation extends IntermediateClassInheritingImplementation
|
||||||
|
implements BaseInterfaceWithDefault {
|
||||||
|
int x;
|
||||||
|
|
||||||
|
SubclassWithInheritedImplementation() {
|
||||||
|
x = foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SubclassWithInheritedDefaultImplementation implements BaseInterfaceWithDefault {
|
||||||
|
}
|
||||||
|
|
||||||
interface WithDefaultMethod {
|
interface WithDefaultMethod {
|
||||||
default String foo() {
|
default String foo() {
|
||||||
return "default";
|
return "default";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user