1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 29 import org.aspectj.compiler.base.JavaCompiler; 30 import org.aspectj.compiler.base.CodeWriter; 31 32 import org.aspectj.compiler.base.bcg.CodeBuilder; 33 import org.aspectj.compiler.base.bcg.Label; 34 35 42 43 public class ForStmt extends TestStmt { 44 45 public boolean isBreakable() { return true; } 46 public boolean isContinuable() { return true; } 47 48 private void writeInit(CodeWriter writer) { 49 if (init == null) return; 50 51 if (init instanceof Decs) { 52 Decs decs = (Decs)init; 53 ((VarDec)decs.get(0)).unparse(writer, false, true); 54 for(int i=1; i<decs.size(); i++) { 55 writer.comma(); 56 writer.optionalSpace(); 57 ((VarDec)decs.get(i)).unparse(writer, false, false); 58 } 59 } else if (init instanceof VarDec) { 60 ((VarDec)init).unparse(writer, false, true); 61 } else { 62 writer.write(init); 63 } 64 } 65 66 public void checkSpec() { 67 super.checkSpec(); 68 for (int i=0; i<update.size(); i++) { 69 Expr expr = update.get(i); 70 if (!expr.isLegalStmt()) { 71 expr.showError("not a statement"); 72 } 73 } 74 body.requireStmt(); 75 } 76 77 78 public void unparse(CodeWriter writer) { 79 writer.writeKeyword("for"); 80 writer.requiredSpace(); 81 writer.openParen('('); 82 83 writeInit(writer); 84 writer.write("; "); 85 if (! (test.isSynthetic() && test.isConstantTrue())) { 86 writer.write(test); 87 } 88 writer.write("; "); 89 writer.write(update); 90 writer.closeParen(')'); 91 writer.optionalSpace(); 92 writer.write(body); 93 } 94 95 98 public void walkFlow(FlowCheckerPass w) { 99 w.process(getInit()); 100 101 FlowCheckerPass.Set enteringPossiblyAssigned = w.popPossiblyAssigned(); 102 w.processBoolean(getTest()); 103 FlowCheckerPass.Vars p = w.getVars(); 104 FlowCheckerPass.Vars tv = p.getTrue(); 105 FlowCheckerPass.Vars fv = p.getFalse(); 106 107 w.setLive(! getTest().isConstantFalse()); 108 w.setVars(p.getTrue()); 109 w.enterContext(this); 110 w.process(getBody()); 111 w.leaveContext(); 112 113 FlowCheckerPass.Vars v = w.getVars(); 114 FlowCheckerPass.Vars cv = w.getContinueVars(this); 115 FlowCheckerPass.Vars bv = w.getBreakVars(this); 116 117 w.setLive(true); w.setVars(v.join(cv)); 119 w.process(getUpdate()); 120 FlowCheckerPass.Vars uv = w.getVars(); 121 122 FlowCheckerPass.Set loopPossiblyAssigned = w.popPossiblyAssigned(); 123 124 127 w.checkLoopingFinals(this, loopPossiblyAssigned.inter(enteringPossiblyAssigned), uv); 128 w.mergePossiblyAssigned(enteringPossiblyAssigned); 129 w.mergePossiblyAssigned(loopPossiblyAssigned); 130 131 w.setLive(! getTest().isConstantTrue() || w.isBroken(this)); 132 w.setVars(fv.join(bv)); 133 } 134 135 138 public void walkCleanup(ByteCodeCleanupPass w) { 139 if (getTest().isConstantFalse()) { 140 w.process(getInit()); 141 return; 142 } 143 setInit(w.process(getInit())); 144 w.setLive(true); 145 w.enterContext(this); 146 setBody((Stmt) w.process(getBody())); 147 w.leaveContext(); 148 149 w.setLive(! getTest().isConstantTrue() || w.isBroken(this)); 150 } 151 152 public ASTObject postCleanup(ByteCodeCleanupPass w) { 153 if (getTest().isConstantFalse()) { 154 return getInit(); 155 } else { 156 return this; 157 } 158 } 159 160 163 protected void cgStmt(CodeBuilder cb) { 164 Label testLab = cb.genLabel(); 165 Label startLab = cb.genLabel(); 166 Label updateLab = cb.genLabel(); 167 Label endLab = cb.genLabel(); 168 169 cb.enterBlock(); 170 if (init instanceof Stmt) ((Stmt) init).cgTop(cb); 171 else if (init instanceof Exprs) ((Exprs) init).cgEffects(cb); 172 cb.emitJump(testLab); 173 cb.emitLabel(startLab); 174 cb.enterNonWindingContext(this, endLab, updateLab); 175 body.cgTop(cb); 176 cb.leaveContext(); 177 cb.emitLabel(updateLab); 178 update.cgEffects(cb); 179 cb.emitLabel(testLab); 180 test.cgTest(cb, startLab, endLab); 181 cb.emitLabel(endLab); 182 cb.exitBlock(); 183 } 184 185 188 190 public void walkFrameLoc(FrameLocPass walker) { 191 int start = walker.getfs(); 192 super.walkFrameLoc(walker); 193 walker.setfs(start); 194 } 195 196 protected ASTObject init; 198 public ASTObject getInit() { return init; } 199 public void setInit(ASTObject _init) { 200 if (_init != null) _init.setParent(this); 201 init = _init; 202 } 203 204 protected Expr test; 205 public Expr getTest() { return test; } 206 public void setTest(Expr _test) { 207 if (_test != null) _test.setParent(this); 208 test = _test; 209 } 210 211 protected Exprs update; 212 public Exprs getUpdate() { return update; } 213 public void setUpdate(Exprs _update) { 214 if (_update != null) _update.setParent(this); 215 update = _update; 216 } 217 218 protected Stmt body; 219 public Stmt getBody() { return body; } 220 public void setBody(Stmt _body) { 221 if (_body != null) _body.setParent(this); 222 body = _body; 223 } 224 225 public ForStmt(SourceLocation location, ASTObject _init, Expr _test, Exprs _update, Stmt _body) { 226 super(location); 227 setInit(_init); 228 setTest(_test); 229 setUpdate(_update); 230 setBody(_body); 231 } 232 protected ForStmt(SourceLocation source) { 233 super(source); 234 } 235 236 public ASTObject copyWalk(CopyWalker walker) { 237 ForStmt ret = new ForStmt(getSourceLocation()); 238 ret.preCopy(walker, this); 239 if (init != null) ret.setInit( (ASTObject)walker.process(init) ); 240 if (test != null) ret.setTest( (Expr)walker.process(test) ); 241 if (update != null) ret.setUpdate( (Exprs)walker.process(update) ); 242 if (body != null) ret.setBody( (Stmt)walker.process(body) ); 243 return ret; 244 } 245 246 public ASTObject getChildAt(int childIndex) { 247 switch(childIndex) { 248 case 0: return init; 249 case 1: return test; 250 case 2: return update; 251 case 3: return body; 252 default: return super.getChildAt(childIndex); 253 } 254 } 255 public String getChildNameAt(int childIndex) { 256 switch(childIndex) { 257 case 0: return "init"; 258 case 1: return "test"; 259 case 2: return "update"; 260 case 3: return "body"; 261 default: return super.getChildNameAt(childIndex); 262 } 263 } 264 public void setChildAt(int childIndex, ASTObject child) { 265 switch(childIndex) { 266 case 0: setInit((ASTObject)child); return; 267 case 1: setTest((Expr)child); return; 268 case 2: setUpdate((Exprs)child); return; 269 case 3: setBody((Stmt)child); return; 270 default: super.setChildAt(childIndex, child); return; 271 } 272 } 273 public int getChildCount() { 274 return 4; 275 } 276 277 public String getDefaultDisplayName() { 278 return "ForStmt()"; 279 } 280 281 } 283 284 285 | Popular Tags |