8132096: Augment the Compiler Tree API to support the new Simplified Doclet API

Reviewed-by: jjg, jlahoda
This commit is contained in:
Kumar Srinivasan 2015-10-28 10:41:30 -07:00
parent 1b3ee82ffc
commit 2711685247
18 changed files with 1388 additions and 122 deletions

View File

@ -25,11 +25,14 @@
package com.sun.source.util;
import java.io.IOException;
import java.text.BreakIterator;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaCompiler.CompilationTask;
import com.sun.source.doctree.DocCommentTree;
@ -64,6 +67,16 @@ public abstract class DocTrees extends Trees {
return (DocTrees) getJavacTrees(ProcessingEnvironment.class, env);
}
/**
* Returns the break iterator used to compute the first sentence of
* documentation comments.
* Returns {@code null} if none has been specified.
* @return the break iterator
*
* @since 1.9
*/
public abstract BreakIterator getBreakIterator();
/**
* Returns the doc comment tree, if any, for the Tree node identified by a given TreePath.
* Returns {@code null} if no doc comment was found.
@ -72,6 +85,47 @@ public abstract class DocTrees extends Trees {
*/
public abstract DocCommentTree getDocCommentTree(TreePath path);
/**
* Returns the doc comment tree of the given element.
* Returns {@code null} if no doc comment was found.
* @param e an element whose documentation is required
* @return the doc comment tree
*
* @since 1.9
*/
public abstract DocCommentTree getDocCommentTree(Element e);
/**
* Returns the doc comment tree of the given file. The file must be
* an HTML file, in which case the doc comment tree represents the
* contents of the <body> tag, and any enclosing tags are ignored.
* Returns {@code null} if no doc comment was found.
* Future releases may support additional file types.
*
* @param fileObject the content container
* @return the doc comment tree
*
* @since 1.9
*/
public abstract DocCommentTree getDocCommentTree(FileObject fileObject);
/**
* Returns the doc comment tree of the given file whose path is
* specified relative to the given element. The file must be an HTML
* file, in which case the doc comment tree represents the contents
* of the <body> tag, and any enclosing tags are ignored.
* Returns {@code null} if no doc comment was found.
* Future releases may support additional file types.
*
* @param e an element whose path is used as a reference
* @param relativePath the relative path from the Element
* @return the doc comment tree
* @throws java.io.IOException if an exception occurs
*
* @since 1.9
*/
public abstract DocCommentTree getDocCommentTree(Element e, String relativePath) throws IOException;
/**
* Returns the language model element referred to by the leaf node of the given
* {@link DocTreePath}, or {@code null} if unknown.
@ -112,4 +166,14 @@ public abstract class DocTrees extends Trees {
com.sun.source.doctree.DocTree t,
com.sun.source.doctree.DocCommentTree c,
com.sun.source.tree.CompilationUnitTree root);
/**
* Sets the break iterator to compute the first sentence of
* documentation comments.
* @param breakiterator a break iterator or {@code null} to specify the default
* sentence breaker
*
* @since 1.9
*/
public abstract void setBreakIterator(BreakIterator breakiterator);
}

View File

