1 24 25 package org.aspectj.compiler.crosscuts.ast; 26 import org.aspectj.compiler.base.ast.*; 27 import org.aspectj.compiler.base.cst.*; 28 import org.aspectj.compiler.crosscuts.joinpoints.*; 29 import org.aspectj.compiler.crosscuts.*; 30 31 import org.aspectj.compiler.base.JavaCompiler; 32 33 import java.util.*; 34 35 42 public class NamePcd extends Pcd { 43 44 private static final Map EMPTY_MAP 45 = Collections.unmodifiableMap(new TreeMap()); 46 47 public String toShortString() { 48 String ret = id + formals.toShortString(); 49 if (parentName != null) { 50 ret = parentName.toShortString() + '.' + ret; 51 } 52 return ret; 53 } 54 55 public void checkStatic() { 56 getPointcut().getPcd().checkStatic(); 58 } 59 60 public PointcutDec getPointcutDec() { 62 return getPointcut().getPointcutDec(); 63 } 64 65 68 public boolean allowsNameBinding() { return true; } 69 70 public JpPlanner makePlanner(PlanData planData) { 71 if (planData.isPlanning(this)) { 72 showError("recursive pointcut reference not allowed"); 73 return JpPlanner.NO_PLANNER; 74 } 75 76 PointcutSO innerPointcut = concretizePointcut(planData.getNameBindingType()); 77 if (innerPointcut.isAbstract()) { 78 planData.getPlanMaker().showError("references an abstract pointcut -- see below"); 79 innerPointcut.getCorrespondingDec().showError("can't use abstract pointcut where concrete is required"); 80 } 81 82 final JpPlanner planner = 83 innerPointcut.getPcd().makePlanner(planData.makeInner(this)); 84 final Map remapFormals = makeFormalsRemap(innerPointcut); 85 86 return new WrappedJpPlanner(planner) { 89 public JpPlan makePlan(JoinPoint jp) { 90 JpPlan plan = super.makePlan(jp); 91 if (plan == JpPlan.NEVER_PLAN || 92 plan == JpPlan.NO_PLAN) { 93 return plan; 94 } 95 plan.moveBindings(remapFormals); 96 return plan; 97 } 98 }; 99 } 100 101 Map makeFormalsRemap(PointcutSO pointcut) { 102 GenTypeNames params = getFormals().getNames(); 103 Formals decFormals = pointcut.getFormals(); 104 105 final int N = params.size(); 106 if (decFormals.size() != N) { 107 getFormals().showError("arguments don't match pointcut signature: " + 108 pointcut.getFormals().toShortString()); 109 return NamePcd.EMPTY_MAP; 110 } 111 112 Map remap = new HashMap(); 113 for (int i = 0; i < N; i++) { 114 FormalDec formal = decFormals.get(i); 115 GenTypeName param = params.get(i); 116 117 if (param.matchesInstance(formal.getType()).maybeFalse()) { 119 param.showError("doesn't match " + formal.getType().getString()); 120 break; 121 } 122 123 if (param instanceof VarTypeName) { 124 FormalDec paramFormal = ((VarTypeName)param).getFormalDec(); 125 remap.put(formal, paramFormal); 126 } 127 } 128 return remap; 129 } 130 131 public ASTObject postScope(ScopeWalker walker) { 133 if (!walker.walkBodies()) return this; 134 if (pointcut != null) return this; 135 bindPointcut(); 136 return super.postScope(walker); 137 } 138 139 private PointcutSO findPointcut() { 140 if (isStaticReference()) { 141 PointcutSO ret = parentName.getType().getPointcut(id, this, true); 142 if (ret.isAbstract()) { 143 this.showError("can't reference abstract pointcut using static qualified name: " + 144 ret.toShortString()); 145 } 146 return ret; 147 } else { 148 Type inType = getLexicalType(); 149 PointcutSO ret = inType.getPointcut(id, this, false); 150 if (ret != null) return ret; 151 152 while (ret == null) { 156 inType = inType.getDeclaringType(); 157 if (inType == null || inType == getTypeManager().TYPE_NOT_FOUND) { 158 showError("named pointcut not found: " + toShortString()); 159 return ret; 160 } 161 ret = inType.getPointcut(id, this, false); 162 } 163 164 setParentName(inType.makeTypeD()); 167 if (ret.isAbstract()) { 168 this.showError("can't reference abstract pointcut using static qualified name: " + 169 ret.toShortString()); 170 } 171 172 return ret; 173 } 174 } 175 176 private boolean isStaticReference() { return parentName != null; } 177 178 private void bindPointcut() { 179 pointcut = findPointcut(); 180 ((AspectJCompiler)getCompiler()).getCorrespondences(). 181 addPointsTo(findNonPcd(getParent()), pointcut.getPointcutDec()); 182 } 183 184 private ASTObject findNonPcd(ASTObject node) { 185 if (!(node instanceof Pcd)) return node; 186 return findNonPcd(node.getParent()); 187 } 188 189 190 191 public PointcutSO concretizePointcut(Type inType) { 192 if (pointcut == null) return null; 194 195 if (inType == null || isStaticReference()) return pointcut; 196 197 PointcutSO ret = pointcut; 198 199 while (inType != ret.getDeclaringType()) { 202 if (!ret.getModifiers().isPrivate() && ret.isAccessible(inType.getTypeDec().getBody())) { 203 ret = inType.getPointcut(id, inType.getTypeDec().getBody(), true); 204 break; 205 } 206 inType = inType.getTypeDec().getSuperClassType(); 207 } 208 209 return ret; 210 } 211 212 protected TypeD parentName; 214 public TypeD getParentName() { return parentName; } 215 public void setParentName(TypeD _parentName) { 216 if (_parentName != null) _parentName.setParent(this); 217 parentName = _parentName; 218 } 219 220 protected String id; 221 public String getId() { return id; } 222 public void setId(String _id) { id = _id; } 223 224 protected FormalsPattern formals; 225 public FormalsPattern getFormals() { return formals; } 226 public void setFormals(FormalsPattern _formals) { 227 if (_formals != null) _formals.setParent(this); 228 formals = _formals; 229 } 230 231 protected PointcutSO pointcut; 232 public PointcutSO getPointcut() { return pointcut; } 233 public void setPointcut(PointcutSO _pointcut) { pointcut = _pointcut; } 234 235 public NamePcd(SourceLocation location, TypeD _parentName, String _id, FormalsPattern _formals, PointcutSO _pointcut) { 236 super(location); 237 setParentName(_parentName); 238 setId(_id); 239 setFormals(_formals); 240 setPointcut(_pointcut); 241 } 242 protected NamePcd(SourceLocation source) { 243 super(source); 244 } 245 246 public ASTObject copyWalk(CopyWalker walker) { 247 NamePcd ret = new NamePcd(getSourceLocation()); 248 ret.preCopy(walker, this); 249 if (parentName != null) ret.setParentName( (TypeD)walker.process(parentName) ); 250 ret.id = id; 251 if (formals != null) ret.setFormals( (FormalsPattern)walker.process(formals) ); 252 ret.pointcut = pointcut; 253 return ret; 254 } 255 256 public ASTObject getChildAt(int childIndex) { 257 switch(childIndex) { 258 case 0: return parentName; 259 case 1: return formals; 260 default: return super.getChildAt(childIndex); 261 } 262 } 263 public String getChildNameAt(int childIndex) { 264 switch(childIndex) { 265 case 0: return "parentName"; 266 case 1: return "formals"; 267 default: return super.getChildNameAt(childIndex); 268 } 269 } 270 public void setChildAt(int childIndex, ASTObject child) { 271 switch(childIndex) { 272 case 0: setParentName((TypeD)child); return; 273 case 1: setFormals((FormalsPattern)child); return; 274 default: super.setChildAt(childIndex, child); return; 275 } 276 } 277 public int getChildCount() { 278 return 2; 279 } 280 281 public String getDefaultDisplayName() { 282 return "NamePcd(id: "+id+", "+"pointcut: "+pointcut+")"; 283 } 284 285 } 287 288 | Popular Tags |