8146208: Add a public DocTreeFactory to the Compiler Tree API
authorjjg
Fri, 15 Jan 2016 15:40:24 -0800
changeset 35346 c0614a805fad
parent 35005 2dc4c11fe488
child 35347 12e87a369cc9
8146208: Add a public DocTreeFactory to the Compiler Tree API Reviewed-by: ksrini
langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java
langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java
langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java	Fri Jan 15 15:40:24 2016 -0800
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2011, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 com.sun.source.util;
+
+import java.util.List;
+
+import javax.lang.model.element.Name;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import com.sun.source.doctree.AttributeTree;
+import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.source.doctree.AuthorTree;
+import com.sun.source.doctree.CommentTree;
+import com.sun.source.doctree.DeprecatedTree;
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocRootTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.EndElementTree;
+import com.sun.source.doctree.EntityTree;
+import com.sun.source.doctree.ErroneousTree;
+import com.sun.source.doctree.IdentifierTree;
+import com.sun.source.doctree.IndexTree;
+import com.sun.source.doctree.InheritDocTree;
+import com.sun.source.doctree.LinkTree;
+import com.sun.source.doctree.LiteralTree;
+import com.sun.source.doctree.ParamTree;
+import com.sun.source.doctree.ReferenceTree;
+import com.sun.source.doctree.ReturnTree;
+import com.sun.source.doctree.SeeTree;
+import com.sun.source.doctree.SerialDataTree;
+import com.sun.source.doctree.SerialFieldTree;
+import com.sun.source.doctree.SerialTree;
+import com.sun.source.doctree.SinceTree;
+import com.sun.source.doctree.StartElementTree;
+import com.sun.source.doctree.TextTree;
+import com.sun.source.doctree.ThrowsTree;
+import com.sun.source.doctree.UnknownBlockTagTree;
+import com.sun.source.doctree.UnknownInlineTagTree;
+import com.sun.source.doctree.ValueTree;
+import com.sun.source.doctree.VersionTree;
+
+/**
+ *  Factory for creating {@code DocTree} nodes.
+ *
+ *  @implNote The methods in an implementation of this interface may only accept {@code DocTree}
+ *  nodes that have been created by the same implementation.
+ *
+ *  @since 9
+ */
+public interface DocTreeFactory {
+    /**
+     * Create a new {@code AttributeTree} object, to represent an HTML attribute in an HTML tag.
+     * @param name  the name of the attribute
+     * @param vkind the kind of attribute value
+     * @param value the value, if any, of the attribute
+     * @return an {@code AttributeTree} object
+     */
+    AttributeTree newAttributeTree(Name name, ValueKind vkind, List<? extends DocTree> value);
+
+    /**
+     * Create a new {@code AuthorTree} object, to represent an {@code {@author } } tag.
+     * @param name the name of the author
+     * @return an {@code AuthorTree} object
+     */
+    AuthorTree newAuthorTree(List<? extends DocTree> name);
+
+    /**
+     * Create a new {@code CodeTree} object, to represent a {@code {@code } } tag.
+     * @param text the content of the tag
+     * @return a {@code CodeTree} object
+     */
+    LiteralTree newCodeTree(TextTree text);
+
+    /**
+     * Create a new {@code CommentTree}, to represent an HTML comment.
+     * @param text the content of the comment
+     * @return a {@code CommentTree} object
+     */
+    CommentTree newCommentTree(String text);
+
+    /**
+     * Create a new {@code DeprecatedTree} object, to represent an {@code {@deprecated } } tag.
+     * @param text the content of the tag
+     * @return a {@code DeprecatedTree} object
+     */
+    DeprecatedTree newDeprecatedTree(List<? extends DocTree> text);
+
+    /**
+     * Create a new {@code DocCommentTree} object, to represent a complete doc comment.
+     * @param firstSentence the first sentence of the doc comment
+     * @param body the body of the doc comment following the first sentence
+     * @param tags the block tags in the doc comment
+     * @return a {@code DocCommentTree} object
+     */
+    DocCommentTree newDocCommentTree(List<? extends DocTree> firstSentence, List<? extends DocTree> body, List<? extends DocTree> tags);
+
+    /**
+     * Create a new {@code DocRootTree} object, to represent an {@code {@docroot} } tag.
+     * @return a {@code DocRootTree} object
+     */
+    DocRootTree newDocRootTree();
+
+    /**
+     * Create a new {@code EndElement} object, to represent the end of an HTML element.
+     * @param name the name of the HTML element
+     * @return an {@code EndElementTree} object
+     */
+    EndElementTree newEndElementTree(Name name);
+
+    /**
+     * Create a new {@code EntityTree} object, to represent an HTML entity.
+     * @param name the name of the entity, representing the characters between '&lt;' and ';'
+     * in the representation of the entity in an HTML document
+     * @return an {@code EntityTree} object
+     */
+    EntityTree newEntityTree(Name name);
+
+    /**
+     * Create a new {@code ErroneousTree} object, to represent some unparseable input.
+     * @param text the unparseable text
+     * @param diag a diagnostic associated with the unparseable text, or null
+     * @return an {@code ErroneousTree} object
+     */
+    ErroneousTree newErroneousTree(String text, Diagnostic<JavaFileObject> diag);
+
+    /**
+     * Create a new {@code ExceptionTree} object, to represent an {@code @exception } tag.
+     * @param name the name of the exception
+     * @param description a description of why the exception might be thrown
+     * @return an {@code ExceptionTree} object
+     */
+    ThrowsTree newExceptionTree(ReferenceTree name, List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code IdentifierTree} object, to represent an identifier, such as in a
+     * {@code @param } tag.
+     * @param name the name of the identifier
+     * @return an {@code IdentifierTree} object
+     */
+    IdentifierTree newIdentifierTree(Name name);
+
+    /**
+     * Create a new {@code IndexTree} object, to represent an {@code {@index } } tag.
+     * @param term the search term
+     * @param description an optional description of the search term
+     * @return an {@code IndexTree} object
+     */
+    IndexTree newIndexTree(DocTree term, List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code InheritDocTree} object, to represent an {@code {@inheritDoc} } tag.
+     * @return an {@code InheritDocTree} object
+     */
+    InheritDocTree newInheritDocTree();
+
+    /**
+     * Create a new {@code LinkTree} object, to represent a {@code {@link } } tag.
+     * @param ref the API element being referenced
+     * @param label an optional label for the link
+     * @return a {@code LinkTree} object
+     */
+    LinkTree newLinkTree(ReferenceTree ref, List<? extends DocTree> label);
+
+    /**
+     * Create a new {@code LinkPlainTree} object, to represent a {@code {@linkplain } } tag.
+     * @param ref the API element being referenced
+     * @param label an optional label for the link
+     * @return a {@code LinkPlainTree} object
+     */
+    LinkTree newLinkPlainTree(ReferenceTree ref, List<? extends DocTree> label);
+
+    /**
+     * Create a new {@code LiteralTree} object, to represent a {@code {@literal } } tag.
+     * @param text the content of the tag
+     * @return a {@code LiteralTree} object
+     */
+    LiteralTree newLiteralTree(TextTree text);
+
+    /**
+     * Create a new {@code ParamTree} object, to represent a {@code @param } tag.
+     * @param isTypeParameter true if this is a type parameter, and false otherwise
+     * @param name the parameter being described
+     * @param description the description of the parameter
+     * @return a {@code ParamTree} object
+     */
+    ParamTree newParamTree(boolean isTypeParameter, IdentifierTree name, List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code ReferenceTree} object, to represent a reference to an API element.
+     *
+     * @param signature the doc comment signature of the reference
+     * @return a {@code ReferenceTree} object
+     */
+    ReferenceTree newReferenceTree(String signature);
+
+    /**
+     * Create a new {@code ReturnTree} object, to represent a {@code @return } tag.
+     * @param description the description of the return value of a method
+     * @return a {@code ReturnTree} object
+     */
+    ReturnTree newReturnTree(List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code SeeTree} object, to represent a {@code @see } tag.
+     * @param reference the reference
+     * @return a {@code SeeTree} object
+     */
+    SeeTree newSeeTree(List<? extends DocTree> reference);
+
+    /**
+     * Create a new {@code SerialTree} object, to represent a {@code @serial } tag.
+     * @param description the description for the tag
+     * @return a {@code SerialTree} object
+     */
+    SerialTree newSerialTree(List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code SerialDataTree} object, to represent a {@code @serialData } tag.
+     * @param description the description for the tag
+     * @return a {@code SerialDataTree} object
+     */
+    SerialDataTree newSerialDataTree(List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code SerialFieldTree} object, to represent a {@code @serialField } tag.
+     * @param name the name of the field
+     * @param type the type of the field
+     * @param description the description of the field
+     * @return a {@code SerialFieldTree} object
+     */
+    SerialFieldTree newSerialFieldTree(IdentifierTree name, ReferenceTree type, List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code SinceTree} object, to represent a {@code @since } tag.
+     * @param text the content of the tag
+     * @return a {@code SinceTree} object
+     */
+    SinceTree newSinceTree(List<? extends DocTree> text);
+
+    /**
+     * Create a new {@code StartElementTree} object, to represent the start of an HTML element.
+     * @param name the name of the HTML element
+     * @param attrs the attributes
+     * @param selfClosing true if the start element is marked as self-closing; otherwise false
+     * @return a {@code StartElementTree} object
+     */
+    StartElementTree newStartElementTree(Name name, List<? extends DocTree> attrs, boolean selfClosing);
+
+    /**
+     * Create a new {@code TextTree} object, to represent some plain text.
+     * @param text the text
+     * @return a {@code TextTree} object
+     */
+    TextTree newTextTree(String text);
+
+    /**
+     * Create a new {@code ThrowsTree} object, to represent a {@code @throws } tag.
+     * @param name the name of the exception
+     * @param description a description of why the exception might be thrown
+     * @return a {@code ThrowsTree} object
+     */
+    ThrowsTree newThrowsTree(ReferenceTree name, List<? extends DocTree> description);
+
+    /**
+     * Create a new {@code UnknownBlockTagTree} object, to represent an unrecognized block tag.
+     * @param name the name of the block tag
+     * @param content the content
+     * @return an {@code UnknownBlockTagTree} object
+     */
+    UnknownBlockTagTree newUnknownBlockTagTree(Name name, List<? extends DocTree> content);
+
+    /**
+     * Create a new {@code UnknownInlineTagTree} object, to represent an unrecognized inline tag.
+     * @param name the name of the inline tag
+     * @param content the content
+     * @return an {@code UnknownInlineTagTree} object
+     */
+    UnknownInlineTagTree newUnknownInlineTagTree(Name name, List<? extends DocTree> content);
+
+    /**
+     * Create a new {@code ValueTree} object, to represent a {@code {@value } } tag.
+     * @param ref a reference to the value
+     * @return a {@code ValueTree} object
+     */
+    ValueTree newValueTree(ReferenceTree ref);
+
+    /**
+     * Create a new {@code VersionTree} object, to represent a {@code {@version } } tag.
+     * @param text the content of the tag
+     * @return a {@code VersionTree} object
+     */
+    VersionTree newVersionTree(List<? extends DocTree> text);
+
+    /**
+     * Set the position to be recorded in subsequent tree nodes created by this factory.
+     * The position should be a character offset relative to the beginning of the source file
+     * or {@link javax.tools.Diagnostic#NOPOS NOPOS}.
+     * @param pos the position
+     * @return this object, to facilitate method chaining
+     */
+    DocTreeFactory at(int pos);
+
+    /**
+     * Get the first sentence contained in a list of content.
+     * The determination of the first sentence is implementation specific, and may
+     * involve the use of a locale-specific {@link java.text.BreakIterator BreakIterator}
+     * and other heuristics.
+     * The resulting list may share a common set of initial items with the input list.
+     * @param list the list
+     * @return a list containing the first sentence of the list.
+     */
+    List<DocTree> getFirstSentence(List<? extends DocTree> list);
+
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -70,6 +70,7 @@
         }
 
         class PathFinder extends DocTreePathScanner<DocTreePath,DocTree> {
+            @Override
             public DocTreePath scan(DocTree tree, DocTree target) {
                 if (tree == target) {
                     throw new Result(new DocTreePath(getCurrentPath(), target));
@@ -151,18 +152,22 @@
         return parent;
     }
 
+    @Override
     public Iterator<DocTree> iterator() {
         return new Iterator<DocTree>() {
+            @Override
             public boolean hasNext() {
                 return next != null;
             }
 
+            @Override
             public DocTree next() {
                 DocTree t = next.leaf;
                 next = next.parent;
                 return t;
             }
 
+            @Override
             public void remove() {
                 throw new UnsupportedOperationException();
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -126,6 +126,20 @@
     public abstract DocCommentTree getDocCommentTree(Element e, String relativePath) throws IOException;
 
     /**
+     * Returns a doc tree path containing 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 &lt;body&gt; 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 a doc tree path containing the doc comment read from the given file.
+     *
+     * @since 9
+     */
+    public abstract DocTreePath getDocTreePath(FileObject fileObject);
+
+    /**
      * 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
@@ -175,4 +189,12 @@
      * @since 9
      */
     public abstract void setBreakIterator(BreakIterator breakiterator);
+
+    /**
+     * Returns a utility object for creating {@code DocTree} objects.
+     * @return  a utility object for creating {@code DocTree} objects
+     *
+     * @since 9
+     */
+    public abstract DocTreeFactory getDocTreeFactory();
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -49,7 +49,6 @@
 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;
@@ -160,7 +159,7 @@
     private JavacTaskImpl javacTaskImpl;
     private Names names;
     private Types types;
-    private DocTreeMaker doctreeMaker;
+    private DocTreeMaker docTreeMaker;
     private BreakIterator breakIterator;
     private JavaFileManager fileManager;
     private ParserFactory parser;
@@ -206,7 +205,7 @@
         memberEnter = MemberEnter.instance(context);
         names = Names.instance(context);
         types = Types.instance(context);
-        doctreeMaker = DocTreeMaker.instance(context);
+        docTreeMaker = DocTreeMaker.instance(context);
         parser = ParserFactory.instance(context);
         fileManager = context.get(JavaFileManager.class);
         JavacTask t = context.get(JavacTask.class);
@@ -294,6 +293,11 @@
             };
     }
 
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DocTreeMaker getDocTreeFactory() {
+        return docTreeMaker;
+    }
+
     private DocTree getLastChild(DocTree tree) {
         final DocTree[] last = new DocTree[] {null};
 
@@ -398,7 +402,7 @@
 
     @Override @DefinedBy(Api.COMPILER_TREE)
     public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
-        return doctreeMaker.getFirstSentence(list);
+        return docTreeMaker.getFirstSentence(list);
     }
 
     private Symbol attributeDocReference(TreePath path, DCReference ref) {
@@ -411,9 +415,9 @@
             final Name memberName;
             if (ref.qualifierExpression == null) {
                 tsym = env.enclClass.sym;
-                memberName = ref.memberName;
+                memberName = (Name) ref.memberName;
             } else {
-                // See if the qualifierExpression is a type or package name.
+                // newSeeTree if the qualifierExpression is a type or package name.
                 // javac does not provide the exact method required, so
                 // we first check if qualifierExpression identifies a type,
                 // and if not, then we check to see if it identifies a package.
@@ -437,7 +441,7 @@
                     }
                 } else {
                     tsym = t.tsym;
-                    memberName = ref.memberName;
+                    memberName = (Name) ref.memberName;
                 }
             }
 
@@ -449,7 +453,7 @@
                 paramTypes = null;
             else {
                 ListBuffer<Type> lb = new ListBuffer<>();
-                for (List<JCTree> l = ref.paramTypes; l.nonEmpty(); l = l.tail) {
+                for (List<JCTree> l = (List<JCTree>) ref.paramTypes; l.nonEmpty(); l = l.tail) {
                     JCTree tree = l.head;
                     Type t = attr.attribType(tree, env);
                     lb.add(t);
@@ -913,7 +917,7 @@
         }
     }
 
-    private JavaFileObject asJavaFileObject(FileObject fileObject) {
+    static JavaFileObject asJavaFileObject(FileObject fileObject) {
         JavaFileObject jfo = null;
 
         if (fileObject instanceof JavaFileObject) {
@@ -927,11 +931,11 @@
         return jfo;
     }
 
-    private void checkHtmlKind(FileObject fileObject) {
+    private static void checkHtmlKind(FileObject fileObject) {
         checkHtmlKind(fileObject, BaseFileManager.getKind(fileObject.getName()));
     }
 
-    private void checkHtmlKind(FileObject fileObject, JavaFileObject.Kind kind) {
+    private static void checkHtmlKind(FileObject fileObject, JavaFileObject.Kind kind) {
         if (kind != JavaFileObject.Kind.HTML) {
             throw new IllegalArgumentException("HTML file expected:" + fileObject.getName());
         }
@@ -1012,6 +1016,12 @@
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
+    public DocTreePath getDocTreePath(FileObject fileObject) {
+        JavaFileObject jfo = asJavaFileObject(fileObject);
+        return new DocTreePath(makeTreePath(jfo), getDocCommentTree(jfo));
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public void setBreakIterator(BreakIterator breakiterator) {
         this.breakIterator = breakiterator;
     }
@@ -1126,11 +1136,10 @@
         }
     }
 
-    public TreePath makeTreePath(final FileObject fileObject, final int offset) {
-        JavaFileObject jfo = asJavaFileObject(fileObject);
+    private TreePath makeTreePath(final JavaFileObject jfo) {
         JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
             public int getPos() {
-                return offset;
+                return Position.FIRSTPOS;
             }
 
             public JavaFileObject getSourcefile() {
@@ -1140,7 +1149,7 @@
             @Override @DefinedBy(Api.COMPILER_TREE)
             public Position.LineMap getLineMap() {
                 try {
-                    CharSequence content = fileObject.getCharContent(true);
+                    CharSequence content = jfo.getCharContent(true);
                     String s = content.toString();
                     return Position.makeLineMap(s.toCharArray(), s.length(), true);
                 } catch (IOException ignore) {}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -121,7 +121,7 @@
                 ? body.head.pos
                 : !tags.isEmpty() ? tags.head.pos : Position.NOPOS;
 
-        DCDocComment dc = m.at(pos).DocComment(comment, body, tags);
+        DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags);
         return dc;
     }
 
@@ -171,7 +171,7 @@
                 case '>':
                     newline = false;
                     addPendingText(trees, bp - 1);
-                    trees.add(m.at(bp).Erroneous(newString(bp, bp+1), diagSource, "dc.bad.gt"));
+                    trees.add(m.at(bp).newErroneousTree(newString(bp, bp + 1), diagSource, "dc.bad.gt"));
                     nextChar();
                     if (textStart == -1) {
                         textStart = bp;
@@ -231,7 +231,7 @@
                 TagParser tp = tagParsers.get(name);
                 if (tp == null) {
                     List<DCTree> content = blockContent();
-                    return m.at(p).UnknownBlockTag(name, content);
+                    return m.at(p).newUnknownBlockTagTree(name, content);
                 } else {
                     switch (tp.getKind()) {
                         case BLOCK:
@@ -284,7 +284,7 @@
                     DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_ALL);
                     if (text != null) {
                         nextChar();
-                        return m.at(p).UnknownInlineTag(name, List.of(text)).setEndPos(bp);
+                        return m.at(p).newUnknownInlineTagTree(name, List.of(text)).setEndPos(bp);
                     }
                 } else {
                     if (!tp.retainWhiteSpace) {
@@ -354,7 +354,7 @@
 
                 case '}':
                     if (--depth == 0) {
-                        return m.at(pos).Text(newString(pos, bp));
+                        return m.at(pos).newTextTree(newString(pos, bp));
                     }
                     newline = false;
                     lastNonWhite = bp;
@@ -384,6 +384,7 @@
      */
     // TODO: boolean allowMember should be enum FORBID, ALLOW, REQUIRE
     // TODO: improve quality of parse to forbid bad constructions.
+    // TODO: update to use ReferenceParser
     @SuppressWarnings("fallthrough")
     protected DCReference reference(boolean allowMember) throws ParseException {
         int pos = bp;
@@ -481,7 +482,7 @@
             fac.log.popDiagnosticHandler(deferredDiagnosticHandler);
         }
 
-        return m.at(pos).Reference(sig, qualExpr, member, paramTypes).setEndPos(bp);
+        return m.at(pos).newReferenceTree(sig, qualExpr, member, paramTypes).setEndPos(bp);
     }
 
     JCTree parseType(String s) throws ParseException {
@@ -537,7 +538,7 @@
 
         if (isJavaIdentifierStart(ch)) {
             Name name = readJavaIdentifier();
-            return m.at(pos).Identifier(name);
+            return m.at(pos).newIdentifierTree(name);
         }
 
         throw new ParseException("dc.identifier.expected");
@@ -565,7 +566,7 @@
                 case '"':
                     nextChar();
                     // trim trailing white-space?
-                    return m.at(pos).Text(newString(pos, bp));
+                    return m.at(pos).newTextTree(newString(pos, bp));
 
                 case '@':
                     if (newline)
@@ -593,7 +594,7 @@
                     // fallthrough
 
                 case '\r': case '\f': case ' ': case '\t':
-                    return m.at(pos).Text(newString(pos, bp));
+                    return m.at(pos).newTextTree(newString(pos, bp));
 
                 case '@':
                     if (newline)
@@ -605,7 +606,7 @@
 
                 case '}':
                     if (depth == 0 || --depth == 0)
-                        return m.at(pos).Text(newString(pos, bp));
+                        return m.at(pos).newTextTree(newString(pos, bp));
                     break;
             }
             newline = false;
@@ -729,7 +730,7 @@
             if (ch != ';')
                 return erroneous("dc.missing.semicolon", p);
             nextChar();
-            return m.at(p).Entity(name);
+            return m.at(p).newEntityTree(name);
         }
     }
 
@@ -751,7 +752,7 @@
                 }
                 if (ch == '>') {
                     nextChar();
-                    DCTree dctree = m.at(p).StartElement(name, attrs, selfClosing).setEndPos(bp);
+                    DCTree dctree = m.at(p).newStartElementTree(name, attrs, selfClosing).setEndPos(bp);
                     return dctree;
                 }
             }
@@ -762,7 +763,7 @@
                 skipWhitespace();
                 if (ch == '>') {
                     nextChar();
-                    return m.at(p).EndElement(name);
+                    return m.at(p).newEndElementTree(name);
                 }
             }
         } else if (ch == '!') {
@@ -777,11 +778,13 @@
                             dash++;
                             nextChar();
                         }
-                        // strictly speaking, a comment should not contain "--"
+                        // Strictly speaking, a comment should not contain "--"
                         // so dash > 2 is an error, dash == 2 implies ch == '>'
+                        // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments
+                        // for more details.
                         if (dash >= 2 && ch == '>') {
                             nextChar();
-                            return m.at(p).Comment(newString(p, bp));
+                            return m.at(p).newCommentTree(newString(p, bp));
                         }
 
                         nextChar();
@@ -844,7 +847,7 @@
                 skipWhitespace();
                 value = v.toList();
             }
-            DCAttribute attr = m.at(namePos).Attribute(name, vkind, value);
+            DCAttribute attr = m.at(namePos).newAttributeTree(name, vkind, value);
             attrs.add(attr);
         }
 
@@ -869,7 +872,7 @@
     protected void addPendingText(ListBuffer<DCTree> list, int textEnd) {
         if (textStart != -1) {
             if (textStart <= textEnd) {
-                list.add(m.at(textStart).Text(newString(textStart, textEnd + 1)));
+                list.add(m.at(textStart).newTextTree(newString(textStart, textEnd + 1)));
             }
             textStart = -1;
         }
@@ -891,7 +894,7 @@
             i--;
         }
         textStart = -1;
-        return m.at(pos).Erroneous(newString(pos, i + 1), diagSource, code);
+        return m.at(pos).newErroneousTree(newString(pos, i + 1), diagSource, code);
     }
 
     protected boolean isIdentifierStart(char ch) {
@@ -1017,7 +1020,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.AUTHOR) {
                 public DCTree parse(int pos) {
                     List<DCTree> name = blockContent();
-                    return m.at(pos).Author(name);
+                    return m.at(pos).newAuthorTree(name);
                 }
             },
 
@@ -1026,7 +1029,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
-                    return m.at(pos).Code((DCText) text);
+                    return m.at(pos).newCodeTree((DCText) text);
                 }
             },
 