@ -25,8 +25,13 @@
package com.sun.tools.javac.api;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.BreakIterator;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
@ -34,13 +39,22 @@ import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.ForwardingFileObject;
import javax.tools.ForwardingJavaFileObject;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
@ -74,7 +88,12 @@ import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.MemberEnter;
import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.parser.DocCommentParser;
import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.DCTree;
import com.sun.tools.javac.tree.DCTree.DCBlockTag;
@ -104,6 +123,7 @@ import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.DiagnosticSource;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.List;
@ -141,6 +161,9 @@ public class JavacTrees extends DocTrees {
private Names names;
private Types types;
private DocTreeMaker doctreeMaker;
private BreakIterator breakIterator;
private JavaFileManager fileManager;
private ParserFactory parser;
// called reflectively from Trees.instance(CompilationTask task)
public static JavacTrees instance(JavaCompiler.CompilationTask task) {
@ -164,6 +187,7 @@ public class JavacTrees extends DocTrees {
}
protected JavacTrees(Context context) {
this.breakIterator = null;
context.put(JavacTrees.class, this);
init(context);
}
@ -183,31 +207,37 @@ public class JavacTrees extends DocTrees {
names = Names.instance(context);
types = Types.instance(context);
doctreeMaker = DocTreeMaker.instance(context);
parser = ParserFactory.instance(context);
fileManager = context.get(JavaFileManager.class);
JavacTask t = context.get(JavacTask.class);
if (t instanceof JavacTaskImpl)
javacTaskImpl = (JavacTaskImpl) t;
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public BreakIterator getBreakIterator() {
return breakIterator;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public DocSourcePositions getSourcePositions() {
return new DocSourcePositions() {
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public long getStartPosition(CompilationUnitTree file, Tree tree) {
return TreeInfo.getStartPos((JCTree) tree);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public long getEndPosition(CompilationUnitTree file, Tree tree) {
EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
return TreeInfo.getEndPos((JCTree) tree, endPosTable);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
return ((DCTree) tree).getSourcePosition((DCDocComment) comment);
}
@SuppressWarnings("fallthrough") @DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("fallthrough")
public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
DCDocComment dcComment = (DCDocComment) comment;
if (tree instanceof DCEndPosTree) {
@ -278,27 +308,27 @@ public class JavacTrees extends DocTrees {
return last[0];
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JCClassDecl getTree(TypeElement element) {
return (JCClassDecl) getTree((Element) element);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JCMethodDecl getTree(ExecutableElement method) {
return (JCMethodDecl) getTree((Element) method);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree getTree(Element element) {
return getTree(element, null);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree getTree(Element e, AnnotationMirror a) {
return getTree(e, a, null);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree getTree(Element e, AnnotationMirror a, AnnotationValue v) {
Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
if (treeTopLevel == null)
@ -306,22 +336,22 @@ public class JavacTrees extends DocTrees {
return treeTopLevel.fst;
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TreePath getPath(CompilationUnitTree unit, Tree node) {
return TreePath.getPath(unit, node);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TreePath getPath(Element e) {
return getPath(e, null, null);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TreePath getPath(Element e, AnnotationMirror a) {
return getPath(e, a, null);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TreePath getPath(Element e, AnnotationMirror a, AnnotationValue v) {
final Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
if (treeTopLevel == null)
@ -329,7 +359,7 @@ public class JavacTrees extends DocTrees {
return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public Symbol getElement(TreePath path) {
JCTree tree = (JCTree) path.getLeaf();
Symbol sym = TreeInfo.symbolFor(tree);
@ -479,7 +509,7 @@ public class JavacTrees extends DocTrees {
/** @see com.sun.tools.javadoc.ClassDocImpl#findField */
private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
return searchField(tsym, fieldName, new HashSet<ClassSymbol>());
return searchField(tsym, fieldName, new HashSet<>());
}
/** @see com.sun.tools.javadoc.ClassDocImpl#searchField */
@ -543,7 +573,7 @@ public class JavacTrees extends DocTrees {
/** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */
private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
return searchMethod(tsym, methodName, paramTypes, new HashSet<ClassSymbol>());
return searchMethod(tsym, methodName, paramTypes, new HashSet<>());
}
/** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */
@ -708,19 +738,19 @@ public class JavacTrees extends DocTrees {
}
};
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TypeMirror getTypeMirror(TreePath path) {
Tree t = path.getLeaf();
Type ty = ((JCTree)t).type;
return ty == null ? null : ty.stripMetadataIfNeeded();
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public JavacScope getScope(TreePath path) {
return JavacScope.create(getAttrContext(path));
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public String getDocComment(TreePath path) {
CompilationUnitTree t = path.getCompilationUnit();
Tree leaf = path.getLeaf();
@ -733,7 +763,7 @@ public class JavacTrees extends DocTrees {
return null;
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public DocCommentTree getDocCommentTree(TreePath path) {
CompilationUnitTree t = path.getCompilationUnit();
Tree leaf = path.getLeaf();
@ -746,7 +776,28 @@ public class JavacTrees extends DocTrees {
return null;
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public DocCommentTree getDocCommentTree(Element e) {
TreePath path = getPath(e);
if (path == null) {
return null;
}
return getDocCommentTree(path);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public DocCommentTree getDocCommentTree(Element e, String relativeFileName) throws IOException {
PackageElement pkg = elements.getPackageOf(e);
FileObject fileForInput = fileManager.getFileForInput(StandardLocation.SOURCE_PATH,
pkg.getQualifiedName().toString(), relativeFileName);
if (fileForInput == null) {
throw new FileNotFoundException(relativeFileName);
}
return getDocCommentTree(fileForInput);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public boolean isAccessible(Scope scope, TypeElement type) {
if (scope instanceof JavacScope && type instanceof ClassSymbol) {
Env<AttrContext> env = ((JavacScope) scope).env;
@ -755,7 +806,7 @@ public class JavacTrees extends DocTrees {
return false;
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public boolean isAccessible(Scope scope, Element member, DeclaredType type) {
if (scope instanceof JavacScope
&& member instanceof Symbol
@ -862,6 +913,109 @@ public class JavacTrees extends DocTrees {
}
}
private JavaFileObject asJavaFileObject(FileObject fileObject) {
JavaFileObject jfo = null;
if (fileObject instanceof JavaFileObject) {
jfo = (JavaFileObject) fileObject;
checkHtmlKind(fileObject, Kind.HTML);
return jfo;
}
checkHtmlKind(fileObject);
jfo = new HtmlFileObject(fileObject);
return jfo;
}
private void checkHtmlKind(FileObject fileObject) {
checkHtmlKind(fileObject, BaseFileManager.getKind(fileObject.getName()));
}
private void checkHtmlKind(FileObject fileObject, JavaFileObject.Kind kind) {
if (kind != JavaFileObject.Kind.HTML) {
throw new IllegalArgumentException("HTML file expected:" + fileObject.getName());
}
}
private static class HtmlFileObject extends ForwardingFileObject<FileObject>
implements JavaFileObject {
public HtmlFileObject(FileObject fileObject) {
super(fileObject);
}
@Override @DefinedBy(Api.COMPILER)
public Kind getKind() {
return BaseFileManager.getKind(fileObject.getName());
}
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String simpleName, Kind kind) {
return false;
}
@Override @DefinedBy(Api.COMPILER)
public NestingKind getNestingKind() {
return null;
}
@Override @DefinedBy(Api.COMPILER)
public Modifier getAccessLevel() {
return null;
}
}
@Override @DefinedBy(Api.COMPILER_TREE)
public DocCommentTree getDocCommentTree(FileObject fileObject) {
JavaFileObject jfo = asJavaFileObject(fileObject);
DiagnosticSource diagSource = new DiagnosticSource(jfo, log);
final Comment comment = new Comment() {
int offset = 0;
@Override
public String getText() {
try {
CharSequence rawDoc = fileObject.getCharContent(true);
Pattern bodyPat =
Pattern.compile("(?is).*?<body\\b[^>]*>(.*)</body\\b.*");
Matcher m = bodyPat.matcher(rawDoc);
if (m.matches()) {
offset = m.end(1);
return m.group(1);
} else {
// Assume doclint will do the right thing.
return "";
}
} catch (IOException ignore) {
// do nothing
}
return "";
}
@Override
public int getSourcePos(int index) {
return offset + index;
}
@Override
public CommentStyle getStyle() {
throw new UnsupportedOperationException();
}
@Override
public boolean isDeprecated() {
throw new UnsupportedOperationException();
}
};
return new DocCommentParser(parser, diagSource, comment).parse();
}
@Override @DefinedBy(Api.COMPILER_TREE)
public void setBreakIterator(BreakIterator breakiterator) {
this.breakIterator = breakiterator;
}
/**
* Makes a copy of a tree, noting the value resulting from copying a particular leaf.
**/
@ -891,7 +1045,7 @@ public class JavacTrees extends DocTrees {
* @return TypeMirror corresponding to the original type, replaced by the ErrorType.
* noType (type.tag == NONE) is returned if there is no original type.
*/
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) {
return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType();
@ -909,14 +1063,14 @@ public class JavacTrees extends DocTrees {
* @param t the tree to use as a position hint
* @param root the compilation unit that contains tree
*/
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public void printMessage(Diagnostic.Kind kind, CharSequence msg,
com.sun.source.tree.Tree t,
com.sun.source.tree.CompilationUnitTree root) {
printMessage(kind, msg, ((JCTree) t).pos(), root);
}
@DefinedBy(Api.COMPILER_TREE)
@Override @DefinedBy(Api.COMPILER_TREE)
public void printMessage(Diagnostic.Kind kind, CharSequence msg,
com.sun.source.doctree.DocTree t,
com.sun.source.doctree.DocCommentTree c,
@ -971,4 +1125,30 @@ public class JavacTrees extends DocTrees {
return v.type;
}
}
public TreePath makeTreePath(final FileObject fileObject, final int offset) {
JavaFileObject jfo = asJavaFileObject(fileObject);
JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
public int getPos() {
return offset;
}
public JavaFileObject getSourcefile() {
return jfo;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public Position.LineMap getLineMap() {
try {
CharSequence content = fileObject.getCharContent(true);
String s = content.toString();
return Position.makeLineMap(s.toCharArray(), s.length(), true);
} catch (IOException ignore) {}
return null;
}
};
jcCompilationUnit.sourcefile = jfo;
enter.main(List.of(jcCompilationUnit));
return new TreePath(jcCompilationUnit);
}
}

View File

@ -30,15 +30,15 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.ListIterator;
import java.util.Locale;
import com.sun.source.doctree.AttributeTree.ValueKind;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.tools.doclint.HtmlTag;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.tree.DCTree.DCAttribute;
import com.sun.tools.javac.tree.DCTree.DCAuthor;
@ -75,7 +75,6 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair;
import com.sun.tools.javac.util.Position;
@ -97,8 +96,6 @@ public class DocTreeMaker {
// anywhere but the zero'th position in the first sentence.
final EnumSet<HtmlTag> sentenceBreakTags;
private final BreakIterator sentenceBreaker;
/** Get the TreeMaker instance. */
public static DocTreeMaker instance(Context context) {
DocTreeMaker instance = context.get(treeMakerKey);
@ -114,21 +111,16 @@ public class DocTreeMaker {
/** Access to diag factory for ErroneousTrees. */
private final JCDiagnostic.Factory diags;
private final JavacTrees trees;
/** Create a tree maker with NOPOS as initial position.
*/
protected DocTreeMaker(Context context) {
context.put(treeMakerKey, this);
diags = JCDiagnostic.Factory.instance(context);
this.pos = Position.NOPOS;
trees = JavacTrees.instance(context);
sentenceBreakTags = EnumSet.of(H1, H2, H3, H4, H5, H6, PRE, P);
Locale locale = (context.get(Locale.class) != null)
? context.get(Locale.class)
: Locale.getDefault();
Options options = Options.instance(context);
boolean useBreakIterator = options.isSet("breakiterator");
sentenceBreaker = (useBreakIterator || !locale.getLanguage().equals(Locale.ENGLISH.getLanguage()))
? BreakIterator.getSentenceInstance(locale)
: null;
}
/** Reassign current position.
@ -176,10 +168,23 @@ public class DocTreeMaker {
}
public DCDocComment DocComment(Comment comment, List<DCTree> fullBody, List<DCTree> tags) {
final int savepos = pos;
Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
DCDocComment tree = new DCDocComment(comment, fullBody, pair.fst, pair.snd, tags);
this.pos = tree.pos = savepos;
tree.pos = pos;
return tree;
}
/*
* Primarily to produce a DocCommenTree when given a
* first sentence and a body, this is useful, in cases
* where the trees are being synthesized by a tool.
*/
public DCDocComment DocComment(List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
ListBuffer<DCTree> lb = new ListBuffer<>();
lb.addAll(firstSentence);
lb.addAll(body);
List<DCTree> fullBody = lb.toList();
DCDocComment tree = new DCDocComment(null, fullBody, firstSentence, body, tags);
return tree;
}
@ -341,74 +346,88 @@ public class DocTreeMaker {
/*
* Breaks up the body tags into the first sentence and its successors.
* The first sentence is determined with the presence of a period, block tag,
* or a sentence break, as returned by the BreakIterator. Trailing
* whitespaces are trimmed.
* The first sentence is determined with the presence of a period,
* block tag, or a sentence break, as returned by the BreakIterator.
* Trailing whitespaces are trimmed.
*/
Pair<List<DCTree>, List<DCTree>> splitBody(Collection<? extends DocTree> list) {
ListBuffer<DCTree> body = new ListBuffer<>();
// split body into first sentence and body
ListBuffer<DCTree> fs = new ListBuffer<>();
if (list.isEmpty()) {
return new Pair<>(fs.toList(), body.toList());
}
boolean foundFirstSentence = false;
ArrayList<DocTree> alist = new ArrayList<>(list);
ListIterator<DocTree> itr = alist.listIterator();
while (itr.hasNext()) {
boolean isFirst = itr.previousIndex() == -1;
DocTree dt = itr.next();
int spos = ((DCTree)dt).pos;
if (foundFirstSentence) {
body.add((DCTree) dt);
continue;
private Pair<List<DCTree>, List<DCTree>> splitBody(Collection<? extends DocTree> list) {
// pos is modified as we create trees, therefore
// we save the pos and restore it later.
final int savedpos = this.pos;
try {
ListBuffer<DCTree> body = new ListBuffer<>();
// split body into first sentence and body
ListBuffer<DCTree> fs = new ListBuffer<>();
if (list.isEmpty()) {
return new Pair<>(fs.toList(), body.toList());
}
switch (dt.getKind()) {
case TEXT:
DCText tt = (DCText)dt;
String s = tt.getBody();
int sbreak = getSentenceBreak(s);
if (sbreak > 0) {
s = removeTrailingWhitespace(s.substring(0, sbreak));
DCText text = this.at(spos).Text(s);
fs.add(text);
foundFirstSentence = true;
int nwPos = skipWhiteSpace(tt.getBody(), sbreak);
if (nwPos > 0) {
DCText text2 = this.at(spos + nwPos).Text(tt.getBody().substring(nwPos));
body.add(text2);
}
continue;
} else if (itr.hasNext()) {
// if the next doctree is a break, remove trailing spaces
DocTree next = itr.next();
boolean sbrk = isSentenceBreak(next, false);
if (sbrk) {
s = removeTrailingWhitespace(s);
boolean foundFirstSentence = false;
ArrayList<DocTree> alist = new ArrayList<>(list);
ListIterator<DocTree> itr = alist.listIterator();
while (itr.hasNext()) {
boolean isFirst = !itr.hasPrevious();
DocTree dt = itr.next();
int spos = ((DCTree) dt).pos;
if (foundFirstSentence) {
body.add((DCTree) dt);
continue;
}
switch (dt.getKind()) {
case TEXT:
DCText tt = (DCText) dt;
String s = tt.getBody();
DocTree peekedNext = itr.hasNext()
? alist.get(itr.nextIndex())
: null;
int sbreak = getSentenceBreak(s, peekedNext);
if (sbreak > 0) {
s = removeTrailingWhitespace(s.substring(0, sbreak));
DCText text = this.at(spos).Text(s);
fs.add(text);
body.add((DCTree)next);
foundFirstSentence = true;
int nwPos = skipWhiteSpace(tt.getBody(), sbreak);
if (nwPos > 0) {
DCText text2 = this.at(spos + nwPos).Text(tt.getBody().substring(nwPos));
body.add(text2);
}
continue;
} else if (itr.hasNext()) {
// if the next doctree is a break, remove trailing spaces
peekedNext = alist.get(itr.nextIndex());
boolean sbrk = isSentenceBreak(peekedNext, false);
if (sbrk) {
DocTree next = itr.next();
s = removeTrailingWhitespace(s);
DCText text = this.at(spos).Text(s);
fs.add(text);
body.add((DCTree) next);
foundFirstSentence = true;
continue;
}
}
break;
default:
if (isSentenceBreak(dt, isFirst)) {
body.add((DCTree) dt);
foundFirstSentence = true;
continue;
}
// reset to previous for further processing
itr.previous();
}
break;
default:
if (isSentenceBreak(dt, isFirst)) {
body.add((DCTree)dt);
foundFirstSentence = true;
continue;
}
break;
}
fs.add((DCTree) dt);
}
fs.add((DCTree)dt);
return new Pair<>(fs.toList(), body.toList());
} finally {
this.pos = savedpos;
}
return new Pair<>(fs.toList(), body.toList());
}
private boolean isTextTree(DocTree tree) {
return tree.getKind() == Kind.TEXT;
}
/*
* Computes the first sentence break.
* Computes the first sentence break, a simple dot-space algorithm.
*/
int defaultSentenceBreak(String s) {
// scan for period followed by whitespace
@ -437,12 +456,74 @@ public class DocTreeMaker {
return -1;
}
int getSentenceBreak(String s) {
if (sentenceBreaker == null) {
/*
* Computes the first sentence, if using a default breaker,
* the break is returned, if not then a -1, indicating that
* more doctree elements are required to be examined.
*
* BreakIterator.next points to the the start of the following sentence,
* and does not provide an easy way to disambiguate between "sentence break",
* "possible sentence break" and "not a sentence break" at the end of the input.
* For example, BreakIterator.next returns the index for the end
* of the string for all of these examples,
* using vertical bars to delimit the bounds of the example text
* |Abc| (not a valid end of sentence break, if followed by more text)
* |Abc.| (maybe a valid end of sentence break, depending on the following text)
* |Abc. | (maybe a valid end of sentence break, depending on the following text)
* |"Abc." | (maybe a valid end of sentence break, depending on the following text)
* |Abc. | (definitely a valid end of sentence break)
* |"Abc." | (definitely a valid end of sentence break)
* Therefore, we have to probe further to determine whether
* there really is a sentence break or not at the end of this run of text.
*/
int getSentenceBreak(String s, DocTree dt) {
BreakIterator breakIterator = trees.getBreakIterator();
if (breakIterator == null) {
return defaultSentenceBreak(s);
}
sentenceBreaker.setText(s);
return sentenceBreaker.first();
breakIterator.setText(s);
final int sbrk = breakIterator.next();
// This is the last doctree, found the droid we are looking for
if (dt == null) {
return sbrk;
}
// If the break is well within the span of the string ie. not
// at EOL, then we have a clear break.
if (sbrk < s.length() - 1) {
return sbrk;
}
if (isTextTree(dt)) {
// Two adjacent text trees, a corner case, perhaps
// produced by a tool synthesizing a doctree. In
// this case, does the break lie within the first span,
// then we have the droid, otherwise allow the callers
// logic to handle the break in the adjacent doctree.
TextTree ttnext = (TextTree) dt;
String combined = s + ttnext.getBody();
breakIterator.setText(combined);
int sbrk2 = breakIterator.next();
if (sbrk < sbrk2) {
return sbrk;
}
}
// Is the adjacent tree a sentence breaker ?
if (isSentenceBreak(dt, false)) {
return sbrk;
}
// At this point the adjacent tree is either a javadoc tag ({@..),
// html tag (<..) or an entity (&..). Perform a litmus test, by
// concatenating a sentence, to validate the break earlier identified.
String combined = s + "Dummy Sentence.";
breakIterator.setText(combined);
int sbrk2 = breakIterator.next();
if (sbrk2 <= sbrk) {
return sbrk2;
}
return -1; // indeterminate at this time
}
boolean isSentenceBreak(javax.lang.model.element.Name tagName) {
@ -476,7 +557,7 @@ public class DocTreeMaker {
}
String removeTrailingWhitespace(String s) {
for (int i = s.length() - 1 ; i > 0 ; i--) {
for (int i = s.length() - 1 ; i >= 0 ; i--) {
char ch = s.charAt(i);
if (!Character.isWhitespace(ch)) {
return s.substring(0, i + 1);

View File

@ -27,10 +27,14 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.lang.model.element.Name;
import javax.tools.JavaFileObject;
@ -55,16 +59,28 @@ import com.sun.tools.javac.tree.DocPretty;
public class DocCommentTester {
public static final String BI_MARKER = "BREAK_ITERATOR";
public final boolean useBreakIterator;
public DocCommentTester(boolean useBreakIterator) {
this.useBreakIterator = useBreakIterator;
}
public static void main(String... args) throws Exception {
new DocCommentTester().run(args);
ArrayList<String> list = new ArrayList(Arrays.asList(args));
if (!list.isEmpty() && "-useBreakIterator".equals(list.get(0))) {
list.remove(0);
new DocCommentTester(true).run(list);
} else {
new DocCommentTester(false).run(list);
}
}
public void run(String... args) throws Exception {
public void run(List<String> args) throws Exception {
String testSrc = System.getProperty("test.src");
List<File> files = new ArrayList<File>();
for (String arg: args)
files.add(new File(testSrc, arg));
List<File> files = args.stream()
.map(arg -> new File(testSrc, arg))
.collect(Collectors.toList());
JavacTool javac = JavacTool.create();
StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
@ -74,6 +90,11 @@ public class DocCommentTester {
JavacTask t = javac.getTask(null, fm, null, null, null, fos);
final DocTrees trees = DocTrees.instance(t);
if (useBreakIterator) {
// BreakIterators are locale dependent wrt. behavior
trees.setBreakIterator(BreakIterator.getSentenceInstance(Locale.ENGLISH));
}
final Checker[] checkers = {
new ASTChecker(this, trees),
new PosChecker(this, trees),
@ -179,9 +200,11 @@ public class DocCommentTester {
static final String NEWLINE = System.getProperty("line.separator");
Printer printer = new Printer();
String source;
DocCommentTester test;
ASTChecker(DocCommentTester test, DocTrees t) {
test.super(t);
this.test = test;
}
@Override
@ -200,11 +223,21 @@ public class DocCommentTester {
out.flush();
String found = out.toString().replace(NEWLINE, "\n");
// Look for the first block comment after the first occurrence of name
int start = source.indexOf("\n/*\n", findName(source, name));
/*
* Look for the first block comment after the first occurrence
* of name, noting that, block comments with BI_MARKER may
* very well be present.
*/
int start = test.useBreakIterator
? source.indexOf("\n/*\n" + BI_MARKER + "\n", findName(source, name))
: source.indexOf("\n/*\n", findName(source, name));
int end = source.indexOf("\n*/\n", start);
String expect = source.substring(start + 4, end + 1);
int startlen = start + (test.useBreakIterator ? BI_MARKER.length() + 1 : 0) + 4;
String expect = source.substring(startlen, end + 1);
if (!found.equals(expect)) {
if (test.useBreakIterator) {
System.err.println("Using BreakIterator");
}
System.err.println("Expect:\n" + expect);
System.err.println("Found:\n" + found);
error("AST mismatch for " + name);

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 7021614 8078320
* @bug 7021614 8078320 8132096
* @summary extend com.sun.source API to support parsing javadoc comments
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@ -31,6 +31,7 @@
* jdk.compiler/com.sun.tools.javac.util
* @build DocCommentTester
* @run main DocCommentTester FirstSentenceTest.java
* @run main DocCommentTester -useBreakIterator FirstSentenceTest.java
*/
class FirstSentenceTest {
@ -42,6 +43,14 @@ DocComment[DOC_COMMENT, pos:-1
body: empty
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:-1
firstSentence: empty
body: empty
block tags: empty
]
*/
/** abc def ghi */
@ -53,6 +62,15 @@ DocComment[DOC_COMMENT, pos:0
body: empty
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:0
firstSentence: 1
Text[TEXT, pos:0, abc_def_ghi]
body: empty
block tags: empty
]
*/
/**
@ -67,7 +85,15 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi.]
body: empty
block tags: empty
]
*/
/**
* abc def ghi. jkl mno pqr.
*/
@ -81,7 +107,15 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi._jkl_mno_pqr.]
body: empty
block tags: empty
]
*/
/**
* abc def ghi.
* jkl mno pqr
@ -96,7 +130,16 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi.]
body: 1
Text[TEXT, pos:15, jkl_mno_pqr]
block tags: empty
]
*/
/**
* abc def ghi
* <p>jkl mno pqr
@ -115,7 +158,20 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi]
body: 2
StartElement[START_ELEMENT, pos:14
name:p
attributes: empty
]
Text[TEXT, pos:17, jkl_mno_pqr]
block tags: empty
]
*/
/**
*
* <p>abc def ghi.
@ -135,7 +191,20 @@ DocComment[DOC_COMMENT, pos:2
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:2
firstSentence: 2
StartElement[START_ELEMENT, pos:2
name:p
attributes: empty
]
Text[TEXT, pos:5, abc_def_ghi.]
body: 1
Text[TEXT, pos:19, jdl_mno_pqf]
block tags: empty
]
*/
/**
* abc def ghi
* </p>jkl mno pqr
@ -151,7 +220,17 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi]
body: 2
EndElement[END_ELEMENT, pos:14, p]
Text[TEXT, pos:18, jkl_mno_pqr]
block tags: empty
]
*/
/**
* abc &lt; ghi. jkl mno pqr.
*/
@ -167,7 +246,17 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 3
Text[TEXT, pos:1, abc_]
Entity[ENTITY, pos:5, lt]
Text[TEXT, pos:9, _ghi._jkl_mno_pqr.]
body: empty
block tags: empty
]
*/
/**
* abc {@code code} ghi. jkl mno pqr.
*/
@ -183,7 +272,17 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 3
Text[TEXT, pos:1, abc_]
Literal[CODE, pos:5, code]
Text[TEXT, pos:17, _ghi._jkl_mno_pqr.]
body: empty
block tags: empty
]
*/
/**
* abc def ghi
* @author jjg
@ -201,7 +300,19 @@ DocComment[DOC_COMMENT, pos:1
]
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc_def_ghi]
body: empty
block tags: 1
Author[AUTHOR, pos:14
name: 1
Text[TEXT, pos:22, jjg]
]
]
*/
/**
* @author jjg
*/
@ -216,6 +327,18 @@ DocComment[DOC_COMMENT, pos:1
Text[TEXT, pos:9, jjg]
]
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: empty
body: empty
block tags: 1
Author[AUTHOR, pos:1
name: 1
Text[TEXT, pos:9, jjg]
]
]
*/
/**
* <p> abc def.
@ -235,6 +358,21 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 2
StartElement[START_ELEMENT, pos:1
name:p
attributes: empty
]
Text[TEXT, pos:4, _abc_def.]
body: 1
Text[TEXT, pos:15, ghi_jkl]
block tags: empty
]
*/
/**
* abc <p> def. ghi jkl
*/
@ -252,5 +390,19 @@ DocComment[DOC_COMMENT, pos:1
block tags: empty
]
*/
/*
BREAK_ITERATOR
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, abc]
body: 2
StartElement[START_ELEMENT, pos:5
name:p
attributes: empty
]
Text[TEXT, pos:8, _def._ghi_jkl]
block tags: empty
]
*/
}

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8132096
* @summary test the APIs in the DocTree interface
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util
* @compile ../DocCommentTester.java DocCommentTreeApiTester.java
* @run main DocCommentTreeApiTester
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.tree.DocPretty;
public class DocCommentTreeApiTester {
private static final String MARKER_START = "<!-- EXPECT_START";
private static final String MARKER_END = "EXPECT_END -->";
private static final String testSrc = System.getProperty("test.src", ".");
private static final JavacTool javac = JavacTool.create();
private static final DocCommentTester.ASTChecker.Printer printer =
new DocCommentTester.ASTChecker.Printer();
int pass;
int fail;
public DocCommentTreeApiTester() {
pass = 0;
fail = 0;
}
public static void main(String... args) throws Exception {
DocCommentTreeApiTester test = new DocCommentTreeApiTester();
try {
// test getting a DocTree from an element
test.runElementAndBreakIteratorTests("OverviewTest.java", "OverviewTest test.");
// test relative paths in a class within a package
test.runRelativePathTest("pkg/Anchor.java", "package.html");
// tests files relative path in an unnamed package
test.runRelativePathTest("OverviewTest.java", "overview0.html");
// test for correct parsing using valid and some invalid html tags
for (int i = 0; i < 7; i++) {
String hname = "overview" + i + ".html";
test.runFileObjectTest(hname);
}
} finally {
test.status();
}
}
void status() throws Exception {
System.err.println("pass:" + pass + " fail: " + fail);
if (fail > 0) {
throw new Exception("Fails");
}
}
/**
* Tests getting a DocCommentTree from an element, as well
* as test if break iterator setter/getter works correctly.
*
* @param javaFileName a test file to be processed
* @param expected the expected output
* @throws java.io.IOException
*/
public void runElementAndBreakIteratorTests(String javaFileName, String expected) throws IOException {
List<File> javaFiles = new ArrayList<>();
javaFiles.add(new File(testSrc, javaFileName));
List<File> dirs = new ArrayList<>();
dirs.add(new File(testSrc));
try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
fm.setLocation(javax.tools.StandardLocation.SOURCE_PATH, dirs);
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
final DocTrees trees = DocTrees.instance(t);
Iterable<? extends Element> elements = t.analyze();
Element klass = elements.iterator().next();
DocCommentTree dcTree = trees.getDocCommentTree(klass);
List<? extends DocTree> firstSentence = dcTree.getFirstSentence();
StringWriter sw = new StringWriter();
DocPretty pretty = new DocPretty(sw);
pretty.print(firstSentence);
check("getDocCommentTree(Element)", expected, sw.toString());
BreakIterator bi = BreakIterator.getSentenceInstance(Locale.FRENCH);
trees.setBreakIterator(bi);
BreakIterator nbi = trees.getBreakIterator();
if (bi.equals(nbi)) {
pass++;
check("getDocCommentTree(Element) with BreakIterator", expected, sw.toString());
} else {
fail++;
System.err.println("BreakIterators don't match");
}
}
}
/**
* Tests DocTrees.getDocCommentTree(Element e, String relpath) using relative path.
*
* @param javaFileName the reference java file
* @param fileName the relative html file
* @throws java.lang.Exception ouch
*/
public void runRelativePathTest(String javaFileName, String fileName) throws Exception {
List<File> javaFiles = new ArrayList<>();
javaFiles.add(new File(testSrc, javaFileName));
List<File> dirs = new ArrayList<>();
dirs.add(new File(testSrc));
try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
fm.setLocation(javax.tools.StandardLocation.SOURCE_PATH, dirs);
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
final DocTrees trees = DocTrees.instance(t);
Iterable<? extends Element> elements = t.analyze();
Element klass = elements.iterator().next();
DocCommentTree dcTree = trees.getDocCommentTree(klass, fileName);
StringWriter sw = new StringWriter();
printer.print(dcTree, sw);
String found = sw.toString();
FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
t.getElements().getPackageOf(klass).getQualifiedName().toString(),
fileName);
String expected = getExpected(htmlFo.openReader(true));
astcheck(fileName, expected, found);
}
}
/**
* Tests DocTrees.getDocCommentTree(FileObject fo).
*
* @param htmlfileName the file to be parsed
* @throws Exception when an error occurs.
*/
public void runFileObjectTest(String htmlfileName) throws Exception {
List<File> javaFiles = Collections.emptyList();
List<File> otherFiles = new ArrayList<>();
otherFiles.add(new File(testSrc, htmlfileName));
try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
Iterable<? extends JavaFileObject> others = fm.getJavaFileObjectsFromFiles(otherFiles);
final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
final DocTrees trees = DocTrees.instance(t);
StringWriter sw = new StringWriter();
printer.print(trees.getDocCommentTree(others.iterator().next()), sw);
String found = sw.toString();
String expected = getExpected(otherFiles.iterator().next().toPath());
astcheck(otherFiles.toString(), expected, found);
}
}
void astcheck(String testinfo, String expected, String found) {
System.err.print("ASTChecker: " + testinfo);
check0(expected, found);
}
void check(String testinfo, String expected, String found) {
System.err.print(testinfo);
check0(expected, found);
}
void check0(String expected, String found) {
if (expected.equals(found)) {
pass++;
System.err.println(" PASS");
} else {
fail++;
System.err.println(" FAILED");
System.err.println("Expect:\n" + expected);
System.err.println("Found:\n" + found);
}
}
String getExpected(Reader inrdr) throws IOException {
BufferedReader rdr = new BufferedReader(inrdr);
List<String> lines = new ArrayList<>();
String line = rdr.readLine();
while (line != null) {
lines.add(line);
line = rdr.readLine();
}
return getExpected(lines);
}
String getExpected(Path p) throws IOException {
return getExpected(Files.readAllLines(p));
}
String getExpected(List<String> lines) {
boolean start = false;
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
for (String line : lines) {
if (!start) {
start = line.startsWith(MARKER_START);
continue;
}
if (line.startsWith(MARKER_END)) {
out.flush();
return sw.toString();
}
out.println(line);
}
return out.toString() + "Warning: html comment end not found";
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* OverviewTest test.
*/
public class OverviewTest {}

View File

@ -0,0 +1,48 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, A_simple_well_fo...rmed_html_document]
body: 4
StartElement[START_ELEMENT, pos:36
name:pre
attributes: empty
]
Text[TEXT, pos:41, overview0.html]
StartElement[START_ELEMENT, pos:55
name:pre
attributes: empty
]
Text[TEXT, pos:60, .]
block tags: empty
]
EXPECT_END -->
<HTML>
<HEAD>
</HEAD>
<BODY>
A simple well formed html document <pre>overview0.html<pre>.
</BODY>
</HTML>

View File

@ -0,0 +1,47 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, Html_document]
body: 4
StartElement[START_ELEMENT, pos:15
name:pre
attributes: empty
]
Text[TEXT, pos:20, overview1.html]
StartElement[START_ELEMENT, pos:34
name:pre
attributes: empty
]
Text[TEXT, pos:39, .|Missing_HTML.]
block tags: empty
]
EXPECT_END -->
<HEAD>
</HEAD>
<BODY>
Html document <pre>overview1.html<pre>.
Missing HTML.
</BODY>
</HTML>

View File

@ -0,0 +1,47 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, Html_document]
body: 4
StartElement[START_ELEMENT, pos:15
name:pre
attributes: empty
]
Text[TEXT, pos:20, overview2.html]
StartElement[START_ELEMENT, pos:34
name:pre
attributes: empty
]
Text[TEXT, pos:39, .|Missing_HEAD.]
block tags: empty
]
EXPECT_END -->
<HTML>
</HEAD>
<BODY>
Html document <pre>overview2.html<pre>.
Missing HEAD.
</BODY>
</HTML>

View File

@ -0,0 +1,47 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, Html_document]
body: 4
StartElement[START_ELEMENT, pos:15
name:pre
attributes: empty
]
Text[TEXT, pos:20, overview3.html]
StartElement[START_ELEMENT, pos:34
name:pre
attributes: empty
]
Text[TEXT, pos:39, .|Missing_enclosing_HEAD.]
block tags: empty
]
EXPECT_END -->
<HTML>
<HEAD>
<BODY>
Html document <pre>overview3.html<pre>.
Missing enclosing HEAD.
</BODY>
</HTML>

View File

@ -0,0 +1,44 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, Html_document]
body: 4
StartElement[START_ELEMENT, pos:15
name:pre
attributes: empty
]
Text[TEXT, pos:20, overview4.html]
StartElement[START_ELEMENT, pos:34
name:pre
attributes: empty
]
Text[TEXT, pos:39, .|Only_BODY]
block tags: empty
]
EXPECT_END -->
<BODY>
Html document <pre>overview4.html<pre>.
Only BODY
</BODY>

View File

@ -0,0 +1,47 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, Html_document]
body: 4
StartElement[START_ELEMENT, pos:15
name:pre
attributes: empty
]
Text[TEXT, pos:20, overview5.html]
StartElement[START_ELEMENT, pos:34
name:pre
attributes: empty
]
Text[TEXT, pos:39, .|Missing_enclosing_HTML]
block tags: empty
]
EXPECT_END -->
<HTML>
<HEAD>
</HEAD>
<BODY>
Html document <pre>overview5.html<pre>.
Missing enclosing HTML
</BODY>

View File

@ -0,0 +1,49 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, The_first_correct_body_pair.]
body: 4
EndElement[END_ELEMENT, pos:30, BODY]
Text[TEXT, pos:37, ||]
StartElement[START_ELEMENT, pos:39
name:BODY
attributes: empty
]
Text[TEXT, pos:45, |Illegal_second_...body_pair,_the_first_body_should_not_be_ignored.]
block tags: empty
]
EXPECT_END -->
<HTML>
<HEAD>
</HEAD>
<BODY>
The first correct body pair.
</BODY>
<BODY>
Illegal second body pair, the first body should not be ignored.
</BODY>
</HTML>

View File

@ -0,0 +1,47 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<HTML>
<HEAD>
</HEAD>
<BODY>
A simple well formed html document <pre>package.html<pre>.
</BODY>
</HTML>
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, This_is_a_very_simple]
body: 4
StartElement[START_ELEMENT, pos:23
name:pre
attributes: empty
]
Text[TEXT, pos:28, _well_formed_html_document_]
StartElement[START_ELEMENT, pos:55
name:pre
attributes: empty
]
Text[TEXT, pos:60, _using_some_html_tags.]
block tags: empty
]
EXPECT_END -->

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg;
/**
* The anchor class.
*/
public class Anchor {}

View File

@ -0,0 +1,48 @@
<!--
Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!-- EXPECT_START
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Text[TEXT, pos:1, A_simple_well_fo...rmed_html_document]
body: 4
StartElement[START_ELEMENT, pos:36
name:pre
attributes: empty
]
Text[TEXT, pos:41, package.html]
StartElement[START_ELEMENT, pos:53
name:pre
attributes: empty
]
Text[TEXT, pos:58, .|In_package_pkg.]
block tags: empty
]
EXPECT_END -->
<HTML>
<HEAD>
</HEAD>
<BODY>
A simple well formed html document <pre>package.html<pre>.
In package pkg.
</BODY>
</HTML>

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8026180
* @bug 8026180 8132096
* @summary Ensuring javax.lang.model.**, javax.tools.**, javax.annotation.processing.**
* and com.sun.source.** don't export inappropriate types.
* @library /tools/javac/lib
@ -87,6 +87,7 @@ public class NoPrivateTypesExported extends JavacTestingAbstractProcessor {
"java.lang.",
"java.net.",
"java.nio.",
"java.text.",
"java.util.",
"javax.lang.model.",
"javax.annotation.processing.SupportedSourceVersion",