1 24 25 package org.aspectj.compiler.base.ast; 26 import org.aspectj.compiler.base.ExceptionFinder; 27 28 import org.aspectj.compiler.base.*; 29 30 import java.util.*; 31 32 import org.aspectj.compiler.base.cst.*; 33 34 import org.aspectj.compiler.base.bcg.CodeBuilder; 35 import org.aspectj.compiler.base.bcg.MethodBuilder; 36 import org.aspectj.compiler.base.bcg.ClassfileBuilder; 37 38 45 public abstract class CodeDec extends Dec implements PossibleSoftThrowable { 46 private boolean _isSoft = false; 47 public boolean isSoftThrowable() { return _isSoft; } 48 public void setSoftThrowable() { _isSoft = true; } 49 50 53 public void walkFlow(FlowCheckerPass w) { 55 if (getBody() != null) { 56 setupFlowWalker(w); 57 w.setLive(true); 58 w.process(getBody()); 59 60 if (! getResultType().isVoid() && w.isLive()) { 61 showError("missing return statement"); 62 } 63 } 64 } 65 66 68 69 protected void setupFlowWalker(FlowCheckerPass w) { } 70 71 74 public final void walkCleanup(ByteCodeCleanupPass w) { 75 w.setLive(true); 76 super.walkCleanup(w); 77 } 78 79 public ASTObject postCleanup(ByteCodeCleanupPass w) { 80 if (getBody() != null 81 && getResultType().isVoid() 82 && w.isLive()) { 83 ReturnStmt s = 84 (ReturnStmt) getAST().makeReturn(null).setSource(getBody()); 85 s.setCompletesNormally(false); 86 getBody().getStmts().add(s); 87 getBody().setCompletesNormally(false); 88 } 89 return this; 90 } 91 92 95 public void walkInnerInfo(InnerInfoPass w) { 96 int context = w.inMember(isStatic()); 97 super.walkInnerInfo(w); 98 w.restoreContext(context); 99 } 100 102 public static CodeBody blockToBody(BlockStmt block) { 103 if (block == null) return null; 104 block.getStmts().clearParent(); 105 CodeBody body = new CodeBody(block.getSourceLocation(),block.getStmts(),true); 106 body.setSource(block); 107 return body; 108 } 109 110 public void setBody(BlockStmt block) { 111 setBody(blockToBody(block)); 112 } 113 114 115 public abstract String getId(); 116 public abstract TypeD getResultTypeD(); 117 118 public Type getResultType() { 120 return getResultTypeD().getType(); 121 } 122 123 public boolean canThrow(Type t) { 124 if (t.isUncheckedThrowable()) return true; 125 if (_throws == null) return false; 126 for (int i=0; i<_throws.size(); i++) { 127 if (t.isSubtypeOf(_throws.get(i).getType())) return true; 128 } 129 return false; 130 } 131 132 133 public void addThrowsType(Type t) { 134 if (canThrow(t)) return; 135 136 if (_throws == null) { 137 _throws = getAST().makeTypeDs(); 138 } 139 140 _throws.add(t.makeTypeD()); 141 } 142 143 public void addThrows(Collection throwTypes) { 144 for (Iterator i = throwTypes.iterator(); i.hasNext(); ) { 145 addThrowsType((Type)i.next()); 146 } 147 } 148 155 public Set getPossibleCheckedExceptions() { 156 if (_throws == null) return Collections.EMPTY_SET; 157 Set ret = new HashSet(); 158 159 for (int i=0; i<_throws.size(); i++) { 160 ret.add(_throws.get(i).getType()); 161 } 162 163 return Type.filterTopTypes(ret); 164 } 165 166 public void checkSpec() { 167 if (_throws == null) return; 169 Type throwableType = getTypeManager().getThrowableType(); 170 for (int i=0; i<_throws.size(); i++) { 171 TypeD throwsTypeD = _throws.get(i); 172 if (!throwsTypeD.getType().isSubtypeOf(throwableType)) { 173 throwsTypeD.showTypeError(throwsTypeD.getType(), throwableType); 174 } 175 } 176 } 177 178 public boolean appearsStaticToCaller() { return isStatic(); } 179 180 181 public boolean hasThis() { 182 return !isStatic(); 183 } 184 185 public boolean isAlmostApplicable(Exprs params) { 186 return params.size() == getFormals().size(); 187 } 188 189 public boolean isApplicable(Exprs parameters) { 190 return getFormals().canBeCalledWith(parameters); 191 } 192 193 public boolean conflictsWith(Dec otherDec) { 194 if (!getId().equals(otherDec.getId())) return false; 195 if (!this.isAccessible(otherDec) && !otherDec.isAccessible(this)) return false; 196 197 if (!(otherDec instanceof CodeDec)) return false; 198 199 CodeDec otherCodeDec = (CodeDec)otherDec; 200 201 205 return getFormals().matches(otherCodeDec.getFormals()); 206 } 207 208 209 public boolean isMoreSpecificThan(Dec otherDec) { 210 if (!(otherDec instanceof CodeDec)) return false; 211 212 CodeDec other = (CodeDec)otherDec; 213 214 if (!super.isMoreSpecificThan(other)) return false; 215 217 Formals formals1 = getFormals(); 219 Formals formals2 = other.getFormals(); 220 if (formals1.size() != formals2.size()) return false; 221 for(int i=0; i<formals1.size(); i++) { 222 if (!formals1.get(i).getType().isMethodConvertableTo(formals2.get(i).getType())) { 223 return false; 224 } 225 } 226 227 return true; 228 } 229 230 public Set getEffectivelyFinalFormals() { 231 FinalFinderWalker ffw = new FinalFinderWalker(getCompiler(), getFormals().makeSet()); 232 ffw.process(getBody()); 233 return ffw.curr; 234 } 235 236 private class FinalFinderWalker extends Walker { 237 Set curr; 238 239 FinalFinderWalker(JavaCompiler c, Set curr) { 240 super(c); 241 this.curr = curr; 242 } 243 244 public void postProcess(ASTObject o) { 245 if (o instanceof BangExpr) { 246 BangExpr be = (BangExpr) o; 247 Expr lhs = be.getLhs(); 248 if (lhs instanceof VarExpr) { 249 VarDec vd = ((VarExpr)lhs).getVarDec(); 250 curr.remove(vd); 251 } 252 } 253 } 254 255 } 256 257 258 public void preScope(ScopeWalker walker) { 260 walker.pushScope(makeBlockScope(walker)); 261 } 262 public ASTObject postScope(ScopeWalker walker) { walker.popScope(); return this; } 263 264 boolean computingMinimalThrows = false; 266 public void computeMinimalThrows() { 267 if (computingMinimalThrows || getBody() == null) return; 271 272 computingMinimalThrows = true; 273 Set exceptions = ExceptionFinder.getPossibleExceptions(getBody(), false); 274 computingMinimalThrows = false; 276 277 final int N = exceptions.size(); 278 if (N == 0) { 279 setThrows(null); 280 return; 281 } 282 283 exceptions = Type.filterTopTypes(exceptions); 284 285 TypeDs newThrows = getAST().makeTypeDs(); for(Iterator iter = exceptions.iterator(); iter.hasNext(); ) { 287 Type type = (Type)iter.next(); 288 newThrows.add(type.makeTypeD()); 289 } 290 setThrows(newThrows); 291 } 292 293 public Set getCallExprs() { 295 return null; 297 } 298 309 public void cleanup() { 310 if (body != null) 312 body.cleanup(); 313 super.cleanup(); 314 } 315 316 319 private int frameSize; 320 public int getFrameSize() { return frameSize; } 321 public void setFrameSize(int frameSize) { this.frameSize = frameSize; } 322 323 public void walkFrameLoc(FrameLocPass walker) { 324 walker.setfs((!isStatic() || this instanceof ConstructorDec) ? 325 1 : 0); 326 super.walkFrameLoc(walker); setFrameSize(walker.getmaxfs()); 328 } 329 330 333 public void walkAnalysis(LocalClassPass.AnalysisWalker walker) { 334 walker.enterCodeDec(this); 335 walker.inCode(isStatic()); 336 this.walk(walker); 337 walker.leaveCodeDec(); 338 } 339 340 343 355 protected void cgMember(ClassfileBuilder cfb) { 356 if (getOptions().bcgverbose) System.err.println("generating for " + this); 357 MethodBuilder mb = cfb.getMethodBuilder(); 358 mb.addAccessFlags(getModifiers().getValue()); 359 mb.setName(getInternalId()); 360 mb.setDescriptor(getDescriptor()); 361 if (isDeprecated()) mb.setDeprecated(); 362 TypeDs exns = getThrows(); 364 if (exns != null) { 365 for (Iterator i = exns.iterator(); i.hasNext(); ) { 366 TypeD typeD = (TypeD)i.next(); 367 mb.addToExceptionsAttribute((NameType)typeD.getType()); 368 } 369 } 370 371 if (getBody() != null) { 372 CodeBuilder cb = mb.getCodeBuilder(); 373 cgCodeMember(cb); 374 mb.setCode(cb); 375 } 376 cfb.addMethod(mb); 377 } 378 379 383 protected void cgCodeMember(CodeBuilder cb) { 384 throw new RuntimeException ("unsupported " + this); 385 } 386 387 388 public String getDescriptor() { 389 throw new RuntimeException ("unsupported " + this); 390 } 391 392 397 public int getStackDelta() { 398 throw new RuntimeException ("unsupported " + this); 399 } 400 401 String getInternalId() { 402 return getBytecodeId(); 403 } 404 405 protected Modifiers modifiers; 407 public Modifiers getModifiers() { return modifiers; } 408 public void setModifiers(Modifiers _modifiers) { 409 if (_modifiers != null) _modifiers.setParent(this); 410 modifiers = _modifiers; 411 } 412 413 protected Formals formals; 414 public Formals getFormals() { return formals; } 415 public void setFormals(Formals _formals) { 416 if (_formals != null) _formals.setParent(this); 417 formals = _formals; 418 } 419 420 protected TypeDs _throws; 421 public TypeDs getThrows() { return _throws; } 422 public void setThrows(TypeDs __throws) { 423 if (__throws != null) __throws.setParent(this); 424 _throws = __throws; 425 } 426 427 protected CodeBody body; 428 public CodeBody getBody() { return body; } 429 public void setBody(CodeBody _body) { 430 if (_body != null) _body.setParent(this); 431 body = _body; 432 } 433 434 public CodeDec(SourceLocation location, Modifiers _modifiers, Formals _formals, TypeDs __throws, CodeBody _body) { 435 super(location); 436 setModifiers(_modifiers); 437 setFormals(_formals); 438 setThrows(__throws); 439 setBody(_body); 440 } 441 protected CodeDec(SourceLocation source) { 442 super(source); 443 } 444 445 public ASTObject getChildAt(int childIndex) { 446 switch(childIndex) { 447 case 0: return modifiers; 448 case 1: return formals; 449 case 2: return _throws; 450 case 3: return body; 451 default: return super.getChildAt(childIndex); 452 } 453 } 454 public String getChildNameAt(int childIndex) { 455 switch(childIndex) { 456 case 0: return "modifiers"; 457 case 1: return "formals"; 458 case 2: return "throws"; 459 case 3: return "body"; 460 default: return super.getChildNameAt(childIndex); 461 } 462 } 463 public void setChildAt(int childIndex, ASTObject child) { 464 switch(childIndex) { 465 case 0: setModifiers((Modifiers)child); return; 466 case 1: setFormals((Formals)child); return; 467 case 2: setThrows((TypeDs)child); return; 468 case 3: setBody((CodeBody)child); return; 469 default: super.setChildAt(childIndex, child); return; 470 } 471 } 472 public int getChildCount() { 473 return 4; 474 } 475 476 public String getDefaultDisplayName() { 477 return "CodeDec()"; 478 } 479 480 } 482 | Popular Tags |