]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * Robert M. Fuhrer (rfuhrer@watson.ibm.com), IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets; | |
12 | ||
13 | import java.util.Iterator; | |
14 | ||
15 | import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType; | |
16 | import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; | |
17 | import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes; | |
18 | ||
19 | public class SuperTypesSet extends TypeSet { | |
20 | private TypeSet fLowerBounds; | |
21 | ||
22 | SuperTypesSet(TType subType, TypeSetEnvironment typeSetEnvironment) { | |
23 | super(typeSetEnvironment); | |
24 | fLowerBounds= new SingletonTypeSet(subType, typeSetEnvironment); | |
25 | } | |
26 | ||
27 | SuperTypesSet(TypeSet subTypes, TypeSetEnvironment typeSetEnvironment) { | |
28 | super(typeSetEnvironment); | |
29 | fLowerBounds= subTypes; | |
30 | } | |
31 | ||
32 | /* (non-Javadoc) | |
33 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse() | |
34 | */ | |
35 | @Override | |
36 | public boolean isUniverse() { | |
37 | return fLowerBounds.isUniverse(); | |
38 | } | |
39 | ||
40 | /* (non-Javadoc) | |
41 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone() | |
42 | */ | |
43 | @Override | |
44 | public TypeSet makeClone() { | |
45 | return this; //new SuperTypesSet(fLowerBounds.makeClone(), getTypeSetEnvironment()); | |
46 | } | |
47 | ||
48 | /* (non-Javadoc) | |
49 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound() | |
50 | */ | |
51 | @Override | |
52 | public TypeSet upperBound() { | |
53 | return new SingletonTypeSet(getTypeSetEnvironment().getJavaLangObject(), getTypeSetEnvironment()); | |
54 | } | |
55 | ||
56 | /* (non-Javadoc) | |
57 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound() | |
58 | */ | |
59 | @Override | |
60 | public TypeSet lowerBound() { | |
61 | // Ask the operand for its lower-bound, in case it's something like an | |
62 | // EnumeratedTypeSet, which may have things in it other than the lower | |
63 | // bound... | |
64 | return fLowerBounds.lowerBound(); | |
65 | } | |
66 | ||
67 | /* (non-Javadoc) | |
68 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet) | |
69 | */ | |
70 | @Override | |
71 | protected TypeSet specialCasesIntersectedWith(TypeSet s2) { | |
72 | if (fLowerBounds.equals(s2)) | |
73 | return s2; // xsect(superTypes(A),A) = A | |
74 | if (s2 instanceof SuperTypesSet) { | |
75 | SuperTypesSet st2= (SuperTypesSet) s2; | |
76 | ||
77 | if (fLowerBounds.isSingleton() && st2.fLowerBounds.isSingleton()) { | |
78 | TType t1= this.fLowerBounds.anyMember(); | |
79 | TType t2= st2.fLowerBounds.anyMember(); | |
80 | ||
81 | if (TTypes.canAssignTo(t1, t2)) | |
82 | return new SuperTypesSet(st2.fLowerBounds, getTypeSetEnvironment()); | |
83 | } else if (fLowerBounds instanceof SubTypesSet) { | |
84 | // xsect(superTypes(subTypes(A)), superTypes(A)) = superTypes(A) | |
85 | SubTypesSet myLowerSubTypes= (SubTypesSet) fLowerBounds; | |
86 | ||
87 | if (myLowerSubTypes.upperBound().equals(st2.upperBound())) | |
88 | return st2; | |
89 | } | |
90 | } | |
91 | if (s2 instanceof SuperTypesOfSingleton) { | |
92 | SuperTypesOfSingleton st2= (SuperTypesOfSingleton) s2; | |
93 | ||
94 | if (fLowerBounds.isSingleton()) { | |
95 | TType t1= this.fLowerBounds.anyMember(); | |
96 | TType t2= st2.uniqueLowerBound(); | |
97 | ||
98 | if (TTypes.canAssignTo(t1, t2)) | |
99 | return getTypeSetEnvironment().createSuperTypesOfSingleton(t2); | |
100 | } else if (fLowerBounds instanceof SubTypesOfSingleton) { | |
101 | // xsect(superTypes(subTypes(A)), superTypes(A)) = superTypes(A) | |
102 | SubTypesOfSingleton myLowerSubTypes= (SubTypesOfSingleton) fLowerBounds; | |
103 | ||
104 | if (myLowerSubTypes.uniqueUpperBound().equals(st2.uniqueUpperBound())) | |
105 | return st2; | |
106 | } | |
107 | } | |
108 | if (s2 instanceof SubTypesSet) { | |
109 | SubTypesSet st2= (SubTypesSet) s2; | |
110 | if (fLowerBounds.equals(st2.upperBound())) | |
111 | return fLowerBounds; | |
112 | ||
113 | if (fLowerBounds instanceof TypeSetIntersection) { | |
114 | // (intersect (superTypes (intersect (subTypes A) B)) | |
115 | // (subTypes A)) => | |
116 | // (intersect (subTypes A) (superTypes B)) | |
117 | TypeSetIntersection lbXSect= (TypeSetIntersection) fLowerBounds; | |
118 | TypeSet xsectLeft= lbXSect.getLHS(); | |
119 | TypeSet xsectRight= lbXSect.getRHS(); | |
120 | ||
121 | if (xsectLeft.equals(st2.upperBound())) | |
122 | return new TypeSetIntersection(s2, new SuperTypesSet(xsectRight, getTypeSetEnvironment())); | |
123 | } | |
124 | } | |
125 | return null; | |
126 | } | |
127 | ||
128 | /* (non-Javadoc) | |
129 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes() | |
130 | */ | |
131 | @Override | |
132 | public TypeSet superTypes() { | |
133 | return this; // makeClone(); | |
134 | } | |
135 | ||
136 | /* (non-Javadoc) | |
137 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty() | |
138 | */ | |
139 | @Override | |
140 | public boolean isEmpty() { | |
141 | return fLowerBounds.isEmpty(); | |
142 | } | |
143 | ||
144 | /* (non-Javadoc) | |
145 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType) | |
146 | */ | |
147 | @Override | |
148 | public boolean contains(TType t) { | |
149 | if (fEnumCache != null) return fEnumCache.contains(t); | |
150 | ||
151 | if (t.equals(getJavaLangObject())) | |
152 | return true; | |
153 | if (fLowerBounds.contains(t)) | |
154 | return true; | |
155 | ||
156 | // Find the "lower frontier", i.e. the lower bound, and see whether | |
157 | // the given type is a supertype of any of those. | |
158 | for(Iterator<TType> lbIter= fLowerBounds /*.lowerBound() */.iterator(); lbIter.hasNext(); ) { | |
159 | TType lb= lbIter.next(); | |
160 | ||
161 | if (TTypes.canAssignTo(lb, t)) | |
162 | return true; | |
163 | } | |
164 | return false; | |
165 | } | |
166 | ||
167 | /* (non-Javadoc) | |
168 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet) | |
169 | */ | |
170 | @Override | |
171 | public boolean containsAll(TypeSet s) { | |
172 | if (fEnumCache != null) return fEnumCache.containsAll(s); | |
173 | ||
174 | if (!isUniverse() && s.isUniverse()) // this is more general than just SuperTypesSet; probably belongs in TypeSet | |
175 | return false; | |
176 | if (equals(s)) | |
177 | return true; | |
178 | if (fLowerBounds.containsAll(s)) | |
179 | return true; | |
180 | ||
181 | // Make sure all elements of s are contained in this set | |
182 | for(Iterator<TType> sIter= s.iterator(); sIter.hasNext(); ) { | |
183 | TType t= sIter.next(); | |
184 | boolean found= false; | |
185 | ||
186 | // Scan the "lower frontier", i.e. the lower bound set, and see whether | |
187 | // 't' is a supertype of any of those. | |
188 | for(Iterator<TType> lbIter= fLowerBounds /*.lowerBound()*/.iterator(); lbIter.hasNext(); ) { | |
189 | TType lb= lbIter.next(); | |
190 | ||
191 | if (TTypes.canAssignTo(lb, t)) { | |
192 | found= true; | |
193 | break; | |
194 | } | |
195 | } | |
196 | if (!found) return false; | |
197 | } | |
198 | return true; | |
199 | } | |
200 | ||
201 | /* (non-Javadoc) | |
202 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton() | |
203 | */ | |
204 | @Override | |
205 | public boolean isSingleton() { | |
206 | if (fEnumCache != null) return fEnumCache.isSingleton(); | |
207 | ||
208 | return fLowerBounds.isSingleton() && (fLowerBounds.anyMember() == getJavaLangObject()); | |
209 | } | |
210 | ||
211 | /* (non-Javadoc) | |
212 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember() | |
213 | */ | |
214 | @Override | |
215 | public TType anyMember() { | |
216 | return fLowerBounds.anyMember(); | |
217 | } | |
218 | ||
219 | /* (non-Javadoc) | |
220 | * @see java.lang.Object#equals(java.lang.Object) | |
221 | */ | |
222 | @Override | |
223 | public boolean equals(Object o) { | |
224 | if (o instanceof SuperTypesSet) { | |
225 | SuperTypesSet other= (SuperTypesSet) o; | |
226 | return other.fLowerBounds.equals(fLowerBounds); | |
227 | // } else if (o instanceof TypeSet) { | |
228 | // TypeSet other= (TypeSet) o; | |
229 | // if (other.isUniverse() && isUniverse()) | |
230 | // return true; | |
231 | // return enumerate().equals(other.enumerate()); | |
232 | } else | |
233 | return false; | |
234 | } | |
235 | ||
236 | @Override | |
237 | public int hashCode() { | |
238 | return fLowerBounds.hashCode(); | |
239 | } | |
240 | ||
241 | /* (non-Javadoc) | |
242 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator() | |
243 | */ | |
244 | @Override | |
245 | public Iterator<TType> iterator() { | |
246 | return enumerate().iterator(); | |
247 | } | |
248 | ||
249 | @Override | |
250 | public String toString() { | |
251 | return "<" + fID + ": superTypes(" + fLowerBounds + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
252 | } | |
253 | ||
254 | /* (non-Javadoc) | |
255 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound() | |
256 | */ | |
257 | @Override | |
258 | public boolean hasUniqueLowerBound() { | |
259 | return fLowerBounds.isSingleton(); | |
260 | } | |
261 | ||
262 | /* (non-Javadoc) | |
263 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound() | |
264 | */ | |
265 | @Override | |
266 | public boolean hasUniqueUpperBound() { | |
267 | return false; | |
268 | } | |
269 | ||
270 | /* (non-Javadoc) | |
271 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound() | |
272 | */ | |
273 | @Override | |
274 | public TType uniqueLowerBound() { | |
275 | return fLowerBounds.isSingleton() ? fLowerBounds.anyMember() : null; | |
276 | } | |
277 | ||
278 | /* (non-Javadoc) | |
279 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound() | |
280 | */ | |
281 | @Override | |
282 | public TType uniqueUpperBound() { | |
283 | return null; | |
284 | } | |
285 | ||
286 | private EnumeratedTypeSet fEnumCache= null; | |
287 | ||
288 | /* (non-Javadoc) | |
289 | * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate() | |
290 | */ | |
291 | @Override | |
292 | public EnumeratedTypeSet enumerate() { | |
293 | if (fEnumCache == null) { | |
294 | fEnumCache= new EnumeratedTypeSet(getTypeSetEnvironment()); | |
295 | boolean anyLBIsIntfOrArray= false; | |
296 | ||
297 | for(Iterator<TType> iter= fLowerBounds.iterator(); iter.hasNext(); ) { | |
298 | TType lb= iter.next(); | |
299 | ||
300 | if (lb instanceof ArrayType) { | |
301 | ArrayType at= (ArrayType) lb; | |
302 | int numDims= at.getDimensions(); | |
303 | for(Iterator<TType> elemSuperIter=TTypes.getAllSuperTypesIterator(at.getElementType()); elemSuperIter.hasNext(); ) | |
304 | fEnumCache.add(TTypes.createArrayType(elemSuperIter.next(), numDims)); | |
305 | anyLBIsIntfOrArray= true; | |
306 | } else { | |
307 | for (Iterator<TType> iterator= TTypes.getAllSuperTypesIterator(lb); iterator.hasNext(); ) | |
308 | fEnumCache.fMembers.add(iterator.next()); | |
309 | } | |
310 | fEnumCache.add(lb); | |
311 | } | |
312 | if (anyLBIsIntfOrArray) fEnumCache.add(getJavaLangObject()); | |
313 | //fEnumCache.initComplete(); | |
314 | } | |
315 | return fEnumCache; | |
316 | } | |
317 | } |