1 16 package com.google.gwt.dev.jjs.ast; 17 18 import com.google.gwt.dev.jjs.InternalCompilerException; 19 20 import java.util.ArrayList ; 21 import java.util.List ; 22 23 26 public class JModVisitor extends JVisitor { 27 28 private interface ContextFactory { 29 Context create(); 30 } 31 32 private class ContextPool extends ArrayList { 33 34 private ContextFactory factory; 35 private int pos = 0; 36 37 public ContextPool(ContextFactory factory) { 38 this.factory = factory; 39 } 40 41 public void release(Context ctx) { 42 if (get(--pos) != ctx) { 43 throw new InternalCompilerException( 44 "Tried to release the wrong context"); 45 } 46 } 47 48 public Context take() { 49 if (pos == size()) { 50 add(factory.create()); 51 } 52 return (Context) get(pos++); 53 } 54 } 55 56 private class ListContext implements Context { 57 private int index; 58 private List list; 59 private boolean removed; 60 private boolean replaced; 61 62 public boolean canInsert() { 63 return true; 64 } 65 66 public boolean canRemove() { 67 return true; 68 } 69 70 public void insertAfter(JNode node) { 71 checkRemoved(); 72 list.add(index + 1, node); 73 didChange = true; 74 } 75 76 public void insertBefore(JNode node) { 77 checkRemoved(); 78 list.add(index++, node); 79 didChange = true; 80 } 81 82 public void removeMe() { 83 checkState(); 84 list.remove(index--); 85 didChange = removed = true; 86 } 87 88 public void replaceMe(JNode node) { 89 checkState(); 90 checkReplacement((JNode) list.get(index), node); 91 list.set(index, node); 92 didChange = replaced = true; 93 } 94 95 protected void doReplace(Class targetClass, JNode x) { 96 checkState(); 97 checkReplacement((JNode) list.get(index), x); 98 list.set(index, x); 99 didChange = replaced = true; 100 } 101 102 protected void traverse(List list) { 103 this.list = list; 104 for (index = 0; index < list.size(); ++index) { 105 removed = replaced = false; 106 doTraverse((JNode) list.get(index), this); 107 } 108 } 109 110 private void checkRemoved() { 111 if (removed) { 112 throw new InternalCompilerException("Node was already removed"); 113 } 114 } 115 116 private void checkState() { 117 checkRemoved(); 118 if (replaced) { 119 throw new InternalCompilerException("Node was already replaced"); 120 } 121 } 122 } 123 124 private class NodeContext implements Context { 125 private JNode node; 126 private boolean replaced; 127 128 public boolean canInsert() { 129 return false; 130 } 131 132 public boolean canRemove() { 133 return false; 134 } 135 136 public void insertAfter(JNode node) { 137 throw new UnsupportedOperationException (); 138 } 139 140 public void insertBefore(JNode node) { 141 throw new UnsupportedOperationException (); 142 } 143 144 public void removeMe() { 145 throw new UnsupportedOperationException (); 146 } 147 148 public void replaceMe(JNode node) { 149 if (replaced) { 150 throw new InternalCompilerException("Node was already replaced"); 151 } 152 checkReplacement(this.node, node); 153 this.node = node; 154 didChange = replaced = true; 155 } 156 157 protected JNode traverse(JNode node) { 158 this.node = node; 159 replaced = false; 160 doTraverse(node, this); 161 return this.node; 162 } 163 } 164 165 protected static void checkReplacement(JNode origNode, JNode newNode) { 166 if (newNode == null) { 167 throw new InternalCompilerException("Cannot replace with null"); 168 } 169 if (newNode == origNode) { 170 throw new InternalCompilerException( 171 "The replacement is the same as the original"); 172 } 173 } 174 175 protected boolean didChange = false; 176 177 private final ContextPool listContextPool = new ContextPool( 178 new ContextFactory() { 179 public Context create() { 180 return new ListContext(); 181 } 182 }); 183 184 private final ContextPool nodeContextPool = new ContextPool( 185 new ContextFactory() { 186 public Context create() { 187 return new NodeContext(); 188 } 189 }); 190 191 public boolean didChange() { 192 return didChange; 193 } 194 195 protected JNode doAccept(JNode node) { 196 NodeContext ctx = (NodeContext) nodeContextPool.take(); 197 try { 198 return ctx.traverse(node); 199 } finally { 200 nodeContextPool.release(ctx); 201 } 202 } 203 204 protected void doAccept(List list) { 205 NodeContext ctx = (NodeContext) nodeContextPool.take(); 206 try { 207 for (int i = 0, c = list.size(); i < c; ++i) { 208 list.set(i, ctx.traverse((JNode) list.get(i))); 209 } 210 } finally { 211 nodeContextPool.release(ctx); 212 } 213 } 214 215 protected void doAcceptWithInsertRemove(List list) { 216 ListContext ctx = (ListContext) listContextPool.take(); 217 try { 218 ctx.traverse(list); 219 } finally { 220 listContextPool.release(ctx); 221 } 222 } 223 224 } 225 | Popular Tags |