# HG changeset patch # User jlahoda # Date 1486983476 -3600 # Node ID 8d85938715750e1879e4b031dbd33f3559eb0dd0 # Parent 4e5350b7be75eb813de65f448eb5149f000fcae2 8174245: Javadoc is not working for some methods Summary: Parsing source file as if they were part of their corresponding modules. Reviewed-by: rfield diff -r 4e5350b7be75 -r 8d8593871575 langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java --- 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 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 source = findSource(moduleName, binaryName); if (source == null) return null; @@ -636,7 +644,8 @@ }.scan(cut, null); } - private Pair findSource(String binaryName) throws IOException { + private Pair 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 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 cuts = task.parse(); task.enter(); @@ -657,6 +669,61 @@ public void close() throws IOException { fm.close(); } + + private static final class PatchModuleFileManager + extends ForwardingJavaFileManager { + + 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; + } + + }; + } } } diff -r 4e5350b7be75 -r 8d8593871575 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java --- 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) { diff -r 4e5350b7be75 -r 8d8593871575 langtools/test/jdk/jshell/JavadocTest.java --- 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.min(java.util.Collection coll, java.util.Comparator comp)\n" + + " min comparator\n", + "T java.util.Collections.>min(java.util.Collection 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 min(Collection coll) {" + + " return null;\n" + + " }\n" + + " /**\n" + + " * min comparator\n" + + " */\n" + + " public static T min(Collection coll, Comparator 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); + } + } + }