1 24 25 package org.aspectj.compiler.crosscuts.ast; 26 27 import org.aspectj.compiler.base.ast.*; 28 import org.aspectj.compiler.crosscuts.joinpoints.*; 29 import org.aspectj.compiler.base.*; 30 import org.aspectj.compiler.base.cst.*; 31 32 import org.aspectj.compiler.base.JavaCompiler; 33 34 import java.util.*; 35 36 40 41 public abstract class AdviceDec extends CodeDec implements JpPlannerMaker { 42 public String getKind() { return "advice"; } 43 44 public AspectDec getAspectDec() { 46 return (AspectDec)getDeclaringType().getTypeDec(); 47 } 48 49 54 public FormalDec getExtraFormal() { return null; } 55 56 protected boolean isAfterAdvice() { return false; } 57 58 protected boolean reverseSortOrder(AdviceDec a1, AdviceDec a2) { 59 return a1.isAfterAdvice() || a2.isAfterAdvice(); 60 } 61 62 public boolean dominates(AdviceDec otherAdvice) { 63 AspectDec myAspectDec = getAspectDec(); 64 AspectDec otherAspectDec = otherAdvice.getAspectDec(); 65 66 if (myAspectDec == otherAspectDec) { 67 if (reverseSortOrder(this, otherAdvice)) { 68 return this.getBeginLine() > otherAdvice.getBeginLine(); 69 } else { 70 return this.getBeginLine() < otherAdvice.getBeginLine(); 71 } 72 } else { 73 return myAspectDec.dominates(otherAspectDec); 74 } 75 } 76 77 public JpPlanner makePlanner(PlanData planData) { 78 if (planData.inAspect.isAbstract()) return JpPlanner.NO_PLANNER; 79 80 JpPlanner planner = getPcd().makePlanner(planData); 81 planner = planData.inAspect.findPerClause().makeInnerPlanner(planData).and(planner); 84 return new AdvicePlanner(planData.inAspect, this, planner); 85 } 86 87 public void wrapJoinPoint(JoinPoint joinPoint, AdvicePlan plan) { 88 joinPoint.setStmts(this.wrapStmts(joinPoint.getStmts(), plan)); 89 } 90 91 protected Stmts wrapStmts(Stmts stmts, AdvicePlan plan) { 92 this.showError("didn't implement code to concretize this advice"); 93 return null; 94 } 95 96 protected final Formals makeFormals() { 97 Formals newFormals = getAST().makeFormals(); 98 Formals oldFormals = getFormals(); 99 100 for (int i = 0; i < oldFormals.size(); i++) { 101 oldFormals.get(i).clearParent(); 102 newFormals.add(oldFormals.get(i)); 103 } 104 105 if (getExtraFormal() != null) { 106 getExtraFormal().clearParent(); 107 newFormals.add(getExtraFormal()); 108 } 109 110 return newFormals; 111 } 112 113 public final Type getExtraArgType() { 114 if (getExtraFormal() == null) return null; 115 return getExtraFormal().getType(); 116 } 117 118 public MethodDec makeConcreteMethod() { 119 if (methodDec == null) { 120 methodDec = getMethodDec(); 121 } 122 123 if (methodDec == null) return null; 124 methodDec.setBody(makeMethodBody()); 125 finishMethodDec(methodDec); 126 return methodDec; 127 } 128 129 130 135 protected CodeBody makeMethodBody() { 136 return body; 137 } 138 139 140 protected void finishMethodDec(MethodDec methodDec) { 141 if (modifiers.isStrict()) methodDec.getModifiers().setStrict(true); 142 } 143 144 int getDepth(AspectDec ad) { 147 Type superType = ad.getSuperClassType(); 148 if (superType.isAspect()) { 149 return 1 + getDepth((AspectDec)superType.getTypeDec()); 150 } else { 151 return 0; 152 } 153 } 154 155 String makeUniqueAspectString() { 156 int depth = getDepth(getAspectDec()); 157 if (depth == 0) return ""; 158 else return Integer.toString(depth, 36); 159 } 160 161 String makeUniqueAdviceString() { 162 String kind = getAdviceKind(); 163 Decs body = (Decs)getParent(); 164 int position = 0; 165 final int N = body.size(); 166 for (int i = 0; i < N; i++) { 168 Dec dec = body.get(i); 169 if (dec == this) break; 171 if (!(dec instanceof AdviceDec)) continue; 172 AdviceDec ad = (AdviceDec)dec; 173 if (ad.getAdviceKind().equals(kind)) position++; 174 } 175 return kind + Integer.toString(position, 36); 176 } 177 178 179 String makeUniqueName() { 180 return makeUniqueAdviceString() + "$ajc" + makeUniqueAspectString(); 181 } 182 183 private MethodDec methodDec; 184 public synchronized MethodDec getMethodDec() { 185 if (methodDec != null) return methodDec; 186 187 final AST ast = getAST(); 188 189 String name = makeUniqueName(); 190 Modifiers modifiers = ast.makeModifiers(getModifiers().getValue()); 191 modifiers.setPublic(true); 192 modifiers.setFinal(true); 193 194 Formals formals = makeFormals(); 195 addJoinPointFormals(formals); 196 197 methodDec = ast.makeMethod(modifiers, getResultType(), name, 198 formals, null); 199 if (_throws != null) methodDec.setThrows((TypeDs)_throws.copy()); 200 201 methodDec.setAllEnclosingTypes(getAspectDec().getType()); 202 return methodDec; 203 } 204 205 206 public Expr makeCall(Expr parent, Exprs baseExprs) { 207 Exprs args = (Exprs)baseExprs.copy(); 208 if (parent == null) { 209 parent = getAST().makeTypeExpr(getAspectDec().getType()); 210 } 211 CallExpr ret = getAST().makeCall(getMethodDec().getMethod(), parent, args); 212 return ret; 213 } 214 215 216 217 218 221 private boolean joinPointFlagsSet = false; 222 private boolean needsStaticEnclosingJoinPoint; 223 private boolean needsStaticJoinPoint; 224 private boolean needsDynamicJoinPoint; 225 226 private void setJoinPointFlags() { 227 if (!joinPointFlagsSet) { 228 joinPointFlagsSet = true; 229 DynamicJoinPointChecker jpChecker = new DynamicJoinPointChecker(getCompiler()); 230 jpChecker.checkAndFix(getBody()); 231 needsDynamicJoinPoint = jpChecker.needsDynamicJoinPoint(); 232 needsStaticJoinPoint = jpChecker.needsStaticJoinPoint(); 233 needsStaticEnclosingJoinPoint = jpChecker.needsStaticEnclosingJoinPoint(); 234 } 235 } 236 237 public boolean needsStaticEnclosingJoinPointFormal() { 238 setJoinPointFlags(); 239 return needsStaticEnclosingJoinPoint; 240 } 241 242 public boolean needsStaticJoinPointFormal() { 243 setJoinPointFlags(); 244 return needsStaticJoinPoint; 245 } 246 247 public boolean needsDynamicJoinPointFormal() { 248 setJoinPointFlags(); 249 return needsDynamicJoinPoint; 250 } 251 252 public boolean needsCallSiteContext() { 253 return needsDynamicJoinPointFormal() || 254 needsStaticJoinPointFormal() || 255 needsStaticEnclosingJoinPointFormal(); 256 } 257 258 public void addJoinPointFormals(Formals formals) { 259 if (needsStaticEnclosingJoinPointFormal()) formals.add(thisStaticEnclosingJoinPointFormal); 260 if (needsStaticJoinPointFormal()) formals.add(thisStaticJoinPointFormal); 261 if (needsDynamicJoinPointFormal()) formals.add(thisDynamicJoinPointFormal); 262 } 263 264 265 266 class DynamicJoinPointChecker extends Walker { 267 boolean needsDynamic = false; 268 boolean needsStatic = false; 269 boolean needsStaticEnclosing = false; 270 boolean needsFakeStatic = false; 271 272 boolean makeFakeStatics = false; 273 274 public boolean needsDynamicJoinPoint() { return needsDynamic; } 275 public boolean needsStaticJoinPoint() { return needsStatic; } 276 public boolean needsStaticEnclosingJoinPoint() { return needsStaticEnclosing; } 277 278 DynamicJoinPointChecker(JavaCompiler compiler) { 279 super(compiler); 280 } 281 282 public void checkAndFix(ASTObject body) { 283 this.process(body); 284 if (needsFakeStatic && !needsDynamic) { 285 if (!this.getCompiler().getOptions().noMetaJoinPointOptimization) { 286 makeFakeStatics = true; 287 needsStatic = true; 288 this.process(body); 289 } else { 290 needsDynamic = true; 291 } 292 } 293 } 294 295 boolean isStaticEnclosingJoinPoint(VarExpr varExpr) { 296 return varExpr.getVarDec() == thisStaticEnclosingJoinPointFormal; 297 } 298 299 boolean isStaticJoinPoint(VarExpr varExpr) { 300 return varExpr.getVarDec() == thisStaticJoinPointFormal; 301 } 302 303 boolean isDynamicJoinPoint(VarExpr varExpr) { 304 return varExpr.getVarDec() == thisDynamicJoinPointFormal; 305 } 306 307 void checkNoBang(VarExpr varExpr) { 308 if (varExpr.isLhs()) { 309 varExpr.showError("not allowed to set thisJoinPoint"); 310 } 311 } 312 313 boolean isStaticPartCall(CallExpr callExpr) { 314 Expr expr = callExpr.getExpr(); 315 if (expr != null && expr instanceof VarExpr && 316 isDynamicJoinPoint( (VarExpr)expr )) 317 { 318 return callExpr.getMethod().getId().equals("getStaticPart"); 319 } 320 return false; 321 } 322 323 boolean canTreatAsStatic(Method method) { 324 String id = method.getId(); 325 return id.equals("toString") || 326 id.equals("toShortString") || 327 id.equals("toLongString") || 328 id.equals("getKind") || 329 id.equals("getSignature") || 330 id.equals("getSourceLocation") || 331 id.equals("getStaticPart"); 332 } 333 334 335 boolean canTreatAsStatic(VarExpr varExpr) { 336 ASTObject parent = varExpr.getParent(); 337 if (parent instanceof CallExpr) { 338 Method calledMethod = ((CallExpr)parent).getMethod(); 339 return canTreatAsStatic(calledMethod); 340 341 } else if (parent instanceof BinopExpr) { 344 BinopExpr binop = (BinopExpr)parent; 345 if (binop.getType().isEquivalent(this.getTypeManager().getStringType())) { 346 return true; 347 } else { 348 return false; 349 } 350 } else { 351 return false; 352 } 353 } 354 355 356 boolean inBlockThatCantRun = false; 357 358 boolean isFinalBoolean(Expr expr) { 359 return (expr instanceof BooleanLiteralExpr); 361 } 362 363 boolean getFinalBooleanValue(Expr expr) { 364 return ((BooleanLiteralExpr)expr).getBooleanValue(); 365 } 366 367 protected Expr makeNullJoinPoint() { 368 final AST ast = this.getAST(); 369 return ast.makeParen(ast.forceCast(this.getTypeManager().getJoinPointType(), 370 ast.makeNull())); 371 } 372 373 public ASTObject process(ASTObject node) { 374 if (node instanceof IfStmt) { 377 IfStmt ifStmt = (IfStmt)node; 378 379 if (!inBlockThatCantRun && isFinalBoolean(ifStmt.getTest())) { 380 ifStmt.setTest((Expr)process(ifStmt.getTest())); 381 382 inBlockThatCantRun = !getFinalBooleanValue(ifStmt.getTest()); 383 384 ifStmt.setThen((Stmt)process(ifStmt.getThen())); 385 386 inBlockThatCantRun = !inBlockThatCantRun; 387 388 if (ifStmt.getElse() != null) { 389 ifStmt.setElse((Stmt)process(ifStmt.getElse())); 390 } 391 392 inBlockThatCantRun = false; 393 return ifStmt; 394 } else { 395 return super.process(ifStmt); 396 } 397 } else if (node instanceof CallExpr) { 398 CallExpr callExpr = (CallExpr)node; 399 if (isStaticPartCall(callExpr)) { 400 needsFakeStatic = true; 401 if (makeFakeStatics) { 402 return AdviceDec.this.getAST().makeVar(thisStaticJoinPointFormal); 403 } 404 } 405 } else if (node instanceof VarExpr) { 406 VarExpr varExpr = (VarExpr)node; 407 408 if (isStaticEnclosingJoinPoint(varExpr)) { 409 needsStaticEnclosing = true; 410 checkNoBang(varExpr); 411 } else if (isStaticJoinPoint(varExpr)) { 412 needsStatic = true; 413 checkNoBang(varExpr); 414 } else if (isDynamicJoinPoint(varExpr)) { 415 checkNoBang(varExpr); 416 if (inBlockThatCantRun) { 417 return makeNullJoinPoint(); 419 } else if (canTreatAsStatic(varExpr)) { 421 needsFakeStatic = true; 422 if (makeFakeStatics) { 423 varExpr.setVarDec(thisStaticJoinPointFormal); 424 varExpr.setType(null); 425 varExpr.getType(); } 427 } else { 428 needsDynamic = true; 429 } 430 } 431 return node; 432 } 433 434 return super.process(node); 435 } 436 } 437 438 protected FormalDec makeJoinPointFormal(String name) { 439 return getAST().makeFormal(getTypeManager().getJoinPointType(), name); 440 } 441 442 protected FormalDec makeJoinPointStaticPartFormal(String name) { 443 return getAST().makeFormal(getTypeManager().getJoinPointStaticPartType(), name); 444 } 445 446 protected FormalDec thisDynamicJoinPointFormal = null; 447 protected FormalDec thisStaticJoinPointFormal = null; 448 protected FormalDec thisStaticEnclosingJoinPointFormal = null; 449 450 453 protected void setupFlowWalker(FlowCheckerPass w) { 454 if (thisDynamicJoinPointFormal == null || 455 thisStaticJoinPointFormal == null || 456 thisStaticEnclosingJoinPointFormal == null ) { 457 throw new RuntimeException ("join point formals not created yet"); 458 } 459 w.setVars(w.getVars().addAssigned(thisDynamicJoinPointFormal) 460 .addAssigned(thisStaticJoinPointFormal) 461 .addAssigned(thisStaticEnclosingJoinPointFormal)); 462 super.setupFlowWalker(w); 463 } 464 465 469 public ASTObject postFixAST(final ASTFixerPass fixer) { 470 return makeConcreteMethod(); 471 } 472 473 protected BlockScope makeBodyScope(Scope parent) { 474 return new BlockScope(getCompiler(), parent); 475 } 476 477 public void preScope(ScopeWalker walker) { 479 super.preScope(walker); 480 481 if (thisDynamicJoinPointFormal == null ) { 482 thisDynamicJoinPointFormal = makeJoinPointFormal("thisJoinPoint"); 483 } 484 if (thisStaticJoinPointFormal == null ) { 485 thisStaticJoinPointFormal = makeJoinPointStaticPartFormal("thisJoinPointStaticPart"); 486 } 487 if (thisStaticEnclosingJoinPointFormal == null ) { 488 thisStaticEnclosingJoinPointFormal = makeJoinPointStaticPartFormal("thisEnclosingJoinPointStaticPart"); 489 } 490 491 walker.process(thisDynamicJoinPointFormal); 492 walker.process(thisStaticJoinPointFormal); 493 walker.process(thisStaticEnclosingJoinPointFormal); 494 495 } 498 499 public void checkSpec() { 500 if (isStatic()) { 501 getCompiler().warnVersion("0.8beta1", this, "no static modifier on advice"); 502 } 503 for (int i=0; i<formals.size(); i++) { 504 if (!formals.get(i).isBound) { 505 formals.get(i).showError("not bound in this PCD"); 506 } 507 } 508 getBody().checkReturnType(getReturnType()); 509 510 getMethodDec(); 512 } 513 514 515 public String getId() { 516 return getAdviceKind(); 518 } 519 520 public TypeD getResultTypeD() { 521 return getReturnType().makeTypeD(); 522 } 523 524 public Type getReturnType() { 525 return getTypeManager().voidType; 526 } 527 528 529 public String toShortString() { 530 String modString = getModifiers().toShortString(); 531 if (modString.length() > 0) { 532 modString += " "; 533 } 534 535 return modString + getAdviceKind() + getFormals().toShortString(); 536 } 537 538 abstract protected String getAdviceKind(); 539 540 public void unparse(CodeWriter writer) { 541 } 543 544 protected Pcd pcd; 546 public Pcd getPcd() { return pcd; } 547 public void setPcd(Pcd _pcd) { 548 if (_pcd != null) _pcd.setParent(this); 549 pcd = _pcd; 550 } 551 552 public AdviceDec(SourceLocation location, Modifiers _modifiers, Formals _formals, TypeDs __throws, Pcd _pcd, CodeBody _body) { 553 super(location, _modifiers, _formals, __throws, _body); 554 setPcd(_pcd); 555 } 556 protected AdviceDec(SourceLocation source) { 557 super(source); 558 } 559 560 public ASTObject getChildAt(int childIndex) { 561 switch(childIndex) { 562 case 0: return modifiers; 563 case 1: return formals; 564 case 2: return _throws; 565 case 3: return pcd; 566 case 4: return body; 567 default: return super.getChildAt(childIndex); 568 } 569 } 570 public String getChildNameAt(int childIndex) { 571 switch(childIndex) { 572 case 0: return "modifiers"; 573 case 1: return "formals"; 574 case 2: return "throws"; 575 case 3: return "pcd"; 576 case 4: return "body"; 577 default: return super.getChildNameAt(childIndex); 578 } 579 } 580 public void setChildAt(int childIndex, ASTObject child) { 581 switch(childIndex) { 582 case 0: setModifiers((Modifiers)child); return; 583 case 1: setFormals((Formals)child); return; 584 case 2: setThrows((TypeDs)child); return; 585 case 3: setPcd((Pcd)child); return; 586 case 4: setBody((CodeBody)child); return; 587 default: super.setChildAt(childIndex, child); return; 588 } 589 } 590 public int getChildCount() { 591 return 5; 592 } 593 594 public String getDefaultDisplayName() { 595 return "AdviceDec()"; 596 } 597 598 } 600 | Popular Tags |