8169608: Compiler Tree API's Doctrees.getDocTreePath needs to accept a PackageElement
authorksrini
Thu, 19 Jan 2017 13:16:19 -0800
changeset 43265 4ec472ee5135
parent 43264 7b06e19184de
child 43266 14e6159a2c17
8169608: Compiler Tree API's Doctrees.getDocTreePath needs to accept a PackageElement 8157611: field visiblePackages is null for the unnamed module producing NPE when accessed Reviewed-by: jjg, jlahoda
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/code/Symbol.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java
langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java
langtools/test/jdk/javadoc/tool/treeapi/overview.html
langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -31,6 +31,7 @@
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
 import javax.tools.Diagnostic;
 import javax.tools.FileObject;
 import javax.tools.JavaCompiler.CompilationTask;
@@ -127,17 +128,22 @@
 
     /**
      * 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 <body> tag, and any enclosing tags are ignored.
+     * The file must be an HTML file, in which case the doc comment tree represents
+     * the contents of the {@code <body>} tag, and any enclosing tags are ignored.
+     * Any references to source code elements contained in {@code @see} and
+     * {@code {@link}} tags in the doc comment tree will be evaluated in the
+     * context of the given package element.
      * 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.
+     * @param fileObject a file object encapsulating the HTML content
+     * @param packageElement a package element to associate with the given file object
+     * representing a legacy package.html, null otherwise
+     * @return a doc tree path containing the doc comment parsed from the given file
+     * @throws IllegalArgumentException if the fileObject is not an HTML file
      *
      * @since 9
      */
