KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > ext > jl > types > MethodInstance_c


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 /**
9  * A <code>MethodInstance</code> represents the type information for a Java
10  * method.
11  */

12 public class MethodInstance_c extends ProcedureInstance_c
13                                 implements MethodInstance
14 {
15     protected String JavaDoc name;
16     protected Type returnType;
17
18     /** Used for deserializing types. */
19     protected MethodInstance_c() { }
20
21     public MethodInstance_c(TypeSystem ts, Position pos,
22                 ReferenceType container,
23                         Flags flags, Type returnType, String JavaDoc 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 JavaDoc name() {
40         return name;
41     }
42
43     public MethodInstance name(String JavaDoc 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 container.hashCode() + flags.hashCode() +
95
// returnType.hashCode() + name.hashCode();
96
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 JavaDoc toString() {
111     String JavaDoc 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 JavaDoc signature() {
122         return name + "(" + TypeSystem_c.listToString(formalTypes) + ")";
123     }
124
125     public String JavaDoc designator() {
126         return "method";
127     }
128
129     /** Returns true iff <this> is the same method as <m> */
130     public final boolean isSameMethod(MethodInstance m) {
131         return ts.isSameMethod(this, m);
132     }
133
134     /** Returns true iff <this> is the same method as <m> */
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 JavaDoc name, List argTypes) {
147         return ts.methodCallValid(this, name, argTypes);
148     }
149
150     public boolean methodCallValidImpl(String JavaDoc 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             // add any method with the same name and formalTypes from
164
// rt
165
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     /**
187      * Leave this method in for historic reasons, to make sure that extensions
188      * modify their code correctly.
189      */

190     public final boolean canOverrideImpl(MethodInstance mj) throws SemanticException {
191         throw new RuntimeException JavaDoc("canOverrideImpl(MethodInstance mj) should not be called.");
192     }
193         
194     /**
195      * @param quiet If true, then no Semantic Exceptions will be thrown, and the
196      * return value will be true or false. Otherwise, if the method
197      * cannot override, then a SemanticException will be thrown, else
198      * the method will return true.
199      */

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         // mi can "override" a final method mj if mi and mj are the same method instance.
267
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