jlahoda@1726: /* jlahoda@1726: * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. jlahoda@1726: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jlahoda@1726: * jlahoda@1726: * This code is free software; you can redistribute it and/or modify it jlahoda@1726: * under the terms of the GNU General Public License version 2 only, as jlahoda@1726: * published by the Free Software Foundation. Oracle designates this jlahoda@1726: * particular file as subject to the "Classpath" exception as provided jlahoda@1726: * by Oracle in the LICENSE file that accompanied this code. jlahoda@1726: * jlahoda@1726: * This code is distributed in the hope that it will be useful, but WITHOUT jlahoda@1726: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jlahoda@1726: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jlahoda@1726: * version 2 for more details (a copy is included in the LICENSE file that jlahoda@1726: * accompanied this code). jlahoda@1726: * jlahoda@1726: * You should have received a copy of the GNU General Public License version jlahoda@1726: * 2 along with this work; if not, write to the Free Software Foundation, jlahoda@1726: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jlahoda@1726: * jlahoda@1726: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jlahoda@1726: * or visit www.oracle.com if you need additional information or have any jlahoda@1726: * questions. jlahoda@1726: */ jlahoda@1726: jlahoda@1726: package com.sun.source.util; jlahoda@1726: jlahoda@1726: import com.sun.source.doctree.DocCommentTree; jlahoda@1726: import com.sun.source.doctree.DocTree; jlahoda@1726: import java.util.Iterator; jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * A path of tree nodes, typically used to represent the sequence of ancestor jlahoda@1726: * nodes of a tree node up to the top level DocCommentTree node. jlahoda@1726: * jlahoda@1726: * @since 1.8 jlahoda@1726: */ darcy@2083: @jdk.Exported jlahoda@1726: public class DocTreePath implements Iterable { jlahoda@1726: /** jlahoda@1726: * Gets a documentation tree path for a tree node within a compilation unit. jlahoda@1726: * @return null if the node is not found jlahoda@1726: */ jlahoda@1726: public static DocTreePath getPath(TreePath treePath, DocCommentTree doc, DocTree target) { jlahoda@1726: return getPath(new DocTreePath(treePath, doc), target); jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Gets a documentation tree path for a tree node within a subtree identified by a DocTreePath object. jlahoda@1726: * @return null if the node is not found jlahoda@1726: */ jlahoda@1726: public static DocTreePath getPath(DocTreePath path, DocTree target) { jlahoda@1726: path.getClass(); jlahoda@1726: target.getClass(); jlahoda@1726: jlahoda@1726: class Result extends Error { jlahoda@1726: static final long serialVersionUID = -5942088234594905625L; jlahoda@1726: DocTreePath path; jlahoda@1726: Result(DocTreePath path) { jlahoda@1726: this.path = path; jlahoda@1726: } jlahoda@1726: } jlahoda@1726: jlahoda@1726: class PathFinder extends DocTreePathScanner { jlahoda@1726: public DocTreePath scan(DocTree tree, DocTree target) { jlahoda@1726: if (tree == target) { jlahoda@1726: throw new Result(new DocTreePath(getCurrentPath(), target)); jlahoda@1726: } jlahoda@1726: return super.scan(tree, target); jlahoda@1726: } jlahoda@1726: } jlahoda@1726: jlahoda@1726: if (path.getLeaf() == target) { jlahoda@1726: return path; jlahoda@1726: } jlahoda@1726: jlahoda@1726: try { jlahoda@1726: new PathFinder().scan(path, target); jlahoda@1726: } catch (Result result) { jlahoda@1726: return result.path; jlahoda@1726: } jlahoda@1726: return null; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Creates a DocTreePath for a root node. jlahoda@1726: * jlahoda@1726: * @param treePath the TreePath from which the root node was created. jlahoda@1726: * @param t the DocCommentTree to create the path for. jlahoda@1726: */ jlahoda@1726: public DocTreePath(TreePath treePath, DocCommentTree t) { jlahoda@1726: treePath.getClass(); jlahoda@1726: t.getClass(); jlahoda@1726: jlahoda@1726: this.treePath = treePath; jlahoda@1726: this.docComment = t; jlahoda@1726: this.parent = null; jlahoda@1726: this.leaf = t; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Creates a DocTreePath for a child node. jlahoda@1726: */ jlahoda@1726: public DocTreePath(DocTreePath p, DocTree t) { jlahoda@1726: if (t.getKind() == DocTree.Kind.DOC_COMMENT) { jlahoda@1726: throw new IllegalArgumentException("Use DocTreePath(TreePath, DocCommentTree) to construct DocTreePath for a DocCommentTree."); jlahoda@1726: } else { jlahoda@1726: treePath = p.treePath; jlahoda@1726: docComment = p.docComment; jlahoda@1726: parent = p; jlahoda@1726: } jlahoda@1726: leaf = t; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Get the TreePath associated with this path. jlahoda@1726: * @return TreePath for this DocTreePath jlahoda@1726: */ jlahoda@1726: public TreePath getTreePath() { jlahoda@1726: return treePath; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Get the DocCommentTree associated with this path. jlahoda@1726: * @return DocCommentTree for this DocTreePath jlahoda@1726: */ jlahoda@1726: public DocCommentTree getDocComment() { jlahoda@1726: return docComment; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Get the leaf node for this path. jlahoda@1726: * @return DocTree for this DocTreePath jlahoda@1726: */ jlahoda@1726: public DocTree getLeaf() { jlahoda@1726: return leaf; jlahoda@1726: } jlahoda@1726: jlahoda@1726: /** jlahoda@1726: * Get the path for the enclosing node, or null if there is no enclosing node. jlahoda@1726: * @return DocTreePath of parent jlahoda@1726: */ jlahoda@1726: public DocTreePath getParentPath() { jlahoda@1726: return parent; jlahoda@1726: } jlahoda@1726: jlahoda@1726: public Iterator iterator() { jlahoda@1726: return new Iterator() { jlahoda@1726: public boolean hasNext() { jlahoda@1726: return next != null; jlahoda@1726: } jlahoda@1726: jlahoda@1726: public DocTree next() { jlahoda@1726: DocTree t = next.leaf; jlahoda@1726: next = next.parent; jlahoda@1726: return t; jlahoda@1726: } jlahoda@1726: jlahoda@1726: public void remove() { jlahoda@1726: throw new UnsupportedOperationException(); jlahoda@1726: } jlahoda@1726: jlahoda@1726: private DocTreePath next = DocTreePath.this; jlahoda@1726: }; jlahoda@1726: } jlahoda@1726: jlahoda@1726: private final TreePath treePath; jlahoda@1726: private final DocCommentTree docComment; jlahoda@1726: private final DocTree leaf; jlahoda@1726: private final DocTreePath parent; jlahoda@1726: }