001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.source.util;
027:
028: import com.sun.source.tree.*;
029: import java.util.Iterator;
030:
031: /**
032: * A path of tree nodes, typically used to represent the sequence of ancestor
033: * nodes of a tree node up to the top level CompilationUnitTree node.
034: *
035: * @author Jonathan Gibbons
036: * @since 1.6
037: */
038: public class TreePath implements Iterable<Tree> {
039: /**
040: * Gets a tree path for a tree node within a compilation unit.
041: * @return null if the node is not found
042: */
043: public static TreePath getPath(CompilationUnitTree unit, Tree target) {
044: return getPath(new TreePath(unit), target);
045: }
046:
047: /**
048: * Gets a tree path for a tree node within a subtree identified by a TreePath object.
049: * @return null if the node is not found
050: */
051: public static TreePath getPath(TreePath path, Tree target) {
052: path.getClass();
053: target.getClass();
054:
055: class Result extends Error {
056: static final long serialVersionUID = -5942088234594905625L;
057: TreePath path;
058:
059: Result(TreePath path) {
060: this .path = path;
061: }
062: }
063: class PathFinder extends TreePathScanner<TreePath, Tree> {
064: public TreePath scan(Tree tree, Tree target) {
065: if (tree == target)
066: throw new Result(new TreePath(getCurrentPath(),
067: target));
068: return super .scan(tree, target);
069: }
070: }
071:
072: try {
073: new PathFinder().scan(path, target);
074: } catch (Result result) {
075: return result.path;
076: }
077: return null;
078: }
079:
080: /**
081: * Creates a TreePath for a root node.
082: */
083: public TreePath(CompilationUnitTree t) {
084: this (null, t);
085: }
086:
087: /**
088: * Creates a TreePath for a child node.
089: */
090: public TreePath(TreePath p, Tree t) {
091: if (t.getKind() == Tree.Kind.COMPILATION_UNIT) {
092: compilationUnit = (CompilationUnitTree) t;
093: parent = null;
094: } else {
095: compilationUnit = p.compilationUnit;
096: parent = p;
097: }
098: leaf = t;
099: }
100:
101: /**
102: * Get the compilation unit associated with this path.
103: */
104: public CompilationUnitTree getCompilationUnit() {
105: return compilationUnit;
106: }
107:
108: /**
109: * Get the leaf node for this path.
110: */
111: public Tree getLeaf() {
112: return leaf;
113: }
114:
115: /**
116: * Get the path for the enclosing node, or null if there is no enclosing node.
117: */
118: public TreePath getParentPath() {
119: return parent;
120: }
121:
122: public Iterator<Tree> iterator() {
123: return new Iterator<Tree>() {
124: public boolean hasNext() {
125: return curr.parent != null;
126: }
127:
128: public Tree next() {
129: curr = curr.parent;
130: return curr.leaf;
131: }
132:
133: public void remove() {
134: throw new UnsupportedOperationException();
135: }
136:
137: private TreePath curr;
138: };
139: }
140:
141: private CompilationUnitTree compilationUnit;
142: private Tree leaf;
143: private TreePath parent;
144: }
|