KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > HaltingVisitor


1 package polyglot.visit;
2
3 import polyglot.ast.Node;
4 import polyglot.util.*;
5 import java.util.*;
6
7 /**
8  * A HaltingVisitor is used to prune the traversal of the AST at a
9  * particular node. Clients can call <code>bypass(Node n) </code> to
10  * have the visitor skip n and its children when recursing through the AST.
11  */

12 public abstract class HaltingVisitor extends NodeVisitor implements Copy
13 {
14     Node bypassParent;
15     Collection bypass;
16
17     public HaltingVisitor bypassChildren(Node n) {
18         HaltingVisitor v = (HaltingVisitor) copy();
19         v.bypassParent = n;
20         return v;
21     }
22
23     public HaltingVisitor visitChildren() {
24         HaltingVisitor v = (HaltingVisitor) copy();
25         v.bypassParent = null;
26         v.bypass = null;
27         return v;
28     }
29
30     public HaltingVisitor bypass(Node n) {
31         if (n == null) return this;
32
33         HaltingVisitor v = (HaltingVisitor) copy();
34
35         // FIXME: Using a collection is expensive, but is hopefully not
36
// often used.
37
if (this.bypass == null) {
38             v.bypass = Collections.singleton(n);
39         }
40         else {
41             v.bypass = new ArrayList(this.bypass.size()+1);
42             v.bypass.addAll(bypass);
43             v.bypass.add(n);
44         }
45
46         return v;
47     }
48
49     public HaltingVisitor bypass(Collection c) {
50         if (c == null) return this;
51
52         HaltingVisitor v = (HaltingVisitor) copy();
53
54         // FIXME: Using a collection is expensive, but is hopefully not
55
// often used.
56
if (this.bypass == null) {
57             v.bypass = new ArrayList(c);
58         }
59         else {
60             v.bypass = new ArrayList(this.bypass.size()+c.size());
61             v.bypass.addAll(bypass);
62             v.bypass.addAll(c);
63         }
64
65         return v;
66     }
67
68     public final Node override(Node parent, Node n) {
69         if (bypassParent != null && bypassParent == parent) {
70             // System.out.println("bypassing " + n +
71
// " (child of " + parent + ")");
72
return n;
73         }
74
75         if (bypass != null) {
76             for (Iterator i = bypass.iterator(); i.hasNext(); ) {
77                 if (i.next() == n) {
78                     // System.out.println("bypassing " + n);
79
return n;
80                 }
81             }
82         }
83
84         return null;
85     }
86
87     public Object JavaDoc copy() {
88         try {
89             HaltingVisitor v = (HaltingVisitor) super.clone();
90             // v.bypassParent = null;
91
// v.bypass = null;
92
return v;
93         }
94         catch (CloneNotSupportedException JavaDoc e) {
95             throw new InternalCompilerError("Java clone() weirdness.");
96         }
97     }
98 }
99
Popular Tags