@@ -1034,7 +1037,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.DEPRECATED) {
                 public DCTree parse(int pos) {
                     List<DCTree> reason = blockContent();
-                    return m.at(pos).Deprecated(reason);
+                    return m.at(pos).newDeprecatedTree(reason);
                 }
             },
 
@@ -1043,7 +1046,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     if (ch == '}') {
                         nextChar();
-                        return m.at(pos).DocRoot();
+                        return m.at(pos).newDocRootTree();
                     }
                     inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
                     nextChar();
@@ -1057,7 +1060,7 @@
                     skipWhitespace();
                     DCReference ref = reference(false);
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Exception(ref, description);
+                    return m.at(pos).newExceptionTree(ref, description);
                 }
             },
 
@@ -1079,7 +1082,7 @@
                     } else {
                         nextChar();
                     }
-                    return m.at(pos).Index(term, description);
+                    return m.at(pos).newIndexTree(term, description);
                 }
             },
 
@@ -1088,7 +1091,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     if (ch == '}') {
                         nextChar();
-                        return m.at(pos).InheritDoc();
+                        return m.at(pos).newInheritDocTree();
                     }
                     inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
                     nextChar();
@@ -1101,7 +1104,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     DCReference ref = reference(true);
                     List<DCTree> label = inlineContent();
