8174245: Javadoc is not working for some methods
authorjlahoda
Mon, 13 Feb 2017 11:57:56 +0100
changeset 43773 8d8593871575
parent 43772 4e5350b7be75
child 43774 fa3e76b47782
child 43855 f402e32dfbf3
child 43856 fcdebb803c62
8174245: Javadoc is not working for some methods Summary: Parsing source file as if they were part of their corresponding modules. Reviewed-by: rfield
langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
langtools/test/jdk/jshell/JavadocTest.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<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);
+        }
+    }
+
 }