8131025: JShell: crash on tab-complete reference to bad class file

Catching CompletionFailure when iterating through Scope.

Reviewed-by: rfield
This commit is contained in:
Jan Lahoda 2016-09-08 15:48:28 +02:00
parent 426f1d9d47
commit 835354dfa6
2 changed files with 48 additions and 3 deletions

View File

@ -838,8 +838,31 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
}
private Stream<Element> localElements(Scope scope) {
@SuppressWarnings("unchecked")
Stream<Element> elements = Util.stream((Iterable<Element>)scope.getLocalElements());
//workaround for: JDK-8024687
Iterable<Element> elementsIt = () -> new Iterator<Element>() {
Iterator<? extends Element> it = scope.getLocalElements().iterator();
@Override
public boolean hasNext() {
while (true) {
try {
return it.hasNext();
} catch (CompletionFailure cf) {
//ignore...
}
}
}
@Override
public Element next() {
while (true) {
try {
return it.next();
} catch (CompletionFailure cf) {
//ignore...
}
}
}
};
Stream<Element> elements = Util.stream(elementsIt);
if (scope.getEnclosingScope() != null &&
scope.getEnclosingClass() != scope.getEnclosingScope().getEnclosingClass()) {

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8141092 8153761
* @bug 8131025 8141092 8153761
* @summary Test Completion
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -610,4 +610,26 @@ public class CompletionSuggestionTest extends KullaTesting {
keepParameterNames.setAccessible(true);
keepParameterNames.set(getAnalysis(), new String[0]);
}
public void testBrokenClassFile2() throws IOException {
Path broken = outDir.resolve("broken");
compiler.compile(broken,
"package p;\n" +
"public class BrokenA {\n" +
"}",
"package p.q;\n" +
"public class BrokenB {\n" +
"}",
"package p;\n" +
"public class BrokenC {\n" +
"}");
Path cp = compiler.getPath(broken);
Path target = cp.resolve("p").resolve("BrokenB.class");
Files.deleteIfExists(target);
Files.move(cp.resolve("p").resolve("q").resolve("BrokenB.class"), target);
addToClasspath(cp);
assertEval("import p.*;");
assertCompletion("Broke|", "BrokenA", "BrokenC");
}
}