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