8174245: Javadoc is not working for some methods

Parsing source file as if they were part of their corresponding modules.

Reviewed-by: rfield
This commit is contained in:
Jan Lahoda 2017-02-13 11:57:56 +01:00
parent 261ce92be5
commit 4c9c591399
3 changed files with 121 additions and 5 deletions

View File

@ -49,12 +49,15 @@ import java.util.stream.Stream;
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 @@ public abstract class JavadocHelper implements AutoCloseable {
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 @@ public abstract class JavadocHelper implements AutoCloseable {
}.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 @@ public abstract class JavadocHelper implements AutoCloseable {
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 abstract class JavadocHelper implements AutoCloseable {
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;
}
};
}
}
}

View File

@ -310,6 +310,8 @@ class ConsoleIOContext extends IOContext {
int firstLine = 0;
PRINT_PAGE: while (true) {
in.print(lastNote.replaceAll(".", " ") + ConsoleReader.RESET_LINE);
int toPrint = height - 1;
while (toPrint > 0 && firstLine < lines.length) {

View File

@ -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 @@ public class JavadocTest extends KullaTesting {
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);
}
}
}