1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 import org.aspectj.compiler.crosscuts.AccessFixer; 29 30 import org.aspectj.compiler.base.bcg.CodeBuilder; 31 import org.aspectj.compiler.base.bcg.Label; 32 33 39 public class FieldAccessExpr extends AssignableExpr implements SOLink { 40 public FieldDec getFieldDec() { return (FieldDec)field.getCorrespondingDec(); } 41 42 protected Type discoverType() { 43 return field.getFieldType(); 44 } 45 46 49 public void walkFlow(FlowCheckerPass w) { 50 Expr e = getExpr(); 51 FieldDec dec = getFieldDec(); 52 if (e != null) w.process(e); 53 if (dec.isFinal() 54 && isBare() 55 && w.isCurrent(dec) 56 && ! w.getVars().isDefinitelyAssigned(dec)) { 57 showError("Field " + getId() + " might not have a value"); 58 } 59 } 60 61 public boolean isBare() { 62 Expr e = getExpr(); 63 if (e == null) return true; 64 if (getField().isStatic()) { 65 return e instanceof TypeExpr && e.isSynthetic(); 66 } else { 67 return e instanceof ThisExpr 68 || ((e instanceof QualifiedThisExpr) && e.isSynthetic()); 69 } 70 } 71 72 75 public void postInnerInfo(InnerInfoPass w) { 76 if (expr == null ) { 77 w.checkStaticAccess(this, field); 78 } 79 if (expr == null) { 80 setExpr(getAST().makePrimary(getField(), w.currentType())); 81 } 82 } 83 84 88 public boolean hasLegalProtectedAccess(Type fromType) { 89 if (expr == null || getIsSuper()) return true; 91 return expr.getType().isSubtypeOf(fromType); 92 } 93 94 95 public void checkSpec() { 96 if (field == null) return; 97 98 if (field.getModifiers().isProtected() && !field.isAccessible(this)) { 99 showError(field.toShortString() + " has protected access"); 100 } 101 102 if (expr instanceof TypeExpr && !field.isStatic()) { 103 showError("non-static field " + field.toShortString() + 104 " cannot be accessed through a static reference"); 105 } 106 } 107 108 111 public void walkForwardReference(ForwardReferenceChecker w) { 112 super.walkForwardReference(w); 113 if (isLhs() && (getParent() instanceof BasicAssignExpr)) 114 return; 115 if (getExpr() != null && ! getExpr().isSynthetic()) return; 116 w.checkReference(this); 118 } 119 120 121 124 public ASTObject postAssignmentCheck(AssignmentCheckerPass walker) { 125 if (isLhs()) return this; 126 Field field = getField(); 127 FieldDec fieldDec = getFieldDec(); 128 fieldDec.ensureFolded(walker); 129 Expr initExpr = fieldDec.getInitializer(); 130 131 if (fieldDec.isConstant() && isLegalConstantPrimary(getExpr())) { 132 return 133 fieldDec.getType().foldCast((LiteralExpr)initExpr).setSource(this); 134 } else { 135 return this; 136 } 137 } 138 139 private boolean isLegalConstantPrimary(Expr expr) { 140 if (expr == null) return true; 141 142 if (expr instanceof ParenExpr) { 143 return isLegalConstantPrimary(((ParenExpr)expr).getExpr()); 144 } 145 if (expr instanceof TypeExpr) { 146 return true; 147 } 148 if (expr.isSynthetic() || !expr.fromSource()) { 150 return (expr instanceof ThisExpr); 151 } 152 153 return false; 154 } 155 156 public ASTObject fixAccessPost(AccessFixer fixer) { 158 if (isLhs()) return this; 160 Field field = getField(); 161 if (field == null) return this; if (field.isAccessible(this, true)) return this; 165 166 getCompiler().showMessage(" fixing privileged get: " + field.toShortString()); 167 168 Method method = field.getBackdoorGetterMethod(); 169 if (!fixer.apply) return this; 170 171 return getAST().makeCall(method, getExpr()).setSource(this); 172 } 173 174 public FieldAccessExpr(SourceLocation source, Type type, String name) { 175 this(source, null, type.getField(name, null, true), false); 176 } 177 178 public FieldAccessExpr(SourceLocation source, Expr expr, String name) { 179 this(source, expr, expr.getType().getField(name, expr, true), false); 180 } 181 182 public String getId() { return getField().getId(); } 183 184 public ASTObject postMove(MovingWalker walker) { 186 return walker.moveLinkExpr(this); 187 } 188 189 public ASTObject postFixAST(ASTFixerPass fixer) { 191 setExpr(field.updateTargetExpr(getExpr())); 193 194 if (!isLhs() && getField().getDeclaringType().isInterface() && !getField().isStatic()) { 195 return getAST().makeCall(getField().getBackdoorGetterMethod(), getExpr()); 196 } else { 197 return this; 198 } 199 } 200 201 public SemanticObject getTarget() { 203 return getField(); 204 } 205 206 public void setTarget(SemanticObject newTarget) { 207 setField((Field)newTarget); 208 } 209 210 public Type getTargetType() { 211 Type declaringType = getField().getDeclaringType(); 212 if (declaringType.isInterface() && ! getOptions().strict) { 213 return declaringType; 215 } 216 if (expr != null) 217 declaringType = expr.getType(); 218 return declaringType; 219 } 220 221 public void unparse(CodeWriter writer) { 222 writer.write(expr); 223 writer.write('.'); 224 writer.write(getField().getBytecodeId()); 225 } 226 227 230 public ASTObject postInnerAccess(InnerAccessFixer w) { 231 if (isLhs()) return this; 232 233 Expr q = getExpr(); 234 FieldDec dec = getFieldDec(); 235 if (w.isAccessible(dec, q)) return this; 236 237 final AST ast = getAST(); 238 Type qType = q.getType(); 239 MethodDec newMethodDec = w.getAccessMethod(qType, dec, "x", this); 240 Exprs newArgs = ast.makeExprs(); 241 Expr newExpr = w.makeOutsidePrimary(dec.isStatic(), newArgs, q); 242 return ast.makeCall(newMethodDec, newExpr, newArgs); 243 } 244 245 public MethodDec buildAccessMethod(InnerAccessFixer w) { 246 final AST ast = getAST(); 247 Expr q = getExpr(); 248 Type qType = q.getType(); 249 FieldDec dec = getFieldDec(); 250 Type fieldType = dec.getType(); 251 252 Formals newFormals = ast.makeFormals(); 253 Expr newExpr = w.makeInsidePrimary(dec.isStatic(), newFormals, qType); 254 255 return 256 w.makeAccessMethod(fieldType, 257 newFormals, 258 ast.makeGet(newExpr, dec)); 259 } 260 261 264 protected void cgLvalue(CodeBuilder cb) { 265 if (field.isStatic() || field.isConstant()) expr.cgEffect(cb); 266 else expr.cgValue(cb); 267 } 268 protected void cgLtoRvalue(CodeBuilder cb) { 269 if (expr.getType() instanceof ArrayType) { 270 cb.emitARRAYLENGTH(); 271 } else { 272 NameType qualifyingType = (NameType) getTargetType(); 273 String name = field.getBytecodeId(); 274 String descriptor = field.getDescriptor(); 275 int delta = getType().getSlotCount(); 276 if (field.isConstant()) { 277 field.getFieldDec().getInitializer().cgValue(cb); 278 } else if (field.isStatic()) { 279 cb.emitGETSTATIC(qualifyingType, name, descriptor, delta); 280 } else { 281 cb.emitGETFIELD(qualifyingType, name, descriptor, delta - 1); 282 } 283 } 284 } 285 protected void cgAssignment(CodeBuilder cb) { 286 NameType qualifyingType = (NameType) getTargetType(); 287 String name = field.getBytecodeId(); 288 String descriptor = field.getDescriptor(); 289 int delta = getType().getSlotCount(); 290 if (field.isStatic()) { 291 cb.emitPUTSTATIC(qualifyingType, name, descriptor, - delta); 292 } else { 293 cb.emitPUTFIELD(qualifyingType, name, descriptor, - delta - 1); 294 } 295 } 296 protected void cgDupLvalue(CodeBuilder cb) { 297 if (! field.isStatic()) cb.emitDUP(); 298 } 299 protected void cgDupRvalue(CodeBuilder cb) { 300 if (field.isStatic()) getType().emitDup(cb); 301 else getType().emitDupX1(cb); 302 } 303 304 protected Expr expr; 306 public Expr getExpr() { return expr; } 307 public void setExpr(Expr _expr) { 308 if (_expr != null) _expr.setParent(this); 309 expr = _expr; 310 } 311 312 protected Field field; 313 public Field getField() { return field; } 314 public void setField(Field _field) { field = _field; } 315 316 protected boolean isSuper; 317 public boolean getIsSuper() { return isSuper; } 318 public void setIsSuper(boolean _isSuper) { isSuper = _isSuper; } 319 320 public FieldAccessExpr(SourceLocation location, Expr _expr, Field _field, boolean _isSuper) { 321 super(location); 322 setExpr(_expr); 323 setField(_field); 324 setIsSuper(_isSuper); 325 } 326 protected FieldAccessExpr(SourceLocation source) { 327 super(source); 328 } 329 330 public ASTObject copyWalk(CopyWalker walker) { 331 FieldAccessExpr ret = new FieldAccessExpr(getSourceLocation()); 332 ret.preCopy(walker, this); 333 if (expr != null) ret.setExpr( (Expr)walker.process(expr) ); 334 ret.field = field; 335 ret.isSuper = isSuper; 336 return ret; 337 } 338 339 public ASTObject getChildAt(int childIndex) { 340 switch(childIndex) { 341 case 0: return expr; 342 default: return super.getChildAt(childIndex); 343 } 344 } 345 public String getChildNameAt(int childIndex) { 346 switch(childIndex) { 347 case 0: return "expr"; 348 default: return super.getChildNameAt(childIndex); 349 } 350 } 351 public void setChildAt(int childIndex, ASTObject child) { 352 switch(childIndex) { 353 case 0: setExpr((Expr)child); return; 354 default: super.setChildAt(childIndex, child); return; 355 } 356 } 357 public int getChildCount() { 358 return 1; 359 } 360 361 public String getDefaultDisplayName() { 362 return "FieldAccessExpr(field: "+field+", "+"isSuper: "+isSuper+")"; 363 } 364 365 } 367 | Popular Tags |