8131025: JShell: crash on tab-complete reference to bad class file
authorjlahoda
Thu, 08 Sep 2016 15:48:28 +0200
changeset 40837 d071bcc8d32e
parent 40836 2c3901225ff2
child 40838 1cba2e436777
8131025: JShell: crash on tab-complete reference to bad class file Summary: Catching CompletionFailure when iterating through Scope. Reviewed-by: rfield
langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java
langtools/test/jdk/jshell/CompletionSuggestionTest.java
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Wed Sep 07 12:15:22 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Thu Sep 08 15:48:28 2016 +0200
@@ -838,8 +838,31 @@
     }
 
     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()) {
--- a/langtools/test/jdk/jshell/CompletionSuggestionTest.java	Wed Sep 07 12:15:22 2016 -0700
+++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java	Thu Sep 08 15:48:28 2016 +0200
@@ -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 @@
         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");
+    }
 }