Path: blob/master/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java
41175 views
/*1* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.source.util;2627import com.sun.source.doctree.DocCommentTree;28import com.sun.source.doctree.DocTree;2930import java.util.Iterator;31import java.util.NoSuchElementException;32import java.util.Objects;3334/**35* A path of tree nodes, typically used to represent the sequence of ancestor36* nodes of a tree node up to the top-level {@code DocCommentTree} node.37*38* @since 1.839*/40public class DocTreePath implements Iterable<DocTree> {41/**42* Returns a documentation tree path for a tree node within a compilation unit,43* or {@code null} if the node is not found.44* @param treePath the path for the node with which the doc comment is associated45* @param doc the doc comment associated with the node46* @param target a node within the doc comment47* @return a path identifying the target within the tree48*/49public static DocTreePath getPath(TreePath treePath, DocCommentTree doc, DocTree target) {50return getPath(new DocTreePath(treePath, doc), target);51}5253/**54* Returns a documentation tree path for a tree node within a subtree55* identified by a {@code DocTreePath} object, or {@code null} if the node is not found.56* @param path a path identifying a node within a doc comment tree57* @param target a node to be located within the given node58* @return a path identifying the target node59*/60public static DocTreePath getPath(DocTreePath path, DocTree target) {61Objects.requireNonNull(path); //null check62Objects.requireNonNull(target); //null check6364class Result extends Error {65static final long serialVersionUID = -5942088234594905625L;66DocTreePath path;67Result(DocTreePath path) {68this.path = path;69}70}7172class PathFinder extends DocTreePathScanner<DocTreePath,DocTree> {73@Override74public DocTreePath scan(DocTree tree, DocTree target) {75if (tree == target) {76throw new Result(new DocTreePath(getCurrentPath(), target));77}78return super.scan(tree, target);79}80}8182if (path.getLeaf() == target) {83return path;84}8586try {87new PathFinder().scan(path, target);88} catch (Result result) {89return result.path;90}91return null;92}9394/**95* Creates a {@code DocTreePath} for a root node.96*97* @param treePath the {@code TreePath} from which the root node was created98* @param t the {@code DocCommentTree} to create the path for99*/100public DocTreePath(TreePath treePath, DocCommentTree t) {101this.treePath = treePath;102this.docComment = Objects.requireNonNull(t);103this.parent = null;104this.leaf = t;105}106107/**108* Creates a {@code DocTreePath} for a child node.109* @param p the parent node110* @param t the child node111*/112public DocTreePath(DocTreePath p, DocTree t) {113if (t.getKind() == DocTree.Kind.DOC_COMMENT) {114throw new IllegalArgumentException("Use DocTreePath(TreePath, DocCommentTree) to construct DocTreePath for a DocCommentTree.");115} else {116treePath = p.treePath;117docComment = p.docComment;118parent = p;119}120leaf = t;121}122123/**124* Returns the {@code TreePath} associated with this path.125* @return the {@code TreePath} for this {@code DocTreePath}126*/127public TreePath getTreePath() {128return treePath;129}130131/**132* Returns the {@code DocCommentTree} associated with this path.133* @return the {@code DocCommentTree} for this {@code DocTreePath}134*/135public DocCommentTree getDocComment() {136return docComment;137}138139/**140* Returns the leaf node for this path.141* @return the {@code DocTree} for this {@code DocTreePath}142*/143public DocTree getLeaf() {144return leaf;145}146147/**148* Returns the path for the enclosing node, or {@code null} if there is no enclosing node.149* @return {@code DocTreePath} of parent150*/151public DocTreePath getParentPath() {152return parent;153}154155@Override156public Iterator<DocTree> iterator() {157return new Iterator<>() {158@Override159public boolean hasNext() {160return next != null;161}162163@Override164public DocTree next() {165if (next == null) {166throw new NoSuchElementException();167}168DocTree t = next.leaf;169next = next.parent;170return t;171}172173@Override174public void remove() {175throw new UnsupportedOperationException();176}177178private DocTreePath next = DocTreePath.this;179};180}181182private final TreePath treePath;183private final DocCommentTree docComment;184private final DocTree leaf;185private final DocTreePath parent;186}187188189