-    public abstract DocTreePath getDocTreePath(FileObject fileObject);
+    public abstract DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement);
 
     /**
      * Returns the language model element referred to by the leaf node of the given
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Thu Jan 19 13:16:19 2017 -0800
@@ -174,7 +174,6 @@
     private JavaFileManager fileManager;
     private ParserFactory parser;
     private Symtab syms;
-    private Map<JavaFileObject, PackageSymbol> javaFileObjectToPackageMap;
 
     // called reflectively from Trees.instance(CompilationTask task)
     public static JavacTrees instance(JavaCompiler.CompilationTask task) {
@@ -198,7 +197,6 @@
     }
 
     protected JavacTrees(Context context) {
-        javaFileObjectToPackageMap = new HashMap<>();
         this.breakIterator = null;
         context.put(JavacTrees.class, this);
         init(context);
@@ -1039,10 +1037,11 @@
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
-    public DocTreePath getDocTreePath(FileObject fileObject) {
+    public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
         JavaFileObject jfo = asJavaFileObject(fileObject);
         DocCommentTree docCommentTree = getDocCommentTree(jfo);
-        return new DocTreePath(makeTreePath(jfo, docCommentTree), docCommentTree);
+        TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
+        return new DocTreePath(treePath, docCommentTree);
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
@@ -1160,17 +1159,8 @@
         }
     }
 
-    /**
-     * Register a file object, such as for a package.html, that provides
-     * doc comments for a package.
-     * @param psym the PackageSymbol representing the package.
-     * @param jfo  the JavaFileObject for the given package.
-     */
-    public void putJavaFileObject(PackageSymbol psym, JavaFileObject jfo) {
-        javaFileObjectToPackageMap.putIfAbsent(jfo, psym);
-    }
-
-    private TreePath makeTreePath(final JavaFileObject jfo, DocCommentTree dcTree) {
+    private TreePath makeTreePath(final PackageSymbol psym, final JavaFileObject jfo,
+            DocCommentTree dcTree) {
         JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
             public int getPos() {
                 return Position.FIRSTPOS;
@@ -1191,9 +1181,6 @@
             }
         };
 
-        PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
-                syms.unnamedModule.unnamedPackage);
-
         jcCompilationUnit.docComments = new DocCommentTable() {
             @Override
             public boolean hasComment(JCTree tree) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1070,6 +1070,8 @@
         public Name fullname;
         public ClassSymbol package_info; // see bug 6443073
         public ModuleSymbol modle;
+        // the file containing the documentation comments for the package
+        public JavaFileObject sourcefile;
 
         public PackageSymbol(Name name, Type type, Symbol owner) {
             super(PCK, 0, name, type, owner);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,6 +35,19 @@
 package jdk.javadoc.internal.doclets.toolkit;
 
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
@@ -45,22 +58,6 @@
 import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.TreePath;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.Elements;
-import javax.tools.FileObject;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
@@ -177,10 +174,18 @@
      */
     public DocCommentDuo getHtmlCommentDuo(Element e) {
         FileObject fo = null;
-        if (e.getKind().equals(ElementKind.OTHER)) {
-            fo = configuration.getOverviewPath();
-        } else if (e.getKind().equals(ElementKind.PACKAGE)) {
-            fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
+        PackageElement pe = null;
+        switch (e.getKind()) {
+            case OTHER:
+                fo = configuration.getOverviewPath();
+                pe = configuration.workArounds.getUnnamedPackage();
+                break;
+            case PACKAGE:
+                fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
+                pe = (PackageElement)e;
+                break;
+            default:
+                return null;
         }
         if (fo == null) {
             return null;
@@ -190,7 +195,7 @@
         if (dcTree == null) {
             return null;
         }
-        DocTreePath treePath = trees.getDocTreePath(fo);
+        DocTreePath treePath = trees.getDocTreePath(fo, pe);
         return new DocCommentDuo(treePath.getTreePath(), dcTree);
     }
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Thu Jan 19 13:16:19 2017 -0800
@@ -44,6 +44,7 @@
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
 import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
@@ -59,7 +60,9 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.model.JavacElements;
@@ -192,11 +195,24 @@
         return ((VarSymbol)ve).getConstValue();
     }
 
-    //TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
+    // TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
     public Map<Element, TreePath> getElementToTreePath() {
         return toolEnv.elementToTreePath;
     }
 
+    // TODO: we need ElementUtils.getPackage to cope with input strings
+    // to return the proper unnamedPackage for all supported releases.
+    PackageElement getUnnamedPackage() {
+        return (toolEnv.source.allowModules())
+                ? toolEnv.syms.unnamedModule.unnamedPackage
+                : toolEnv.syms.noModule.unnamedPackage;
+    }
+
+    // TODO: implement in either jx.l.m API (preferred) or DocletEnvironment.
+    FileObject getJavaFileObject(PackageElement packageElement) {
+        return ((PackageSymbol)packageElement).sourcefile;
+    }
+
     // TODO: needs to ported to jx.l.m.
     public TypeElement searchClass(TypeElement klass, String className) {
         // search by qualified name first
@@ -530,12 +546,6 @@
         }
     }
 
-    // TODO: this is a fast way to get the JavaFileObject for
-    // a package.html file, however we need to eliminate this.
-    public JavaFileObject getJavaFileObject(PackageElement pe) {
-        return toolEnv.pkgToJavaFOMap.get(pe);
-    }
-
     // TODO: we need to eliminate this, as it is hacky.
     /**
      * Returns a representation of the package truncated to two levels.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -39,14 +39,12 @@
 
 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.ModuleElement;
 import javax.lang.model.element.ModuleElement.ExportsDirective;
 import javax.lang.model.element.ModuleElement.RequiresDirective;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.SimpleElementVisitor9;
 import javax.tools.JavaFileManager;
@@ -54,15 +52,12 @@
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
 
-import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.Modules;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@@ -75,9 +70,11 @@
 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
 
 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static javax.tools.JavaFileObject.Kind.*;
 import static jdk.javadoc.internal.tool.Main.Result.*;
 import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
 
+
 /**
  * This class manages elements specified on the command line, and
  * produces "specified" and "included" data sets, needed by the
@@ -864,7 +861,7 @@
     }
 
     private boolean isTypeElementSelected(TypeElement te) {
-        return (xclasses || toolEnv.isFromSource(te)) && isSelected(te);
+        return (xclasses || toolEnv.getFileKind(te) == SOURCE) && isSelected(te);
     }
 
     SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java	Thu Jan 19 13:16:19 2017 -0800
@@ -88,8 +88,7 @@
     @Override
     protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
         if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML)) {
-            toolEnv.pkgToJavaFOMap.put(pack, fo);
-            trees.putJavaFileObject(pack, fo);
+            pack.sourcefile = fo;
         }
     }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,7 +29,6 @@
 import java.util.*;
 
 import javax.lang.model.element.Element;
-import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.Elements;
 import javax.tools.JavaFileManager;
@@ -116,8 +115,6 @@
 
     WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
 
-    public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
-
     /** Allow documenting from class files? */
     boolean docClasses = false;
 
@@ -193,21 +190,11 @@
         elementToTreePath.put(e, tree);
     }
 
-    /**
-     * Returns true if the type element originates from source.
-     * Primarily used to disambiguate a type element associated with a source
-     * file versus a class file.
-     * @param te the type element
-     * @return true if the symbol is from source
-     */
-    public boolean isFromSource(TypeElement te) {
-        return getFileKind(te) == Kind.SOURCE;
-    }
-
     public Kind getFileKind(TypeElement te) {
         JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
         return jfo == null ? Kind.SOURCE : jfo.getKind();
     }
+
     /**
      * Print a notice, iff <em>quiet</em> is not specified.
      *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java	Thu Jan 19 13:16:19 2017 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8157611
+ * @summary test DocTrees is working correctly relative to HTML access
+ * @modules
+ *      jdk.javadoc/jdk.javadoc.internal.api
+ *      jdk.javadoc/jdk.javadoc.internal.tool
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main TestDocTrees
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+import toolbox.Task.Expect;
+
+import static toolbox.Task.OutputKind.*;
+
+/**
+ * This class is used to test DocTrees functionality relating to
+ * package and overview HTML files.
+ */
+public class TestDocTrees extends TestRunner {
+    final ToolBox tb;
+    final File testFile;
+    final File testSrc;
+    final File overviewFile;
+
+    TestDocTrees() throws IOException {
+        super(System.err);
+        tb = new ToolBox();
+        testSrc = new File(System.getProperty("test.src"));
+        testFile = new File(testSrc, "TestDocTrees.java");
+        overviewFile = new File(testSrc, "overview.html");
+    }
+
+    protected void runTests() throws Exception {
+        runTests(m -> new Object[]{Paths.get(m.getName())});
+    }
+
+    public static void main(String... args) throws Exception {
+        new TestDocTrees().runTests();
+    }
+
+    @Test
+    public void testOverviewWithRelease8(Path out) {
+        execTask("-d", out.toString(),
+                "--release", "8",
+                "-Xdoclint:all",
+                "-Xdoclint:-missing",
+                "-sourcepath", testSrc.getAbsolutePath(),
+                testFile.getAbsolutePath(),
+                "-overview", overviewFile.getAbsolutePath());
+    }
+
+    @Test
+    public void testOverviewWithoutRelease(Path out) throws Exception {
+        execTask("-d", out.toString(),
+                "-Xdoclint:all",
+                "-Xdoclint:-missing",
+                "-sourcepath", testSrc.getAbsolutePath(),
+                testFile.getAbsolutePath(),
+                "-overview", overviewFile.getAbsolutePath());
+    }
+
+    private Task.Result execTask(String... args) {
+        JavadocTask et = new JavadocTask(tb, Task.Mode.CMDLINE);
+        //args.forEach((a -> System.err.println("arg: " + a)));
+        return et.options(args).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/overview.html	Thu Jan 19 13:16:19 2017 -0800
@@ -0,0 +1,27 @@
+<!--
+  Copyright (c) 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.
+
+  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
+  along with this work; if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+  or visit www.oracle.com if you need additional information or have any
+  questions.
+-->
+<html>
+  <body>
+    <b>{@link omg.what.gives}</b>
+  </body>
+</html>
\ No newline at end of file
--- a/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java	Thu Jan 19 11:17:11 2017 -0800
+++ b/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java	Thu Jan 19 13:16:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug  8132096
+ * @bug  8132096 8157611
  * @summary test the APIs  in the DocTree interface
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
@@ -48,12 +48,15 @@
 import java.util.Locale;
 
 import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.util.Elements;
 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.DocTreePath;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.api.JavacTool;
@@ -90,6 +93,9 @@
             // tests files relative path in an unnamed package
             test.runRelativePathTest("OverviewTest.java", "overview0.html");
 
+            // tests doctreepath using package element and package.html
+            test.runDocTreePath("pkg/Anchor.java", "package.html");
+
             // test for correct parsing using valid and some invalid html tags
             for (int i = 0; i < 7; i++) {
                 String hname = "overview" + i + ".html";
@@ -152,6 +158,7 @@
             }
         }
     }
+
     /**
      * Tests DocTrees.getDocCommentTree(Element e, String relpath) using relative path.
      *
@@ -219,6 +226,49 @@
         }
     }
 
+    /**
+     * Tests DocTrees.getDocTreePath(PackageElement p, FileObject fo).
+     *
+     * @param javaFileName the java anchor file
+     * @param pkgFileName the package file name
+     * @throws Exception e if something goes awry
+     */
+    public void runDocTreePath(String javaFileName, String pkgFileName) throws Exception  {
+        List<File> javaFiles = new ArrayList<>();
+        javaFiles.add(new File(testSrc, javaFileName));
+
+        List<File> dirs = new ArrayList<>();
+        dirs.add(new File(testSrc));
+
+        try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
+            fm.setLocation(javax.tools.StandardLocation.SOURCE_PATH, dirs);
+            Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
+
+            final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+            final DocTrees trees = DocTrees.instance(t);
+            final Elements elementUtils = t.getElements();
+
+            Iterable<? extends Element> elements = t.analyze();
+
+            Element klass = elements.iterator().next();
+            PackageElement pkg = elementUtils.getPackageOf(klass);
+
+            FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
+                    t.getElements().getPackageOf(klass).getQualifiedName().toString(),
+                    "package.html");
+            System.out.println();
+            DocTreePath treePath = trees.getDocTreePath(htmlFo, pkg);
+            DocCommentTree dcTree = treePath.getDocComment();
+
+            StringWriter sw = new StringWriter();
+            printer.print(dcTree, sw);
+            String found = sw.toString();
+
+            String expected = getExpected(htmlFo.openReader(true));
+            astcheck(pkgFileName, expected, found);
+        }
+    }
+
     void astcheck(String testinfo, String expected, String found) {
         System.err.print("ASTChecker: " + testinfo);
         check0(expected, found);