# HG changeset patch # User lana # Date 1446673588 28800 # Node ID 58661e1ec098fd166cd5fa2b1775323e72270087 # Parent cddccda51c71e4d0c70239f694243134fe3cdeac# Parent dce6b447e07a3735abc480c681dedde7bc93e897 Merge diff -r cddccda51c71 -r 58661e1ec098 langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Fri Oct 30 10:29:03 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Wed Nov 04 13:46:28 2015 -0800 @@ -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; @@ -65,6 +68,16 @@ } /** + * 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. * @param path the path for the tree node @@ -73,6 +86,47 @@ 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. * @param path the path for the tree node @@ -112,4 +166,14 @@ 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); } diff -r cddccda51c71 -r 58661e1ec098 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Oct 30 10:29:03 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Wed Nov 04 13:46:28 2015 -0800 @@ -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.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.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.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 @@ 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 @@ } protected JavacTrees(Context context) { + this.breakIterator = null; context.put(JavacTrees.class, this); init(context); } @@ -183,31 +207,37 @@ 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 @@ 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 treeTopLevel = elements.getTreeAndTopLevel(e, a, v); if (treeTopLevel == null) @@ -306,22 +336,22 @@ 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 treeTopLevel = elements.getTreeAndTopLevel(e, a, v); if (treeTopLevel == null) @@ -329,7 +359,7 @@ 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 @@ /** @see com.sun.tools.javadoc.ClassDocImpl#findField */ private VarSymbol findField(ClassSymbol tsym, Name fieldName) { - return searchField(tsym, fieldName, new HashSet()); + return searchField(tsym, fieldName, new HashSet<>()); } /** @see com.sun.tools.javadoc.ClassDocImpl#searchField */ @@ -543,7 +573,7 @@ /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */ private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List paramTypes) { - return searchMethod(tsym, methodName, paramTypes, new HashSet()); + return searchMethod(tsym, methodName, paramTypes, new HashSet<>()); } /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */ @@ -708,19 +738,19 @@ } }; - @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 @@ 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 @@ 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 env = ((JavacScope) scope).env; @@ -755,7 +806,7 @@ 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 @@ } } + 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 + 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).*?]*>(.*) sentenceBreakTags; - private final BreakIterator sentenceBreaker; - /** Get the TreeMaker instance. */ public static DocTreeMaker instance(Context context) { DocTreeMaker instance = context.get(treeMakerKey); @@ -114,21 +111,16 @@ /** 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 DCDocComment DocComment(Comment comment, List fullBody, List tags) { - final int savepos = pos; Pair, List> 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 firstSentence, List body, List tags) { + ListBuffer lb = new ListBuffer<>(); + lb.addAll(firstSentence); + lb.addAll(body); + List fullBody = lb.toList(); + DCDocComment tree = new DCDocComment(null, fullBody, firstSentence, body, tags); return tree; } @@ -341,74 +346,88 @@ /* * 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> splitBody(Collection list) { - ListBuffer body = new ListBuffer<>(); - // split body into first sentence and body - ListBuffer fs = new ListBuffer<>(); - if (list.isEmpty()) { - return new Pair<>(fs.toList(), body.toList()); - } - boolean foundFirstSentence = false; - ArrayList alist = new ArrayList<>(list); - ListIterator 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> splitBody(Collection list) { + // pos is modified as we create trees, therefore + // we save the pos and restore it later. + final int savedpos = this.pos; + try { + ListBuffer body = new ListBuffer<>(); + // split body into first sentence and body + ListBuffer 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 alist = new ArrayList<>(list); + ListIterator 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 @@ 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 @@ } 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); diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/DocCommentTester.java --- a/langtools/test/tools/javac/doctree/DocCommentTester.java Fri Oct 30 10:29:03 2015 -0700 +++ b/langtools/test/tools/javac/doctree/DocCommentTester.java Wed Nov 04 13:46:28 2015 -0800 @@ -27,10 +27,14 @@ 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 @@ 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 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 args) throws Exception { String testSrc = System.getProperty("test.src"); - List files = new ArrayList(); - for (String arg: args) - files.add(new File(testSrc, arg)); + List 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 @@ 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 @@ 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 @@ 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); diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/FirstSentenceTest.java --- a/langtools/test/tools/javac/doctree/FirstSentenceTest.java Fri Oct 30 10:29:03 2015 -0700 +++ b/langtools/test/tools/javac/doctree/FirstSentenceTest.java Wed Nov 04 13:46:28 2015 -0800 @@ -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 { @@ -43,6 +44,14 @@ block tags: empty ] */ +/* +BREAK_ITERATOR +DocComment[DOC_COMMENT, pos:-1 + firstSentence: empty + body: empty + block tags: empty +] +*/ /** abc def ghi */ void no_terminator() { } @@ -54,6 +63,15 @@ block tags: empty ] */ +/* +BREAK_ITERATOR +DocComment[DOC_COMMENT, pos:0 + firstSentence: 1 + Text[TEXT, pos:0, abc_def_ghi] + body: empty + block tags: empty +] +*/ /** * abc def ghi. @@ -67,7 +85,15 @@ 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 @@ 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 @@ 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 *

