1 package polyglot.ext.jl.types; 2 3 import java.util.Collection ; 4 import java.util.Iterator ; 5 import java.util.List ; 6 7 import polyglot.types.ClassType; 8 import polyglot.types.FieldInstance; 9 import polyglot.types.Flags; 10 import polyglot.types.Named; 11 import polyglot.types.Package; 12 import polyglot.types.ReferenceType; 13 import polyglot.types.Resolver; 14 import polyglot.types.SemanticException; 15 import polyglot.types.Type; 16 import polyglot.types.TypeSystem; 17 import polyglot.util.InternalCompilerError; 18 import polyglot.util.Position; 19 20 24 public abstract class ClassType_c extends ReferenceType_c implements ClassType 25 { 26 27 protected ClassType_c() { } 28 29 public ClassType_c(TypeSystem ts) { 30 this(ts, null); 31 } 32 33 public ClassType_c(TypeSystem ts, Position pos) { 34 super(ts, pos); 35 } 36 37 38 public abstract Kind kind(); 39 40 41 public abstract ClassType outer(); 42 43 44 public abstract String name(); 45 46 47 public ReferenceType container() { 48 if (! isMember()) 49 throw new InternalCompilerError("Non-member classes cannot have container classes."); 50 if (outer() == null) 51 throw new InternalCompilerError("Nested classes must have outer classes."); 52 return outer(); 53 } 54 55 56 public String fullName() { 57 String name; 58 if (isAnonymous()) { 59 if (superType() != null) { 60 name = "<anon subtype of " + superType().toString() + ">"; 61 } 62 else { 63 name = "<anon subtype of unknown>"; 64 } 65 } 66 else { 67 name = name(); 68 } 69 if (isTopLevel() && package_() != null) { 70 return package_().fullName() + "." + name; 71 } 72 else if (isMember() && container() instanceof Named) { 73 return ((Named) container()).fullName() + "." + name; 74 } 75 else { 76 return name; 77 } 78 } 79 80 public boolean isTopLevel() { return kind() == TOP_LEVEL; } 81 public boolean isMember() { return kind() == MEMBER; } 82 public boolean isLocal() { return kind() == LOCAL; } 83 public boolean isAnonymous() { return kind() == ANONYMOUS; } 84 85 89 public final boolean isInner() { 90 return isNested(); 91 } 92 93 public boolean isNested() { 94 return kind() == MEMBER || kind() == LOCAL || kind() == ANONYMOUS; 97 } 98 99 public boolean isInnerClass() { 100 return !flags().isInterface() && isNested() && !flags().isStatic() && !inStaticContext(); 103 } 104 105 public boolean isCanonical() { return true; } 106 public boolean isClass() { return true; } 107 public ClassType toClass() { return this; } 108 109 110 public abstract Package package_(); 111 112 113 public abstract Flags flags(); 114 115 116 public abstract List constructors(); 117 118 119 public abstract List memberClasses(); 120 121 122 public abstract List methods(); 123 124 125 public abstract List fields(); 126 127 128 public abstract List interfaces(); 129 130 131 public abstract Type superType(); 132 133 134 public FieldInstance fieldNamed(String name) { 135 for (Iterator i = fields().iterator(); i.hasNext(); ) { 136 FieldInstance fi = (FieldInstance) i.next(); 137 if (fi.name().equals(name)) { 138 return fi; 139 } 140 } 141 142 return null; 143 } 144 145 146 public ClassType memberClassNamed(String name) { 147 for (Iterator i = memberClasses().iterator(); i.hasNext(); ) { 148 ClassType t = (ClassType) i.next(); 149 if (t.name().equals(name)) { 150 return t; 151 } 152 } 153 154 return null; 155 } 156 157 public boolean descendsFromImpl(Type ancestor) { 158 if (! ancestor.isCanonical()) { 159 return false; 160 } 161 162 if (ancestor.isNull()) { 163 return false; 164 } 165 166 if (ts.equals(this, ancestor)) { 167 return false; 168 } 169 170 if (! ancestor.isReference()) { 171 return false; 172 } 173 174 if (ts.equals(ancestor, ts.Object())) { 175 return true; 176 } 177 178 if (! flags().isInterface()) { 180 if (ts.equals(this, ts.Object())) { 181 return false; 182 } 183 184 if (superType() == null) { 185 return false; 186 } 187 188 if (ts.isSubtype(superType(), ancestor)) { 189 return true; 190 } 191 } 192 193 for (Iterator i = interfaces().iterator(); i.hasNext(); ) { 195 Type parentType = (Type) i.next(); 196 197 if (ts.isSubtype(parentType, ancestor)) { 198 return true; 199 } 200 } 201 202 return false; 203 } 204 205 public boolean isThrowable() { 206 return ts.isSubtype(this, ts.Throwable()); 207 } 208 209 public boolean isUncheckedException() { 210 if (isThrowable()) { 211 Collection c = ts.uncheckedExceptions(); 212 213 for (Iterator i = c.iterator(); i.hasNext(); ) { 214 Type t = (Type) i.next(); 215 216 if (ts.isSubtype(this, t)) { 217 return true; 218 } 219 } 220 } 221 222 return false; 223 } 224 225 public boolean isImplicitCastValidImpl(Type toType) { 226 if (! toType.isClass()) return false; 227 return ts.isSubtype(this, toType); 228 } 229 230 236 public boolean isCastValidImpl(Type toType) { 237 if (! toType.isCanonical()) return false; 238 if (! toType.isReference()) return false; 239 240 if (toType.isArray()) { 241 return ts.isSubtype(toType, this); 245 } 246 247 if (! toType.isClass()) return false; 249 250 boolean fromInterface = flags().isInterface(); 252 boolean toInterface = toType.toClass().flags().isInterface(); 253 boolean fromFinal = flags().isFinal(); 254 boolean toFinal = toType.toClass().flags().isFinal(); 255 256 if (! fromInterface) { 258 if (! toInterface) { 260 return ts.isSubtype(this, toType) || ts.isSubtype(toType, this); 262 } 263 264 if (fromFinal) { 265 return ts.isSubtype(this, toType); 267 } 268 269 return true; 271 } 272 else { 273 if (! toInterface && ! toFinal) { 275 return true; 277 } 278 279 if (toFinal) { 280 return ts.isSubtype(toType, this); 282 } 283 284 return true; 286 } 287 } 288 289 public final boolean isEnclosed(ClassType maybe_outer) { 290 return ts.isEnclosed(this, maybe_outer); 291 } 292 293 public final boolean hasEnclosingInstance(ClassType encl) { 294 return ts.hasEnclosingInstance(this, encl); 295 } 296 297 public String translate(Resolver c) { 298 if (isTopLevel()) { 299 if (package_() == null) { 300 return name(); 301 } 302 303 if (c != null) { 305 try { 306 Named x = c.find(name()); 307 308 if (ts.equals(this, x)) { 309 return name(); 310 } 311 } 312 catch (SemanticException e) { 313 } 314 } 315 316 return package_().translate(c) + "." + name(); 317 } 318 else if (isMember()) { 319 if (container().toClass().isAnonymous()) { 321 return name(); 322 } 323 324 if (c != null) { 326 try { 327 Named x = c.find(name()); 328 329 if (ts.equals(this, x)) { 330 return name(); 331 } 332 } 333 catch (SemanticException e) { 334 } 335 } 336 337 return container().translate(c) + "." + name(); 338 } 339 else if (isLocal()) { 340 return name(); 341 } 342 else { 343 throw new InternalCompilerError("Cannot translate an anonymous class."); 344 } 345 } 346 347 public String toString() { 348 if (isTopLevel()) { 349 if (package_() != null) { 350 return package_().toString() + "." + name(); 351 } 352 353 return name(); 354 } 355 else if (isMember()) { 356 return container().toString() + "." + name(); 357 } 358 else if (isLocal()) { 359 return name(); 360 } 361 else { 362 if (superType() != null) { 363 return "<anon subtype of " + superType().toString() + ">"; 364 } 365 else { 366 return "<anon subtype of unknown>"; 367 } 368 } 369 } 370 371 public boolean isEnclosedImpl(ClassType maybe_outer) { 372 if (isTopLevel()) 373 return false; 374 else if (outer() != null) 375 return outer().equals(maybe_outer) || 376 outer().isEnclosed(maybe_outer); 377 else 378 throw new InternalCompilerError("Non top-level classes " + 379 "must have outer classes."); 380 } 381 382 386 public boolean hasEnclosingInstanceImpl(ClassType encl) { 387 if (this.equals(encl)) { 388 return true; 390 } 391 392 if (!isInnerClass() || inStaticContext()) { 393 return false; 397 } 398 399 return this.outer().hasEnclosingInstance(encl); 402 } 403 } 404 | Popular Tags |