Properly report missing virtual methods

This commit is contained in:
Alexey Andreev 2017-11-19 14:36:04 +03:00
parent 3f487f8a7d
commit 62f639f92b
2 changed files with 36 additions and 36 deletions

View File

@ -31,16 +31,16 @@ public class MissingItemsProcessor {
private List<Instruction> instructionsToAdd = new ArrayList<>(); private List<Instruction> instructionsToAdd = new ArrayList<>();
private MethodHolder methodHolder; private MethodHolder methodHolder;
private Program program; private Program program;
private Collection<String> achievableClasses; private Collection<String> reachableClasses;
private Collection<MethodReference> reachableMethods; private Collection<MethodReference> reachableMethods;
private Collection<FieldReference> achievableFields; private Collection<FieldReference> reachableFields;
public MissingItemsProcessor(DependencyInfo dependencyInfo, Diagnostics diagnostics) { public MissingItemsProcessor(DependencyInfo dependencyInfo, Diagnostics diagnostics) {
this.dependencyInfo = dependencyInfo; this.dependencyInfo = dependencyInfo;
this.diagnostics = diagnostics; this.diagnostics = diagnostics;
achievableClasses = dependencyInfo.getReachableClasses(); reachableClasses = dependencyInfo.getReachableClasses();
reachableMethods = dependencyInfo.getReachableMethods(); reachableMethods = dependencyInfo.getReachableMethods();
achievableFields = dependencyInfo.getReachableFields(); reachableFields = dependencyInfo.getReachableFields();
} }
public void processClass(ClassHolder cls) { public void processClass(ClassHolder cls) {
@ -126,7 +126,7 @@ public class MissingItemsProcessor {
} }
private boolean checkClass(TextLocation location, String className) { private boolean checkClass(TextLocation location, String className) {
if (!achievableClasses.contains(className) || !dependencyInfo.getClass(className).isMissing()) { if (!reachableClasses.contains(className) || !dependencyInfo.getClass(className).isMissing()) {
return true; return true;
} }
diagnostics.error(new CallLocation(methodHolder.getReference(), location), "Class {{c0}} was not found", diagnostics.error(new CallLocation(methodHolder.getReference(), location), "Class {{c0}} was not found",
@ -163,11 +163,29 @@ public class MissingItemsProcessor {
return true; return true;
} }
private boolean checkVirtualMethod(TextLocation location, MethodReference method) {
if (!checkClass(location, method.getClassName())) {
return false;
}
if (!reachableMethods.contains(method)) {
return true;
}
if (dependencyInfo.getClassSource().resolve(method) != null) {
return true;
}
diagnostics.error(new CallLocation(methodHolder.getReference(), location), "Method {{m0}} was not found",
method);
emitExceptionThrow(location, NoSuchMethodError.class.getName(), "Method not found: " + method);
return true;
}
private boolean checkField(TextLocation location, FieldReference field) { private boolean checkField(TextLocation location, FieldReference field) {
if (!checkClass(location, field.getClassName())) { if (!checkClass(location, field.getClassName())) {
return false; return false;
} }
if (!achievableFields.contains(field) || !dependencyInfo.getField(field).isMissing()) { if (!reachableFields.contains(field) || !dependencyInfo.getField(field).isMissing()) {
return true; return true;
} }
diagnostics.error(new CallLocation(methodHolder.getReference(), location), "Field {{f0}} was not found", diagnostics.error(new CallLocation(methodHolder.getReference(), location), "Field {{f0}} was not found",
@ -193,7 +211,11 @@ public class MissingItemsProcessor {
@Override @Override
public void visit(InvokeInstruction insn) { public void visit(InvokeInstruction insn) {
if (insn.getType() != InvocationType.VIRTUAL) {
checkMethod(insn.getLocation(), insn.getMethod()); checkMethod(insn.getLocation(), insn.getMethod());
} else {
checkVirtualMethod(insn.getLocation(), insn.getMethod());
}
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import java.net.URISyntaxException;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.teavm.interop.PlatformMarker;
import org.teavm.junit.TeaVMTestRunner; import org.teavm.junit.TeaVMTestRunner;
@RunWith(TeaVMTestRunner.class) @RunWith(TeaVMTestRunner.class)
@ -1079,34 +1080,6 @@ public class FileTest {
f.delete(); f.delete();
} }
@Test
public void isHidden() throws IOException, InterruptedException {
boolean onUnix = File.separatorChar == '/';
File f = File.createTempFile("harmony-test-FileTest_isHidden_", ".tmp");
// On Unix hidden files are marked with a "." at the beginning
// of the file name.
if (onUnix) {
File f2 = new File(".test.tst" + platformId);
FileOutputStream fos2 = new FileOutputStream(f2);
fos2.close();
assertTrue("File returned hidden on Unix", !f.isHidden());
assertTrue("File returned visible on Unix", f2.isHidden());
assertTrue("File did not delete.", f2.delete());
} else {
// For windows, the file is being set hidden by the attrib
// command.
Runtime r = Runtime.getRuntime();
assertTrue("File returned hidden", !f.isHidden());
Process p = r.exec("attrib +h \"" + f.getAbsolutePath() + "\"");
p.waitFor();
assertTrue("File returned visible", f.isHidden());
p = r.exec("attrib -h \"" + f.getAbsolutePath() + "\"");
p.waitFor();
assertTrue("File returned hidden", !f.isHidden());
}
f.delete();
}
@Test @Test
public void lastModified() throws IOException { public void lastModified() throws IOException {
File f = new File(System.getProperty("java.io.tmpdir"), platformId + "lModTest.tst"); File f = new File(System.getProperty("java.io.tmpdir"), platformId + "lModTest.tst");
@ -1283,7 +1256,7 @@ public class FileTest {
// Test to make sure that listFiles can read hidden files. // Test to make sure that listFiles can read hidden files.
boolean onUnix = File.separatorChar == '/'; boolean onUnix = File.separatorChar == '/';
boolean onWindows = File.separatorChar == '\\'; boolean onWindows = File.separatorChar == '\\';
if (onWindows) { if (!isTeaVM() && onWindows) {
files[3] = "4.tst"; files[3] = "4.tst";
File f = new File(dir, "4.tst"); File f = new File(dir, "4.tst");
FileOutputStream fos = new FileOutputStream(f); FileOutputStream fos = new FileOutputStream(f);
@ -1951,4 +1924,9 @@ public class FileTest {
} }
assertTrue(exist); assertTrue(exist);
} }
@PlatformMarker
private static boolean isTeaVM() {
return false;
}
} }