1 24 25 package org.aspectj.compiler.base.ast; 26 27 import org.aspectj.compiler.base.*; 28 import org.aspectj.compiler.crosscuts.*; 29 import org.aspectj.compiler.base.bcg.CodeBuilder; 30 import java.util.*; 31 32 33 37 public class ConstructorDec extends CodeDec { 38 39 public boolean isSuper() { 40 ConstructorBody body = (ConstructorBody) getBody(); 41 return body.getConstructorCall().getIsSuper(); 42 } 43 44 public ConstructorDec getNextConstructorDec() { 45 ConstructorBody body = (ConstructorBody) getBody(); 46 return body.getConstructorCall().getConstructor().getConstructorDec(); 47 } 48 49 public ASTObject postFixAST(ASTFixerPass fixer) { 51 fixIntroducedDec(null); 52 return this; 53 } 54 55 public String getId() { return "new"; } 56 57 public TypeD getResultTypeD() { 58 return getTypeManager().voidType.makeTypeD(); 59 } 60 61 public boolean isFinal() { return true; } 62 public boolean isStatic() { return false; } 64 65 public boolean appearsStaticToCaller() { return true; } 66 67 public boolean hasThis() { 68 return true; 69 } 70 71 private String getDeclaringTypeD() { 72 if (getDeclaringType() == null) return ""; 73 75 return getDeclaringType().toShortString(); 76 } 77 78 public String toShortString() { 79 return modifiers.toShortString()+" "+getDeclaringTypeName()+formals.toShortString(); 80 } 81 82 public String getKind() { return "constructor"; } 83 84 public SemanticObject makeCorrespondingSemanticObject() { 85 return new Constructor(this); 86 } 87 88 public Constructor getConstructor() { 89 return (Constructor)getCorrespondingSemanticObject(); 90 } 91 92 public String toString() { return toShortString(); } 93 94 95 String getDeclaringTypeName() { 96 return getDeclaringType().getId(); 97 } 103 104 105 FormalDec extraFormalDec = null; 106 public FormalDec getExtraFormalDec() { 107 if (extraFormalDec != null) return extraFormalDec; 108 if (!isIntroduced()) return null; 109 110 if (isPrivate()) { 111 extraFormalDec = 112 getAST().makeFormal(getLexicalType().getPrivateCookieType(), "ajc$cookie"); 113 } else if (isProtected()) { 114 showError("protected introduction not allowed"); 115 return null; 116 } else if (isPublic()) { 117 return null; 118 } else { 119 extraFormalDec = 120 getAST().makeFormal(getLexicalType().getPackageCookieType(), "ajc$cookie"); 121 } 122 return extraFormalDec; 123 } 124 125 126 public Expr getExtraArgExpr() { 127 FormalDec extraFormal = getExtraFormalDec(); 128 if (extraFormal == null) return null; 129 130 return new CastExpr(getSourceLocation(), extraFormal.getTypeD(), getAST().makeNull()); 131 } 132 133 protected void fixIntroducedAccessibility() { 134 if (isPublic()) return; 135 136 getFormals().add(getExtraFormalDec()); 137 getModifiers().setPublic(true); 138 } 139 140 141 protected void makeMixinConcrete(TypeDec onTypeDec) { 142 CodeDec newDec = (CodeDec)this.copy(); 143 onTypeDec.getBody().add(newDec); 145 } 146 147 public void makePublicAccessible() { 148 if (isIntroduced()) fixIntroducedAccessibility(); 149 else getModifiers().setPublic(true); 150 } 151 152 public void fixIntroducedDec(TypeDec onTypeDec) { 153 if (!isIntroduced()) return; 154 155 if (onTypeDec == null || getDeclaringType().getTypeDec() == onTypeDec) { 156 fixIntroducedAccessibility(); 157 } else if (getDeclaringType().isInterface()) { 158 Type superType = onTypeDec.getSuperClassType(); 160 if (!superType.getTypeDec().fromSource() || 161 !superType.isSubtypeOf(getDeclaringType())) { 162 makeMixinConcrete(onTypeDec); 163 } 164 } 165 } 166 167 public ASTObject postImplementMixin(MixinImplementationPass fixer) { 169 final TypeDec inTypeDec = getBytecodeTypeDec(); 170 171 if (!(inTypeDec instanceof InterfaceDec) || getBody() == null || isStatic()) return this; 172 173 Set topmostImplementors = 174 Type.filterTopTypes(Type.filterConcreteTypes(inTypeDec.getType().getSubTypes())); 175 176 for (Iterator i = topmostImplementors.iterator(); i.hasNext(); ) { 177 final Type implType = (Type)i.next(); 178 TypeDec implDec = implType.getTypeDec(); 179 180 CodeDec newDec = (CodeDec)fixer.copyToClass(this, implDec); 181 newDec = getAST().makeInitializer(newDec.getBody().getStmts()); 182 183 Decs decs = implDec.getBody(); 185 int j = decs.size()-1; 186 for (; j >= 0; j--) { 187 if (decs.get(j) instanceof InitializerDec) { 188 implDec.getBody().add(j, newDec); 189 break; 190 } 191 } 192 if (j < 0) implDec.getBody().add( newDec ); 193 194 } 195 196 return null; 197 } 198 199 public void unparse(CodeWriter writer) { 200 setAllEnclosingTypes(null); 202 203 writer.write(modifiers); 204 writer.write(getDeclaringTypeName()); 206 if (getEnclosingInstanceFormal() == null) { 207 writer.write(formals); 208 } else { 209 Formals f = (Formals) formals.copy(); 210 f.add(0, (FormalDec) getEnclosingInstanceFormal().copy()); 211 writer.write(f); 212 } 213 214 writeNames(writer, "throws", getThrows()); 215 216 if (!writer.isOnlySignatures()) { 217 writer.optionalSpace(); 218 219 writer.write(body); 220 } 222 } 223 224 227 public void walkAnalysis(LocalClassPass.AnalysisWalker walker) { 228 walker.enterCodeDec(this); 229 walker.inConstructor(); 230 this.walk(walker); 231 walker.leaveCodeDec(); 232 } 233 234 237 public void preThreading(LocalClassPass.ThreadingWalker walker) { 238 walker.pushConstructorEnv(getFormals()); 239 } 240 241 public ASTObject postThreading(LocalClassPass.ThreadingWalker walker) { 242 walker.popEnv(); 243 return this; 244 } 245 246 249 public ASTObject walkMemberMunger(MemberClassMunger w) { 250 NameType currentType = w.currentType(); 251 if (currentType.isInner()) { 252 final AST ast = getAST(); 253 NameType enclosingInstanceType = currentType.getEnclosingInstanceType(); 254 FormalDec formalDec = 255 ast.makeFormal(enclosingInstanceType, "enclosing$instance"); 256 setEnclosingInstanceFormal(formalDec); 257 258 ConstructorBody body = (ConstructorBody) getBody(); 259 ConstructorCallExpr call = body.getConstructorCall(); 260 261 if (call.getIsSuper()) { 262 Stmt stmt = ast.makeStmt(ast.makeSet(ast.makeThis(currentType), 263 w.currentField(), 264 ast.makeVar(formalDec))); 265 body.getStmts().add(0, stmt); 266 } 267 } 268 return super.walkMemberMunger(w); 269 } 270 271 String getInternalId() { 274 return "<init>"; 275 } 276 277 protected void cgCodeMember(CodeBuilder cb) { 278 cb.setMaxFrame(getFrameSize()); 279 cb.enterBlock(); 280 if (getEnclosingInstanceFormal() != null) { 282 cb.enterVar(getEnclosingInstanceFormal()); 283 } 284 Formals f = getFormals(); 285 for (int i = 0, len = f.size(); i < len; i++) { 286 cb.enterVar(f.get(i)); 287 } 288 getBody().cgTop(cb); 289 cb.exitBlock(); 290 } 291 292 private String descriptor; 293 public synchronized String getDescriptor() { 294 if (descriptor == null) { 295 descriptor = "("; 296 if (getEnclosingInstanceFormal() != null) { 297 descriptor += getEnclosingInstanceFormal().getType().getDescriptor(); 298 } 299 for (Iterator i = getFormals().iterator(); i.hasNext(); ) { 300 FormalDec dec = (FormalDec)i.next(); 301 descriptor += dec.getType().getDescriptor(); 302 } 303 descriptor += ")"; 304 descriptor += getResultType().getDescriptor(); 305 } 306 return descriptor; 307 } 308 309 private boolean isDeltaComputed = false; 310 private int stackDelta; 311 public synchronized int getStackDelta() { 312 if (!isDeltaComputed) { 313 stackDelta = (getEnclosingInstanceFormal() == null) ? -1 : -2; 315 for (Iterator i = getFormals().iterator(); i.hasNext(); ) { 317 FormalDec dec = (FormalDec)i.next(); 318 stackDelta -= dec.getType().getSlotCount(); 319 } 320 isDeltaComputed = true; 322 } 323 return stackDelta; 325 } 326 327 330 public ConstructorDec(SourceLocation location, Modifiers _modifiers, Formals _formals, TypeDs __throws, CodeBody _body) { 331 this(location, _modifiers, null, _formals, __throws, _body); 332 } 333 334 protected FormalDec enclosingInstanceFormal; 336 public FormalDec getEnclosingInstanceFormal() { return enclosingInstanceFormal; } 337 public void setEnclosingInstanceFormal(FormalDec _enclosingInstanceFormal) { 338 if (_enclosingInstanceFormal != null) _enclosingInstanceFormal.setParent(this); 339 enclosingInstanceFormal = _enclosingInstanceFormal; 340 } 341 342 public ConstructorDec(SourceLocation location, Modifiers _modifiers, FormalDec _enclosingInstanceFormal, Formals _formals, TypeDs __throws, CodeBody _body) { 343 super(location, _modifiers, _formals, __throws, _body); 344 setEnclosingInstanceFormal(_enclosingInstanceFormal); 345 } 346 protected ConstructorDec(SourceLocation source) { 347 super(source); 348 } 349 350 public ASTObject copyWalk(CopyWalker walker) { 351 ConstructorDec ret = new ConstructorDec(getSourceLocation()); 352 ret.preCopy(walker, this); 353 if (modifiers != null) ret.setModifiers( (Modifiers)walker.process(modifiers) ); 354 if (enclosingInstanceFormal != null) ret.setEnclosingInstanceFormal( (FormalDec)walker.process(enclosingInstanceFormal) ); 355 if (formals != null) ret.setFormals( (Formals)walker.process(formals) ); 356 if (_throws != null) ret.setThrows( (TypeDs)walker.process(_throws) ); 357 if (body != null) ret.setBody( (CodeBody)walker.process(body) ); 358 return ret; 359 } 360 361 public ASTObject getChildAt(int childIndex) { 362 switch(childIndex) { 363 case 0: return modifiers; 364 case 1: return enclosingInstanceFormal; 365 case 2: return formals; 366 case 3: return _throws; 367 case 4: return body; 368 default: return super.getChildAt(childIndex); 369 } 370 } 371 public String getChildNameAt(int childIndex) { 372 switch(childIndex) { 373 case 0: return "modifiers"; 374 case 1: return "enclosingInstanceFormal"; 375 case 2: return "formals"; 376 case 3: return "throws"; 377 case 4: return "body"; 378 default: return super.getChildNameAt(childIndex); 379 } 380 } 381 public void setChildAt(int childIndex, ASTObject child) { 382 switch(childIndex) { 383 case 0: setModifiers((Modifiers)child); return; 384 case 1: setEnclosingInstanceFormal((FormalDec)child); return; 385 case 2: setFormals((Formals)child); return; 386 case 3: setThrows((TypeDs)child); return; 387 case 4: setBody((CodeBody)child); return; 388 default: super.setChildAt(childIndex, child); return; 389 } 390 } 391 public int getChildCount() { 392 return 5; 393 } 394 395 public String getDefaultDisplayName() { 396 return "ConstructorDec()"; 397 } 398 399 } 401 | Popular Tags |