1 package polyglot.ext.jl.ast; 2 3 import java.util.Collections ; 4 import java.util.Iterator ; 5 import java.util.List ; 6 7 import polyglot.ast.*; 8 import polyglot.main.Report; 9 import polyglot.types.*; 10 import polyglot.util.CodeWriter; 11 import polyglot.util.CollectionUtil; 12 import polyglot.util.Position; 13 import polyglot.util.TypedList; 14 import polyglot.visit.*; 15 16 21 public class ClassDecl_c extends Term_c implements ClassDecl 22 { 23 protected Flags flags; 24 protected String name; 25 protected TypeNode superClass; 26 protected List interfaces; 27 protected ClassBody body; 28 29 protected ParsedClassType type; 30 31 public ClassDecl_c(Position pos, Flags flags, String name, 32 TypeNode superClass, List interfaces, ClassBody body) { 33 super(pos); 34 this.flags = flags; 35 this.name = name; 36 this.superClass = superClass; 37 this.interfaces = TypedList.copyAndCheck(interfaces, TypeNode.class, true); 38 this.body = body; 39 } 40 41 public Named declaration() { 42 return type(); 43 } 44 45 public ParsedClassType type() { 46 return type; 47 } 48 49 public ClassDecl type(ParsedClassType type) { 50 ClassDecl_c n = (ClassDecl_c) copy(); 51 n.type = type; 52 return n; 53 } 54 55 public Flags flags() { 56 return this.flags; 57 } 58 59 public ClassDecl flags(Flags flags) { 60 ClassDecl_c n = (ClassDecl_c) copy(); 61 n.flags = flags; 62 return n; 63 } 64 65 public String name() { 66 return this.name; 67 } 68 69 public ClassDecl name(String name) { 70 ClassDecl_c n = (ClassDecl_c) copy(); 71 n.name = name; 72 return n; 73 } 74 75 public TypeNode superClass() { 76 return this.superClass; 77 } 78 79 public ClassDecl superClass(TypeNode superClass) { 80 ClassDecl_c n = (ClassDecl_c) copy(); 81 n.superClass = superClass; 82 return n; 83 } 84 85 public List interfaces() { 86 return this.interfaces; 87 } 88 89 public ClassDecl interfaces(List interfaces) { 90 ClassDecl_c n = (ClassDecl_c) copy(); 91 n.interfaces = TypedList.copyAndCheck(interfaces, TypeNode.class, true); 92 return n; 93 } 94 95 public ClassBody body() { 96 return this.body; 97 } 98 99 public ClassDecl body(ClassBody body) { 100 ClassDecl_c n = (ClassDecl_c) copy(); 101 n.body = body; 102 return n; 103 } 104 105 protected ClassDecl_c reconstruct(TypeNode superClass, List interfaces, ClassBody body) { 106 if (superClass != this.superClass || ! CollectionUtil.equals(interfaces, this.interfaces) || body != this.body) { 107 ClassDecl_c n = (ClassDecl_c) copy(); 108 n.superClass = superClass; 109 n.interfaces = TypedList.copyAndCheck(interfaces, TypeNode.class, true); 110 n.body = body; 111 return n; 112 } 113 114 return this; 115 } 116 117 121 public Term entry() { 122 return this.body().entry(); 123 } 124 125 128 public List acceptCFG(CFGBuilder v, List succs) { 129 v.visitCFG(this.body(), this); 130 return succs; 131 } 132 133 public Node visitChildren(NodeVisitor v) { 134 TypeNode superClass = (TypeNode) visitChild(this.superClass, v); 135 List interfaces = visitList(this.interfaces, v); 136 ClassBody body = (ClassBody) visitChild(this.body, v); 137 return reconstruct(superClass, interfaces, body); 138 } 139 140 public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException { 141 tb = tb.pushClass(position(), flags, name); 142 143 ParsedClassType ct = tb.currentClass(); 144 145 if (ct.isMember() && ct.outer().flags().isInterface()) { 147 ct.flags(ct.flags().Public().Static()); 148 } 149 150 if (ct.isMember() && ct.flags().isInterface()) { 152 ct.flags(ct.flags().Static()); 153 } 154 155 if (ct.flags().isInterface()) { 157 ct.flags(ct.flags().Abstract()); 158 } 159 160 return tb; 161 } 162 163 public Node buildTypes(TypeBuilder tb) throws SemanticException { 164 ParsedClassType type = tb.currentClass(); 165 if (type != null) { 166 return type(type).flags(type.flags()); 167 } 168 return this; 169 } 170 171 public Context enterScope(Node child, Context c) { 172 if (child == this.body) { 173 TypeSystem ts = c.typeSystem(); 174 c = c.pushClass(type, ts.staticTarget(type).toClass()); 175 } 176 return super.enterScope(child, c); 177 } 178 179 public NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException { 180 if (ar.kind() == AmbiguityRemover.SUPER) { 181 return ar.bypass(body); 182 } 183 184 return ar; 185 } 186 187 protected void disambiguateSuperType(AmbiguityRemover ar) throws SemanticException { 188 TypeSystem ts = ar.typeSystem(); 189 190 if (this.superClass != null) { 191 Type t = this.superClass.type(); 192 193 if (! t.isCanonical()) { 194 throw new SemanticException("Could not disambiguate super" + 195 " class of " + type + ".", superClass.position()); 196 } 197 198 if (! t.isClass() || t.toClass().flags().isInterface()) { 199 throw new SemanticException("Super class " + t + " of " + 200 type + " is not a class.", superClass.position()); 201 } 202 203 if (Report.should_report(Report.types, 3)) 204 Report.report(3, "setting super type of " + this.type + " to " + t); 205 206 this.type.superType(t); 207 208 ts.checkCycles(t.toReference()); 209 } 210 else if (ts.Object() != this.type && 211 !ts.Object().fullName().equals(this.type.fullName())) { 212 this.type.superType(ts.Object()); 216 } 217 else { 218 this.type.superType(null); 220 } 221 } 222 223 public Node disambiguate(AmbiguityRemover ar) throws SemanticException { 224 if (ar.kind() == AmbiguityRemover.SIGNATURES) { 225 Context ctxt = ar.context(); 228 this.type().inStaticContext(ctxt.inStaticContext()); 229 230 231 } 232 233 if (ar.kind() == AmbiguityRemover.SIGNATURES) { 234 ar.addSuperDependencies(this.type()); 237 } 238 239 if (ar.kind() != AmbiguityRemover.SUPER) { 240 return this; 241 } 242 243 TypeSystem ts = ar.typeSystem(); 244 245 if (Report.should_report(Report.types, 2)) 246 Report.report(2, "Cleaning " + type + "."); 247 248 disambiguateSuperType(ar); 249 250 for (Iterator i = this.interfaces.iterator(); i.hasNext(); ) { 251 TypeNode tn = (TypeNode) i.next(); 252 Type t = tn.type(); 253 254 if (! t.isCanonical()) { 255 throw new SemanticException("Could not disambiguate super" + 256 " class of " + type + ".", tn.position()); 257 } 258 259 if (! t.isClass() || ! t.toClass().flags().isInterface()) { 260 throw new SemanticException("Interface " + t + " of " + 261 type + " is not an interface.", tn.position()); 262 } 263 264 if (Report.should_report(Report.types, 3)) 265 Report.report(3, "adding interface of " + this.type + " to " + t); 266 267 if (!this.type.interfaces().contains(t)) this.type.addInterface(t); 268 269 ts.checkCycles(t.toReference()); 270 } 271 272 return this; 273 } 274 275 public Node addMembers(AddMemberVisitor tc) throws SemanticException { 276 TypeSystem ts = tc.typeSystem(); 277 NodeFactory nf = tc.nodeFactory(); 278 return addDefaultConstructorIfNeeded(ts, nf); 279 } 280 281 protected Node addDefaultConstructorIfNeeded(TypeSystem ts, 282 NodeFactory nf) { 283 if (defaultConstructorNeeded()) { 284 return addDefaultConstructor(ts, nf); 285 } 286 return this; 287 } 288 289 protected boolean defaultConstructorNeeded() { 290 if (flags().isInterface()) { 291 return false; 292 } 293 return type().constructors().isEmpty(); 294 } 295 296 protected Node addDefaultConstructor(TypeSystem ts, NodeFactory nf) { 297 ConstructorInstance ci = ts.defaultConstructor(position(), this.type); 298 this.type.addConstructor(ci); 299 Block block = null; 300 if (this.type.superType() instanceof ClassType) { 301 ConstructorInstance sci = ts.defaultConstructor(position(), 302 (ClassType) this.type.superType()); 303 ConstructorCall cc = nf.SuperCall(position(), 304 Collections.EMPTY_LIST); 305 cc = cc.constructorInstance(sci); 306 block = nf.Block(position(), cc); 307 } 308 else { 309 block = nf.Block(position()); 310 } 311 ConstructorDecl cd = nf.ConstructorDecl(position(), Flags.PUBLIC, 312 name, Collections.EMPTY_LIST, 313 Collections.EMPTY_LIST, 314 block); 315 cd = (ConstructorDecl) cd.constructorInstance(ci); 316 return body(body.addMember(cd)); 317 } 318 319 public Node typeCheck(TypeChecker tc) throws SemanticException { 320 if (this.type().isNested() && (this.type() instanceof Named)) { 321 ClassType container = this.type.outer(); 323 324 while (container instanceof Named) { 325 if (!container.isAnonymous()) { 326 String name = ((Named) container).name(); 327 328 if (name.equals(this.name)) { 329 throw new SemanticException("Cannot declare member " + 330 "class \"" + this.type + 331 "\" inside class with the " + 332 "same name.", position()); 333 } 334 } 335 if (container.isNested()) { 336 container = container.outer(); 337 } 338 else { 339 break; 340 } 341 } 342 343 if (this.type().isLocal()) { 344 Context ctxt = tc.context(); 347 348 if (ctxt.isLocal(this.name)) { 349 Named nm = ctxt.find(this.name); 352 if (nm instanceof Type) { 353 Type another = (Type)nm; 354 if (another.isClass() && another.toClass().isLocal()) { 355 throw new SemanticException("Cannot declare local " + 356 "class \"" + this.type + "\" within the same " + 357 "method, constructor or initializer as another " + 358 "local class of the same name.", position()); 359 } 360 } 361 } 362 } 363 } 364 365 if (type().isMember() && flags().isInterface() && 367 type().outer().isInnerClass()) { 368 throw new SemanticException("Inner classes cannot declare " + 370 "member interfaces.", this.position()); 371 } 372 373 if (type().isMember() && type().flags().isStatic() 375 && type().outer().isInnerClass()) { 376 throw new SemanticException("Inner classes cannot declare static " 377 + "member classes.", position()); 378 } 379 380 if (type.superType() != null) { 381 if (! type.superType().isClass()) { 382 throw new SemanticException("Cannot extend non-class \"" + 383 type.superType() + "\".", 384 position()); 385 } 386 387 if (type.superType().toClass().flags().isFinal()) { 388 throw new SemanticException("Cannot extend final class \"" + 389 type.superType() + "\".", 390 position()); 391 } 392 } 393 394 TypeSystem ts = tc.typeSystem(); 395 396 try { 397 if (type.isTopLevel()) { 398 ts.checkTopLevelClassFlags(type.flags()); 399 } 400 if (type.isMember()) { 401 ts.checkMemberClassFlags(type.flags()); 402 } 403 if (type.isLocal()) { 404 ts.checkLocalClassFlags(type.flags()); 405 } 406 } 407 catch (SemanticException e) { 408 throw new SemanticException(e.getMessage(), position()); 409 } 410 411 ts.checkClassConformance(type); 413 414 return this; 415 } 416 417 public String toString() { 418 return flags.clearInterface().translate() + 419 (flags.isInterface() ? "interface " : "class ") + name + " " + body; 420 } 421 422 public void prettyPrintHeader(CodeWriter w, PrettyPrinter tr) { 423 if (flags.isInterface()) { 424 w.write(flags.clearInterface().clearAbstract().translate()); 425 } 426 else { 427 w.write(flags.translate()); 428 } 429 430 if (flags.isInterface()) { 431 w.write("interface "); 432 } 433 else { 434 w.write("class "); 435 } 436 437 w.write(name); 438 439 if (superClass() != null) { 440 w.write(" extends "); 441 print(superClass(), w, tr); 442 } 443 444 if (! interfaces.isEmpty()) { 445 if (flags.isInterface()) { 446 w.write(" extends "); 447 } 448 else { 449 w.write(" implements "); 450 } 451 452 for (Iterator i = interfaces().iterator(); i.hasNext(); ) { 453 TypeNode tn = (TypeNode) i.next(); 454 print(tn, w, tr); 455 456 if (i.hasNext()) { 457 w.write (", "); 458 } 459 } 460 } 461 462 w.write(" {"); 463 } 464 465 public void prettyPrintFooter(CodeWriter w, PrettyPrinter tr) { 466 w.write("}"); 467 w.newline(0); 468 } 469 470 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 471 prettyPrintHeader(w, tr); 472 print(body(), w, tr); 473 prettyPrintFooter(w, tr); 474 } 475 476 public void dump(CodeWriter w) { 477 super.dump(w); 478 479 w.allowBreak(4, " "); 480 w.begin(0); 481 w.write("(name " + name + ")"); 482 w.end(); 483 484 if (type != null) { 485 w.allowBreak(4, " "); 486 w.begin(0); 487 w.write("(type " + type + ")"); 488 w.end(); 489 } 490 } 491 } 492 | Popular Tags |