Path: blob/master/src/jdk.compiler/share/classes/com/sun/source/util/TreePath.java
41175 views
/*1* Copyright (c) 2006, 2021, 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 java.util.Iterator;28import java.util.NoSuchElementException;29import java.util.Objects;3031import com.sun.source.tree.*;3233/**34* A path of tree nodes, typically used to represent the sequence of ancestor35* nodes of a tree node up to the top-level {@code CompilationUnitTree} node.36*37* @author Jonathan Gibbons38* @since 1.639*/40public class TreePath implements Iterable<Tree> {41/**42* Returns a tree path for a tree node within a compilation unit,43* or {@code null} if the node is not found.44* @param unit the compilation unit to search45* @param target the node to locate46* @return the tree path47*/48public static TreePath getPath(CompilationUnitTree unit, Tree target) {49return getPath(new TreePath(unit), target);50}5152/**53* Returns a tree path for a tree node within a subtree identified by a TreePath object.54* Returns {@code null} if the node is not found.55* @param path the path in which to search56* @param target the node to locate57* @return the tree path of the target node58*/59public static TreePath getPath(TreePath path, Tree target) {60Objects.requireNonNull(path);61Objects.requireNonNull(target);6263class Result extends Error {64static final long serialVersionUID = -5942088234594905625L;65TreePath path;66Result(TreePath path) {67this.path = path;68}69}7071class PathFinder extends TreePathScanner<TreePath,Tree> {72public TreePath scan(Tree tree, Tree target) {73if (tree == target) {74throw new Result(new TreePath(getCurrentPath(), target));75}76return super.scan(tree, target);77}78}7980if (path.getLeaf() == target) {81return path;82}8384try {85new PathFinder().scan(path, target);86} catch (Result result) {87return result.path;88}89return null;90}9192/**93* Creates a TreePath for a root node.94* @param node the root node95*/96public TreePath(CompilationUnitTree node) {97this(null, node);98}99100/**101* Creates a TreePath for a child node.102* @param path the parent path103* @param tree the child node104*/105public TreePath(TreePath path, Tree tree) {106if (tree.getKind() == Tree.Kind.COMPILATION_UNIT) {107compilationUnit = (CompilationUnitTree) tree;108parent = null;109}110else {111compilationUnit = path.compilationUnit;112parent = path;113}114leaf = tree;115}116/**117* Returns the compilation unit associated with this path.118* @return the compilation unit119*/120public CompilationUnitTree getCompilationUnit() {121return compilationUnit;122}123124/**125* Returns the leaf node for this path.126* @return the leaf node127*/128public Tree getLeaf() {129return leaf;130}131132/**133* Returns the path for the enclosing node, or {@code null} if there is no enclosing node.134* @return the path for the enclosing node135*/136public TreePath getParentPath() {137return parent;138}139140/**141* Iterates from leaves to root.142*/143@Override144public Iterator<Tree> iterator() {145return new Iterator<>() {146@Override147public boolean hasNext() {148return next != null;149}150151@Override152public Tree next() {153if (next == null) {154throw new NoSuchElementException();155}156Tree t = next.leaf;157next = next.parent;158return t;159}160161@Override162public void remove() {163throw new UnsupportedOperationException();164}165166private TreePath next = TreePath.this;167};168}169170private CompilationUnitTree compilationUnit;171private Tree leaf;172private TreePath parent;173}174175176