1 package polyglot.ext.jl.ast; 2 3 import java.util.*; 4 5 import polyglot.ast.*; 6 import polyglot.main.Report; 7 import polyglot.types.*; 8 import polyglot.util.*; 9 import polyglot.visit.*; 10 11 15 public class FieldDecl_c extends Term_c implements FieldDecl { 16 Flags flags; 17 TypeNode type; 18 String name; 19 Expr init; 20 FieldInstance fi; 21 InitializerInstance ii; 22 23 public FieldDecl_c(Position pos, Flags flags, TypeNode type, 24 String name, Expr init) 25 { 26 super(pos); 27 this.flags = flags; 28 this.type = type; 29 this.name = name; 30 this.init = init; 31 } 32 33 34 public InitializerInstance initializerInstance() { 35 return ii; 36 } 37 38 39 public FieldDecl initializerInstance(InitializerInstance ii) { 40 FieldDecl_c n = (FieldDecl_c) copy(); 41 n.ii = ii; 42 return n; 43 } 44 45 46 public Type declType() { 47 return type.type(); 48 } 49 50 51 public Flags flags() { 52 return flags; 53 } 54 55 56 public FieldDecl flags(Flags flags) { 57 FieldDecl_c n = (FieldDecl_c) copy(); 58 n.flags = flags; 59 return n; 60 } 61 62 63 public TypeNode type() { 64 return type; 65 } 66 67 68 public FieldDecl type(TypeNode type) { 69 FieldDecl_c n = (FieldDecl_c) copy(); 70 n.type = type; 71 return n; 72 } 73 74 75 public String name() { 76 return name; 77 } 78 79 80 public FieldDecl name(String name) { 81 FieldDecl_c n = (FieldDecl_c) copy(); 82 n.name = name; 83 return n; 84 } 85 86 87 public Expr init() { 88 return init; 89 } 90 91 92 public FieldDecl init(Expr init) { 93 FieldDecl_c n = (FieldDecl_c) copy(); 94 n.init = init; 95 return n; 96 } 97 98 99 public FieldDecl fieldInstance(FieldInstance fi) { 100 FieldDecl_c n = (FieldDecl_c) copy(); 101 n.fi = fi; 102 return n; 103 } 104 105 106 public FieldInstance fieldInstance() { 107 return fi; 108 } 109 110 111 protected FieldDecl_c reconstruct(TypeNode type, Expr init) { 112 if (this.type != type || this.init != init) { 113 FieldDecl_c n = (FieldDecl_c) copy(); 114 n.type = type; 115 n.init = init; 116 return n; 117 } 118 119 return this; 120 } 121 122 123 public Node visitChildren(NodeVisitor v) { 124 TypeNode type = (TypeNode) visitChild(this.type, v); 125 Expr init = (Expr) visitChild(this.init, v); 126 return reconstruct(type, init); 127 } 128 129 public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException { 130 return tb.pushCode(); 131 } 132 133 public Node buildTypes(TypeBuilder tb) throws SemanticException { 134 TypeSystem ts = tb.typeSystem(); 135 136 FieldDecl n; 137 138 if (init != null) { 139 ClassType ct = tb.currentClass(); 140 Flags f = (flags.isStatic()) ? Flags.STATIC : Flags.NONE; 141 InitializerInstance ii = ts.initializerInstance(init.position(), 142 ct, f); 143 n = initializerInstance(ii); 144 } 145 else { 146 n = this; 147 } 148 149 FieldInstance fi = ts.fieldInstance(n.position(), ts.Object(), 150 Flags.NONE, 151 ts.unknownType(position()), 152 n.name()); 153 154 return n.fieldInstance(fi); 155 } 156 157 158 public NodeVisitor disambiguateEnter(AmbiguityRemover ar) 159 throws SemanticException 160 { 161 if (ar.kind() == AmbiguityRemover.SUPER) { 162 return ar.bypassChildren(this); 163 } 164 else if (ar.kind() == AmbiguityRemover.SIGNATURES) { 165 if (init != null) { 166 return ar.bypass(init); 167 } 168 } 169 170 return ar; 171 } 172 173 public Node disambiguate(AmbiguityRemover ar) throws SemanticException { 174 if (ar.kind() == AmbiguityRemover.SIGNATURES) { 175 Context c = ar.context(); 176 TypeSystem ts = ar.typeSystem(); 177 178 ParsedClassType ct = c.currentClassScope(); 179 180 Flags f = flags; 181 182 if (ct.flags().isInterface()) { 183 f = f.Public().Static().Final(); 184 } 185 186 FieldInstance fi = ts.fieldInstance(position(), ct, f, 187 declType(), name); 188 189 return flags(f).fieldInstance(fi); 190 } 191 192 if (ar.kind() == AmbiguityRemover.ALL) { 193 checkFieldInstanceConstant(); 194 } 195 196 return this; 197 } 198 199 protected void checkFieldInstanceConstant() { 200 FieldInstance fi = this.fi; 201 202 if (init != null && fi.flags().isFinal() && init.isConstant()) { 203 Object value = init.constantValue(); 204 fi.setConstantValue(value); 205 } 206 } 207 208 public NodeVisitor addMembersEnter(AddMemberVisitor am) { 209 ParsedClassType ct = am.context().currentClassScope(); 210 211 FieldInstance fi = this.fi; 212 213 if (fi == null) { 214 throw new InternalCompilerError("null field instance"); 215 } 216 217 if (Report.should_report(Report.types, 5)) 218 Report.report(5, "adding " + fi + " to " + ct); 219 220 ct.addField(fi); 221 222 return am.bypassChildren(this); 223 } 224 225 public Context enterScope(Context c) { 226 if (ii != null) { 227 return c.pushCode(ii); 228 } 229 return c; 230 } 231 232 233 public Node typeCheck(TypeChecker tc) throws SemanticException { 234 TypeSystem ts = tc.typeSystem(); 235 236 checkFieldInstanceConstant(); 237 238 try { 239 ts.checkFieldFlags(flags); 240 } 241 catch (SemanticException e) { 242 throw new SemanticException(e.getMessage(), position()); 243 } 244 245 if (tc.context().currentClass().flags().isInterface()) { 246 if (flags.isProtected() || flags.isPrivate()) { 247 throw new SemanticException("Interface members must be public.", 248 position()); 249 } 250 } 251 252 if (init != null) { 253 if (init instanceof ArrayInit) { 254 ((ArrayInit) init).typeCheckElements(type.type()); 255 } 256 else { 257 boolean intConversion = false; 258 259 if (! ts.isImplicitCastValid(init.type(), type.type()) && 260 ! ts.equals(init.type(), type.type()) && 261 ! ts.numericConversionValid(type.type(), 262 init.constantValue())) { 263 264 throw new SemanticException("The type of the variable " + 265 "initializer \"" + init.type() + 266 "\" does not match that of " + 267 "the declaration \"" + 268 type.type() + "\".", 269 init.position()); 270 } 271 } 272 } 273 274 if (flags().isStatic() && 277 fieldInstance().container().toClass().isInnerClass()) { 278 if (!flags().isFinal() || init == null || !init.isConstant()) { 280 throw new SemanticException("Inner classes cannot declare " + 281 "static fields, unless they are compile-time " + 282 "constant fields.", this.position()); 283 } 284 285 } 286 287 return this; 288 } 289 290 public Node exceptionCheck(ExceptionChecker ec) throws SemanticException { 291 TypeSystem ts = ec.typeSystem(); 292 293 SubtypeSet s = (SubtypeSet) ec.throwsSet(); 294 295 for (Iterator i = s.iterator(); i.hasNext(); ) { 296 Type t = (Type) i.next(); 297 298 if (! t.isUncheckedException()) { 299 ec.throwsSet().clear(); 300 throw new SemanticException( 301 "A field initializer may not throw a " 302 + t + ".", position()); 303 } 304 } 305 306 ec.throwsSet().clear(); 307 308 return super.exceptionCheck(ec); 309 } 310 311 public Type childExpectedType(Expr child, AscriptionVisitor av) { 312 if (child == init) { 313 TypeSystem ts = av.typeSystem(); 314 315 if (ts.numericConversionValid(type.type(), child.constantValue())) { 318 return child.type(); 319 } 320 else { 321 return type.type(); 322 } 323 } 324 325 return child.type(); 326 } 327 328 332 public Term entry() { 333 return init != null ? init.entry() : this; 334 } 335 336 339 public List acceptCFG(CFGBuilder v, List succs) { 340 if (init != null) { 341 v.visitCFG(init, this); 342 } 343 return succs; 344 } 345 346 347 public String toString() { 348 return flags.translate() + type + " " + name + 349 (init != null ? " = " + init : ""); 350 } 351 352 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 353 boolean isInterface = fi != null && fi.container() != null && 354 fi.container().toClass().flags().isInterface(); 355 356 Flags f = flags; 357 358 if (isInterface) { 359 f = f.clearPublic(); 360 f = f.clearStatic(); 361 f = f.clearFinal(); 362 } 363 364 w.write(f.translate()); 365 print(type, w, tr); 366 w.write(" "); 367 w.write(name); 368 369 if (init != null) { 370 w.write(" ="); 371 w.allowBreak(2, " "); 372 print(init, w, tr); 373 } 374 375 w.write(";"); 376 } 377 378 public void dump(CodeWriter w) { 379 super.dump(w); 380 381 if (fi != null) { 382 w.allowBreak(4, " "); 383 w.begin(0); 384 w.write("(instance " + fi + ")"); 385 w.end(); 386 } 387 388 w.allowBreak(4, " "); 389 w.begin(0); 390 w.write("(name " + name + ")"); 391 w.end(); 392 } 393 } 394 | Popular Tags |