001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Robert M. Fuhrer (rfuhrer@watson.ibm.com), IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets;
011:
012: import java.util.Iterator;
013:
014: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType;
015: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
016: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes;
017:
018: public class SuperTypesSet extends TypeSet {
019: private TypeSet fLowerBounds;
020:
021: SuperTypesSet(TType subType, TypeSetEnvironment typeSetEnvironment) {
022: super (typeSetEnvironment);
023: fLowerBounds = new SingletonTypeSet(subType, typeSetEnvironment);
024: }
025:
026: SuperTypesSet(TypeSet subTypes,
027: TypeSetEnvironment typeSetEnvironment) {
028: super (typeSetEnvironment);
029: fLowerBounds = subTypes;
030: }
031:
032: /* (non-Javadoc)
033: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse()
034: */
035: public boolean isUniverse() {
036: return fLowerBounds.isUniverse();
037: }
038:
039: /* (non-Javadoc)
040: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone()
041: */
042: public TypeSet makeClone() {
043: return this ; //new SuperTypesSet(fLowerBounds.makeClone(), getTypeSetEnvironment());
044: }
045:
046: /* (non-Javadoc)
047: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound()
048: */
049: public TypeSet upperBound() {
050: return new SingletonTypeSet(getTypeSetEnvironment()
051: .getJavaLangObject(), getTypeSetEnvironment());
052: }
053:
054: /* (non-Javadoc)
055: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound()
056: */
057: public TypeSet lowerBound() {
058: // Ask the operand for its lower-bound, in case it's something like an
059: // EnumeratedTypeSet, which may have things in it other than the lower
060: // bound...
061: return fLowerBounds.lowerBound();
062: }
063:
064: /* (non-Javadoc)
065: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet)
066: */
067: protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
068: if (fLowerBounds.equals(s2))
069: return s2; // xsect(superTypes(A),A) = A
070: if (s2 instanceof SuperTypesSet) {
071: SuperTypesSet st2 = (SuperTypesSet) s2;
072:
073: if (fLowerBounds.isSingleton()
074: && st2.fLowerBounds.isSingleton()) {
075: TType t1 = this .fLowerBounds.anyMember();
076: TType t2 = st2.fLowerBounds.anyMember();
077:
078: if (TTypes.canAssignTo(t1, t2))
079: return new SuperTypesSet(st2.fLowerBounds,
080: getTypeSetEnvironment());
081: } else if (fLowerBounds instanceof SubTypesSet) {
082: // xsect(superTypes(subTypes(A)), superTypes(A)) = superTypes(A)
083: SubTypesSet myLowerSubTypes = (SubTypesSet) fLowerBounds;
084:
085: if (myLowerSubTypes.upperBound().equals(
086: st2.upperBound()))
087: return st2;
088: }
089: }
090: if (s2 instanceof SuperTypesOfSingleton) {
091: SuperTypesOfSingleton st2 = (SuperTypesOfSingleton) s2;
092:
093: if (fLowerBounds.isSingleton()) {
094: TType t1 = this .fLowerBounds.anyMember();
095: TType t2 = st2.uniqueLowerBound();
096:
097: if (TTypes.canAssignTo(t1, t2))
098: return getTypeSetEnvironment()
099: .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(
105: st2.uniqueUpperBound()))
106: return st2;
107: }
108: }
109: if (s2 instanceof SubTypesSet) {
110: SubTypesSet st2 = (SubTypesSet) s2;
111: if (fLowerBounds.equals(st2.upperBound()))
112: return fLowerBounds;
113:
114: if (fLowerBounds instanceof TypeSetIntersection) {
115: // (intersect (superTypes (intersect (subTypes A) B))
116: // (subTypes A)) =>
117: // (intersect (subTypes A) (superTypes B))
118: TypeSetIntersection lbXSect = (TypeSetIntersection) fLowerBounds;
119: TypeSet xsectLeft = lbXSect.getLHS();
120: TypeSet xsectRight = lbXSect.getRHS();
121:
122: if (xsectLeft.equals(st2.upperBound()))
123: return new TypeSetIntersection(s2,
124: new SuperTypesSet(xsectRight,
125: getTypeSetEnvironment()));
126: }
127: }
128: return null;
129: }
130:
131: /* (non-Javadoc)
132: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes()
133: */
134: public TypeSet super Types() {
135: return this ; // makeClone();
136: }
137:
138: /* (non-Javadoc)
139: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty()
140: */
141: public boolean isEmpty() {
142: return fLowerBounds.isEmpty();
143: }
144:
145: /* (non-Javadoc)
146: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType)
147: */
148: public boolean contains(TType t) {
149: if (fEnumCache != null)
150: return fEnumCache.contains(t);
151:
152: if (t.equals(getJavaLangObject()))
153: return true;
154: if (fLowerBounds.contains(t))
155: return true;
156:
157: // Find the "lower frontier", i.e. the lower bound, and see whether
158: // the given type is a supertype of any of those.
159: for (Iterator lbIter = fLowerBounds
160: /*.lowerBound() */.iterator(); lbIter.hasNext();) {
161: TType lb = (TType) lbIter.next();
162:
163: if (TTypes.canAssignTo(lb, t))
164: return true;
165: }
166: return false;
167: }
168:
169: /* (non-Javadoc)
170: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.EnumeratedTypeSet)
171: */
172: public boolean containsAll(TypeSet s) {
173: if (fEnumCache != null)
174: return fEnumCache.containsAll(s);
175:
176: if (!isUniverse() && s.isUniverse()) // this is more general than just SuperTypesSet; probably belongs in TypeSet
177: return false;
178: if (equals(s))
179: return true;
180: if (fLowerBounds.containsAll(s))
181: return true;
182:
183: // Make sure all elements of s are contained in this set
184: for (Iterator sIter = s.iterator(); sIter.hasNext();) {
185: TType t = (TType) sIter.next();
186: boolean found = false;
187:
188: // Scan the "lower frontier", i.e. the lower bound set, and see whether
189: // 't' is a supertype of any of those.
190: for (Iterator lbIter = fLowerBounds
191: /*.lowerBound()*/.iterator(); lbIter.hasNext();) {
192: TType lb = (TType) lbIter.next();
193:
194: if (TTypes.canAssignTo(lb, t)) {
195: found = true;
196: break;
197: }
198: }
199: if (!found)
200: return false;
201: }
202: return true;
203: }
204:
205: /* (non-Javadoc)
206: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton()
207: */
208: public boolean isSingleton() {
209: if (fEnumCache != null)
210: return fEnumCache.isSingleton();
211:
212: return fLowerBounds.isSingleton()
213: && (fLowerBounds.anyMember() == getJavaLangObject());
214: }
215:
216: /* (non-Javadoc)
217: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember()
218: */
219: public TType anyMember() {
220: return fLowerBounds.anyMember();
221: }
222:
223: /* (non-Javadoc)
224: * @see java.lang.Object#equals(java.lang.Object)
225: */
226: public boolean equals(Object o) {
227: if (o instanceof SuperTypesSet) {
228: SuperTypesSet other = (SuperTypesSet) o;
229: return other.fLowerBounds.equals(fLowerBounds);
230: // } else if (o instanceof TypeSet) {
231: // TypeSet other= (TypeSet) o;
232: // if (other.isUniverse() && isUniverse())
233: // return true;
234: // return enumerate().equals(other.enumerate());
235: } else
236: return false;
237: }
238:
239: /* (non-Javadoc)
240: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator()
241: */
242: public Iterator iterator() {
243: return enumerate().iterator();
244: }
245:
246: public String toString() {
247: return "<" + fID + ": superTypes(" + fLowerBounds + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
248: }
249:
250: /* (non-Javadoc)
251: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound()
252: */
253: public boolean hasUniqueLowerBound() {
254: return fLowerBounds.isSingleton();
255: }
256:
257: /* (non-Javadoc)
258: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound()
259: */
260: public boolean hasUniqueUpperBound() {
261: return false;
262: }
263:
264: /* (non-Javadoc)
265: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound()
266: */
267: public TType uniqueLowerBound() {
268: return fLowerBounds.isSingleton() ? fLowerBounds.anyMember()
269: : null;
270: }
271:
272: /* (non-Javadoc)
273: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound()
274: */
275: public TType uniqueUpperBound() {
276: return null;
277: }
278:
279: private EnumeratedTypeSet fEnumCache = null;
280:
281: /* (non-Javadoc)
282: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate()
283: */
284: public EnumeratedTypeSet enumerate() {
285: if (fEnumCache == null) {
286: fEnumCache = new EnumeratedTypeSet(getTypeSetEnvironment());
287: boolean anyLBIsIntfOrArray = false;
288:
289: for (Iterator iter = fLowerBounds.iterator(); iter
290: .hasNext();) {
291: TType lb = (TType) iter.next();
292:
293: if (lb instanceof ArrayType) {
294: ArrayType at = (ArrayType) lb;
295: int numDims = at.getDimensions();
296: for (Iterator elemSuperIter = TTypes
297: .getAllSuperTypesIterator(at
298: .getElementType()); elemSuperIter
299: .hasNext();)
300: fEnumCache.add(TTypes.createArrayType(
301: (TType) elemSuperIter.next(), numDims));
302: anyLBIsIntfOrArray = true;
303: } else {
304: for (Iterator iterator = TTypes
305: .getAllSuperTypesIterator(lb); iterator
306: .hasNext();)
307: fEnumCache.fMembers.add(iterator.next());
308: }
309: fEnumCache.add(lb);
310: }
311: if (anyLBIsIntfOrArray)
312: fEnumCache.add(getJavaLangObject());
313: //fEnumCache.initComplete();
314: }
315: return fEnumCache;
316: }
317: }
|