-                    return m.at(pos).Link(ref, label);
+                    return m.at(pos).newLinkTree(ref, label);
                 }
             },
 
@@ -1110,7 +1113,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     DCReference ref = reference(true);
                     List<DCTree> label = inlineContent();
-                    return m.at(pos).LinkPlain(ref, label);
+                    return m.at(pos).newLinkPlainTree(ref, label);
                 }
             },
 
@@ -1119,7 +1122,7 @@
                 public DCTree parse(int pos) throws ParseException {
                     DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
-                    return m.at(pos).Literal((DCText) text);
+                    return m.at(pos).newLiteralTree((DCText) text);
                 }
             },
 
@@ -1144,7 +1147,7 @@
 
                     skipWhitespace();
                     List<DCTree> desc = blockContent();
-                    return m.at(pos).Param(typaram, id, desc);
+                    return m.at(pos).newParamTree(typaram, id, desc);
                 }
             },
 
@@ -1152,7 +1155,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.RETURN) {
                 public DCTree parse(int pos) {
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Return(description);
+                    return m.at(pos).newReturnTree(description);
                 }
             },
 
@@ -1167,7 +1170,7 @@
                                 skipWhitespace();
                                 if (ch == '@'
                                         || ch == EOI && bp == buf.length - 1) {
-                                    return m.at(pos).See(List.<DCTree>of(string));
+                                    return m.at(pos).newSeeTree(List.<DCTree>of(string));
                                 }
                             }
                             break;
