1 package polyglot.ext.jl.ast; 2 3 import java.util.*; 4 import polyglot.ast.*; 5 import polyglot.types.*; 6 import polyglot.util.*; 7 import polyglot.visit.*; 8 9 13 public class ConstructorCall_c extends Stmt_c implements ConstructorCall 14 { 15 protected Kind kind; 16 protected Expr qualifier; 17 protected List arguments; 18 protected ConstructorInstance ci; 19 20 public ConstructorCall_c(Position pos, Kind kind, Expr qualifier, List arguments) { 21 super(pos); 22 this.kind = kind; 23 this.qualifier = qualifier; 24 this.arguments = TypedList.copyAndCheck(arguments, Expr.class, true); 25 } 26 27 28 public Expr qualifier() { 29 return this.qualifier; 30 } 31 32 33 public ConstructorCall qualifier(Expr qualifier) { 34 ConstructorCall_c n = (ConstructorCall_c) copy(); 35 n.qualifier = qualifier; 36 return n; 37 } 38 39 40 public Kind kind() { 41 return this.kind; 42 } 43 44 45 public ConstructorCall kind(Kind kind) { 46 ConstructorCall_c n = (ConstructorCall_c) copy(); 47 n.kind = kind; 48 return n; 49 } 50 51 52 public List arguments() { 53 return Collections.unmodifiableList(this.arguments); 54 } 55 56 57 public ProcedureCall arguments(List arguments) { 58 ConstructorCall_c n = (ConstructorCall_c) copy(); 59 n.arguments = TypedList.copyAndCheck(arguments, Expr.class, true); 60 return n; 61 } 62 63 public ProcedureInstance procedureInstance() { 64 return constructorInstance(); 65 } 66 67 68 public ConstructorInstance constructorInstance() { 69 return ci; 70 } 71 72 73 public ConstructorCall constructorInstance(ConstructorInstance ci) { 74 ConstructorCall_c n = (ConstructorCall_c) copy(); 75 n.ci = ci; 76 return n; 77 } 78 79 83 public Context enterScope(Context c) { 84 return c.pushStatic(); 85 } 86 87 88 protected ConstructorCall_c reconstruct(Expr qualifier, List arguments) { 89 if (qualifier != this.qualifier || ! CollectionUtil.equals(arguments, this.arguments)) { 90 ConstructorCall_c n = (ConstructorCall_c) copy(); 91 n.qualifier = qualifier; 92 n.arguments = TypedList.copyAndCheck(arguments, Expr.class, true); 93 return n; 94 } 95 96 return this; 97 } 98 99 100 public Node visitChildren(NodeVisitor v) { 101 Expr qualifier = (Expr) visitChild(this.qualifier, v); 102 List arguments = visitList(this.arguments, v); 103 return reconstruct(qualifier, arguments); 104 } 105 106 public Node buildTypes(TypeBuilder tb) throws SemanticException { 107 TypeSystem ts = tb.typeSystem(); 108 109 if (kind == SUPER && tb.currentClass() == ts.Object()) { 111 return tb.nodeFactory().Empty(position()); 112 } 113 114 ConstructorCall_c n = (ConstructorCall_c) super.buildTypes(tb); 115 116 List l = new ArrayList(arguments.size()); 117 for (int i = 0; i < arguments.size(); i++) { 118 l.add(ts.unknownType(position())); 119 } 120 121 ConstructorInstance ci = ts.constructorInstance(position(), ts.Object(), 122 Flags.NONE, l, 123 Collections.EMPTY_LIST); 124 return n.constructorInstance(ci); 125 } 126 127 128 public Node typeCheck(TypeChecker tc) throws SemanticException { 129 TypeSystem ts = tc.typeSystem(); 130 Context c = tc.context(); 131 132 ClassType ct = c.currentClass(); 133 Type superType = ct.superType(); 134 135 if (qualifier != null) { 149 if (kind != SUPER) { 150 throw new SemanticException("Can only qualify a \"super\"" + 151 "constructor invocation.", 152 position()); 153 } 154 155 if (!superType.isClass() || !superType.toClass().isInnerClass() || 156 superType.toClass().inStaticContext()) { 157 throw new SemanticException("The class \"" + superType + "\"" + 158 " is not an inner class, or was declared in a static " + 159 "context; a qualified constructor invocation cannot " + 160 "be used.", position()); 161 } 162 163 Type qt = qualifier.type(); 164 165 if (! qt.isClass() || !qt.isSubtype(superType.toClass().outer())) { 166 throw new SemanticException("The type of the qualifier " + 167 "\"" + qt + "\" does not match the immediately enclosing " + 168 "class of the super class \"" + 169 superType.toClass().outer() + "\".", qualifier.position()); 170 } 171 } 172 173 if (kind == SUPER) { 174 if (! superType.isClass()) { 175 throw new SemanticException("Super type of " + ct + 176 " is not a class.", position()); 177 } 178 179 if (qualifier == null && superType.isClass() && superType.toClass().isInnerClass()) { 184 ClassType superContainer = superType.toClass().outer(); 185 ClassType e = ct; 188 189 while (e != null) { 190 if (e.isSubtype(superContainer) && ct.hasEnclosingInstance(e)) { 191 break; 192 } 193 e = e.outer(); 194 } 195 196 if (e == null) { 197 throw new SemanticException(ct + " must have an enclosing instance" + 198 " that is a subtype of " + superContainer, position()); 199 } 200 if (e == ct) { 201 throw new SemanticException(ct + " is a subtype of " + superContainer + 202 "; an enclosing instance that is a subtype of " + superContainer + 203 " must be specified in the super constructor call.", position()); 204 } 205 } 206 207 ct = ct.superType().toClass(); 208 } 209 210 List argTypes = new LinkedList(); 211 212 for (Iterator iter = this.arguments.iterator(); iter.hasNext();) { 213 Expr e = (Expr) iter.next(); 214 argTypes.add(e.type()); 215 } 216 217 ConstructorInstance ci = ts.findConstructor(ct, argTypes, c.currentClass()); 218 219 return constructorInstance(ci); 220 } 221 222 public Type childExpectedType(Expr child, AscriptionVisitor av) { 223 TypeSystem ts = av.typeSystem(); 224 225 if (child == qualifier) { 226 return ts.Object(); 228 } 229 230 Iterator i = this.arguments.iterator(); 231 Iterator j = ci.formalTypes().iterator(); 232 233 while (i.hasNext() && j.hasNext()) { 234 Expr e = (Expr) i.next(); 235 Type t = (Type) j.next(); 236 237 if (e == child) { 238 return t; 239 } 240 } 241 242 return child.type(); 243 } 244 245 public String toString() { 246 return (qualifier != null ? qualifier + "." : "") + kind + "(...)"; 247 } 248 249 250 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 251 if (qualifier != null) { 252 print(qualifier, w, tr); 253 w.write("."); 254 } 255 256 w.write(kind + "("); 257 258 w.begin(0); 259 260 for (Iterator i = arguments.iterator(); i.hasNext(); ) { 261 Expr e = (Expr) i.next(); 262 print(e, w, tr); 263 264 if (i.hasNext()) { 265 w.write(","); 266 w.allowBreak(0); 267 } 268 } 269 270 w.end(); 271 272 w.write(");"); 273 } 274 275 public Term entry() { 276 if (qualifier != null) { 277 return qualifier.entry(); 278 } 279 return listEntry(arguments, this); 280 } 281 282 public List acceptCFG(CFGBuilder v, List succs) { 283 if (qualifier != null) { 284 v.visitCFG(qualifier, listEntry(arguments, this)); 285 } 286 287 v.visitCFGList(arguments, this); 288 289 return succs; 290 } 291 292 public List throwTypes(TypeSystem ts) { 293 List l = new LinkedList(); 294 l.addAll(ci.throwTypes()); 295 l.addAll(ts.uncheckedExceptions()); 296 return l; 297 } 298 } 299 | Popular Tags |