KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > ruby > AstPath


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.ruby;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ListIterator JavaDoc;
26 import org.jruby.ast.Node;
27 import org.jruby.lexer.yacc.ISourcePosition;
28
29
30 /**
31  * This represents a path in a JRuby AST.
32  *
33  * @author Tor Norbye
34  */

35 public class AstPath implements Iterable JavaDoc<Node> {
36     private ArrayList JavaDoc<Node> path = new ArrayList JavaDoc<Node>(30);
37
38     public AstPath() {
39     }
40     
41     public AstPath(ArrayList JavaDoc<Node> path) {
42         this.path = path;
43     }
44     
45     public void descend(Node node) {
46         path.add(node);
47     }
48     
49     public void ascend() {
50         path.remove(path.size()-1);
51     }
52
53     /**
54      * Initialize a node path to the given caretOffset
55      */

56     public AstPath(Node root, int caretOffset) {
57         findPathTo(root, caretOffset);
58     }
59
60     /**
61      * Find the path to the given node in the AST
62      */

63     @SuppressWarnings JavaDoc("unchecked")
64     public AstPath(Node node, Node target) {
65         if (!find(node, target)) {
66             path.clear();
67         } else {
68             // Reverse the list such that node is on top
69
// When I get time rewrite the find method to build the list that way in the first place
70
Collections.reverse(path);
71         }
72     }
73
74     /**
75      * Find the position closest to the given offset in the AST. Place the path from the leaf up to the path in the
76      * passed in path list.
77      */

78     @SuppressWarnings JavaDoc("unchecked")
79     public Node findPathTo(Node node, int offset) {
80         Node result = find(node, offset);
81         path.add(node);
82         
83         // Reverse the list such that node is on top
84
// When I get time rewrite the find method to build the list that way in the first place
85
Collections.reverse(path);
86
87         return result;
88     }
89
90     @SuppressWarnings JavaDoc("unchecked")
91     private Node find(Node node, int offset) {
92         ISourcePosition pos = node.getPosition();
93         int begin = pos.getStartOffset();
94         int end = pos.getEndOffset();
95
96         if ((offset >= begin) && (offset <= end)) {
97             List JavaDoc<Node> children = (List JavaDoc<Node>)node.childNodes();
98
99             for (Node child : children) {
100                 Node found = find(child, offset);
101
102                 if (found != null) {
103                     path.add(child);
104
105                     return found;
106                 }
107             }
108
109             return node;
110         } else {
111             List JavaDoc<Node> children = (List JavaDoc<Node>)node.childNodes();
112
113             for (Node child : children) {
114                 Node found = find(child, offset);
115
116                 if (found != null) {
117                     path.add(child);
118
119                     return found;
120                 }
121             }
122
123             return null;
124         }
125     }
126
127     /**
128      * Find the path to the given node in the AST
129      */

130     @SuppressWarnings JavaDoc("unchecked")
131     public boolean find(Node node, Node target) {
132         if (node == target) {
133             return true;
134         }
135
136         List JavaDoc<Node> children = (List JavaDoc<Node>)node.childNodes();
137
138         for (Node child : children) {
139             boolean found = find(child, target);
140
141             if (found) {
142                 path.add(child);
143
144                 return found;
145             }
146         }
147
148         return false;
149     }
150     
151     @Override JavaDoc
152     public String JavaDoc toString() {
153         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
154         sb.append("Path(");
155         sb.append(path.size());
156         sb.append(")=[");
157         for (Node n : path) {
158             String JavaDoc name = n.getClass().getName();
159             name = name.substring(name.lastIndexOf('.')+1);
160             sb.append(name);
161             sb.append(":");
162         }
163         sb.append("]");
164         return sb.toString();
165     }
166     
167     public Node leaf() {
168         if (path.size() == 0) {
169             return null;
170         } else {
171             return path.get(path.size()-1);
172         }
173     }
174
175     public Node leafParent() {
176         if (path.size() < 2) {
177             return null;
178         } else {
179             return path.get(path.size()-2);
180         }
181     }
182
183     public Node leafGrandParent() {
184         if (path.size() < 3) {
185             return null;
186         } else {
187             return path.get(path.size()-3);
188         }
189     }
190     
191     
192     public Node root() {
193         if (path.size() == 0) {
194             return null;
195         } else {
196             return path.get(0);
197         }
198     }
199     
200     /** Return an iterator that returns the elements from the leaf back up to the root */
201     public Iterator JavaDoc<Node> iterator() {
202         return new LeafToRootIterator();
203     }
204
205     /** REturn an iterator that starts at the root and walks down to the leaf */
206     public ListIterator JavaDoc<Node> rootToLeaf() {
207         return path.listIterator();
208     }
209
210     /** Return an iterator that walks from the leaf back up to the root */
211     public ListIterator JavaDoc<Node> leafToRoot() {
212         return new LeafToRootIterator();
213     }
214
215     private class LeafToRootIterator implements ListIterator JavaDoc<Node> {
216         private ListIterator JavaDoc<Node> it;
217         
218         private LeafToRootIterator() {
219             it = path.listIterator(path.size());
220         }
221     
222         public boolean hasNext() {
223             return it.hasPrevious();
224         }
225
226         public Node next() {
227             return it.previous();
228         }
229
230         public boolean hasPrevious() {
231             return it.hasNext();
232         }
233
234         public Node previous() {
235             return it.next();
236         }
237
238         public int nextIndex() {
239             return it.previousIndex();
240         }
241
242         public int previousIndex() {
243             return it.nextIndex();
244         }
245
246         public void remove() {
247             throw new UnsupportedOperationException JavaDoc("Not supported yet.");
248         }
249
250         public void set(Node arg0) {
251             throw new UnsupportedOperationException JavaDoc("Not supported yet.");
252         }
253
254         public void add(Node arg0) {
255             throw new UnsupportedOperationException JavaDoc("Not supported yet.");
256         }
257     }
258 }
259
Popular Tags