1 package polyglot.ext.coffer.ast; 2 3 import polyglot.ext.jl.ast.*; 4 import polyglot.ext.coffer.types.*; 5 import polyglot.ext.coffer.extension.*; 6 import polyglot.ast.*; 7 import polyglot.types.*; 8 import polyglot.visit.*; 9 import polyglot.util.*; 10 import java.util.*; 11 12 15 public class CofferConstructorDecl_c extends ConstructorDecl_c implements CofferConstructorDecl 16 { 17 protected KeySetNode entryKeys; 18 protected KeySetNode returnKeys; 19 protected List throwConstraints; 20 21 public CofferConstructorDecl_c(Position pos, Flags flags, String name, List formals, KeySetNode entryKeys, KeySetNode returnKeys, List throwConstraints, Block body) { 22 super(pos, flags, name, formals, Collections.EMPTY_LIST, body); 23 this.entryKeys = entryKeys; 24 this.returnKeys = returnKeys; 25 this.throwConstraints = TypedList.copyAndCheck(throwConstraints, ThrowConstraintNode.class, true); 26 } 27 28 public KeySetNode entryKeys() { 29 return this.entryKeys; 30 } 31 32 public CofferConstructorDecl entryKeys(KeySetNode entryKeys) { 33 CofferConstructorDecl_c n = (CofferConstructorDecl_c) copy(); 34 n.entryKeys = entryKeys; 35 return n; 36 } 37 38 public KeySetNode returnKeys() { 39 return this.returnKeys; 40 } 41 42 public CofferConstructorDecl returnKeys(KeySetNode returnKeys) { 43 CofferConstructorDecl_c n = (CofferConstructorDecl_c) copy(); 44 n.returnKeys = returnKeys; 45 return n; 46 } 47 48 public List throwConstraints() { 49 return this.throwConstraints; 50 } 51 52 public List throwTypes() { 53 return new CachingTransformingList(throwConstraints, new GetType()); 54 } 55 56 public class GetType implements Transformation { 57 public Object transform(Object o) { 58 return ((ThrowConstraintNode) o).type(); 59 } 60 } 61 62 public ConstructorDecl throwTypes(List l) { 63 throw new InternalCompilerError("unimplemented"); 64 } 65 66 public CofferConstructorDecl throwConstraints(List throwConstraints) { 67 CofferConstructorDecl_c n = (CofferConstructorDecl_c) copy(); 68 n.throwConstraints = TypedList.copyAndCheck(throwConstraints, ThrowConstraintNode.class, true); 69 return n; 70 } 71 72 87 88 protected CofferConstructorDecl_c reconstruct(List formals, KeySetNode entryKeys, KeySetNode returnKeys, List throwConstraints, Block body) { 89 if (entryKeys != this.entryKeys || returnKeys != this.returnKeys || !CollectionUtil.equals(throwConstraints, this.throwConstraints)) { 90 CofferConstructorDecl_c n = (CofferConstructorDecl_c) copy(); 91 n.entryKeys = entryKeys; 92 n.returnKeys = returnKeys; 93 n.throwConstraints = TypedList.copyAndCheck(throwConstraints, ThrowConstraintNode.class, true); 94 return (CofferConstructorDecl_c) n.reconstruct(formals, Collections.EMPTY_LIST, body); 95 } 96 97 return (CofferConstructorDecl_c) super.reconstruct(formals, Collections.EMPTY_LIST, body); 98 } 99 100 public Node visitChildren(NodeVisitor v) { 101 List formals = visitList(this.formals, v); 102 KeySetNode entryKeys = (KeySetNode) visitChild(this.entryKeys, v); 103 KeySetNode returnKeys = (KeySetNode) visitChild(this.returnKeys, v); 104 List throwConstraints = visitList(this.throwConstraints, v); 105 Block body = (Block) visitChild(this.body, v); 106 return reconstruct(formals, entryKeys, returnKeys, throwConstraints, body); 107 } 108 109 public Node buildTypes(TypeBuilder tb) throws SemanticException { 110 CofferNodeFactory nf = (CofferNodeFactory) tb.nodeFactory(); 111 CofferConstructorDecl n = (CofferConstructorDecl) super.buildTypes(tb); 112 CofferConstructorInstance ci = 113 (CofferConstructorInstance) n.constructorInstance(); 114 115 if (n.entryKeys() == null) { 116 n = n.entryKeys(nf.CanonicalKeySetNode(position(), 117 ci.entryKeys())); 118 } 119 120 if (n.returnKeys() == null) { 121 n = n.returnKeys(nf.CanonicalKeySetNode(position(), 122 ci.returnKeys())); 123 } 124 125 List l = new LinkedList(); 126 boolean changed = false; 127 128 for (Iterator i = n.throwConstraints().iterator(); i.hasNext(); ) { 129 ThrowConstraintNode cn = (ThrowConstraintNode) i.next(); 130 if (cn.keys() == null) { 131 cn = cn.keys(n.entryKeys()); 132 changed = true; 133 } 134 l.add(cn); 135 } 136 137 if (changed) { 138 n = n.throwConstraints(l); 139 } 140 141 return n; 142 } 143 144 public Node typeCheck(TypeChecker tc) throws SemanticException { 145 CofferClassType ct = (CofferClassType) tc.context().currentClass(); 146 147 CofferConstructorInstance ci = 148 (CofferConstructorInstance) this.constructorInstance(); 149 150 if (ct.key() != null) { 151 if (ci.entryKeys().contains(ct.key())) { 152 throw new SemanticException("Constructor cannot hold key \"" + 153 ct.key() + "\" (associated with " + 154 "this) on entry.", position()); 155 } 156 157 if (! ci.returnKeys().contains(ct.key())) { 158 throw new SemanticException("Constructor must hold key \"" + 159 ct.key() + "\" (associated with " + 160 "this) on exit.", position()); 161 } 162 } 163 164 return super.typeCheck(tc); 165 } 166 167 protected ConstructorInstance makeConstructorInstance(ClassType ct, 168 TypeSystem ts) 169 throws SemanticException 170 { 171 CofferConstructorInstance ci = (CofferConstructorInstance) 172 super.makeConstructorInstance(ct, ts); 173 174 CofferTypeSystem vts = (CofferTypeSystem) ts; 175 176 KeySet entryKeys; 177 KeySet returnKeys; 178 179 if (this.entryKeys == null) { 180 entryKeys = vts.emptyKeySet(position()); 181 } 182 else { 183 entryKeys = this.entryKeys.keys(); 184 } 185 186 if (this.returnKeys == null) { 187 returnKeys = vts.emptyKeySet(position()); 188 189 if (ct instanceof CofferClassType) { 190 CofferClassType vct = (CofferClassType) ct; 191 if (vct.key() != null) 192 returnKeys = returnKeys.add(vct.key()); 193 } 194 } 195 else { 196 returnKeys = this.returnKeys.keys(); 197 } 198 199 ci = (CofferConstructorInstance) ci.entryKeys(entryKeys); 200 ci = (CofferConstructorInstance) ci.returnKeys(returnKeys); 201 202 List throwConstraints = new ArrayList(this.throwConstraints.size()); 203 for (Iterator i = this.throwConstraints.iterator(); i.hasNext(); ) { 204 ThrowConstraintNode cn = (ThrowConstraintNode) i.next(); 205 206 if (cn.constraint().keys() != null) { 207 throwConstraints.add(cn.constraint()); 208 } 209 else { 210 throwConstraints.add(cn.constraint().keys(entryKeys)); 211 } 212 } 213 214 return (CofferConstructorInstance) ci.throwConstraints(throwConstraints); 215 } 216 217 218 public void prettyPrintHeader(CodeWriter w, PrettyPrinter tr) { 219 w.begin(0); 220 w.write(flags().translate()); 221 222 w.write(name); 223 w.write("("); 224 225 w.begin(0); 226 227 for (Iterator i = formals.iterator(); i.hasNext(); ) { 228 Formal f = (Formal) i.next(); 229 print(f, w, tr); 230 231 if (i.hasNext()) { 232 w.write(","); 233 w.allowBreak(0, " "); 234 } 235 } 236 237 w.end(); 238 w.write(")"); 239 240 if (! throwConstraints.isEmpty()) { 241 w.allowBreak(6); 242 w.write("throws "); 243 244 for (Iterator i = throwConstraints.iterator(); i.hasNext(); ) { 245 ThrowConstraintNode cn = (ThrowConstraintNode) i.next(); 246 print(cn, w, tr); 247 248 if (i.hasNext()) { 249 w.write(","); 250 w.allowBreak(4, " "); 251 } 252 } 253 } 254 255 w.end(); 256 } 257 } 258 | Popular Tags |