1 package polyglot.ext.jl.ast; 2 3 import java.util.*; 4 5 import polyglot.ast.ClassBody; 6 import polyglot.ast.ClassDecl; 7 import polyglot.ast.ClassMember; 8 import polyglot.ast.Node; 9 import polyglot.ast.Term; 10 import polyglot.frontend.Job; 11 import polyglot.frontend.Pass; 12 import polyglot.main.Report; 13 import polyglot.types.*; 14 import polyglot.util.*; 15 import polyglot.visit.*; 16 17 21 public class ClassBody_c extends Term_c implements ClassBody 22 { 23 protected List members; 24 25 public ClassBody_c(Position pos, List members) { 26 super(pos); 27 this.members = TypedList.copyAndCheck(members, ClassMember.class, true); 28 } 29 30 public List members() { 31 return this.members; 32 } 33 34 public ClassBody members(List members) { 35 ClassBody_c n = (ClassBody_c) copy(); 36 n.members = TypedList.copyAndCheck(members, ClassMember.class, true); 37 return n; 38 } 39 40 public ClassBody addMember(ClassMember member) { 41 ClassBody_c n = (ClassBody_c) copy(); 42 List l = new ArrayList(this.members.size() + 1); 43 l.addAll(this.members); 44 l.add(member); 45 n.members = TypedList.copyAndCheck(l, ClassMember.class, true); 46 return n; 47 } 48 49 protected ClassBody_c reconstruct(List members) { 50 if (! CollectionUtil.equals(members, this.members)) { 51 ClassBody_c n = (ClassBody_c) copy(); 52 n.members = TypedList.copyAndCheck(members, 53 ClassMember.class, true); 54 return n; 55 } 56 57 return this; 58 } 59 60 public Node visitChildren(NodeVisitor v) { 61 List members = visitList(this.members, v); 62 return reconstruct(members); 63 } 64 65 public NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException { 66 if (ar.kind() == AmbiguityRemover.SUPER || 70 ar.kind() == AmbiguityRemover.SIGNATURES) { 71 return ar.bypassChildren(this); 72 } 73 74 89 90 return ar; 91 } 92 93 public Node disambiguate(AmbiguityRemover ar) throws SemanticException { 94 if (ar.kind() == AmbiguityRemover.SIGNATURES) { 96 List l = new ArrayList(members.size()); 97 98 Job j = ar.job(); 99 100 for (Iterator i = members.iterator(); i.hasNext(); ) { 101 ClassMember n = (ClassMember) i.next(); 102 103 if (n instanceof ClassDecl) { 104 Job sj = j.spawn(ar.context(), n, 105 Pass.CLEAN_SUPER, Pass.CLEAN_SUPER_ALL); 106 107 if (! sj.status()) { 108 if (! sj.reportedErrors()) { 109 throw new SemanticException("Could not disambiguate " + 110 "class member.", 111 n.position()); 112 } 113 throw new SemanticException(); 114 } 115 116 ClassDecl m = (ClassDecl) sj.ast(); 117 l.add(m.visit(ar.visitChildren())); 118 } 119 else { 120 l.add(n.visit(ar.visitChildren())); 121 } 122 } 123 124 return members(l); 125 } 126 127 return this; 128 } 129 130 public String toString() { 131 return "{ ... }"; 132 } 133 134 protected void duplicateFieldCheck(TypeChecker tc) throws SemanticException { 135 ClassType type = tc.context().currentClass(); 136 137 ArrayList l = new ArrayList(type.fields()); 138 139 for (int i = 0; i < l.size(); i++) { 140 FieldInstance fi = (FieldInstance) l.get(i); 141 142 for (int j = i+1; j < l.size(); j++) { 143 FieldInstance fj = (FieldInstance) l.get(j); 144 145 if (fi.name().equals(fj.name())) { 146 throw new SemanticException("Duplicate field \"" + fj + "\".", fj.position()); 147 } 148 } 149 } 150 } 151 152 protected void duplicateConstructorCheck(TypeChecker tc) throws SemanticException { 153 ClassType type = tc.context().currentClass(); 154 155 ArrayList l = new ArrayList(type.constructors()); 156 157 for (int i = 0; i < l.size(); i++) { 158 ConstructorInstance ci = (ConstructorInstance) l.get(i); 159 160 for (int j = i+1; j < l.size(); j++) { 161 ConstructorInstance cj = (ConstructorInstance) l.get(j); 162 163 if (ci.hasFormals(cj.formalTypes())) { 164 throw new SemanticException("Duplicate constructor \"" + cj + "\".", cj.position()); 165 } 166 } 167 } 168 } 169 170 protected void duplicateMethodCheck(TypeChecker tc) throws SemanticException { 171 ClassType type = tc.context().currentClass(); 172 TypeSystem ts = tc.typeSystem(); 173 174 ArrayList l = new ArrayList(type.methods()); 175 176 for (int i = 0; i < l.size(); i++) { 177 MethodInstance mi = (MethodInstance) l.get(i); 178 179 for (int j = i+1; j < l.size(); j++) { 180 MethodInstance mj = (MethodInstance) l.get(j); 181 182 if (isSameMethod(ts, mi, mj)) { 183 throw new SemanticException("Duplicate method \"" + mj + "\".", mj.position()); 184 } 185 } 186 } 187 } 188 189 protected void duplicateMemberClassCheck(TypeChecker tc) throws SemanticException { 190 ClassType type = tc.context().currentClass(); 191 TypeSystem ts = tc.typeSystem(); 192 193 ArrayList l = new ArrayList(type.memberClasses()); 194 195 for (int i = 0; i < l.size(); i++) { 196 ClassType mi = (ClassType) l.get(i); 197 198 for (int j = i+1; j < l.size(); j++) { 199 ClassType mj = (ClassType) l.get(j); 200 201 if (mi.name().equals(mj.name())) { 202 throw new SemanticException("Duplicate member type \"" + mj + "\".", mj.position()); 203 } 204 } 205 } 206 } 207 208 protected boolean isSameMethod(TypeSystem ts, MethodInstance mi, 209 MethodInstance mj) { 210 return mi.isSameMethod(mj); 211 } 212 213 public Node typeCheck(TypeChecker tc) throws SemanticException { 214 duplicateFieldCheck(tc); 215 duplicateConstructorCheck(tc); 216 duplicateMethodCheck(tc); 217 duplicateMemberClassCheck(tc); 218 219 return this; 220 } 221 222 public void prettyPrint(CodeWriter w, PrettyPrinter tr) { 223 if (!members.isEmpty()) { 224 w.newline(4); 225 w.begin(0); 226 227 for (Iterator i = members.iterator(); i.hasNext(); ) { 228 ClassMember member = (ClassMember) i.next(); 229 printBlock(member, w, tr); 230 if (i.hasNext()) { 231 w.newline(0); 232 w.newline(0); 233 } 234 } 235 236 w.end(); 237 w.newline(0); 238 } 239 } 240 241 245 public Term entry() { 246 return this; 248 } 249 250 253 public List acceptCFG(CFGBuilder v, List succs) { 254 return succs; 255 } 256 257 private static final Collection TOPICS = 258 CollectionUtil.list(Report.types, Report.context); 259 260 } 261 | Popular Tags |