1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 import org.aspectj.compiler.base.cst.BlockScope; 29 30 import org.aspectj.compiler.base.bcg.CodeBuilder; 31 32 37 public class BlockStmt extends Stmt { 38 39 public boolean isEmpty() { 40 final int len = getStmts().size(); 41 for (int i = 0; i < len; i++) { 42 if (! getStmts().get(i).isEmpty()) 43 return false; 44 } 45 return true; 46 } 47 48 public void requireBlockStmt() { ; } 49 50 private static Stmt makeStmt(ASTObject node) { 51 if (node instanceof Stmt) return (Stmt)node; 52 if (node instanceof Expr) return new ExprStmt(node.getSourceLocation(),(Expr)node); 53 throw new RuntimeException ("node can not be made into a statement: "+node); 54 } 55 56 public BlockStmt(SourceLocation location, ASTObject node1) { 57 this(location,node1 instanceof BlockStmt ? ((BlockStmt)node1).getStmts() : 58 new Stmts(location,new Stmt[] {makeStmt(node1)})); 59 } 60 public BlockStmt(SourceLocation location, ASTObject node1, ASTObject node2) { 61 this(location,new Stmts(location,new Stmt[] {makeStmt(node1), makeStmt(node2)})); 62 } 63 public BlockStmt(SourceLocation location, ASTObject node1, ASTObject node2, ASTObject node3) { 64 this(location,new Stmts(location,new Stmt[] {makeStmt(node1), makeStmt(node2), makeStmt(node3)})); 65 } 66 public BlockStmt(SourceLocation location, ASTObject node1, ASTObject node2, ASTObject node3, ASTObject node4) { 67 this(location,new Stmts(location,new Stmt[] {makeStmt(node1), makeStmt(node2), makeStmt(node3), makeStmt(node4)})); 68 } 69 70 73 78 public boolean mustBeLive() { return !getOptions().lenient; } 79 80 public void walkFlow(FlowCheckerPass w) { 81 Stmts s = getStmts(); 82 for (int i = 0, len = s.size(); i < len; i++) { 83 Stmt st = s.get(i); 84 if (! w.isLive() && st.mustBeLive()) { 85 st.showError("unreachable statement"); 86 break; 87 } else { 88 w.process(s.get(i)); 89 } 90 } 91 } 92 93 96 public void walkCleanup(ByteCodeCleanupPass w) { 97 makeTempsExplicit(); 98 getStmts().walkCleanup(w); 99 } 100 101 public ASTObject postCleanup(ByteCodeCleanupPass w) { 102 if (getStmts().size() == 0) { 103 return getAST().makeEmptyStmt().setSource(this); 104 } else { 105 return this; 106 } 107 } 108 109 protected void makeTempsExplicit() { 110 if (tmpStmts != null) { 111 for (int i = 0, len = tmpStmts.size(); i < len; i++) { 112 getStmts().add(0, tmpStmts.get(i)); 113 } 114 tmpStmts = null; 115 } 116 } 117 118 121 public void walkFrameLoc(FrameLocPass walker) { 122 int start = walker.getfs(); 123 super.walkFrameLoc(walker); 124 walker.setfs(start); 125 } 126 127 public void preScope(ScopeWalker walker) { walker.pushBlock(); } 129 public ASTObject postScope(ScopeWalker walker) { walker.popBlock(); return this; } 130 131 public VarDec makeTemporary(Type type) { 135 141 VarDec tmp = getAST().makeVarDec(type, "ajc$tmp", null); 142 addTemporary(tmp); 143 tmpStmts.add(0, tmp); 144 return tmp; 145 } 146 147 public void addTemporary(VarDec tmp) { 148 if (getTmpStmts() == null) setTmpStmts(getAST().makeStmts()); tmp.setId(tmp.getId() + tmpStmts.size()); 150 tmpStmts.add(0, tmp); 151 } 152 153 public void checkReturnType(Type expectedReturnType) { 154 ReturnTypeChecker rtc = new ReturnTypeChecker(getCompiler(),expectedReturnType); 155 rtc.process(stmts); 156 } 157 158 static class ReturnTypeChecker extends Walker { 160 Type expectedReturnType; 161 162 ReturnTypeChecker(JavaCompiler compiler, Type expectedReturnType) { 163 super(compiler); 164 this.expectedReturnType = expectedReturnType; 165 } 166 167 public boolean preProcess(ASTObject node) { 168 if (node instanceof ReturnStmt) { 169 Expr returnExpr = ((ReturnStmt)node).getExpr(); 170 if (returnExpr == null) { 171 if (!expectedReturnType.isEquivalent(getTypeManager().voidType)) { 172 node.showError(expectedReturnType.toShortString()+" return expected"); 173 } 174 } else { 175 if (!expectedReturnType.isAssignableFrom(returnExpr.getType())) { 176 node.showError(expectedReturnType.toShortString()+" return expected"); 177 } 178 } 179 return true; 180 } 181 return !(node instanceof TypeDec); 182 } 183 } 184 185 public void unparse(CodeWriter writer) { 186 writer.openBlock(); 187 if (tmpStmts != null) writer.write(tmpStmts); 188 writer.write(stmts); 189 writer.closeBlock(); 190 } 191 192 public void cleanup() { 193 stmts = null; 194 tmpStmts = null; 195 super.cleanup(); 196 } 197 198 protected void cgStmt(CodeBuilder cb) { 201 cb.enterBlock(); 202 stmts.cgStmts(cb); 203 cb.exitBlock(); 204 } 205 206 209 public BlockStmt(SourceLocation location, Stmts _stmts) { 210 this(location, null, _stmts); 211 } 212 213 protected Stmts tmpStmts; 215 public Stmts getTmpStmts() { return tmpStmts; } 216 public void setTmpStmts(Stmts _tmpStmts) { 217 if (_tmpStmts != null) _tmpStmts.setParent(this); 218 tmpStmts = _tmpStmts; 219 } 220 221 protected Stmts stmts; 222 public Stmts getStmts() { return stmts; } 223 public void setStmts(Stmts _stmts) { 224 if (_stmts != null) _stmts.setParent(this); 225 stmts = _stmts; 226 } 227 228 public BlockStmt(SourceLocation location, Stmts _tmpStmts, Stmts _stmts) { 229 super(location); 230 setTmpStmts(_tmpStmts); 231 setStmts(_stmts); 232 } 233 protected BlockStmt(SourceLocation source) { 234 super(source); 235 } 236 237 public ASTObject copyWalk(CopyWalker walker) { 238 BlockStmt ret = new BlockStmt(getSourceLocation()); 239 ret.preCopy(walker, this); 240 if (tmpStmts != null) ret.setTmpStmts( (Stmts)walker.process(tmpStmts) ); 241 if (stmts != null) ret.setStmts( (Stmts)walker.process(stmts) ); 242 return ret; 243 } 244 245 public ASTObject getChildAt(int childIndex) { 246 switch(childIndex) { 247 case 0: return tmpStmts; 248 case 1: return stmts; 249 default: return super.getChildAt(childIndex); 250 } 251 } 252 public String getChildNameAt(int childIndex) { 253 switch(childIndex) { 254 case 0: return "tmpStmts"; 255 case 1: return "stmts"; 256 default: return super.getChildNameAt(childIndex); 257 } 258 } 259 public void setChildAt(int childIndex, ASTObject child) { 260 switch(childIndex) { 261 case 0: setTmpStmts((Stmts)child); return; 262 case 1: setStmts((Stmts)child); return; 263 default: super.setChildAt(childIndex, child); return; 264 } 265 } 266 public int getChildCount() { 267 return 2; 268 } 269 270 public String getDefaultDisplayName() { 271 return "BlockStmt()"; 272 } 273 274 } 276 277 278 | Popular Tags |