1 package polyglot.ext.jl.types; 2 3 import java.util.HashMap ; 4 import java.util.List ; 5 import java.util.Collection ; 6 import java.util.Map ; 7 8 import polyglot.main.Report; 9 import polyglot.types.*; 10 import polyglot.types.Package; 11 import polyglot.util.CollectionUtil; 12 import polyglot.util.Enum; 13 import polyglot.util.InternalCompilerError; 14 15 25 public class Context_c implements Context 26 { 27 protected Context outer; 28 protected TypeSystem ts; 29 30 public static class Kind extends Enum { 31 public Kind(String name) { 32 super(name); 33 } 34 } 35 36 public static final Kind BLOCK = new Kind("block"); 37 public static final Kind CLASS = new Kind("class"); 38 public static final Kind CODE = new Kind("code"); 39 public static final Kind OUTER = new Kind("outer"); 40 public static final Kind SOURCE = new Kind("source"); 41 42 public Context_c(TypeSystem ts) { 43 this.ts = ts; 44 this.outer = null; 45 this.kind = OUTER; 46 } 47 48 public boolean isBlock() { return kind == BLOCK; } 49 public boolean isClass() { return kind == CLASS; } 50 public boolean isCode() { return kind == CODE; } 51 public boolean isOuter() { return kind == OUTER; } 52 public boolean isSource() { return kind == SOURCE; } 53 54 public TypeSystem typeSystem() { 55 return ts; 56 } 57 58 public Object copy() { 59 try { 60 return super.clone(); 61 } 62 catch (CloneNotSupportedException e) { 63 throw new InternalCompilerError("Java clone() weirdness."); 64 } 65 } 66 67 protected Context_c push() { 68 Context_c v = (Context_c) this.copy(); 69 v.outer = this; 70 v.types = null; 71 v.vars = null; 72 return v; 73 } 74 75 78 protected ImportTable it; 79 protected Kind kind; 80 protected ClassType type; 81 protected ParsedClassType scope; 82 protected CodeInstance code; 83 protected Map types; 84 protected Map vars; 85 protected boolean inCode; 86 87 90 protected boolean staticContext; 91 92 public Resolver outerResolver() { 93 if (it != null) { 94 return it; 95 } 96 return ts.systemResolver(); 97 } 98 99 public ImportTable importTable() { 100 return it; 101 } 102 103 104 public Package package_() { 105 return importTable().package_(); 106 } 107 108 113 public boolean isLocal(String name) { 114 if (isClass()) { 115 return false; 116 } 117 118 if ((isBlock() || isCode()) && 119 (findVariableInThisScope(name) != null || findInThisScope(name) != null)) { 120 return true; 121 } 122 123 if (outer == null) { 124 return false; 125 } 126 127 return outer.isLocal(name); 128 } 129 130 134 public MethodInstance findMethod(String name, List argTypes) throws SemanticException { 135 if (Report.should_report(TOPICS, 3)) 136 Report.report(3, "find-method " + name + argTypes + " in " + this); 137 138 if (this.currentClass() != null && 142 ts.hasMethodNamed(this.currentClass(), name)) { 143 if (Report.should_report(TOPICS, 3)) 144 Report.report(3, "find-method " + name + argTypes + " -> " + 145 this.currentClass()); 146 147 return ts.findMethod(this.currentClass(), 150 name, argTypes, this.currentClass()); 151 } 152 153 if (outer != null) { 154 return outer.findMethod(name, argTypes); 155 } 156 157 throw new SemanticException("Method " + name + " not found."); 158 } 159 160 163 public LocalInstance findLocal(String name) throws SemanticException { 164 VarInstance vi = findVariableSilent(name); 165 166 if (vi instanceof LocalInstance) { 167 return (LocalInstance) vi; 168 } 169 170 throw new SemanticException("Local " + name + " not found."); 171 } 172 173 176 public ClassType findFieldScope(String name) throws SemanticException { 177 if (Report.should_report(TOPICS, 3)) 178 Report.report(3, "find-field-scope " + name + " in " + this); 179 180 VarInstance vi = findVariableInThisScope(name); 181 182 if (vi instanceof FieldInstance) { 183 if (Report.should_report(TOPICS, 3)) 184 Report.report(3, "find-field-scope " + name + " in " + vi); 185 return type; 186 } 187 188 if (vi == null && outer != null) { 189 return outer.findFieldScope(name); 190 } 191 192 throw new SemanticException("Field " + name + " not found."); 193 } 194 195 197 public ClassType findMethodScope(String name) throws SemanticException { 198 if (Report.should_report(TOPICS, 3)) 199 Report.report(3, "find-method-scope " + name + " in " + this); 200 201 if (this.currentClass() != null && 202 ts.hasMethodNamed(this.currentClass(), name)) { 203 if (Report.should_report(TOPICS, 3)) 204 Report.report(3, "find-method-scope " + name + " -> " + 205 this.currentClass()); 206 return this.currentClass(); 207 } 208 209 if (outer != null) { 210 return outer.findMethodScope(name); 211 } 212 213 throw new SemanticException("Method " + name + " not found."); 214 } 215 216 219 public FieldInstance findField(String name) throws SemanticException { 220 VarInstance vi = findVariableSilent(name); 221 222 if (vi instanceof FieldInstance) { 223 FieldInstance fi = (FieldInstance) vi; 224 225 if (! ts.isAccessible(fi, this)) { 226 throw new SemanticException("Field " + name + " not accessible."); 227 } 228 229 if (Report.should_report(TOPICS, 3)) 230 Report.report(3, "find-field " + name + " -> " + fi); 231 return fi; 232 } 233 234 throw new NoMemberException(NoMemberException.FIELD, "Field " + name + " not found."); 235 } 236 237 240 public VarInstance findVariable(String name) throws SemanticException { 241 VarInstance vi = findVariableSilent(name); 242 243 if (vi != null) { 244 if (Report.should_report(TOPICS, 3)) 245 Report.report(3, "find-var " + name + " -> " + vi); 246 return vi; 247 } 248 249 throw new SemanticException("Variable " + name + " not found."); 250 } 251 252 255 public VarInstance findVariableSilent(String name) { 256 if (Report.should_report(TOPICS, 3)) 257 Report.report(3, "find-var " + name + " in " + this); 258 259 VarInstance vi = findVariableInThisScope(name); 260 261 if (vi != null) { 262 if (Report.should_report(TOPICS, 3)) 263 Report.report(3, "find-var " + name + " -> " + vi); 264 return vi; 265 } 266 267 if (outer != null) { 268 return outer.findVariableSilent(name); 269 } 270 271 return null; 272 } 273 274 protected String mapsToString() { 275 return "types=" + types + " vars=" + vars; 276 } 277 278 public String toString() { 279 return "(" + kind + " " + mapsToString() + " " + outer + ")"; 280 } 281 282 public Context pop() { 283 return outer; 284 } 285 286 289 public Named find(String name) throws SemanticException { 290 if (Report.should_report(TOPICS, 3)) 291 Report.report(3, "find-type " + name + " in " + this); 292 293 if (isOuter()) return outerResolver().find(name); 294 if (isSource()) return it.find(name); 295 296 Named type = findInThisScope(name); 297 298 if (type != null) { 299 if (Report.should_report(TOPICS, 3)) 300 Report.report(3, "find " + name + " -> " + type); 301 return type; 302 } 303 304 if (outer != null) { 305 return outer.find(name); 306 } 307 308 throw new SemanticException("Type " + name + " not found."); 309 } 310 311 314 public Context pushSource(ImportTable it) { 315 Context_c v = push(); 316 v.kind = SOURCE; 317 v.it = it; 318 v.inCode = false; 319 v.staticContext = false; 320 return v; 321 } 322 323 336 public Context pushClass(ParsedClassType classScope, ClassType type) { 337 if (Report.should_report(TOPICS, 4)) 338 Report.report(4, "push class " + classScope + " " + classScope.position()); 339 Context_c v = push(); 340 v.kind = CLASS; 341 v.scope = classScope; 342 v.type = type; 343 v.inCode = false; 344 v.staticContext = false; 345 346 if (! type.isAnonymous()) { 347 v.addNamed(type); 348 } 349 350 return v; 351 } 352 353 356 public Context pushBlock() { 357 if (Report.should_report(TOPICS, 4)) 358 Report.report(4, "push block"); 359 Context_c v = push(); 360 v.kind = BLOCK; 361 return v; 362 } 363 364 367 public Context pushStatic() { 368 if (Report.should_report(TOPICS, 4)) 369 Report.report(4, "push static"); 370 Context_c v = push(); 371 v.staticContext = true; 372 return v; 373 } 374 375 378 public Context pushCode(CodeInstance ci) { 379 if (Report.should_report(TOPICS, 4)) 380 Report.report(4, "push code " + ci + " " + ci.position()); 381 Context_c v = push(); 382 v.kind = CODE; 383 v.code = ci; 384 v.inCode = true; 385 v.staticContext = ci.flags().isStatic(); 386 return v; 387 } 388 389 392 public CodeInstance currentCode() { 393 return code; 394 } 395 396 400 public boolean inCode() { 401 return inCode; 402 } 403 404 405 414 public boolean inStaticContext() { 415 return staticContext; 416 } 417 418 421 public ClassType currentClass() { 422 return type; 423 } 424 425 428 public ParsedClassType currentClassScope() { 429 return scope; 430 } 431 432 435 public void addVariable(VarInstance vi) { 436 if (Report.should_report(TOPICS, 3)) 437 Report.report(3, "Adding " + vi + " to context."); 438 addVariableToThisScope(vi); 439 } 440 441 446 public void addMethod(MethodInstance mi) { 447 if (Report.should_report(TOPICS, 3)) 448 Report.report(3, "Adding " + mi + " to context."); 449 } 450 451 454 public void addNamed(Named t) { 455 if (Report.should_report(TOPICS, 3)) 456 Report.report(3, "Adding type " + t + " to context."); 457 addNamedToThisScope(t); 458 } 459 460 public Named findInThisScope(String name) { 461 Named t = null; 462 if (types != null) { 463 t = (Named) types.get(name); 464 } 465 if (t == null && isClass()) { 466 if (! this.type.isAnonymous() && 467 this.type.name().equals(name)) { 468 return this.type; 469 } 470 else { 471 try { 472 return ts.findMemberClass(this.type, name, this.type); 473 } 474 catch (SemanticException e) { 475 } 476 } 477 } 478 return t; 479 } 480 481 public void addNamedToThisScope(Named type) { 482 if (types == null) types = new HashMap (); 483 types.put(type.name(), type); 484 } 485 486 public ClassType findMethodContainerInThisScope(String name) { 487 if (isClass() && ts.hasMethodNamed(this.currentClass(), name)) { 488 return this.type; 489 } 490 return null; 491 } 492 493 public VarInstance findVariableInThisScope(String name) { 494 VarInstance vi = null; 495 if (vars != null) { 496 vi = (VarInstance) vars.get(name); 497 } 498 if (vi == null && isClass()) { 499 try { 500 return ts.findField(this.type, name, this.type); 501 } 502 catch (SemanticException e) { 503 return null; 504 } 505 } 506 return vi; 507 } 508 509 public void addVariableToThisScope(VarInstance var) { 510 if (vars == null) vars = new HashMap (); 511 vars.put(var.name(), var); 512 } 513 514 private static final Collection TOPICS = 515 CollectionUtil.list(Report.types, Report.context); 516 517 } 518 | Popular Tags |