1 package polyglot.ext.jl.types; 2 3 import polyglot.types.*; 4 import polyglot.util.*; 5 import polyglot.main.Report; 6 import java.util.*; 7 8 12 public class MethodInstance_c extends ProcedureInstance_c 13 implements MethodInstance 14 { 15 protected String name; 16 protected Type returnType; 17 18 19 protected MethodInstance_c() { } 20 21 public MethodInstance_c(TypeSystem ts, Position pos, 22 ReferenceType container, 23 Flags flags, Type returnType, String name, 24 List formalTypes, List excTypes) { 25 super(ts, pos, container, flags, formalTypes, excTypes); 26 this.returnType = returnType; 27 this.name = name; 28 } 29 30 public MethodInstance flags(Flags flags) { 31 if (!flags.equals(this.flags)) { 32 MethodInstance_c n = (MethodInstance_c) copy(); 33 n.flags = flags; 34 return n; 35 } 36 return this; 37 } 38 39 public String name() { 40 return name; 41 } 42 43 public MethodInstance name(String name) { 44 if ((name != null && !name.equals(this.name)) || 45 (name == null && name != this.name)) { 46 MethodInstance_c n = (MethodInstance_c) copy(); 47 n.name = name; 48 return n; 49 } 50 return this; 51 } 52 53 public Type returnType() { 54 return returnType; 55 } 56 57 public MethodInstance returnType(Type returnType) { 58 if (this.returnType != returnType) { 59 MethodInstance_c n = (MethodInstance_c) copy(); 60 n.returnType = returnType; 61 return n; 62 } 63 return this; 64 } 65 66 public MethodInstance formalTypes(List l) { 67 if (!CollectionUtil.equals(this.formalTypes, l)) { 68 MethodInstance_c n = (MethodInstance_c) copy(); 69 n.formalTypes = new ArrayList(l); 70 return n; 71 } 72 return this; 73 } 74 75 public MethodInstance throwTypes(List l) { 76 if (!CollectionUtil.equals(this.excTypes, l)) { 77 MethodInstance_c n = (MethodInstance_c) copy(); 78 n.excTypes = new ArrayList(l); 79 return n; 80 } 81 return this; 82 } 83 84 public MethodInstance container(ReferenceType container) { 85 if (this.container != container) { 86 MethodInstance_c n = (MethodInstance_c) copy(); 87 n.container = container; 88 return n; 89 } 90 return this; 91 } 92 93 public int hashCode() { 94 return flags.hashCode() + name.hashCode(); 97 } 98 99 public boolean equalsImpl(TypeObject o) { 100 if (o instanceof MethodInstance) { 101 MethodInstance i = (MethodInstance) o; 102 return ts.equals(returnType, i.returnType()) 103 && name.equals(i.name()) 104 && super.equalsImpl(i); 105 } 106 107 return false; 108 } 109 110 public String toString() { 111 String s = designator() + " " + flags.translate() + returnType + " " + 112 signature(); 113 114 if (! excTypes.isEmpty()) { 115 s += " throws " + TypeSystem_c.listToString(excTypes); 116 } 117 118 return s; 119 } 120 121 public String signature() { 122 return name + "(" + TypeSystem_c.listToString(formalTypes) + ")"; 123 } 124 125 public String designator() { 126 return "method"; 127 } 128 129 130 public final boolean isSameMethod(MethodInstance m) { 131 return ts.isSameMethod(this, m); 132 } 133 134 135 public boolean isSameMethodImpl(MethodInstance m) { 136 return this.name().equals(m.name()) && hasFormals(m.formalTypes()); 137 } 138 139 public boolean isCanonical() { 140 return container.isCanonical() 141 && returnType.isCanonical() 142 && listIsCanonical(formalTypes) 143 && listIsCanonical(excTypes); 144 } 145 146 public final boolean methodCallValid(String name, List argTypes) { 147 return ts.methodCallValid(this, name, argTypes); 148 } 149 150 public boolean methodCallValidImpl(String name, List argTypes) { 151 return name().equals(name) && ts.callValid(this, argTypes); 152 } 153 154 public List overrides() { 155 return ts.overrides(this); 156 } 157 158 public List overridesImpl() { 159 List l = new LinkedList(); 160 ReferenceType rt = container(); 161 162 while (rt != null) { 163 l.addAll(rt.methods(name, formalTypes)); 166 167 ReferenceType sup = null; 168 if (rt.superType() != null && rt.superType().isReference()) { 169 sup = (ReferenceType) rt.superType(); 170 } 171 172 rt = sup; 173 }; 174 175 return l; 176 } 177 178 public final boolean canOverride(MethodInstance mj) { 179 return ts.canOverride(this, mj); 180 } 181 182 public final void checkOverride(MethodInstance mj) throws SemanticException { 183 ts.checkOverride(this, mj); 184 } 185 186 190 public final boolean canOverrideImpl(MethodInstance mj) throws SemanticException { 191 throw new RuntimeException ("canOverrideImpl(MethodInstance mj) should not be called."); 192 } 193 194 200 public boolean canOverrideImpl(MethodInstance mj, boolean quiet) throws SemanticException { 201 MethodInstance mi = this; 202 203 if (!(mi.name().equals(mj.name()) && mi.hasFormals(mj.formalTypes()))) { 204 if (quiet) return false; 205 throw new SemanticException("Arguments are different", mi.position()); 206 } 207 208 if (! ts.equals(mi.returnType(), mj.returnType())) { 209 if (Report.should_report(Report.types, 3)) 210 Report.report(3, "return type " + mi.returnType() + 211 " != " + mj.returnType()); 212 if (quiet) return false; 213 throw new SemanticException(mi.signature() + " in " + mi.container() + 214 " cannot override " + 215 mj.signature() + " in " + mj.container() + 216 "; attempting to use incompatible " + 217 "return type\n" + 218 "found: " + mi.returnType() + "\n" + 219 "required: " + mj.returnType(), 220 mi.position()); 221 } 222 223 if (! ts.throwsSubset(mi, mj)) { 224 if (Report.should_report(Report.types, 3)) 225 Report.report(3, mi.throwTypes() + " not subset of " + 226 mj.throwTypes()); 227 if (quiet) return false; 228 throw new SemanticException(mi.signature() + " in " + mi.container() + 229 " cannot override " + 230 mj.signature() + " in " + mj.container() + 231 "; the throw set is not a subset of the " + 232 "overridden method's throw set", 233 mi.position()); 234 } 235 236 if (mi.flags().moreRestrictiveThan(mj.flags())) { 237 if (Report.should_report(Report.types, 3)) 238 Report.report(3, mi.flags() + " more restrictive than " + 239 mj.flags()); 240 if (quiet) return false; 241 throw new SemanticException(mi.signature() + " in " + mi.container() + 242 " cannot override " + 243 mj.signature() + " in " + mj.container() + 244 "; attempting to assign weaker " + 245 "access privileges", 246 mi.position()); 247 } 248 249 if (mi.flags().isStatic() != mj.flags().isStatic()) { 250 if (Report.should_report(Report.types, 3)) 251 Report.report(3, mi.signature() + " is " + 252 (mi.flags().isStatic() ? "" : "not") + 253 " static but " + mj.signature() + " is " + 254 (mj.flags().isStatic() ? "" : "not") + " static"); 255 if (quiet) return false; 256 throw new SemanticException(mi.signature() + " in " + mi.container() + 257 " cannot override " + 258 mj.signature() + " in " + mj.container() + 259 "; overridden method is " + 260 (mj.flags().isStatic() ? "" : "not") + 261 "static", 262 mi.position()); 263 } 264 265 if (mi != mj && !mi.equals(mj) && mj.flags().isFinal()) { 266 if (Report.should_report(Report.types, 3)) 268 Report.report(3, mj.flags() + " final"); 269 if (quiet) return false; 270 throw new SemanticException(mi.signature() + " in " + mi.container() + 271 " cannot override " + 272 mj.signature() + " in " + mj.container() + 273 "; overridden method is final", 274 mi.position()); 275 } 276 277 return true; 278 } 279 280 public List implemented() { 281 return ts.implemented(this); 282 } 283 284 public List implementedImpl(ReferenceType rt) { 285 if (rt == null) { 286 return Collections.EMPTY_LIST; 287 } 288 289 List l = new LinkedList(); 290 l.addAll(rt.methods(name, formalTypes)); 291 292 Type superType = rt.superType(); 293 if (superType != null) { 294 l.addAll(implementedImpl(superType.toReference())); 295 } 296 297 List ints = rt.interfaces(); 298 for (Iterator i = ints.iterator(); i.hasNext(); ) { 299 ReferenceType rt2 = (ReferenceType) i.next(); 300 l.addAll(implementedImpl(rt2)); 301 } 302 303 return l; 304 } 305 } 306 | Popular Tags |