8189778: Jshell crash on tab for StringBuilder.append(
Fixing handling of {@inheritDoc} in JShell's documentation. Reviewed-by: jjg, ksrini
This commit is contained in:
parent
f9431b7d26
commit
390de69601
@ -77,6 +77,7 @@ import com.sun.source.tree.ClassTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.tree.VariableTree;
|
||||
import com.sun.source.util.DocSourcePositions;
|
||||
import com.sun.source.util.DocTreePath;
|
||||
import com.sun.source.util.DocTreeScanner;
|
||||
import com.sun.source.util.DocTrees;
|
||||
@ -194,6 +195,8 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
String docComment = trees.getDocComment(el);
|
||||
|
||||
if (docComment == null && element.getKind() == ElementKind.METHOD) {
|
||||
//if a method does not have a javadoc,
|
||||
//try to use javadoc from the methods overridden by this method:
|
||||
ExecutableElement executableElement = (ExecutableElement) element;
|
||||
Iterable<Element> superTypes =
|
||||
() -> superTypeForInheritDoc(task, element.getEnclosingElement()).iterator();
|
||||
@ -215,27 +218,65 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
if (docComment == null)
|
||||
return null;
|
||||
|
||||
Pair<DocCommentTree, Integer> parsed = parseDocComment(task, docComment);
|
||||
DocCommentTree docCommentTree = parsed.fst;
|
||||
int offset = parsed.snd;
|
||||
IOException[] exception = new IOException[1];
|
||||
Map<int[], String> replace = new TreeMap<>((span1, span2) -> span2[0] - span1[0]);
|
||||
Comparator<int[]> spanComp =
|
||||
(span1, span2) -> span1[0] != span2[0] ? span2[0] - span1[0]
|
||||
: span2[1] - span1[0];
|
||||
//spans in the docComment that should be replaced with the given Strings:
|
||||
Map<int[], List<String>> replace = new TreeMap<>(spanComp);
|
||||
DocSourcePositions sp = trees.getSourcePositions();
|
||||
|
||||
//fill in missing elements and resolve {@inheritDoc}
|
||||
//if an element is (silently) missing in the javadoc, a synthetic {@inheritDoc}
|
||||
//is created for it.
|
||||
new DocTreeScanner<Void, Void>() {
|
||||
/* enclosing doctree that may contain {@inheritDoc} (explicit or synthetic)*/
|
||||
private Stack<DocTree> interestingParent = new Stack<>();
|
||||
/* current top-level DocCommentTree*/
|
||||
private DocCommentTree dcTree;
|
||||
private JavacTask inheritedJavacTask;
|
||||
private TreePath inheritedTreePath;
|
||||
/* javadoc from a super method from which we may copy elements.*/
|
||||
private String inherited;
|
||||
/* JavacTask from which inherited originates.*/
|
||||
private JavacTask inheritedJavacTask;
|
||||
/* TreePath to the super method from which inherited originates.*/
|
||||
private TreePath inheritedTreePath;
|
||||
/* Synthetic trees that contain {@inheritDoc} and
|
||||
* texts which which they should be replaced.*/
|
||||
private Map<DocTree, String> syntheticTrees = new IdentityHashMap<>();
|
||||
private long lastPos = 0;
|
||||
/* Position on which the synthetic trees should be inserted.*/
|
||||
private long insertPos = offset;
|
||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||
public Void visitDocComment(DocCommentTree node, Void p) {
|
||||
dcTree = node;
|
||||
interestingParent.push(node);
|
||||
try {
|
||||
scan(node.getFirstSentence(), p);
|
||||
scan(node.getBody(), p);
|
||||
if (node.getFullBody().isEmpty()) {
|
||||
//there is no body in the javadoc, add synthetic {@inheritDoc}, which
|
||||
//will be automatically filled in visitInheritDoc:
|
||||
DocCommentTree dc = parseDocComment(task, "{@inheritDoc}").fst;
|
||||
syntheticTrees.put(dc, "*\n");
|
||||
interestingParent.push(dc);
|
||||
boolean prevInSynthetic = inSynthetic;
|
||||
try {
|
||||
inSynthetic = true;
|
||||
scan(dc.getFirstSentence(), p);
|
||||
scan(dc.getBody(), p);
|
||||
} finally {
|
||||
inSynthetic = prevInSynthetic;
|
||||
interestingParent.pop();
|
||||
}
|
||||
} else {
|
||||
scan(node.getFirstSentence(), p);
|
||||
scan(node.getBody(), p);
|
||||
}
|
||||
//add missing @param, @throws and @return, augmented with {@inheritDoc}
|
||||
//which will be resolved in visitInheritDoc:
|
||||
List<DocTree> augmentedBlockTags = new ArrayList<>(node.getBlockTags());
|
||||
if (element.getKind() == ElementKind.METHOD) {
|
||||
ExecutableElement executableElement = (ExecutableElement) element;
|
||||
@ -269,19 +310,19 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
|
||||
for (String missingParam : missingParams) {
|
||||
DocTree syntheticTag = parseBlockTag(task, "@param " + missingParam + " {@inheritDoc}");
|
||||
syntheticTrees.put(syntheticTag, "@param " + missingParam + " ");
|
||||
syntheticTrees.put(syntheticTag, "@param " + missingParam + " *\n");
|
||||
insertTag(augmentedBlockTags, syntheticTag, parameters, throwsList);
|
||||
}
|
||||
|
||||
for (String missingThrow : missingThrows) {
|
||||
DocTree syntheticTag = parseBlockTag(task, "@throws " + missingThrow + " {@inheritDoc}");
|
||||
syntheticTrees.put(syntheticTag, "@throws " + missingThrow + " ");
|
||||
syntheticTrees.put(syntheticTag, "@throws " + missingThrow + " *\n");
|
||||
insertTag(augmentedBlockTags, syntheticTag, parameters, throwsList);
|
||||
}
|
||||
|
||||
if (!hasReturn) {
|
||||
DocTree syntheticTag = parseBlockTag(task, "@return {@inheritDoc}");
|
||||
syntheticTrees.put(syntheticTag, "@return ");
|
||||
syntheticTrees.put(syntheticTag, "@return *\n");
|
||||
insertTag(augmentedBlockTags, syntheticTag, parameters, throwsList);
|
||||
}
|
||||
}
|
||||
@ -320,26 +361,32 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
}
|
||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||
public Void visitInheritDoc(InheritDocTree node, Void p) {
|
||||
//replace (schedule replacement into the replace map)
|
||||
//{@inheritDoc} with the corresponding text from an overridden method
|
||||
|
||||
//first, fill in inherited, inheritedJavacTask and inheritedTreePath if not
|
||||
//done yet:
|
||||
if (inherited == null) {
|
||||
try {
|
||||
if (element.getKind() == ElementKind.METHOD) {
|
||||
ExecutableElement executableElement = (ExecutableElement) element;
|
||||
Iterable<Element> superTypes = () -> superTypeForInheritDoc(task, element.getEnclosingElement()).iterator();
|
||||
OUTER: for (Element sup : superTypes) {
|
||||
for (ExecutableElement supMethod : ElementFilter.methodsIn(sup.getEnclosedElements())) {
|
||||
if (task.getElements().overrides(executableElement, supMethod, (TypeElement) executableElement.getEnclosingElement())) {
|
||||
Pair<JavacTask, TreePath> source = getSourceElement(task, supMethod);
|
||||
Iterable<ExecutableElement> superMethods =
|
||||
() -> superMethodsForInheritDoc(task, executableElement).
|
||||
iterator();
|
||||
for (Element supMethod : superMethods) {
|
||||
Pair<JavacTask, TreePath> source =
|
||||
getSourceElement(task, supMethod);
|
||||
|
||||
if (source != null) {
|
||||
String overriddenComment = getResolvedDocComment(source.fst, source.snd);
|
||||
if (source != null) {
|
||||
String overriddenComment =
|
||||
getResolvedDocComment(source.fst,
|
||||
source.snd);
|
||||
|
||||
if (overriddenComment != null) {
|
||||
inheritedJavacTask = source.fst;
|
||||
inheritedTreePath = source.snd;
|
||||
inherited = overriddenComment;
|
||||
break OUTER;
|
||||
}
|
||||
}
|
||||
if (overriddenComment != null) {
|
||||
inheritedJavacTask = source.fst;
|
||||
inheritedTreePath = source.snd;
|
||||
inherited = overriddenComment;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -357,6 +404,8 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
DocCommentTree inheritedDocTree = parsed.fst;
|
||||
int offset = parsed.snd;
|
||||
List<List<? extends DocTree>> inheritedText = new ArrayList<>();
|
||||
//find the corresponding piece in the inherited javadoc
|
||||
//(interesting parent keeps the enclosing tree):
|
||||
DocTree parent = interestingParent.peek();
|
||||
switch (parent.getKind()) {
|
||||
case DOC_COMMENT:
|
||||
@ -401,18 +450,29 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
long end = Long.MIN_VALUE;
|
||||
|
||||
for (DocTree t : inheritedText.get(0)) {
|
||||
start = Math.min(start, trees.getSourcePositions().getStartPosition(null, inheritedDocTree, t) - offset);
|
||||
end = Math.max(end, trees.getSourcePositions().getEndPosition(null, inheritedDocTree, t) - offset);
|
||||
start = Math.min(start,
|
||||
sp.getStartPosition(null, inheritedDocTree, t) - offset);
|
||||
end = Math.max(end,
|
||||
sp.getEndPosition(null, inheritedDocTree, t) - offset);
|
||||
}
|
||||
String text = inherited.substring((int) start, (int) end);
|
||||
String text = end >= 0 ? inherited.substring((int) start, (int) end) : "";
|
||||
|
||||
if (syntheticTrees.containsKey(parent)) {
|
||||
replace.put(new int[] {(int) lastPos + 1, (int) lastPos}, "\n" + syntheticTrees.get(parent) + text);
|
||||
//if the {@inheritDoc} is inside a synthetic tree, don't delete anything,
|
||||
//but insert the required text
|
||||
//(insertPos is the position at which new stuff should be added):
|
||||
int[] span = new int[] {(int) insertPos, (int) insertPos};
|
||||
replace.computeIfAbsent(span, s -> new ArrayList<>())
|
||||
.add(syntheticTrees.get(parent).replace("*", text));
|
||||
} else {
|
||||
long inheritedStart = trees.getSourcePositions().getStartPosition(null, dcTree, node);
|
||||
long inheritedEnd = trees.getSourcePositions().getEndPosition(null, dcTree, node);
|
||||
//replace the {@inheritDoc} with the full text from
|
||||
//the overridden method:
|
||||
long inheritedStart = sp.getStartPosition(null, dcTree, node);
|
||||
long inheritedEnd = sp.getEndPosition(null, dcTree, node);
|
||||
int[] span = new int[] {(int) inheritedStart, (int) inheritedEnd};
|
||||
|
||||
replace.put(new int[] {(int) inheritedStart, (int) inheritedEnd}, text);
|
||||
replace.computeIfAbsent(span, s -> new ArrayList<>())
|
||||
.add(text);
|
||||
}
|
||||
}
|
||||
return super.visitInheritDoc(node, p);
|
||||
@ -428,13 +488,31 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
inSynthetic |= syntheticTrees.containsKey(tree);
|
||||
return super.scan(tree, p);
|
||||
} finally {
|
||||
if (!inSynthetic) {
|
||||
lastPos = trees.getSourcePositions().getEndPosition(null, dcTree, tree);
|
||||
if (!inSynthetic && tree != null) {
|
||||
//for nonsynthetic trees, preserve the ending position as the future
|
||||
//insertPos (as future missing elements should be inserted behind
|
||||
//this tree)
|
||||
//if there is a newline immediately behind this tree, insert behind
|
||||
//the newline:
|
||||
long endPos = sp.getEndPosition(null, dcTree, tree);
|
||||
if (endPos >= 0) {
|
||||
if (endPos - offset + 1 < docComment.length() &&
|
||||
docComment.charAt((int) (endPos - offset + 1)) == '\n') {
|
||||
endPos++;
|
||||
}
|
||||
if (endPos - offset < docComment.length()) {
|
||||
insertPos = endPos + 1;
|
||||
} else {
|
||||
insertPos = endPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
inSynthetic = prevInSynthetic;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert a synthetic tag (toInsert) into the list of tags at
|
||||
* an appropriate position.*/
|
||||
private void insertTag(List<DocTree> tags, DocTree toInsert, List<String> parameters, List<String> throwsTypes) {
|
||||
Comparator<DocTree> comp = (tag1, tag2) -> {
|
||||
if (tag1.getKind() == tag2.getKind()) {
|
||||
@ -479,16 +557,30 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
if (replace.isEmpty())
|
||||
return docComment;
|
||||
|
||||
//do actually replace {@inheritDoc} with the new text (as scheduled by the visitor
|
||||
//above):
|
||||
StringBuilder replacedInheritDoc = new StringBuilder(docComment);
|
||||
|
||||
for (Entry<int[], String> e : replace.entrySet()) {
|
||||
replacedInheritDoc.delete(e.getKey()[0] - offset, e.getKey()[1] - offset + 1);
|
||||
replacedInheritDoc.insert(e.getKey()[0] - offset, e.getValue());
|
||||
for (Entry<int[], List<String>> e : replace.entrySet()) {
|
||||
replacedInheritDoc.delete(e.getKey()[0] - offset, e.getKey()[1] - offset);
|
||||
replacedInheritDoc.insert(e.getKey()[0] - offset,
|
||||
e.getValue().stream().collect(Collectors.joining("")));
|
||||
}
|
||||
|
||||
return replacedInheritDoc.toString();
|
||||
}
|
||||
|
||||
/* Find methods from which the given method may inherit javadoc, in the proper order.*/
|
||||
private Stream<ExecutableElement> superMethodsForInheritDoc(JavacTask task,
|
||||
ExecutableElement method) {
|
||||
TypeElement type = (TypeElement) method.getEnclosingElement();
|
||||
|
||||
return this.superTypeForInheritDoc(task, type)
|
||||
.flatMap(sup -> ElementFilter.methodsIn(sup.getEnclosedElements()).stream())
|
||||
.filter(supMethod -> task.getElements().overrides(method, supMethod, type));
|
||||
}
|
||||
|
||||
/* Find types from which methods in type may inherit javadoc, in the proper order.*/
|
||||
private Stream<Element> superTypeForInheritDoc(JavacTask task, Element type) {
|
||||
TypeElement clazz = (TypeElement) type;
|
||||
Stream<Element> result = interfaces(clazz);
|
||||
@ -529,7 +621,7 @@ public abstract class JavadocHelper implements AutoCloseable {
|
||||
};
|
||||
DocCommentTree tree = trees.getDocCommentTree(fo);
|
||||
int offset = (int) trees.getSourcePositions().getStartPosition(null, tree, tree);
|
||||
offset += "<body>".length() + 1;
|
||||
offset += "<body>".length();
|
||||
return Pair.of(tree, offset);
|
||||
} catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
|
@ -23,28 +23,37 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8131019 8190552
|
||||
* @bug 8131019 8189778 8190552
|
||||
* @summary Test JavadocHelper
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/jdk.internal.shellsupport.doc
|
||||
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
|
||||
* @run testng JavadocHelperTest
|
||||
* @run testng/timeout=900/othervm JavadocHelperTest
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.ModuleElement.ExportsDirective;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.DiagnosticListener;
|
||||
@ -70,15 +79,15 @@ public class JavadocHelperTest {
|
||||
"Top level. ");
|
||||
doTestJavadoc("",
|
||||
t -> getFirstMethod(t, "test.Super"),
|
||||
" javadoc1A\n" +
|
||||
" javadoc1\n" +
|
||||
"\n" +
|
||||
" @param p1 param1A\n" +
|
||||
" @param p2 param2A\n" +
|
||||
" @param p3 param3A\n" +
|
||||
" @throws IllegalStateException exc1A\n" +
|
||||
" @throws IllegalArgumentException exc2A\n" +
|
||||
" @throws IllegalAccessException exc3A\n" +
|
||||
" @return valueA\n");
|
||||
" @param p1 param1\n" +
|
||||
" @param p2 param2\n" +
|
||||
" @param p3 param3\n" +
|
||||
" @throws IllegalStateException exc1\n" +
|
||||
" @throws IllegalArgumentException exc2\n" +
|
||||
" @throws IllegalAccessException exc3\n" +
|
||||
" @return value\n");
|
||||
}
|
||||
|
||||
private Element getFirstMethod(JavacTask task, String typeName) {
|
||||
@ -90,15 +99,15 @@ public class JavadocHelperTest {
|
||||
public void testInheritNoJavadoc() throws Exception {
|
||||
doTestJavadoc("",
|
||||
getSubTest,
|
||||
" javadoc1A\n" +
|
||||
" javadoc1\n" +
|
||||
"\n" +
|
||||
" @param p1 param1A\n" +
|
||||
" @param p2 param2A\n" +
|
||||
" @param p3 param3A\n" +
|
||||
" @throws IllegalStateException exc1A\n" +
|
||||
" @throws IllegalArgumentException exc2A\n" +
|
||||
" @throws IllegalAccessException exc3A\n" +
|
||||
" @return valueA\n");
|
||||
" @param p1 param1\n" +
|
||||
" @param p2 param2\n" +
|
||||
" @param p3 param3\n" +
|
||||
" @throws IllegalStateException exc1\n" +
|
||||
" @throws IllegalArgumentException exc2\n" +
|
||||
" @throws IllegalAccessException exc3\n" +
|
||||
" @return value\n");
|
||||
}
|
||||
|
||||
public void testInheritFull() throws Exception {
|
||||
@ -140,7 +149,7 @@ public class JavadocHelperTest {
|
||||
" Prefix javadoc1 suffix.\n" +
|
||||
"\n" +
|
||||
" @param p1 prefix param1 suffix\n" +
|
||||
"@param p2 param2\n" +
|
||||
"@param p2 param2\n" +
|
||||
" @param p3 prefix param3 suffix\n" +
|
||||
" @throws IllegalStateException prefix exc1 suffix\n" +
|
||||
" @throws IllegalArgumentException prefix exc2 suffix\n" +
|
||||
@ -161,8 +170,8 @@ public class JavadocHelperTest {
|
||||
" */\n",
|
||||
getSubTest,
|
||||
" Prefix javadoc1 suffix.\n" +
|
||||
"@param p1 param1\n" +
|
||||
"\n" +
|
||||
"@param p1 param1\n" +
|
||||
" @param p2 prefix param2 suffix\n" +
|
||||
" @param p3 prefix param3 suffix\n" +
|
||||
" @throws IllegalStateException prefix exc1 suffix\n" +
|
||||
@ -189,7 +198,7 @@ public class JavadocHelperTest {
|
||||
" @param p2 prefix param2 suffix\n" +
|
||||
" @param p3 prefix param3 suffix\n" +
|
||||
" @throws IllegalStateException prefix exc1 suffix\n" +
|
||||
"@throws java.lang.IllegalArgumentException exc2\n" +
|
||||
"@throws java.lang.IllegalArgumentException exc2\n" +
|
||||
" @throws IllegalAccessException prefix exc3 suffix\n" +
|
||||
" @return prefix value suffix\n");
|
||||
}
|
||||
@ -214,11 +223,101 @@ public class JavadocHelperTest {
|
||||
" @throws IllegalStateException prefix exc1 suffix\n" +
|
||||
" @throws IllegalArgumentException prefix exc2 suffix\n" +
|
||||
" @throws IllegalAccessException prefix exc3 suffix\n" +
|
||||
"@return value\n");
|
||||
"@return value\n");
|
||||
}
|
||||
|
||||
public void testInheritAllButOne() throws Exception {
|
||||
doTestJavadoc(" /**\n" +
|
||||
" * @throws IllegalArgumentException {@inheritDoc}\n" +
|
||||
" */\n",
|
||||
getSubTest,
|
||||
"javadoc1\n" +
|
||||
"@param p1 param1\n" +
|
||||
"@param p2 param2\n" +
|
||||
"@param p3 param3\n" +
|
||||
"@throws java.lang.IllegalStateException exc1\n" +
|
||||
" @throws IllegalArgumentException exc2\n" +
|
||||
"@throws java.lang.IllegalAccessException exc3\n" +
|
||||
"@return value\n");
|
||||
}
|
||||
|
||||
public void testInheritEmpty() throws Exception {
|
||||
doTestJavadoc(" /**\n" +
|
||||
" */\n",
|
||||
" /**@param p1\n" +
|
||||
" * @param p2\n" +
|
||||
" * @param p3\n" +
|
||||
" * @throws IllegalStateException\n" +
|
||||
" * @throws IllegalArgumentException\n" +
|
||||
" * @throws IllegalAccessException\n" +
|
||||
" * @return\n" +
|
||||
" */\n",
|
||||
getSubTest,
|
||||
"\n" +
|
||||
"@param p1 \n" +
|
||||
"@param p2 \n" +
|
||||
"@param p3 \n" +
|
||||
"@throws java.lang.IllegalStateException \n" +
|
||||
"@throws java.lang.IllegalArgumentException \n" +
|
||||
"@throws java.lang.IllegalAccessException \n" +
|
||||
"@return \n");
|
||||
}
|
||||
|
||||
public void testEmptyValue() throws Exception {
|
||||
doTestJavadoc(" /**\n" +
|
||||
" */\n",
|
||||
" /**@param p1 {@value}\n" +
|
||||
" * @param p2\n" +
|
||||
" * @param p3\n" +
|
||||
" * @throws IllegalStateException\n" +
|
||||
" * @throws IllegalArgumentException\n" +
|
||||
" * @throws IllegalAccessException\n" +
|
||||
" * @return\n" +
|
||||
" */\n",
|
||||
getSubTest,
|
||||
"\n" +
|
||||
"@param p1 {@value}\n" +
|
||||
"@param p2 \n" +
|
||||
"@param p3 \n" +
|
||||
"@throws java.lang.IllegalStateException \n" +
|
||||
"@throws java.lang.IllegalArgumentException \n" +
|
||||
"@throws java.lang.IllegalAccessException \n" +
|
||||
"@return \n");
|
||||
}
|
||||
|
||||
public void testShortComment() throws Exception {
|
||||
doTestJavadoc(" /**Test.*/\n",
|
||||
getSubTest,
|
||||
"Test." +
|
||||
"@param p1 param1\n" +
|
||||
"@param p2 param2\n" +
|
||||
"@param p3 param3\n" +
|
||||
"@throws java.lang.IllegalStateException exc1\n" +
|
||||
"@throws java.lang.IllegalArgumentException exc2\n" +
|
||||
"@throws java.lang.IllegalAccessException exc3\n" +
|
||||
"@return value\n");
|
||||
}
|
||||
|
||||
private void doTestJavadoc(String origJavadoc, Function<JavacTask, Element> getElement, String expectedJavadoc) throws Exception {
|
||||
doTestJavadoc(origJavadoc,
|
||||
" /**\n" +
|
||||
" * javadoc1\n" +
|
||||
" *\n" +
|
||||
" * @param p1 param1\n" +
|
||||
" * @param p2 param2\n" +
|
||||
" * @param p3 param3\n" +
|
||||
" * @throws IllegalStateException exc1\n" +
|
||||
" * @throws IllegalArgumentException exc2\n" +
|
||||
" * @throws IllegalAccessException exc3\n" +
|
||||
" * @return value\n" +
|
||||
" */\n",
|
||||
getElement, expectedJavadoc);
|
||||
}
|
||||
|
||||
private void doTestJavadoc(String origJavadoc,
|
||||
String superJavadoc,
|
||||
Function<JavacTask, Element> getElement,
|
||||
String expectedJavadoc) throws Exception {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
String subClass =
|
||||
"package test;\n" +
|
||||
@ -231,17 +330,7 @@ public class JavadocHelperTest {
|
||||
"/**Top level." +
|
||||
" */\n" +
|
||||
"public class Super {\n" +
|
||||
" /**\n" +
|
||||
" * javadoc1A\n" +
|
||||
" *\n" +
|
||||
" * @param p1 param1A\n" +
|
||||
" * @param p2 param2A\n" +
|
||||
" * @param p3 param3A\n" +
|
||||
" * @throws IllegalStateException exc1A\n" +
|
||||
" * @throws IllegalArgumentException exc2A\n" +
|
||||
" * @throws IllegalAccessException exc3A\n" +
|
||||
" * @return valueA\n" +
|
||||
" */\n" +
|
||||
superJavadoc +
|
||||
" public String test(int p1, int p2, int p3) throws IllegalStateException, IllegalArgumentException, IllegalAccessException { return null;} \n" +
|
||||
"}\n";
|
||||
|
||||
@ -293,4 +382,53 @@ public class JavadocHelperTest {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testAllDocs() throws IOException {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
DiagnosticListener<? super JavaFileObject> noErrors = d -> {
|
||||
if (d.getKind() == Kind.ERROR) {
|
||||
throw new AssertionError(d.getMessage(null));
|
||||
}
|
||||
};
|
||||
|
||||
List<Path> sources = new ArrayList<>();
|
||||
Path home = Paths.get(System.getProperty("java.home"));
|
||||
Path srcZip = home.resolve("lib").resolve("src.zip");
|
||||
if (Files.isReadable(srcZip)) {
|
||||
URI uri = URI.create("jar:" + srcZip.toUri());
|
||||
try (FileSystem zipFO = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
|
||||
Path root = zipFO.getRootDirectories().iterator().next();
|
||||
|
||||
//modular format:
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(root)) {
|
||||
for (Path p : ds) {
|
||||
if (Files.isDirectory(p)) {
|
||||
sources.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
try (StandardJavaFileManager fm =
|
||||
compiler.getStandardFileManager(null, null, null)) {
|
||||
JavacTask task =
|
||||
(JavacTask) compiler.getTask(null, fm, noErrors, null, null, null);
|
||||
task.getElements().getTypeElement("java.lang.Object");
|
||||
for (ModuleElement me : task.getElements().getAllModuleElements()) {
|
||||
List<ExportsDirective> exports =
|
||||
ElementFilter.exportsIn(me.getDirectives());
|
||||
for (ExportsDirective ed : exports) {
|
||||
try (JavadocHelper helper = JavadocHelper.create(task, sources)) {
|
||||
List<? extends Element> content =
|
||||
ed.getPackage().getEnclosedElements();
|
||||
for (TypeElement clazz : ElementFilter.typesIn(content)) {
|
||||
for (Element el : clazz.getEnclosedElements()) {
|
||||
helper.getResolvedDocComment(el);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user