8208184: IllegalArgumentException while invoking code completion on netbeans IDE
Summary: Set Log.useSource and fix the issue in Modules.java when broken module is encountered
Reviewed-by: jjg
Contributed-by: srinivas.dama@oracle.com, jan.lahoda@oracle.com
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Jan 03 02:22:30 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Jan 03 11:21:11 2019 +0530
@@ -450,7 +450,12 @@
String moduleOverride = singleModuleOverride(trees);
switch (rootModules.size()) {
case 0:
- defaultModule = moduleFinder.findSingleModule();
+ try {
+ defaultModule = moduleFinder.findSingleModule();
+ } catch (CompletionFailure cf) {
+ chk.completionError(null, cf);
+ defaultModule = syms.unnamedModule;
+ }
if (defaultModule == syms.unnamedModule) {
if (moduleOverride != null) {
checkNoAllModulePath();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jan 03 02:22:30 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jan 03 11:21:11 2019 +0530
@@ -1761,6 +1761,7 @@
private Name parseAndGetName(JavaFileObject fo,
Function<JCTree.JCCompilationUnit, Name> tree2Name) {
DiagnosticHandler dh = new DiscardDiagnosticHandler(log);
+ JavaFileObject prevSource = log.useSource(fo);
try {
JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false));
return tree2Name.apply(t);
@@ -1768,6 +1769,7 @@
return null;
} finally {
log.popDiagnosticHandler(dh);
+ log.useSource(prevSource);
}
}
--- a/test/langtools/tools/javac/modules/QueryBeforeEnter.java Thu Jan 03 02:22:30 2019 +0100
+++ b/test/langtools/tools/javac/modules/QueryBeforeEnter.java Thu Jan 03 11:21:11 2019 +0530
@@ -23,6 +23,7 @@
/**
* @test
+ * @bug 8208184
* @summary tests for module resolution
* @library /tools/lib
* @modules
@@ -33,19 +34,33 @@
*/
import java.io.File;
+import java.io.IOException;
import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.file.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Arrays;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
// import com.sun.source.util.JavacTask;
@@ -427,6 +442,125 @@
}
+ @Test
+ public void testBrokenModule(Path base) throws Exception {
+ Map<String, String> sourceFileName2Content = new HashMap<>();
+
+ sourceFileName2Content.put("module-info.java", "module test { requires unknown.; } ");
+ sourceFileName2Content.put("test/Test.java", "package test; public class Test {}");
+
+ Path out = base.resolve("out");
+
+ Files.createDirectories(out);
+
+ JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
+ try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) {
+ com.sun.source.util.JavacTask task =
+ (com.sun.source.util.JavacTask) javaCompiler.getTask(null,
+ new TestMemoryFileManager(fm, sourceFileName2Content),
+ null,
+ Arrays.asList("-d", out.toString()),
+ null,
+ null);
+ task.getElements().getTypeElement("test.Test");
+ }
+ }
+
+ private static final class TestMemoryFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+
+ private final Map<String, String> sourceFileName2Content;
+
+ public TestMemoryFileManager(JavaFileManager fileManager, Map<String, String> sourceFileName2Content) {
+ super(fileManager);
+ this.sourceFileName2Content = sourceFileName2Content;
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
+ if (location == StandardLocation.SOURCE_PATH) {
+ List<JavaFileObject> result = new ArrayList<>();
+ String dir = packageName.replace('.', '/') + "/";
+
+ for (Entry<String, String> e : sourceFileName2Content.entrySet()) {
+ if (e.getKey().startsWith(dir) &&
+ !e.getKey().substring(dir.length()).contains("/")) {
+ try {
+ result.add(new SourceFileObject(e.getKey(), e.getValue()));
+ } catch (URISyntaxException ex) {
+ throw new IOException(ex);
+ }
+ }
+ }
+
+ return result;
+ }
+ return super.list(location, packageName, kinds, recurse);
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
+ if (location == StandardLocation.SOURCE_PATH) {
+ String path = className.replace('.', '/') + ".java";
+ String code = sourceFileName2Content.get(path);
+
+ if (code == null) return null;
+
+ try {
+ return new SourceFileObject(path, code);
+ } catch (URISyntaxException ex) {
+ throw new IOException(ex);
+ }
+ }
+ return super.getJavaFileForInput(location, className, kind);
+ }
+
+ @Override
+ public boolean hasLocation(Location location) {
+ return super.hasLocation(location) || location == StandardLocation.SOURCE_PATH;
+ }
+
+ @Override
+ public boolean contains(Location location, FileObject fo) throws IOException {
+ if (location == StandardLocation.SOURCE_PATH) {
+ return fo instanceof SourceFileObject;
+ }
+ return super.contains(location, fo);
+ }
+
+ @Override
+ public String inferBinaryName(Location location, JavaFileObject file) {
+ if (location == StandardLocation.SOURCE_PATH) {
+ String path = ((SourceFileObject) file).path;
+ String fileName = path.substring(path.lastIndexOf('/'));
+ return fileName.substring(0, fileName.length() - ".java".length());
+ }
+ return super.inferBinaryName(location, file);
+ }
+
+ }
+
+ private static final class SourceFileObject extends SimpleJavaFileObject {
+ private final String path;
+ private final String code;
+
+ public SourceFileObject(String path, String code) throws URISyntaxException {
+ super(new URI("mem://" + path), Kind.SOURCE);
+ this.path = path;
+ this.code = code;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return code;
+ }
+
+ @Override
+ public boolean isNameCompatible(String simpleName, Kind kind) {
+ return path.endsWith(simpleName + kind.extension);
+ }
+
+ }
+
private static void assertNotNull(Object actual) {
if (actual == null) {
throw new AssertionError("unexpected null!");