@@ -1175,7 +1178,7 @@
                         case '<':
                             List<DCTree> html = blockContent();
                             if (html != null)
-                                return m.at(pos).See(html);
+                                return m.at(pos).newSeeTree(html);
                             break;
 
                         case '@':
@@ -1192,7 +1195,7 @@
                             if (isJavaIdentifierStart(ch) || ch == '#') {
                                 DCReference ref = reference(true);
                                 List<DCTree> description = blockContent();
-                                return m.at(pos).See(description.prepend(ref));
+                                return m.at(pos).newSeeTree(description.prepend(ref));
                             }
                     }
                     throw new ParseException("dc.unexpected.content");
@@ -1203,7 +1206,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.SERIAL_DATA) {
                 public DCTree parse(int pos) {
                     List<DCTree> description = blockContent();
-                    return m.at(pos).SerialData(description);
+                    return m.at(pos).newSerialDataTree(description);
                 }
             },
 
@@ -1219,7 +1222,7 @@
                         skipWhitespace();
                         description = blockContent();
                     }
-                    return m.at(pos).SerialField(name, type, description);
+                    return m.at(pos).newSerialFieldTree(name, type, description);
                 }
             },
 
@@ -1227,7 +1230,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.SERIAL) {
                 public DCTree parse(int pos) {
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Serial(description);
+                    return m.at(pos).newSerialTree(description);
                 }
             },
 