jkl mno pqr @@ -115,7 +158,20 @@ 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 +] +*/ /** * *

abc def ghi. @@ -135,7 +191,20 @@ 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 *

jkl mno pqr @@ -151,7 +220,17 @@ 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 < ghi. jkl mno pqr. */ @@ -167,7 +246,17 @@ 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 @@ 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 @@ ] ] */ - +/* +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 */ @@ -217,6 +328,18 @@ ] ] */ +/* +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] + ] +] +*/ /** *

abc def. * ghi jkl @@ -235,6 +358,21 @@ 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

def. ghi jkl */ @@ -252,5 +390,19 @@ 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 +] +*/ } diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java Wed Nov 04 13:46:28 2015 -0800 @@ -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 = ""; + + 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 javaFiles = new ArrayList<>(); + javaFiles.add(new File(testSrc, javaFileName)); + + List 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 fos = fm.getJavaFileObjectsFromFiles(javaFiles); + + final JavacTask t = javac.getTask(null, fm, null, null, null, fos); + final DocTrees trees = DocTrees.instance(t); + + Iterable elements = t.analyze(); + + Element klass = elements.iterator().next(); + DocCommentTree dcTree = trees.getDocCommentTree(klass); + + List 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 javaFiles = new ArrayList<>(); + javaFiles.add(new File(testSrc, javaFileName)); + + List 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 fos = fm.getJavaFileObjectsFromFiles(javaFiles); + + final JavacTask t = javac.getTask(null, fm, null, null, null, fos); + final DocTrees trees = DocTrees.instance(t); + + Iterable 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 javaFiles = Collections.emptyList(); + + List otherFiles = new ArrayList<>(); + otherFiles.add(new File(testSrc, htmlfileName)); + + try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) { + Iterable fos = fm.getJavaFileObjectsFromFiles(javaFiles); + Iterable 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 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 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"; + } +} + diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/OverviewTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/doctree/dcapi/OverviewTest.java Wed Nov 04 13:46:28 2015 -0800 @@ -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 {} diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview0.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/doctree/dcapi/overview0.html Wed Nov 04 13:46:28 2015 -0800 @@ -0,0 +1,48 @@ + + + + + + +A simple well formed html document

overview0.html
.
+
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview1.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview1.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,47 @@
+
+
+
+
+
+Html document 
overview1.html
.
+Missing HTML.
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview2.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview2.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,47 @@
+
+
+
+
+
+Html document 
overview2.html
.
+Missing HEAD.
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview3.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview3.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,47 @@
+
+
+
+
+
+Html document 
overview3.html
.
+Missing enclosing HEAD.
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview4.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview4.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,44 @@
+
+
+
+Html document 
overview4.html
.
+Only BODY
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview5.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview5.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+Html document 
overview5.html
.
+Missing enclosing HTML
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/overview6.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/overview6.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+The first correct body pair.
+
+
+
+Illegal second body pair, the first body should not be ignored.
+
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/package.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/package.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,47 @@
+
+
+
+
+
+A simple well formed html document 
package.html
.
+
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/pkg/Anchor.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/pkg/Anchor.java	Wed Nov 04 13:46:28 2015 -0800
@@ -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 {}
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/doctree/dcapi/pkg/package.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/dcapi/pkg/package.html	Wed Nov 04 13:46:28 2015 -0800
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+A simple well formed html document 
package.html
.
+In package pkg.
+
+
diff -r cddccda51c71 -r 58661e1ec098 langtools/test/tools/javac/tree/NoPrivateTypesExported.java
--- a/langtools/test/tools/javac/tree/NoPrivateTypesExported.java	Fri Oct 30 10:29:03 2015 -0700
+++ b/langtools/test/tools/javac/tree/NoPrivateTypesExported.java	Wed Nov 04 13:46:28 2015 -0800
@@ -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 @@
             "java.lang.",
             "java.net.",
             "java.nio.",
+            "java.text.",
             "java.util.",
             "javax.lang.model.",
             "javax.annotation.processing.SupportedSourceVersion",