1 24 package org.aspectj.compiler.crosscuts.ast; 25 26 import org.aspectj.compiler.base.ast.*; 27 import org.aspectj.compiler.base.*; 28 import org.aspectj.compiler.crosscuts.joinpoints.*; 29 30 import java.util.*; 31 import org.aspectj.util.*; 32 33 38 39 public class PerThisOrTarget extends PerClause { 40 public String toShortString() { 41 return "per" + (onThis ? "this" : "target") + 42 "(" + getPcd().toShortString() + ")"; 43 } 44 45 private Set onTypes = new HashSet(); 46 47 public JpPlanner makeInnerPlanner(PlanData planData) { 48 return new JpPlanner() { 49 public FuzzyBoolean fastMatch(JoinPoint jp) { 50 return FuzzyBoolean.MAYBE; 52 } 53 public JpPlan makePlan(JoinPoint jp) { 54 Expr onExpr = makeOnExpr(jp); 55 if (onExpr == null) return JpPlan.NO_PLAN; 56 57 JpPlan plan = new JpPlan(jp); 58 plan.test = getHasAspectExpr(makeOnExpr(jp)); 59 plan.setInstanceExpr(getAspectOfExpr(makeOnExpr(jp))); 60 return plan; 61 } 62 }; 63 } 64 65 public JpPlanner makeInitializerPlanner(PlanData planData) { 66 return new WrappedJpPlanner(getPcd().makePlanner(planData)) { 67 public JpPlan makePlan(JoinPoint jp) { 68 Expr onExpr = makeOnExpr(jp); 69 if (onExpr == null) return JpPlan.NO_PLAN; 70 if (getAspectType().isSubtypeOf(onExpr.getType())) { 72 getPcd().showWarning("will not match containing aspect (compiler limitation)"); 73 return JpPlan.NO_PLAN; 74 } 75 76 JpPlan plan = super.makePlan(jp); 77 78 if (plan.isPossible()) { 79 addHasAspectType(onExpr.getType(), jp); 80 } 81 return new InitializerPlan(plan); 82 } 83 }; 84 } 85 86 private class InitializerPlan extends JpPlan { 87 JpPlan innerPlan; 88 89 public InitializerPlan(JpPlan innerPlan) { 90 super(innerPlan.joinPoint); 91 this.innerPlan = innerPlan; 92 } 93 94 public int getPreSortOrder() { return EACHOBJECT; } 95 96 public String toString() { 97 return "perobject" + super.toString(); 98 } 99 100 public void wrapJoinPoint(JoinPoint jp) { 101 jp.setStmts(this.wrapCheckAndSet(jp, jp.getStmts())); 102 } 103 104 public Stmts wrapCheckAndSet(JoinPoint jp, Stmts stmts) { 105 return PerThisOrTarget.this.wrapCheckAndSet(innerPlan, jp, stmts); 106 } 107 } 108 109 void addHasAspectType(Type toType, JoinPoint jp) { 110 if (onTypes.contains(toType)) return; 111 if (toType == getHasAspectInterfaceType()) return; 112 onTypes.add(toType); 113 if (!toType.getTypeDec().fromSource()) { 114 return; 116 } 117 toType.getTypeDec().addSuperInterfaceType(getHasAspectInterfaceType()); 118 toType.addDirectSuperType(getHasAspectInterfaceType()); 119 } 120 121 122 156 157 158 public Expr makeOnExpr(JoinPoint point) { 159 if (onThis) return point.makeThisExpr(); 160 else return point.makeTargetExpr(); 161 } 162 163 178 private InterfaceDec hasAspectInterface; 179 private MethodDec hasAspectBindMethod; 180 private MethodDec hasAspectGetMethod; 181 182 public Type getHasAspectInterfaceType() { 183 return getHasAspectInterface().getType(); 184 } 185 186 public InterfaceDec getHasAspectInterface() { 187 if (hasAspectInterface != null) return hasAspectInterface; 188 hasAspectInterface = makeHasAspectInterface(); 189 return hasAspectInterface; 190 } 191 192 String makeName(String base) { 193 return getAST().makeGeneratedName(getAspectType().getString() + "_" + base); 194 } 195 196 int getFieldModifiers() { 197 if (getOptions().XserializableAspects) { 198 if (getAspectType().isSubtypeOf(getTypeManager().getSerializableType())) { 199 return Modifiers.PRIVATE; 200 } 201 } 202 return Modifiers.PRIVATE | Modifiers.TRANSIENT; 203 } 204 205 InterfaceDec makeHasAspectInterface() { 206 final AST ast = getAST(); 207 208 hasAspectInterface = ast.makeInterface( 209 ast.makeModifiers(Modifiers.PUBLIC), "AJC_HasAspect", ast.makeTypeDs()); 210 hasAspectInterface.setEnclosingTypeDec(getAspectDec()); 211 getAspectDec().addToBody(hasAspectInterface); 212 213 215 FieldDec aspectField = ast.makeField( 216 ast.makeModifiers(getFieldModifiers()), getAspectType(), makeName("_aspect")); 217 hasAspectInterface.getBody().add(aspectField); 218 219 hasAspectBindMethod = ast.makeMethod( 220 ast.makeModifiers(Modifiers.PRIVATE|Modifiers.SYNCHRONIZED), 221 getTypeManager().voidType, makeName("bind"), 222 ast.makeFormals(), 223 ast.makeBlock( 224 ast.makeIf( 225 ast.makeNonNullTest(ast.makeGet(aspectField.getField())), 226 ast.makeReturn()), 227 ast.makeSet(aspectField.getField(), ast.makeNew(getAspectType())))); 228 hasAspectInterface.getBody().add(hasAspectBindMethod); 229 230 hasAspectGetMethod = ast.makeMethod( 231 ast.makeModifiers(Modifiers.PRIVATE), getAspectType(), makeName("getAspect"), 232 ast.makeFormals(), 233 ast.makeBlock( 234 ast.makeReturn(ast.makeGet(aspectField.getField())))); 235 hasAspectInterface.getBody().add(hasAspectGetMethod); 236 237 return hasAspectInterface; 238 } 239 240 264 private MethodDec bindMethod; 265 MethodDec getBindMethod() { 266 if (bindMethod != null) return bindMethod; 267 268 final AST ast = getAST(); 269 270 FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj"); 271 bindMethod = ast.makeMethod( 272 ast.makeModifiers(Modifiers.STATIC|Modifiers.PUBLIC|Modifiers.SYNCHRONIZED), 273 getTypeManager().voidType, "bind$ajc", ast.makeFormals(objFormal), 274 ast.makeBlock( 275 ast.makeIf( 276 ast.makeNotInstanceofTest(ast.makeVar(objFormal), 277 getHasAspectInterfaceType()), 278 ast.makeReturn()), 279 ast.makeCall(hasAspectBindMethod, 280 ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal))))); 281 getAspectDec().addToBody(bindMethod); 282 return bindMethod; 283 } 284 285 protected MethodDec makeHasAspectMethod() { 286 final AST ast = getAST(); 287 FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj"); 288 289 BlockStmt body = ast.makeBlock( 290 ast.makeIf( 291 ast.makeNotInstanceofTest(ast.makeVar(objFormal), getHasAspectInterfaceType()), 292 ast.makeReturn(ast.makeLiteral(false))), 293 ast.makeReturn(ast.makeNonNullTest(ast.makeCall(hasAspectGetMethod, 294 ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal)))))); 295 return makeHasAspectMethod(ast.makeFormals(objFormal), body); 296 } 297 298 protected MethodDec makeAspectOfMethod() { 299 getHasAspectInterfaceType(); 300 301 final AST ast = getAST(); 302 VarDec aspDec = ast.makeVarDec(getAspectType(), "asp", ast.makeNull()); 303 FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj"); 304 305 BlockStmt body = ast.makeBlock( 306 aspDec, 307 ast.makeIf( 308 ast.makeInstanceof(ast.makeVar(objFormal), getHasAspectInterfaceType()), 309 ast.makeBlock( 310 ast.makeSet(aspDec, ast.makeCall(hasAspectGetMethod, 311 ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal)))))), 312 ast.makeIf( 313 ast.makeNullTest(ast.makeVar(aspDec)), 314 ast.makeBlock( 315 ast.makeThrow(ast.makeNew( 316 getTypeManager().getType("org.aspectj.lang", "NoAspectBoundException"))))), 317 ast.makeReturn(ast.makeVar(aspDec))); 318 319 return makeAspectOfMethod(ast.makeFormals(objFormal), body); 320 } 321 322 Expr bindExpr(Expr onExpr) { 323 return getAST().makeStaticCall(getBindMethod(), onExpr); 324 } 325 326 Expr getHasAspectExpr(Expr onExpr) { 327 final AST ast = getAST(); 328 return ast.makeStaticCall(hasAspectMethod, onExpr); 329 } 330 331 Expr getAspectOfExpr(Expr onExpr) { 332 final AST ast = getAST(); 333 return ast.makeParen(ast.forceCast( 334 getAspectType(), ast.makeStaticCall(aspectOfMethod, onExpr))); 335 } 336 337 338 339 public Stmts wrapCheckAndSet(JpPlan plan, JoinPoint jp, Stmts body) { 341 final AST ast = getAST(); 342 Expr onExpr = makeOnExpr(jp); 343 if (onExpr == null) return body; 344 345 Stmt stmt = ast.makeStmt(bindExpr(onExpr)); 346 stmt = plan.wrapDynamicTest(ast.makeBlock(stmt)); 347 348 body.add(0, stmt); 349 return body; 350 } 351 352 protected Pcd pcd; 354 public Pcd getPcd() { return pcd; } 355 public void setPcd(Pcd _pcd) { 356 if (_pcd != null) _pcd.setParent(this); 357 pcd = _pcd; 358 } 359 360 protected boolean onThis; 361 public boolean getOnThis() { return onThis; } 362 public void setOnThis(boolean _onThis) { onThis = _onThis; } 363 364 public PerThisOrTarget(SourceLocation location, Pcd _pcd, boolean _onThis) { 365 super(location); 366 setPcd(_pcd); 367 setOnThis(_onThis); 368 } 369 protected PerThisOrTarget(SourceLocation source) { 370 super(source); 371 } 372 373 public ASTObject copyWalk(CopyWalker walker) { 374 PerThisOrTarget ret = new PerThisOrTarget(getSourceLocation()); 375 ret.preCopy(walker, this); 376 if (pcd != null) ret.setPcd( (Pcd)walker.process(pcd) ); 377 ret.onThis = onThis; 378 return ret; 379 } 380 381 public ASTObject getChildAt(int childIndex) { 382 switch(childIndex) { 383 case 0: return pcd; 384 default: return super.getChildAt(childIndex); 385 } 386 } 387 public String getChildNameAt(int childIndex) { 388 switch(childIndex) { 389 case 0: return "pcd"; 390 default: return super.getChildNameAt(childIndex); 391 } 392 } 393 public void setChildAt(int childIndex, ASTObject child) { 394 switch(childIndex) { 395 case 0: setPcd((Pcd)child); return; 396 default: super.setChildAt(childIndex, child); return; 397 } 398 } 399 public int getChildCount() { 400 return 1; 401 } 402 403 public String getDefaultDisplayName() { 404 return "PerThisOrTarget(onThis: "+onThis+")"; 405 } 406 407 } 409 410 | Popular Tags |