changeset 2098:a7ff36d06fa2

8009724: Enhance the DocTree API with DocTreePath Summary: Adding DocTreePath and DocTreePathScanner similar to TreePath and TreePathScanner, respectively Reviewed-by: jjg Contributed-by: Ralph Benjamin Ruijs <ralphbenjamin@netbeans.org>, Jan Lahoda <jlahoda@netbeans.org>
author jlahoda
date Mon, 06 May 2013 16:22:45 +0200
parents e8987ce7fb4b
children 68142e69cafb
files src/share/classes/com/sun/source/util/DocTreePath.java src/share/classes/com/sun/source/util/DocTreePathScanner.java src/share/classes/com/sun/source/util/DocTrees.java src/share/classes/com/sun/tools/doclint/Checker.java src/share/classes/com/sun/tools/javac/api/JavacTrees.java test/tools/javac/doctree/DocTreePathScannerTest.java test/tools/javac/doctree/ReferenceTest.java
diffstat 7 files changed, 488 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/util/DocTreePath.java	Mon May 06 16:22:45 2013 +0200
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2006, 2013, 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 com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import java.util.Iterator;
+
+/**
+ * A path of tree nodes, typically used to represent the sequence of ancestor
+ * nodes of a tree node up to the top level DocCommentTree node.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePath implements Iterable<DocTree> {
+    /**
+     * Gets a documentation tree path for a tree node within a compilation unit.
+     * @return null if the node is not found
+     */
+    public static DocTreePath getPath(TreePath treePath, DocCommentTree doc, DocTree target) {
+        return getPath(new DocTreePath(treePath, doc), target);
+    }
+
+    /**
+     * Gets a documentation tree path for a tree node within a subtree identified by a DocTreePath object.
+     * @return null if the node is not found
+     */
+    public static DocTreePath getPath(DocTreePath path, DocTree target) {
+        path.getClass();
+        target.getClass();
+
+        class Result extends Error {
+            static final long serialVersionUID = -5942088234594905625L;
+            DocTreePath path;
+            Result(DocTreePath path) {
+                this.path = path;
+            }
+        }
+
+        class PathFinder extends DocTreePathScanner<DocTreePath,DocTree> {
+            public DocTreePath scan(DocTree tree, DocTree target) {
+                if (tree == target) {
+                    throw new Result(new DocTreePath(getCurrentPath(), target));
+                }
+                return super.scan(tree, target);
+            }
+        }
+
+        if (path.getLeaf() == target) {
+            return path;
+        }
+
+        try {
+            new PathFinder().scan(path, target);
+        } catch (Result result) {
+            return result.path;
+        }
+        return null;
+    }
+
+    /**
+     * Creates a DocTreePath for a root node.
+     *
+     * @param treePath the TreePath from which the root node was created.
+     * @param t the DocCommentTree to create the path for.
+     */
+    public DocTreePath(TreePath treePath, DocCommentTree t) {
+        treePath.getClass();
+        t.getClass();
+
+        this.treePath = treePath;
+        this.docComment = t;
+        this.parent = null;
+        this.leaf = t;
+    }
+
+    /**
+     * Creates a DocTreePath for a child node.
+     */
+    public DocTreePath(DocTreePath p, DocTree t) {
+        if (t.getKind() == DocTree.Kind.DOC_COMMENT) {
+            throw new IllegalArgumentException("Use DocTreePath(TreePath, DocCommentTree) to construct DocTreePath for a DocCommentTree.");
+        } else {
+            treePath = p.treePath;
+            docComment = p.docComment;
+            parent = p;
+        }
+        leaf = t;
+    }
+
+    /**
+     * Get the TreePath associated with this path.
+     * @return TreePath for this DocTreePath
+     */
+    public TreePath getTreePath() {
+        return treePath;
+    }
+
+    /**
+     * Get the DocCommentTree associated with this path.
+     * @return DocCommentTree for this DocTreePath
+     */
+    public DocCommentTree getDocComment() {
+        return docComment;
+    }
+
+    /**
+     * Get the leaf node for this path.
+     * @return DocTree for this DocTreePath
+     */
+    public DocTree getLeaf() {
+        return leaf;
+    }
+
+    /**
+     * Get the path for the enclosing node, or null if there is no enclosing node.
+     * @return DocTreePath of parent
+     */
+    public DocTreePath getParentPath() {
+        return parent;
+    }
+
+    public Iterator<DocTree> iterator() {
+        return new Iterator<DocTree>() {
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            public DocTree next() {
+                DocTree t = next.leaf;
+                next = next.parent;
+                return t;
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+            private DocTreePath next = DocTreePath.this;
+        };
+    }
+
+    private final TreePath treePath;
+    private final DocCommentTree docComment;
+    private final DocTree leaf;
+    private final DocTreePath parent;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/util/DocTreePathScanner.java	Mon May 06 16:22:45 2013 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006, 2013, 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 com.sun.source.doctree.DocTree;
+
+/**
+ * A DocTreeVisitor that visits all the child tree nodes, and provides
+ * support for maintaining a path for the parent nodes.
+ * To visit nodes of a particular type, just override the
+ * corresponding visitorXYZ method.
+ * Inside your method, call super.visitXYZ to visit descendant
+ * nodes.
+ *
+ * @since 1.8
+ */
+@jdk.Supported
+public class DocTreePathScanner<R, P> extends DocTreeScanner<R, P> {
+    /**
+     * Scan a tree from a position identified by a TreePath.
+     */
+    public R scan(DocTreePath path, P p) {
+        this.path = path;
+        try {
+            return path.getLeaf().accept(this, p);
+        } finally {
+            this.path = null;
+        }
+    }
+
+    /**
+     * Scan a single node.
+     * The current path is updated for the duration of the scan.
+     */
+    @Override
+    public R scan(DocTree tree, P p) {
+        if (tree == null)
+            return null;
+
+        DocTreePath prev = path;
+        path = new DocTreePath(path, tree);
+        try {
+            return tree.accept(this, p);
+        } finally {
+            path = prev;
+        }
+    }
+
+    /**
+     * Get the current path for the node, as built up by the currently
+     * active set of scan calls.
+     */
+    public DocTreePath getCurrentPath() {
+        return path;
+    }
+
+    private DocTreePath path;
+}
--- a/src/share/classes/com/sun/source/util/DocTrees.java	Sun May 05 21:04:41 2013 -0700
+++ b/src/share/classes/com/sun/source/util/DocTrees.java	Mon May 06 16:22:45 2013 +0200
@@ -67,10 +67,10 @@
     public abstract DocCommentTree getDocCommentTree(TreePath path);
 
     /**
-     * Gets the language model element referred to by a ReferenceTree that
-     * appears on the declaration identified by the given path.
+     * Gets the language model element referred to by the leaf node of the given
+     * {@link DocTreePath}, or null if unknown.
      */
-    public abstract Element getElement(TreePath path, ReferenceTree reference);
+    public abstract Element getElement(DocTreePath path);
 
     public abstract DocSourcePositions getSourcePositions();
 
--- a/src/share/classes/com/sun/tools/doclint/Checker.java	Sun May 05 21:04:41 2013 -0700
+++ b/src/share/classes/com/sun/tools/doclint/Checker.java	Mon May 06 16:22:45 2013 +0200
@@ -42,7 +42,6 @@
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.tools.Diagnostic.Kind;
@@ -70,7 +69,8 @@
 import com.sun.source.doctree.ThrowsTree;
 import com.sun.source.doctree.ValueTree;
 import com.sun.source.doctree.VersionTree;
-import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
 import com.sun.source.util.TreePath;
 import com.sun.tools.doclint.HtmlTag.AttrKind;
 import com.sun.tools.javac.tree.DocPretty;
@@ -85,7 +85,7 @@
  * risk.  This code and its internal interfaces are subject to change
  * or deletion without notice.</b></p>
  */
-public class Checker extends DocTreeScanner<Void, Void> {
+public class Checker extends DocTreePathScanner<Void, Void> {
     final Env env;
 
     Set<Element> foundParams = new HashSet<Element>();
@@ -152,7 +152,7 @@
         foundInheritDoc = false;
         foundReturn = false;
 
-        scan(tree, (Void) null);
+        scan(new DocTreePath(p, tree), null);
 
         if (!isOverridingMethod) {
             switch (env.currElement.getKind()) {
@@ -620,47 +620,36 @@
     }
 
     @Override
+    @SuppressWarnings("fallthrough")
     public Void visitParam(ParamTree tree, Void ignore) {
         boolean typaram = tree.isTypeParameter();
         IdentifierTree nameTree = tree.getName();
-        Element e = env.currElement;
-        switch (e.getKind()) {
-            case METHOD: case CONSTRUCTOR: {
-                ExecutableElement ee = (ExecutableElement) e;
-                checkParamDeclared(nameTree, typaram ? ee.getTypeParameters() : ee.getParameters());
-                break;
+        Element paramElement = nameTree != null ? env.trees.getElement(new DocTreePath(getCurrentPath(), nameTree)) : null;
+
+        if (paramElement == null) {
+            switch (env.currElement.getKind()) {
+                case CLASS: case INTERFACE: {
+                    if (!typaram) {
+                        env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                        break;
+                    }
+                }
+                case METHOD: case CONSTRUCTOR: {
+                    env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
+                    break;
+                }
+
+                default:
+                    env.messages.error(REFERENCE, tree, "dc.invalid.param");
+                    break;
             }
+        } else {
+            foundParams.add(paramElement);
+        }
 
-            case CLASS: case INTERFACE: {
-                TypeElement te = (TypeElement) e;
-                if (typaram) {
-                    checkParamDeclared(nameTree, te.getTypeParameters());
-                } else {
-                    env.messages.error(REFERENCE, tree, "dc.invalid.param");
-                }
-                break;
-            }
-
-            default:
-                env.messages.error(REFERENCE, tree, "dc.invalid.param");
-                break;
-        }
         warnIfEmpty(tree, tree.getDescription());
         return super.visitParam(tree, ignore);
     }
-    // where
-    private void checkParamDeclared(IdentifierTree nameTree, List<? extends Element> list) {
-        Name name = nameTree.getName();
-        boolean found = false;
-        for (Element e: list) {
-            if (name.equals(e.getSimpleName())) {
-                foundParams.add(e);
-                found = true;
-            }
-        }
-        if (!found)
-            env.messages.error(REFERENCE, nameTree, "dc.param.name.not.found");
-    }
 
     private void checkParamsDocumented(List<? extends Element> list) {
         if (foundInheritDoc)
@@ -678,7 +667,7 @@
 
     @Override
     public Void visitReference(ReferenceTree tree, Void ignore) {
-        Element e = env.trees.getElement(env.currPath, tree);
+        Element e = env.trees.getElement(getCurrentPath());
         if (e == null)
             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
         return super.visitReference(tree, ignore);
@@ -716,7 +705,7 @@
     @Override
     public Void visitThrows(ThrowsTree tree, Void ignore) {
         ReferenceTree exName = tree.getExceptionName();
-        Element ex = env.trees.getElement(env.currPath, exName);
+        Element ex = env.trees.getElement(new DocTreePath(getCurrentPath(), exName));
         if (ex == null) {
             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
         } else if (ex.asType().getKind() == TypeKind.DECLARED
--- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Sun May 05 21:04:41 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Mon May 06 16:22:45 2013 +0200
@@ -33,6 +33,7 @@
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
@@ -44,12 +45,12 @@
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.ReferenceTree;
 import com.sun.source.tree.CatchTree;
 import com.sun.source.tree.CompilationUnitTree;
 import com.sun.source.tree.Scope;
 import com.sun.source.tree.Tree;
 import com.sun.source.util.DocSourcePositions;
+import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTreeScanner;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.JavacTask;
@@ -314,7 +315,7 @@
         return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
     }
 
-    public Element getElement(TreePath path) {
+    public Symbol getElement(TreePath path) {
         JCTree tree = (JCTree) path.getLeaf();
         Symbol sym = TreeInfo.symbolFor(tree);
         if (sym == null) {
@@ -343,11 +344,19 @@
     }
 
     @Override
-    public Element getElement(TreePath path, ReferenceTree reference) {
-        if (!(reference instanceof DCReference))
-            return null;
-        DCReference ref = (DCReference) reference;
+    public Element getElement(DocTreePath path) {
+        DocTree forTree = path.getLeaf();
+        if (forTree instanceof DCReference)
+            return attributeDocReference(path.getTreePath(), ((DCReference) forTree));
+        if (forTree instanceof DCIdentifier) {
+            if (path.getParentPath().getLeaf() instanceof DCParam) {
+                return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf());
+            }
+        }
+        return null;
+    }
 
+    private Symbol attributeDocReference(TreePath path, DCReference ref) {
         Env<AttrContext> env = getAttrContext(path);
 
         Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
@@ -427,6 +436,30 @@
         }
     }
 
+    private Symbol attributeParamIdentifier(TreePath path, DCParam ptag) {
+        Symbol javadocSymbol = getElement(path);
+        if (javadocSymbol == null)
+            return null;
+        ElementKind kind = javadocSymbol.getKind();
+        List<? extends Symbol> params = List.nil();
+        if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
+            MethodSymbol ee = (MethodSymbol) javadocSymbol;
+            params = ptag.isTypeParameter()
+                    ? ee.getTypeParameters()
+                    : ee.getParameters();
+        } else if (kind.isClass() || kind.isInterface()) {
+            ClassSymbol te = (ClassSymbol) javadocSymbol;
+            params = te.getTypeParameters();
+        }
+
+        for (Symbol param : params) {
+            if (param.getSimpleName() == ptag.getName().getName()) {
+                return param;
+            }
+        }
+        return null;
+    }
+
     /** @see com.sun.tools.javadoc.ClassDocImpl#findField */
     private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
         return searchField(tsym, fieldName, new HashSet<ClassSymbol>());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/doctree/DocTreePathScannerTest.java	Mon May 06 16:22:45 2013 +0200
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013, 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 8009724
+ * @summary adding DocTreePath and DocTreePathScanner
+ */
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTree.Kind;
+import com.sun.source.doctree.DocTreeVisitor;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.lang.model.element.Name;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+public class DocTreePathScannerTest {
+    public static void main(String... args) throws Exception {
+        DocTreePathScannerTest t = new DocTreePathScannerTest();
+        t.run();
+    }
+
+    void run() throws Exception {
+        List<File> files = new ArrayList<File>();
+        File testSrc = new File(System.getProperty("test.src"));
+        for (File f: testSrc.listFiles()) {
+            if (f.isFile() && f.getName().endsWith(".java"))
+                files.add(f);
+        }
+
+        JavacTool javac = JavacTool.create();
+        StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+
+        Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
+
+        JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+        DocTrees trees = DocTrees.instance(t);
+
+        Iterable<? extends CompilationUnitTree> units = t.parse();
+
+        DeclScanner ds = new DeclScanner(trees);
+        for (CompilationUnitTree unit: units) {
+            ds.scan(unit, null);
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    class DeclScanner extends TreePathScanner<Void, Void> {
+        DocTrees trees;
+        DocTreePathScanner<Void,Void> cs;
+
+        DeclScanner(DocTrees trees) {
+            this.trees = trees;
+            cs = new CommentPathScanner();
+        }
+
+        @Override
+        public Void visitClass(ClassTree tree, Void ignore) {
+            super.visitClass(tree, ignore);
+            visitDecl(tree, tree.getSimpleName());
+            return null;
+        }
+
+        @Override
+        public Void visitMethod(MethodTree tree, Void ignore) {
+            super.visitMethod(tree, ignore);
+            visitDecl(tree, tree.getName());
+            return null;
+        }
+
+        @Override
+        public Void visitVariable(VariableTree tree, Void ignore) {
+            super.visitVariable(tree, ignore);
+            visitDecl(tree, tree.getName());
+            return null;
+        }
+
+        void visitDecl(Tree tree, Name name) {
+            TreePath path = getCurrentPath();
+            DocCommentTree dc = trees.getDocCommentTree(path);
+            if (dc != null)
+                cs.scan(new DocTreePath(path, dc), null);
+        }
+    }
+
+    class CommentPathScanner extends DocTreePathScanner<Void, Void> {
+        CommentPathScanner() {}
+
+        @Override
+        public Void scan(final DocTree tree, Void ignore) {
+            if (tree != null) {
+                DocTree previous = null;
+                for (DocTree current : getCurrentPath()) {
+                    if (previous != null) {
+                        final List<DocTree> children = new ArrayList<>();
+                        current.accept(new DocTreeScanner<Void, Void>() {
+                            @Override public Void scan(DocTree node, Void p) {
+                                children.add(node);
+                                return null;
+                            }
+                        }, null);
+
+                        if (!children.contains(previous)) {
+                            error("Invalid DocTreePath for: " + tree);
+                        }
+                    }
+
+                    previous = current;
+                }
+            }
+            return super.scan(tree, ignore);
+        }
+    }
+
+}
--- a/test/tools/javac/doctree/ReferenceTest.java	Sun May 05 21:04:41 2013 -0700
+++ b/test/tools/javac/doctree/ReferenceTest.java	Mon May 06 16:22:45 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -36,6 +36,8 @@
 import com.sun.source.doctree.ReferenceTree;
 import com.sun.source.doctree.SeeTree;
 import com.sun.source.doctree.TextTree;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
 import com.sun.source.util.DocTreeScanner;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.TreePath;
@@ -125,7 +127,7 @@
         return true;
     }
 
-    class DocCommentScanner extends DocTreeScanner<Void, Void> {
+    class DocCommentScanner extends DocTreePathScanner<Void, Void> {
         TreePath path;
         DocCommentTree dc;
 
@@ -135,7 +137,7 @@
 
         void scan() {
             dc = trees.getDocCommentTree(path);
-            scan(dc, null);
+            scan(new DocTreePath(path, dc), null);
         }
 
         @Override
@@ -158,7 +160,7 @@
         void checkReference(ReferenceTree tree, List<? extends DocTree> label) {
             String sig = tree.getSignature();
 
-            Element found = trees.getElement(path, tree);
+            Element found = trees.getElement(new DocTreePath(getCurrentPath(), tree));
             if (found == null) {
                 System.err.println(sig + " NOT FOUND");
             } else {