KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > NodeScrambler


1 package polyglot.visit;
2
3 import polyglot.ast.*;
4 import polyglot.types.*;
5 import polyglot.util.*;
6
7 import java.util.*;
8
9 /**
10  * The <code>NodeScrambler</code> is test case generator of sorts. Since it
11  * is ofter useful to introduce ``random'' errors into source code, this
12  * class provides a way of doing so in a semi-structed manner. The process
13  * takes place in two phases. First, a "FirstPass" is made to collect
14  * a list of nodes and their parents. Then a second pass is made to randomly
15  * replace a branch of the tree with another suitable branch.
16  */

17 public class NodeScrambler extends NodeVisitor
18 {
19   public FirstPass fp;
20
21   protected HashMap pairs;
22   protected LinkedList nodes;
23   protected LinkedList currentParents;
24   protected long seed;
25   protected Random ran;
26   protected boolean scrambled = false;
27   protected CodeWriter cw;
28
29   public NodeScrambler()
30   {
31     this.fp = new FirstPass();
32
33     this.pairs = new HashMap();
34     this.nodes = new LinkedList();
35     this.currentParents = new LinkedList();
36     this.cw = new CodeWriter( System.err, 72);
37
38     Random ran = new Random();
39     seed = ran.nextLong();
40     
41     System.err.println( "Using seed: " + seed);
42     this.ran = new Random( seed);
43   }
44
45   /**
46    * Create a new <code>NodeScrambler</code> with the given random number
47    * generator seed.
48    */

49   public NodeScrambler( long seed)
50   {
51     this.fp = new FirstPass();
52     
53     this.pairs = new HashMap();
54     this.nodes = new LinkedList();
55     this.currentParents = new LinkedList();
56     this.cw = new CodeWriter( System.err, 72);
57     this.seed = seed;
58     
59     this.ran = new Random( seed);
60   }
61
62   /**
63    * Scans throught the AST, create a list of all nodes present, along with
64    * the set of parents for each node in the tree. <b>This visitor should be
65    * run before the main <code>NodeScrambler</code> visits the tree.</b>
66    */

67   public class FirstPass extends NodeVisitor
68   {
69     public NodeVisitor enter( Node n)
70     {
71       pairs.put( n, currentParents.clone());
72       nodes.add( n);
73       
74       currentParents.add( n);
75       return this;
76     }
77     
78     public Node leave( Node old, Node n, NodeVisitor v)
79     {
80       currentParents.remove( n);
81       return n;
82     }
83   }
84
85   public long getSeed()
86   {
87     return seed;
88   }
89
90   public Node override( Node n)
91   {
92     if( coinFlip()) {
93       Node m = potentialScramble( n);
94       if( m == null) {
95         /* No potential replacement. */
96         return null;
97       }
98       else {
99         scrambled = true;
100
101         try {
102           System.err.println( "Replacing:");
103           n.dump( cw);
104           cw.newline();
105           cw.flush();
106           System.err.println( "With:");
107           m.dump( cw);
108           cw.newline();
109           cw.flush();
110         }
111         catch( Exception JavaDoc e)
112         {
113           e.printStackTrace();
114           return null;
115         }
116         return m;
117       }
118     }
119     else {
120       return null;
121     }
122   }
123
124   protected boolean coinFlip()
125   {
126     if( scrambled) {
127       return false;
128     }
129     else {
130       if( ran.nextDouble() > 0.9) {
131         return true;
132       }
133       else {
134         return false;
135       }
136     }
137   }
138
139   protected Node potentialScramble( Node n)
140   {
141     Class JavaDoc required = Node.class;
142
143     if( n instanceof SourceFile) {
144       return null;
145     }
146     if( n instanceof Import) {
147       required = Import.class;
148     }
149     else if( n instanceof TypeNode) {
150       required = TypeNode.class;
151     }
152     else if( n instanceof ClassDecl) {
153       required = ClassDecl.class;
154     }
155     else if( n instanceof ClassMember) {
156       required = ClassMember.class;
157     }
158     else if( n instanceof Formal) {
159       required = Formal.class;
160     }
161     else if( n instanceof Expr) {
162       required = Expr.class;
163     }
164     else if( n instanceof Block) {
165       required = Block.class;
166     }
167     else if( n instanceof Catch) {
168       required = Catch.class;
169     }
170     else if( n instanceof LocalDecl) {
171       required = LocalDecl.class;
172     }
173     else if( n instanceof Stmt) {
174       required = Stmt.class;
175     }
176
177     LinkedList parents = (LinkedList)pairs.get( n);
178     Iterator iter1 = nodes.iterator(), iter2;
179     boolean isParent;
180
181     while( iter1.hasNext()) {
182       Node m = (Node)iter1.next();
183       if( required.isAssignableFrom( m.getClass())) {
184
185         isParent = false;
186         iter2 = parents.iterator();
187         while( iter2.hasNext()) {
188           if( m == iter2.next()) {
189             isParent = true;
190           }
191         }
192
193         if( !isParent && m != n) {
194           return m;
195         }
196       }
197     }
198
199     return null;
200   }
201 }
202
Popular Tags