001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.core.runtime.Assert;
015:
016: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType;
017: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
018: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes;
019:
020: public class SubTypesOfSingleton extends TypeSet {
021: /**
022: * The "base type" defining the upper bound of this set.
023: */
024: private final TType fUpperBound;
025:
026: protected SubTypesOfSingleton(TType t,
027: TypeSetEnvironment typeSetEnvironment) {
028: super (typeSetEnvironment);
029: Assert.isNotNull(t);
030: fUpperBound = t;
031: }
032:
033: /* (non-Javadoc)
034: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse()
035: */
036: public boolean isUniverse() {
037: return fUpperBound.equals(getJavaLangObject());
038: }
039:
040: /* (non-Javadoc)
041: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone()
042: */
043: public TypeSet makeClone() {
044: return this ; // new SubTypesOfSingleton(fUpperBound);
045: }
046:
047: /* (non-Javadoc)
048: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#subTypes()
049: */
050: public TypeSet subTypes() {
051: return this ; // makeClone();
052: }
053:
054: /* (non-Javadoc)
055: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet)
056: */
057: public TypeSet specialCasesIntersectedWith(TypeSet other) {
058: if (other.isSingleton()
059: && other.anyMember().equals(fUpperBound))
060: return other; // xsect(subTypes(A),A) = A
061:
062: if (other instanceof SubTypesOfSingleton) {
063: SubTypesOfSingleton otherSub = (SubTypesOfSingleton) other;
064:
065: if (TTypes.canAssignTo(otherSub.fUpperBound, fUpperBound))
066: return otherSub; // .makeClone();
067: if (TTypes.canAssignTo(fUpperBound, otherSub.fUpperBound))
068: return this ; // makeClone();
069: } else if (other.hasUniqueLowerBound()) {
070: TType otherLower = other.uniqueLowerBound();
071:
072: if (otherLower.equals(fUpperBound))
073: return new SingletonTypeSet(fUpperBound,
074: getTypeSetEnvironment());
075: if (otherLower != fUpperBound
076: && TTypes.canAssignTo(fUpperBound, otherLower)
077: || !TTypes.canAssignTo(otherLower, fUpperBound))
078: return getTypeSetEnvironment().getEmptyTypeSet();
079: }
080: // else if (other instanceof SubTypesSet) {
081: // SubTypesSet otherSub= (SubTypesSet) other;
082: // TypeSet otherUppers= otherSub.upperBound();
083: //
084: // for(Iterator iter= otherUppers.iterator(); iter.hasNext(); ) {
085: // TType t= (TType) iter.next();
086: //
087: // if ()
088: // }
089: // }
090: return null;
091: }
092:
093: /* (non-Javadoc)
094: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty()
095: */
096: public boolean isEmpty() {
097: return false;
098: }
099:
100: /* (non-Javadoc)
101: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound()
102: */
103: public TypeSet upperBound() {
104: return new SingletonTypeSet(fUpperBound,
105: getTypeSetEnvironment());
106: }
107:
108: /* (non-Javadoc)
109: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound()
110: */
111: public TypeSet lowerBound() {
112: EnumeratedTypeSet e = enumerate();
113: return e.lowerBound();
114: }
115:
116: /* (non-Javadoc)
117: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound()
118: */
119: public boolean hasUniqueLowerBound() {
120: // TypeSet lowerBound= lowerBound();
121:
122: // return lowerBound.isSingleton();
123: return false; // fast, though perhaps inaccurate, but that's ok
124: }
125:
126: /* (non-Javadoc)
127: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound()
128: */
129: public boolean hasUniqueUpperBound() {
130: return true;
131: }
132:
133: /* (non-Javadoc)
134: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound()
135: */
136: public TType uniqueLowerBound() {
137: TypeSet lowerBound = lowerBound();
138:
139: return lowerBound.anyMember();
140: }
141:
142: /* (non-Javadoc)
143: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound()
144: */
145: public TType uniqueUpperBound() {
146: return fUpperBound;
147: }
148:
149: /* (non-Javadoc)
150: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(org.eclipse.jdt.core.TType)
151: */
152: public boolean contains(TType t) {
153: if (t.equals(fUpperBound))
154: return true;
155: return TTypes.canAssignTo(t, fUpperBound);
156: }
157:
158: /* (non-Javadoc)
159: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet)
160: */
161: public boolean containsAll(TypeSet other) {
162: if (isUniverse())
163: return true;
164:
165: // Optimization: if other is also a SubTypeOfSingleton, just compare bounds
166: if (other instanceof SubTypesOfSingleton) {
167: SubTypesOfSingleton otherSub = (SubTypesOfSingleton) other;
168: return TTypes
169: .canAssignTo(otherSub.fUpperBound, fUpperBound);
170: }
171: // Optimization: if other is a SubTypesSet, just compare each of its bounds to mine
172: if (other instanceof SubTypesSet) {
173: SubTypesSet otherSub = (SubTypesSet) other;
174: TypeSet otherUpperBounds = otherSub.upperBound();
175:
176: for (Iterator iter = otherUpperBounds.iterator(); iter
177: .hasNext();) {
178: TType t = (TType) iter.next();
179: if (!TTypes.canAssignTo(t, fUpperBound))
180: return false;
181: }
182: return true;
183: }
184: // For now, no more tricks up my sleeve; get an iterator
185: for (Iterator iter = other.iterator(); iter.hasNext();) {
186: TType t = (TType) iter.next();
187:
188: if (!TTypes.canAssignTo(t, fUpperBound))
189: return false;
190: }
191: return true;
192: }
193:
194: /* (non-Javadoc)
195: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator()
196: */
197: public Iterator iterator() {
198: return enumerate().iterator();
199: // return new Iterator() {
200: // // First type returned is fUpperBound, then each of the subtypes, in turn
201: // //
202: // // If the upper bound is an array type, return the set of array types
203: // // { Array(subType(elementTypeOf(fUpperBound))) }
204: // private Set/*<TType>*/ subTypes= sTypeHierarchy.getAllSubtypes(getElementTypeOf(fUpperBound));
205: // private Iterator/*<TType>*/ subTypeIter= subTypes.iterator();
206: // private int nDims= getDimsOf(fUpperBound);
207: // private int idx=-1;
208: // public void remove() { /*do nothing*/}
209: // public boolean hasNext() { return idx < subTypes.size(); }
210: // public Object next() {
211: // int i=idx++;
212: // if (i < 0) return fUpperBound;
213: // return makePossiblyArrayTypeFor((TType) subTypeIter.next(), nDims);
214: // }
215: // };
216: }
217:
218: /**
219: * Returns the element type of the given TType, if an array type, or the
220: * given TType itself, otherwise.
221: */
222: private TType getElementTypeOf(TType t) {
223: if (t instanceof ArrayType)
224: return ((ArrayType) t).getElementType();
225: return t;
226: }
227:
228: /* (non-Javadoc)
229: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton()
230: */
231: public boolean isSingleton() {
232: return getElementTypeOf(fUpperBound).getSubTypes().length == 0;
233: }
234:
235: /* (non-Javadoc)
236: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember()
237: */
238: public TType anyMember() {
239: return fUpperBound;
240: }
241:
242: private EnumeratedTypeSet fEnumCache = null;
243:
244: /* (non-Javadoc)
245: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate()
246: */
247: public EnumeratedTypeSet enumerate() {
248: if (fEnumCache == null) {
249: if (fUpperBound instanceof ArrayType) {
250: ArrayType at = (ArrayType) fUpperBound;
251: fEnumCache = EnumeratedTypeSet
252: .makeArrayTypesForElements(TTypes
253: .getAllSubTypesIterator(at
254: .getComponentType()),
255: getTypeSetEnvironment());
256: } else
257: fEnumCache = new EnumeratedTypeSet(TTypes
258: .getAllSubTypesIterator(fUpperBound),
259: getTypeSetEnvironment());
260:
261: fEnumCache.add(fUpperBound);
262: fEnumCache.initComplete();
263: }
264: return fEnumCache;
265: }
266:
267: public boolean equals(Object o) {
268: if (!(o instanceof SubTypesOfSingleton))
269: return false;
270: SubTypesOfSingleton other = (SubTypesOfSingleton) o;
271:
272: return other.fUpperBound.equals(fUpperBound);
273: }
274:
275: public String toString() {
276: return "<" + fID + ": subTypes(" + fUpperBound.getPrettySignature() + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
277: }
278: }
|