001 /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.3 */ 002 package AST; 003 004 import java.util.Collection; 005 import java.util.ArrayList; 006 import java.util.HashSet; 007 /** 008 * @ast node 009 * @declaredat /home/csz-naf/examples/PicoJava/spec/picojava.ast:8 010 * @production ClassDecl : {@link TypeDecl} ::= <span class="component">[Superclass:{@link IdUse}]</span> <span class="component">Body:{@link Block}</span>; 011 012 */ 013 public class ClassDecl extends TypeDecl implements Cloneable { 014 /** 015 * @apilevel internal 016 */ 017 public ClassDecl clone() throws CloneNotSupportedException { 018 ClassDecl node = (ClassDecl) super.clone(); 019 node.remoteLookup_String_visited = null; 020 node.isSubtypeOf_TypeDecl_visited = null; 021 node.isSubtypeOf_TypeDecl_values = null; 022 node.superClass_visited = -1; 023 node.superClass_computed = false; 024 node.superClass_value = null; 025 node.hasCycleOnSuperclassChain_visited = -1; 026 node.hasCycleOnSuperclassChain_computed = false; 027 node.hasCycleOnSuperclassChain_initialized = false; 028 node.in$Circle(false); 029 node.is$Final(false); 030 return node; 031 } 032 /** 033 * @apilevel internal 034 */ 035 public ClassDecl copy() { 036 try { 037 ClassDecl node = (ClassDecl) clone(); 038 node.parent = null; 039 if(children != null) { 040 node.children = (ASTNode[]) children.clone(); 041 } 042 return node; 043 } catch (CloneNotSupportedException e) { 044 throw new Error("Error: clone not supported for " + getClass().getName()); 045 } 046 } 047 /** 048 * Create a deep copy of the AST subtree at this node. 049 * The copy is dangling, i.e. has no parent. 050 * @return dangling copy of the subtree at this node 051 * @apilevel low-level 052 */ 053 public ClassDecl fullCopy() { 054 ClassDecl tree = (ClassDecl) copy(); 055 if (children != null) { 056 for (int i = 0; i < children.length; ++i) { 057 ASTNode child = (ASTNode) children[i]; 058 if(child != null) { 059 child = child.fullCopy(); 060 tree.setChild(child, i); 061 } 062 } 063 } 064 return tree; 065 } 066 /** 067 * @aspect ErrorCheck 068 * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:32 069 */ 070 public void collectErrors(Collection c) { 071 super.collectErrors(c); 072 if(hasCycleOnSuperclassChain()) 073 error(c, "Cyclic inheritance chain for class " + getName()); 074 } 075 /** 076 * @aspect PrettyPrint 077 * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:40 078 */ 079 public void prettyPrint(StringBuilder sb, int t) { 080 sb.append(getIndent(t)).append("class ").append(getName()); 081 if (hasSuperclass()) { 082 sb.append(" extends ").append(getSuperclass()); 083 } 084 sb.append(" "); 085 getBody().prettyPrint(sb, t); 086 } 087 /** 088 */ 089 public ClassDecl() { 090 super(); 091 } 092 /** 093 * Initializes the child array to the correct size. 094 * Initializes List and Opt nta children. 095 * @apilevel internal 096 * @ast method 097 */ 098 public void init$Children() { 099 children = new ASTNode[2]; 100 setChild(new Opt(), 0); 101 } 102 /** 103 */ 104 public ClassDecl(String p0, Opt<IdUse> p1, Block p2) { 105 setName(p0); 106 setChild(p1, 0); 107 setChild(p2, 1); 108 } 109 /** 110 * @apilevel low-level 111 */ 112 protected int numChildren() { 113 return 2; 114 } 115 /** 116 * @apilevel internal 117 */ 118 public boolean mayHaveRewrite() { 119 return false; 120 } 121 /** 122 * @apilevel low-level 123 */ 124 public void flushCache() { 125 super.flushCache(); 126 remoteLookup_String_visited = null; 127 isSubtypeOf_TypeDecl_visited = null; 128 isSubtypeOf_TypeDecl_values = null; 129 superClass_visited = -1; 130 superClass_computed = false; 131 superClass_value = null; 132 hasCycleOnSuperclassChain_visited = -1; 133 hasCycleOnSuperclassChain_computed = false; 134 hasCycleOnSuperclassChain_initialized = false; 135 } 136 /** 137 * @apilevel internal 138 */ 139 public void flushCollectionCache() { 140 super.flushCollectionCache(); 141 } 142 /** 143 * Replaces the lexeme Name. 144 * @param value The new value for the lexeme Name. 145 * @apilevel high-level 146 */ 147 public void setName(String value) { 148 tokenString_Name = value; 149 } 150 /** 151 * Retrieves the value for the lexeme Name. 152 * @return The value for the lexeme Name. 153 * @apilevel high-level 154 */ 155 public String getName() { 156 return tokenString_Name != null ? tokenString_Name : ""; 157 } 158 /** 159 * Replaces the optional node for the Superclass child. This is the <code>Opt</code> 160 * node containing the child Superclass, not the actual child! 161 * @param opt The new node to be used as the optional node for the Superclass child. 162 * @apilevel low-level 163 */ 164 public void setSuperclassOpt(Opt<IdUse> opt) { 165 setChild(opt, 0); 166 } 167 /** 168 * Replaces the (optional) Superclass child. 169 * @param node The new node to be used as the Superclass child. 170 * @apilevel high-level 171 */ 172 public void setSuperclass(IdUse node) { 173 getSuperclassOpt().setChild(node, 0); 174 } 175 /** 176 * Check whether the optional Superclass child exists. 177 * @return {@code true} if the optional Superclass child exists, {@code false} if it does not. 178 * @apilevel high-level 179 */ 180 public boolean hasSuperclass() { 181 return getSuperclassOpt().getNumChild() != 0; 182 } 183 /** 184 * Retrieves the (optional) Superclass child. 185 * @return The Superclass child, if it exists. Returns {@code null} otherwise. 186 * @apilevel low-level 187 */ 188 public IdUse getSuperclass() { 189 return (IdUse) getSuperclassOpt().getChild(0); 190 } 191 /** 192 * Retrieves the optional node for the Superclass child. This is the <code>Opt</code> node containing the child Superclass, not the actual child! 193 * @return The optional node for child the Superclass child. 194 * @apilevel low-level 195 */ 196 public Opt<IdUse> getSuperclassOpt() { 197 return (Opt<IdUse>) getChild(0); 198 } 199 /** 200 * Retrieves the optional node for child Superclass. This is the <code>Opt</code> node containing the child Superclass, not the actual child! 201 * <p><em>This method does not invoke AST transformations.</em></p> 202 * @return The optional node for child Superclass. 203 * @apilevel low-level 204 */ 205 public Opt<IdUse> getSuperclassOptNoTransform() { 206 return (Opt<IdUse>) getChildNoTransform(0); 207 } 208 /** 209 * Replaces the Body child. 210 * @param node The new node to replace the Body child. 211 * @apilevel high-level 212 */ 213 public void setBody(Block node) { 214 setChild(node, 1); 215 } 216 /** 217 * Retrieves the Body child. 218 * @return The current node used as the Body child. 219 * @apilevel high-level 220 */ 221 public Block getBody() { 222 return (Block) getChild(1); 223 } 224 /** 225 * Retrieves the Body child. 226 * <p><em>This method does not invoke AST transformations.</em></p> 227 * @return The current node used as the Body child. 228 * @apilevel low-level 229 */ 230 public Block getBodyNoTransform() { 231 return (Block) getChildNoTransform(1); 232 } 233 /** 234 * @apilevel internal 235 */ 236 protected java.util.Map remoteLookup_String_visited; 237 /** 238 * @attribute syn 239 * @aspect NameResolution 240 * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:62 241 */ 242 public Decl remoteLookup(String name) { 243 Object _parameters = name; 244 if(remoteLookup_String_visited == null) remoteLookup_String_visited = new java.util.HashMap(4); 245 ASTNode$State state = state(); 246 if (Integer.valueOf(state().boundariesCrossed).equals(remoteLookup_String_visited.get(_parameters))) { 247 throw new RuntimeException("Circular definition of attr: remoteLookup in class: org.jastadd.ast.AST.SynDecl"); 248 } 249 remoteLookup_String_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed)); 250 try { 251 // First, look in local declarations 252 if (!getBody().localLookup(name).isUnknown()) 253 return getBody().localLookup(name); 254 // Then, look in the superclass chain 255 if (superClass() != null && superClass().remoteLookup(name) != null 256 && !superClass().remoteLookup(name).isUnknown()) 257 return superClass().remoteLookup(name); 258 // Otherwise, return null object unknown 259 return unknownDecl(); 260 } 261 finally { 262 remoteLookup_String_visited.remove(_parameters); 263 } 264 } 265 /** 266 * @apilevel internal 267 */ 268 protected java.util.Map isSubtypeOf_TypeDecl_visited; 269 protected java.util.Map isSubtypeOf_TypeDecl_values; 270 /** 271 * @attribute syn 272 * @aspect TypeAnalysis 273 * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:44 274 */ 275 public boolean isSubtypeOf(TypeDecl typeDecl) { 276 Object _parameters = typeDecl; 277 if(isSubtypeOf_TypeDecl_visited == null) isSubtypeOf_TypeDecl_visited = new java.util.HashMap(4); 278 if(isSubtypeOf_TypeDecl_values == null) isSubtypeOf_TypeDecl_values = new java.util.HashMap(4); 279 if(isSubtypeOf_TypeDecl_values.containsKey(_parameters)) { 280 return ((Boolean)isSubtypeOf_TypeDecl_values.get(_parameters)).booleanValue(); 281 } 282 ASTNode$State state = state(); 283 if (Integer.valueOf(state().boundariesCrossed).equals(isSubtypeOf_TypeDecl_visited.get(_parameters))) { 284 throw new RuntimeException("Circular definition of attr: isSubtypeOf in class: org.jastadd.ast.AST.SynDecl"); 285 } 286 isSubtypeOf_TypeDecl_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed)); 287 int num = state.boundariesCrossed; 288 boolean isFinal = this.is$Final(); 289 boolean isSubtypeOf_TypeDecl_value = isSubtypeOf_compute(typeDecl); 290 if(isFinal && num == state().boundariesCrossed) { 291 isSubtypeOf_TypeDecl_values.put(_parameters, Boolean.valueOf(isSubtypeOf_TypeDecl_value)); 292 } else { 293 } 294 295 isSubtypeOf_TypeDecl_visited.remove(_parameters); 296 return isSubtypeOf_TypeDecl_value; 297 } 298 /** 299 * @apilevel internal 300 */ 301 private boolean isSubtypeOf_compute(TypeDecl typeDecl) { return typeDecl.isSuperTypeOfClassDecl(this); } 302 /** 303 * @apilevel internal 304 */ 305 protected int superClass_visited = -1; 306 /** 307 * @apilevel internal 308 */ 309 protected boolean superClass_computed = false; 310 /** 311 * @apilevel internal 312 */ 313 protected ClassDecl superClass_value; 314 /** 315 * @attribute syn 316 * @aspect TypeAnalysis 317 * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:51 318 */ 319 public ClassDecl superClass() { 320 if(superClass_computed) { 321 return superClass_value; 322 } 323 ASTNode$State state = state(); 324 if (superClass_visited == state().boundariesCrossed) { 325 throw new RuntimeException("Circular definition of attr: superClass in class: org.jastadd.ast.AST.SynDecl"); 326 } 327 superClass_visited = state().boundariesCrossed; 328 int num = state.boundariesCrossed; 329 boolean isFinal = this.is$Final(); 330 superClass_value = superClass_compute(); 331 if(isFinal && num == state().boundariesCrossed) { 332 superClass_computed = true; 333 } else { 334 } 335 336 superClass_visited = -1; 337 return superClass_value; 338 } 339 /** 340 * @apilevel internal 341 */ 342 private ClassDecl superClass_compute() { 343 if (hasSuperclass() && getSuperclass().decl() instanceof ClassDecl && !hasCycleOnSuperclassChain()) 344 return (ClassDecl) getSuperclass().decl(); 345 else 346 return null; 347 } 348 /** 349 * @apilevel internal 350 */ 351 protected int hasCycleOnSuperclassChain_visited = -1; 352 /** 353 * @apilevel internal 354 */ 355 protected boolean hasCycleOnSuperclassChain_computed = false; 356 /** 357 * @apilevel internal 358 */ 359 protected boolean hasCycleOnSuperclassChain_initialized = false; 360 /** 361 * @apilevel internal 362 */ 363 protected boolean hasCycleOnSuperclassChain_value; 364 /** 365 * @attribute syn 366 * @aspect TypeAnalysis 367 * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:59 368 */ 369 public boolean hasCycleOnSuperclassChain() { 370 if(hasCycleOnSuperclassChain_computed) { 371 return hasCycleOnSuperclassChain_value; 372 } 373 ASTNode$State state = state(); 374 if (!hasCycleOnSuperclassChain_initialized) { 375 hasCycleOnSuperclassChain_initialized = true; 376 hasCycleOnSuperclassChain_value = true; 377 } 378 if (!state.IN_CIRCLE) { 379 state.IN_CIRCLE = true; 380 int num = state.boundariesCrossed; 381 boolean isFinal = this.is$Final(); 382 // TODO: fixme 383 // state().CIRCLE_INDEX = 1; 384 do { 385 hasCycleOnSuperclassChain_visited = state.CIRCLE_INDEX; 386 state.CHANGE = false; 387 boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute(); 388 if (new_hasCycleOnSuperclassChain_value != hasCycleOnSuperclassChain_value) { 389 state.CHANGE = true; 390 } 391 hasCycleOnSuperclassChain_value = new_hasCycleOnSuperclassChain_value; 392 state.CIRCLE_INDEX++; 393 } while (state.CHANGE); 394 if(isFinal && num == state().boundariesCrossed) { 395 hasCycleOnSuperclassChain_computed = true; 396 state.LAST_CYCLE = true; 397 hasCycleOnSuperclassChain_compute(); 398 state.LAST_CYCLE = false; 399 } else { 400 state.RESET_CYCLE = true; 401 hasCycleOnSuperclassChain_compute(); 402 state.RESET_CYCLE = false; 403 hasCycleOnSuperclassChain_computed = false; 404 hasCycleOnSuperclassChain_initialized = false; 405 } 406 state.IN_CIRCLE = false; 407 return hasCycleOnSuperclassChain_value; 408 } 409 if(hasCycleOnSuperclassChain_visited != state.CIRCLE_INDEX) { 410 hasCycleOnSuperclassChain_visited = state.CIRCLE_INDEX; 411 if (state.LAST_CYCLE) { 412 hasCycleOnSuperclassChain_computed = true; 413 boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute(); 414 return new_hasCycleOnSuperclassChain_value; 415 } 416 if (state.RESET_CYCLE) { 417 hasCycleOnSuperclassChain_computed = false; 418 hasCycleOnSuperclassChain_initialized = false; 419 hasCycleOnSuperclassChain_visited = -1; 420 return hasCycleOnSuperclassChain_value; 421 } 422 boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute(); 423 if (new_hasCycleOnSuperclassChain_value != hasCycleOnSuperclassChain_value) { 424 state.CHANGE = true; 425 } 426 hasCycleOnSuperclassChain_value = new_hasCycleOnSuperclassChain_value; 427 return hasCycleOnSuperclassChain_value; 428 } 429 return hasCycleOnSuperclassChain_value; 430 } 431 /** 432 * @apilevel internal 433 */ 434 private boolean hasCycleOnSuperclassChain_compute() { 435 if (hasSuperclass() && getSuperclass().decl() instanceof ClassDecl) //First, check if there is a superclass 436 return ((ClassDecl) getSuperclass().decl()).hasCycleOnSuperclassChain(); 437 else 438 return false; 439 } 440 /** 441 * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:31 442 * @apilevel internal 443 */ 444 public Decl Define_Decl_lookup(ASTNode caller, ASTNode child, String name) { 445 if (caller == getBodyNoTransform()){ 446 // First, look in superclass chain 447 448 // EMMA: alternative impl. for debugging 449 ClassDecl superClass = superClass(); 450 if (superClass != null) { 451 Decl remoteDecl = ((TypeDecl)superClass).remoteLookup(name); 452 if (remoteDecl != null) { 453 if (!remoteDecl.isUnknown()) 454 return remoteDecl; 455 } 456 } 457 return lookup(name); 458 459 460 /* 461 EMMA: old impl before debugging 462 if (superClass() != null && !superClass().remoteLookup(name).isUnknown()) 463 return superClass().remoteLookup(name); 464 // Then, look in surrounding context 465 return lookup(name); 466 */ 467 } 468 else { 469 return getParent().Define_Decl_lookup(this, caller, name); 470 } 471 } 472 /** 473 * @apilevel internal 474 */ 475 public ASTNode rewriteTo() { return super.rewriteTo(); 476 }}