8174245: Javadoc is not working for some methods
Summary: Parsing source file as if they were part of their corresponding modules.
Reviewed-by: rfield
--- a/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Mon Feb 13 09:37:26 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Mon Feb 13 11:57:56 2017 +0100
@@ -49,12 +49,15 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -542,8 +545,13 @@
if (type == null)
return null;
- String binaryName = origin.getElements().getBinaryName(type).toString();
- Pair<JavacTask, CompilationUnitTree> source = findSource(binaryName);
+ Elements elements = origin.getElements();
+ String binaryName = elements.getBinaryName(type).toString();
+ ModuleElement module = elements.getModuleOf(type);
+ String moduleName = module == null || module.isUnnamed()
+ ? null
+ : module.getQualifiedName().toString();
+ Pair<JavacTask, CompilationUnitTree> source = findSource(moduleName, binaryName);
if (source == null)
return null;
@@ -636,7 +644,8 @@
}.scan(cut, null);
}
- private Pair<JavacTask, CompilationUnitTree> findSource(String binaryName) throws IOException {
+ private Pair<JavacTask, CompilationUnitTree> findSource(String moduleName,
+ String binaryName) throws IOException {
JavaFileObject jfo = fm.getJavaFileForInput(StandardLocation.SOURCE_PATH,
binaryName,
JavaFileObject.Kind.SOURCE);
@@ -645,7 +654,10 @@
return null;
List<JavaFileObject> jfos = Arrays.asList(jfo);
- JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, baseFileManager, d -> {}, null, null, jfos);
+ JavaFileManager patchFM = moduleName != null
+ ? new PatchModuleFileManager(baseFileManager, jfo, moduleName)
+ : baseFileManager;
+ JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, patchFM, d -> {}, null, null, jfos);
Iterable<? extends CompilationUnitTree> cuts = task.parse();
task.enter();
@@ -657,6 +669,61 @@
public void close() throws IOException {
fm.close();
}
+
+ private static final class PatchModuleFileManager
+ extends ForwardingJavaFileManager<JavaFileManager> {
+
+ private final JavaFileObject file;
+ private final String moduleName;
+
+ public PatchModuleFileManager(JavaFileManager fileManager,
+ JavaFileObject file,
+ String moduleName) {
+ super(fileManager);
+ this.file = file;
+ this.moduleName = moduleName;
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public Location getLocationForModule(Location location,
+ JavaFileObject fo,
+ String pkgName) throws IOException {
+ return fo == file
+ ? PATCH_LOCATION
+ : super.getLocationForModule(location, fo, pkgName);
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public String inferModuleName(Location location) throws IOException {
+ return location == PATCH_LOCATION
+ ? moduleName
+ : super.inferModuleName(location);
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean hasLocation(Location location) {
+ return location == StandardLocation.PATCH_MODULE_PATH ||
+ super.hasLocation(location);
+ }
+
+ private static final Location PATCH_LOCATION = new Location() {
+ @Override @DefinedBy(Api.COMPILER)
+ public String getName() {
+ return "PATCH_LOCATION";
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean isOutputLocation() {
+ return false;
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean isModuleOrientedLocation() {
+ return false;
+ }
+
+ };
+ }
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Mon Feb 13 09:37:26 2017 +0100
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Mon Feb 13 11:57:56 2017 +0100
@@ -310,6 +310,8 @@
int firstLine = 0;
PRINT_PAGE: while (true) {
+ in.print(lastNote.replaceAll(".", " ") + ConsoleReader.RESET_LINE);
+
int toPrint = height - 1;
while (toPrint > 0 && firstLine < lines.length) {
--- a/langtools/test/jdk/jshell/JavadocTest.java Mon Feb 13 09:37:26 2017 +0100
+++ b/langtools/test/jdk/jshell/JavadocTest.java Mon Feb 13 11:57:56 2017 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8131019 8169561
+ * @bug 8131019 8169561 8174245
* @summary Test Javadoc
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -107,4 +107,51 @@
addToClasspath(compiler.getClassDir());
}
+ public void testCollectionsMin() {
+ prepareJavaUtilZip();
+ assertJavadoc("java.util.Collections.min(|",
+ "T java.util.Collections.<T>min(java.util.Collection<? extends T> coll, java.util.Comparator<? super T> comp)\n" +
+ " min comparator\n",
+ "T java.util.Collections.<T extends Object & Comparable<? super T>>min(java.util.Collection<? extends T> coll)\n" +
+ " min comparable\n");
+ }
+
+ private void prepareJavaUtilZip() {
+ String clazz =
+ "package java.util;\n" +
+ "/**Top level." +
+ " */\n" +
+ "public class Collections {\n" +
+ " /**\n" +
+ " * min comparable\n" +
+ " */\n" +
+ " public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {" +
+ " return null;\n" +
+ " }\n" +
+ " /**\n" +
+ " * min comparator\n" +
+ " */\n" +
+ " public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n";
+
+ Path srcZip = Paths.get("src.zip");
+
+ try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(srcZip))) {
+ out.putNextEntry(new JarEntry("java/util/Collections.java"));
+ out.write(clazz.getBytes());
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+
+ try {
+ Field availableSources = getAnalysis().getClass().getDeclaredField("availableSources");
+ availableSources.setAccessible(true);
+ availableSources.set(getAnalysis(), Arrays.asList(srcZip));
+ } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
}