@@ -1235,7 +1238,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.SINCE) {
                 public DCTree parse(int pos) {
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Since(description);
+                    return m.at(pos).newSinceTree(description);
                 }
             },
 
@@ -1245,7 +1248,7 @@
                     skipWhitespace();
                     DCReference ref = reference(false);
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Throws(ref, description);
+                    return m.at(pos).newThrowsTree(ref, description);
                 }
             },
 
@@ -1256,7 +1259,7 @@
                     skipWhitespace();
                     if (ch == '}') {
                         nextChar();
-                        return m.at(pos).Value(ref);
+                        return m.at(pos).newValueTree(ref);
                     }
                     nextChar();
                     throw new ParseException("dc.unexpected.content");
@@ -1267,7 +1270,7 @@
             new TagParser(Kind.BLOCK, DCTree.Kind.VERSION) {
                 public DCTree parse(int pos) {
                     List<DCTree> description = blockContent();
-                    return m.at(pos).Version(description);
+                    return m.at(pos).newVersionTree(description);
                 }
             },
         };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java	Fri Jan 15 15:40:24 2016 -0800
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2012, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 com.sun.tools.javac.parser;
+
+import com.sun.tools.javac.parser.Tokens.TokenKind;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+
+/**
+ *  A utility class to parse a string in a doc comment containing a
+ *  reference to an API element, such as a type, field or method.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ReferenceParser {
+    /**
+     * An object to contain the result of parsing a reference to an API element.
+     * Any, but not all, of the member fields may be null.
+     */
+    static public class Reference {
+        /** The type, if any, in the signature. */
+        public final JCTree qualExpr;
+        /** The member name, if any, in the signature. */
+        public final Name member;
+        /** The parameter types, if any, in the signature. */
+        public final List<JCTree> paramTypes;
+
+        Reference(JCTree qualExpr, Name member, List<JCTree> paramTypes) {
+            this.qualExpr = qualExpr;
+            this.member = member;
+            this.paramTypes = paramTypes;
+        }
+    }
+
+    /**
+     * An exception that indicates an error occurred while parsing a signature.
+     */
+    static public class ParseException extends Exception {
+        private static final long serialVersionUID = 0;
+        ParseException(String message) {
+            super(message);
+        }
+    }
+
+    private final ParserFactory fac;
+
+    /**
+     * Create a parser object to parse reference signatures.
+     * @param fac a factory for parsing Java source code.
+     */
+    public ReferenceParser(ParserFactory fac) {
+        this.fac = fac;
+    }
+
+    /**
+     * Parse a reference to an API element as may be found in doc comment.
+     * @param sig the signature to be parsed
+     * @return a {@code Reference} object containing the result of parsing the signature
+     * @throws ParseException if there is an error while parsing the signature
+     */
+    public Reference parse(String sig) throws ParseException {
+
+        // Break sig apart into qualifiedExpr member paramTypes.
+        JCTree qualExpr;
+        Name member;
+        List<JCTree> paramTypes;
+
+        Log.DeferredDiagnosticHandler deferredDiagnosticHandler
+                = new Log.DeferredDiagnosticHandler(fac.log);
+
+        try {
+            int hash = sig.indexOf("#");
+            int lparen = sig.indexOf("(", hash + 1);
+            if (hash == -1) {
+                if (lparen == -1) {
+                    qualExpr = parseType(sig);
+                    member = null;
+                } else {
+                    qualExpr = null;
+                    member = parseMember(sig.substring(0, lparen));
+                }
+            } else {
+                qualExpr = (hash == 0) ? null : parseType(sig.substring(0, hash));
+                if (lparen == -1)
+                    member = parseMember(sig.substring(hash + 1));
+                else
+                    member = parseMember(sig.substring(hash + 1, lparen));
+            }
+
+            if (lparen < 0) {
+                paramTypes = null;
+            } else {
+                int rparen = sig.indexOf(")", lparen);
+                if (rparen != sig.length() - 1)
+                    throw new ParseException("dc.ref.bad.parens");
+                paramTypes = parseParams(sig.substring(lparen + 1, rparen));
+            }
+
+            if (!deferredDiagnosticHandler.getDiagnostics().isEmpty())
+                throw new ParseException("dc.ref.syntax.error");
+
+        } finally {
+            fac.log.popDiagnosticHandler(deferredDiagnosticHandler);
+        }
+
+        return new Reference(qualExpr, member, paramTypes);
+    }
+
+    private JCTree parseType(String s) throws ParseException {
+        JavacParser p = fac.newParser(s, false, false, false);
+        JCTree tree = p.parseType();
+        if (p.token().kind != TokenKind.EOF)
+            throw new ParseException("dc.ref.unexpected.input");
+        return tree;
+    }
+
+    private Name parseMember(String s) throws ParseException {
+        JavacParser p = fac.newParser(s, false, false, false);
+        Name name = p.ident();
+        if (p.token().kind != TokenKind.EOF)
+            throw new ParseException("dc.ref.unexpected.input");
+        return name;
+    }
+
+    private List<JCTree> parseParams(String s) throws ParseException {
+        if (s.trim().isEmpty())
+            return List.nil();
+
+        JavacParser p = fac.newParser(s.replace("...", "[]"), false, false, false);
+        ListBuffer<JCTree> paramTypes = new ListBuffer<>();
+        paramTypes.add(p.parseType());
+
+        if (p.token().kind == TokenKind.IDENTIFIER)
+            p.nextToken();
+
+        while (p.token().kind == TokenKind.COMMA) {
+            p.nextToken();
+            paramTypes.add(p.parseType());
+
+            if (p.token().kind == TokenKind.IDENTIFIER)
+                p.nextToken();
+        }
+
+        if (p.token().kind != TokenKind.EOF)
+            throw new ParseException("dc.ref.unexpected.input");
+
+        return paramTypes.toList();
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -35,13 +35,13 @@
 import com.sun.tools.javac.util.DiagnosticSource;
 import com.sun.tools.javac.util.JCDiagnostic;
 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Position;
 
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.List;
 
+import javax.lang.model.element.Name;
 import javax.tools.JavaFileObject;
 
 /**
@@ -122,32 +122,32 @@
             this.tags = tags;
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.DOC_COMMENT;
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
             return v.visitDocComment(this, d);
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<? extends DocTree> getFirstSentence() {
             return firstSentence;
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<? extends DocTree> getFullBody() {
             return fullBody;
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<? extends DocTree> getBody() {
             return body;
         }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<? extends DocTree> getBlockTags() {
             return tags;
         }
@@ -155,14 +155,14 @@
     }
 
     public static abstract class DCBlockTag extends DCTree implements BlockTagTree {
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public String getTagName() {
             return getKind().tagName;
         }
     }
 
     public static abstract class DCInlineTag extends DCEndPosTree<DCInlineTag> implements InlineTagTree {
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public String getTagName() {
             return getKind().tagName;
         }
@@ -343,6 +343,11 @@
             this.diag = diags.error(null, diagSource, this, code, args);
         }
 
+        DCErroneous(String body, JCDiagnostic diag) {
+            this.body = body;
+            this.diag = diag;
+        }
+
         @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.ERRONEOUS;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java	Wed Jul 05 21:13:10 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java	Fri Jan 15 15:40:24 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -29,16 +29,26 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.EnumSet;
+import java.util.List;
 import java.util.ListIterator;
 
+import javax.lang.model.element.Name;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
 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.IdentifierTree;
+import com.sun.source.doctree.ReferenceTree;
 import com.sun.source.doctree.StartElementTree;
 import com.sun.source.doctree.TextTree;
+import com.sun.source.util.DocTreeFactory;
 import com.sun.tools.doclint.HtmlTag;
 import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.ReferenceParser;
 import com.sun.tools.javac.parser.Tokens.Comment;
 import com.sun.tools.javac.tree.DCTree.DCAttribute;
 import com.sun.tools.javac.tree.DCTree.DCAuthor;
@@ -70,12 +80,12 @@
 import com.sun.tools.javac.tree.DCTree.DCValue;
 import com.sun.tools.javac.tree.DCTree.DCVersion;
 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.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.Pair;
 import com.sun.tools.javac.util.Position;
 
@@ -88,7 +98,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class DocTreeMaker {
+public class DocTreeMaker implements DocTreeFactory {
 
     /** The context key for the tree factory. */
     protected static final Context.Key<DocTreeMaker> treeMakerKey = new Context.Key<>();
@@ -114,6 +124,9 @@
 
     private final JavacTrees trees;
 
+    /** Utility class to parse reference signatures. */
+    private final ReferenceParser referenceParser;
+
     /** Create a tree maker with NOPOS as initial position.
      */
     protected DocTreeMaker(Context context) {
@@ -121,11 +134,13 @@
         diags = JCDiagnostic.Factory.instance(context);
         this.pos = Position.NOPOS;
         trees = JavacTrees.instance(context);
+        referenceParser = new ReferenceParser(ParserFactory.instance(context));
         sentenceBreakTags = EnumSet.of(H1, H2, H3, H4, H5, H6, PRE, P);
     }
 
     /** Reassign current position.
      */
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public DocTreeMaker at(int pos) {
         this.pos = pos;
         return this;
@@ -138,39 +153,44 @@
         return this;
     }
 
-    public DCAttribute Attribute(Name name, ValueKind vkind, List<DCTree> value) {
-        DCAttribute tree = new DCAttribute(name, vkind, value);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCAttribute newAttributeTree(javax.lang.model.element.Name name, ValueKind vkind, java.util.List<? extends DocTree> value) {
+        DCAttribute tree = new DCAttribute(name, vkind, cast(value));
         tree.pos = pos;
         return tree;
     }
 
-    public DCAuthor Author(List<DCTree> name) {
-        DCAuthor tree = new DCAuthor(name);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCAuthor newAuthorTree(java.util.List<? extends DocTree> name) {
+        DCAuthor tree = new DCAuthor(cast(name));
         tree.pos = pos;
         return tree;
     }
 
-    public DCLiteral Code(DCText text) {
-        DCLiteral tree = new DCLiteral(Kind.CODE, text);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCLiteral newCodeTree(TextTree text) {
+        DCLiteral tree = new DCLiteral(Kind.CODE, (DCText) text);
         tree.pos = pos;
         return tree;
     }
 
-    public DCComment Comment(String text) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCComment newCommentTree(String text) {
         DCComment tree = new DCComment(text);
         tree.pos = pos;
         return tree;
     }
 
-    public DCDeprecated Deprecated(List<DCTree> text) {
-        DCDeprecated tree = new DCDeprecated(text);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCDeprecated newDeprecatedTree(List<? extends DocTree> text) {
+        DCDeprecated tree = new DCDeprecated(cast(text));
         tree.pos = pos;
         return tree;
     }
 
-    public DCDocComment DocComment(Comment comment, List<DCTree> fullBody, List<DCTree> tags) {
+    public DCDocComment newDocCommentTree(Comment comment, List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
         Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
-        DCDocComment tree = new DCDocComment(comment, fullBody, pair.fst, pair.snd, tags);
+        DCDocComment tree = new DCDocComment(comment, cast(fullBody), pair.fst, pair.snd, cast(tags));
         tree.pos = pos;
         return tree;
     }
@@ -180,172 +200,219 @@
      * 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) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCDocComment newDocCommentTree(List<? extends DocTree> firstSentence, List<? extends DocTree> body, List<? extends DocTree> tags) {
         ListBuffer<DCTree> lb = new ListBuffer<>();
-        lb.addAll(firstSentence);
-        lb.addAll(body);
+        lb.addAll(cast(firstSentence));
+        lb.addAll(cast(body));
         List<DCTree> fullBody = lb.toList();
-        DCDocComment tree = new DCDocComment(null, fullBody, firstSentence, body, tags);
+        DCDocComment tree = new DCDocComment(null, fullBody, cast(firstSentence), cast(body), cast(tags));
         return tree;
     }
 
-    public DCDocRoot DocRoot() {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCDocRoot newDocRootTree() {
         DCDocRoot tree = new DCDocRoot();
         tree.pos = pos;
         return tree;
     }
 
-    public DCEndElement EndElement(Name name) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCEndElement newEndElementTree(Name name) {
         DCEndElement tree = new DCEndElement(name);
         tree.pos = pos;
         return tree;
     }
 
-    public DCEntity Entity(Name name) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCEntity newEntityTree(Name name) {
         DCEntity tree = new DCEntity(name);
         tree.pos = pos;
         return tree;
     }
 
-    public DCErroneous Erroneous(String text, DiagnosticSource diagSource, String code, Object... args) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCErroneous newErroneousTree(String text, Diagnostic<JavaFileObject> diag) {
+        DCErroneous tree = new DCErroneous(text, (JCDiagnostic) diag);
+        tree.pos = pos;
+        return tree;
+    }
+
+    public DCErroneous newErroneousTree(String text, DiagnosticSource diagSource, String code, Object... args) {
         DCErroneous tree = new DCErroneous(text, diags, diagSource, code, args);
         tree.pos = pos;
         return tree;
     }
 
-    public DCThrows Exception(DCReference name, List<DCTree> description) {
-        DCThrows tree = new DCThrows(Kind.EXCEPTION, name, description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCThrows newExceptionTree(ReferenceTree name, List<? extends DocTree> description) {
+        // TODO: verify the reference is just to a type (not a field or method)
+        DCThrows tree = new DCThrows(Kind.EXCEPTION, (DCReference) name, cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCIdentifier Identifier(Name name) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCIdentifier newIdentifierTree(Name name) {
         DCIdentifier tree = new DCIdentifier(name);
         tree.pos = pos;
         return tree;
     }
 
-    public DCIndex Index(DCTree term, List<DCTree> description) {
-        DCIndex tree = new DCIndex(term, description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCIndex newIndexTree(DocTree term, List<? extends DocTree> description) {
+        DCIndex tree = new DCIndex((DCTree) term, cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCInheritDoc InheritDoc() {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCInheritDoc newInheritDocTree() {
         DCInheritDoc tree = new DCInheritDoc();
         tree.pos = pos;
         return tree;
     }
 
-    public DCLink Link(DCReference ref, List<DCTree> label) {
-        DCLink tree = new DCLink(Kind.LINK, ref, label);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCLink newLinkTree(ReferenceTree ref, List<? extends DocTree> label) {
+        DCLink tree = new DCLink(Kind.LINK, (DCReference) ref, cast(label));
         tree.pos = pos;
         return tree;
     }
 
-    public DCLink LinkPlain(DCReference ref, List<DCTree> label) {
-        DCLink tree = new DCLink(Kind.LINK_PLAIN, ref, label);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCLink newLinkPlainTree(ReferenceTree ref, List<? extends DocTree> label) {
+        DCLink tree = new DCLink(Kind.LINK_PLAIN, (DCReference) ref, cast(label));
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCLiteral newLiteralTree(TextTree text) {
+        DCLiteral tree = new DCLiteral(Kind.LITERAL, (DCText) text);
         tree.pos = pos;
         return tree;
     }
 
-    public DCLiteral Literal(DCText text) {
-        DCLiteral tree = new DCLiteral(Kind.LITERAL, text);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCParam newParamTree(boolean isTypeParameter, IdentifierTree name, List<? extends DocTree> description) {
+        DCParam tree = new DCParam(isTypeParameter, (DCIdentifier) name, cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCParam Param(boolean isTypeParameter, DCIdentifier name, List<DCTree> description) {
-        DCParam tree = new DCParam(isTypeParameter, name, description);
-        tree.pos = pos;
-        return tree;
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCReference newReferenceTree(String signature) {
+        try {
+            ReferenceParser.Reference ref = referenceParser.parse(signature);
+            DCReference tree = new DCReference(signature, ref.qualExpr, ref.member, ref.paramTypes);
+            tree.pos = pos;
+            return tree;
+        } catch (ReferenceParser.ParseException e) {
+            throw new IllegalArgumentException("invalid signature", e);
+        }
     }
 
-    public DCReference Reference(String signature,
-            JCTree qualExpr, Name member, List<JCTree> paramTypes) {
+    public DCReference newReferenceTree(String signature, JCTree qualExpr, Name member, List<JCTree> paramTypes) {
         DCReference tree = new DCReference(signature, qualExpr, member, paramTypes);
         tree.pos = pos;
         return tree;
     }
 
-    public DCReturn Return(List<DCTree> description) {
-        DCReturn tree = new DCReturn(description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCReturn newReturnTree(List<? extends DocTree> description) {
+        DCReturn tree = new DCReturn(cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCSee See(List<DCTree> reference) {
-        DCSee tree = new DCSee(reference);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSee newSeeTree(List<? extends DocTree> reference) {
+        DCSee tree = new DCSee(cast(reference));
         tree.pos = pos;
         return tree;
     }
 
-    public DCSerial Serial(List<DCTree> description) {
-        DCSerial tree = new DCSerial(description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSerial newSerialTree(List<? extends DocTree> description) {
+        DCSerial tree = new DCSerial(cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCSerialData SerialData(List<DCTree> description) {
-        DCSerialData tree = new DCSerialData(description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSerialData newSerialDataTree(List<? extends DocTree> description) {
+        DCSerialData tree = new DCSerialData(cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCSerialField SerialField(DCIdentifier name, DCReference type, List<DCTree> description) {
-        DCSerialField tree = new DCSerialField(name, type, description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSerialField newSerialFieldTree(IdentifierTree name, ReferenceTree type, List<? extends DocTree> description) {
+        DCSerialField tree = new DCSerialField((DCIdentifier) name, (DCReference) type, cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCSince Since(List<DCTree> text) {
-        DCSince tree = new DCSince(text);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSince newSinceTree(List<? extends DocTree> text) {
+        DCSince tree = new DCSince(cast(text));
         tree.pos = pos;
         return tree;
     }
 
-    public DCStartElement StartElement(Name name, List<DCTree> attrs, boolean selfClosing) {
-        DCStartElement tree = new DCStartElement(name, attrs, selfClosing);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCStartElement newStartElementTree(Name name, List<? extends DocTree> attrs, boolean selfClosing) {
+        DCStartElement tree = new DCStartElement(name, cast(attrs), selfClosing);
         tree.pos = pos;
         return tree;
     }
 
-    public DCText Text(String text) {
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCText newTextTree(String text) {
         DCText tree = new DCText(text);
         tree.pos = pos;
         return tree;
     }
 
-    public DCThrows Throws(DCReference name, List<DCTree> description) {
-        DCThrows tree = new DCThrows(Kind.THROWS, name, description);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCThrows newThrowsTree(ReferenceTree name, List<? extends DocTree> description) {
+        // TODO: verify the reference is just to a type (not a field or method)
+        DCThrows tree = new DCThrows(Kind.THROWS, (DCReference) name, cast(description));
         tree.pos = pos;
         return tree;
     }
 
-    public DCUnknownBlockTag UnknownBlockTag(Name name, List<DCTree> content) {
-        DCUnknownBlockTag tree = new DCUnknownBlockTag(name, content);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCUnknownBlockTag newUnknownBlockTagTree(Name name, List<? extends DocTree> content) {
+        DCUnknownBlockTag tree = new DCUnknownBlockTag(name, cast(content));
         tree.pos = pos;
         return tree;
     }
 
-    public DCUnknownInlineTag UnknownInlineTag(Name name, List<DCTree> content) {
-        DCUnknownInlineTag tree = new DCUnknownInlineTag(name, content);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCUnknownInlineTag newUnknownInlineTagTree(Name name, List<? extends DocTree> content) {
+        DCUnknownInlineTag tree = new DCUnknownInlineTag(name, cast(content));
         tree.pos = pos;
         return tree;
     }
 
-    public DCValue Value(DCReference ref) {
-        DCValue tree = new DCValue(ref);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCValue newValueTree(ReferenceTree ref) {
+        // TODO: verify the reference is to a constant value
+        DCValue tree = new DCValue((DCReference) ref);
         tree.pos = pos;
         return tree;
     }
 
-    public DCVersion Version(List<DCTree> text) {
-        DCVersion tree = new DCVersion(text);
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCVersion newVersionTree(List<? extends DocTree> text) {
+        DCVersion tree = new DCVersion(cast(text));
         tree.pos = pos;
         return tree;
     }
 
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
         Pair<List<DCTree>, List<DCTree>> pair = splitBody(list);
         return new ArrayList<>(pair.fst);
@@ -389,12 +456,12 @@
                         int sbreak = getSentenceBreak(s, peekedNext);
                         if (sbreak > 0) {
                             s = removeTrailingWhitespace(s.substring(0, sbreak));
-                            DCText text = this.at(spos).Text(s);
+                            DCText text = this.at(spos).newTextTree(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));
+                                DCText text2 = this.at(spos + nwPos).newTextTree(tt.getBody().substring(nwPos));
                                 body.add(text2);
                             }
                             continue;
@@ -405,7 +472,7 @@
                             if (sbrk) {
                                 DocTree next = itr.next();
                                 s = removeTrailingWhitespace(s);
-                                DCText text = this.at(spos).Text(s);
+                                DCText text = this.at(spos).newTextTree(s);
                                 fs.add(text);
                                 body.add((DCTree) next);
                                 foundFirstSentence = true;
@@ -436,7 +503,7 @@
     /*
      * Computes the first sentence break, a simple dot-space algorithm.
      */
-    int defaultSentenceBreak(String s) {
+    private int defaultSentenceBreak(String s) {
         // scan for period followed by whitespace
         int period = -1;
         for (int i = 0; i < s.length(); i++) {
@@ -483,7 +550,7 @@
      * 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) {
+    private int getSentenceBreak(String s, DocTree dt) {
         BreakIterator breakIterator = trees.getBreakIterator();
         if (breakIterator == null) {
             return defaultSentenceBreak(s);
@@ -533,11 +600,11 @@
         return -1; // indeterminate at this time
     }
 
-    boolean isSentenceBreak(javax.lang.model.element.Name tagName) {
+    private boolean isSentenceBreak(javax.lang.model.element.Name tagName) {
         return sentenceBreakTags.contains(get(tagName));
     }
 
-    boolean isSentenceBreak(DocTree dt, boolean isFirstDocTree) {
+    private boolean isSentenceBreak(DocTree dt, boolean isFirstDocTree) {
         switch (dt.getKind()) {
             case START_ELEMENT:
                     StartElementTree set = (StartElementTree)dt;
@@ -553,7 +620,7 @@
     /*
      * Returns the position of the the first non-white space
      */
-    int skipWhiteSpace(String s, int start) {
+    private int skipWhiteSpace(String s, int start) {
         for (int i = start; i < s.length(); i++) {
             char c = s.charAt(i);
             if (!Character.isWhitespace(c)) {
@@ -563,7 +630,7 @@
         return -1;
     }
 
-    String removeTrailingWhitespace(String s) {
+    private String removeTrailingWhitespace(String s) {
         for (int i = s.length() - 1 ; i >= 0 ; i--) {
             char ch = s.charAt(i);
             if (!Character.isWhitespace(ch)) {
@@ -572,4 +639,9 @@
         }
         return s;
     }
+
+    @SuppressWarnings("unchecked")
+    private List<DCTree> cast(List<? extends DocTree> list) {
+        return (List<DCTree>) list;
+    }
 }