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.TType;
015: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet;
016:
017: public abstract class TypeSet implements ITypeSet {
018:
019: public TType chooseSingleType() {
020: return null;
021: }
022:
023: public ITypeSet restrictedTo(ITypeSet restrictionSet) {
024: throw new UnsupportedOperationException();
025: }
026:
027: protected TType getJavaLangObject() {
028: return fTypeSetEnvironment.getJavaLangObject();
029: }
030:
031: protected TypeSetEnvironment getTypeSetEnvironment() {
032: return fTypeSetEnvironment;
033: }
034:
035: static private int sID = 0;
036:
037: static public int getCount() {
038: return sID;
039: }
040:
041: static public void resetCount() {
042: sID = 0;
043: }
044:
045: /**
046: * An ID unique to this EnumeratedTypeSet instance, to aid in debugging the sharing
047: * of TypeSets across ConstraintVariables in a TypeEstimateEnvironment.
048: */
049: protected final int fID;
050: private final TypeSetEnvironment fTypeSetEnvironment;
051:
052: protected TypeSet(TypeSetEnvironment typeSetEnvironment) {
053: fTypeSetEnvironment = typeSetEnvironment;
054: fID = sID++;
055: }
056:
057: /**
058: * @return <code>true</code> iff this set represents the universe of TTypes
059: */
060: abstract public boolean isUniverse();
061:
062: abstract public TypeSet makeClone();
063:
064: protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
065: return null;
066: }
067:
068: /**
069: * Computes and returns a <em>new</em> TypeSet representing the intersection of the
070: * receiver with s2. Does not modify the receiver or argument sets.
071: * @param s2
072: * @return the new TypeSet
073: */
074: public TypeSet intersectedWith(TypeSet s2) {
075: if (s2.isUniverse())
076: return makeClone();
077: else if (isUniverse())
078: return s2.makeClone();
079: else if (isEmpty() || s2.isEmpty())
080: return getTypeSetEnvironment().getEmptyTypeSet();
081: else if (isSingleton()) {
082: if (s2.contains(anyMember()))
083: return makeClone();
084: else
085: return getTypeSetEnvironment().getEmptyTypeSet();
086: } else if (s2.isSingleton()) {
087: if (contains(s2.anyMember()))
088: return s2.makeClone();
089: else
090: return getTypeSetEnvironment().getEmptyTypeSet();
091: } else if (s2 instanceof TypeSetIntersection) {
092: TypeSetIntersection x = (TypeSetIntersection) s2;
093: // xsect(A,xsect(A,B)) = xsect(A,B) and
094: // xsect(B,xsect(A,B)) = xsect(A,B)
095: if (x.getLHS().equals(this ) || x.getRHS().equals(this ))
096: return x;
097: }
098:
099: TypeSet result = specialCasesIntersectedWith(s2);
100:
101: if (result != null)
102: return result;
103: else
104: return new TypeSetIntersection(this , s2);
105: }
106:
107: /**
108: * Returns the TypeSet resulting from union'ing the receiver with the argument.
109: * Does not modify the receiver or the argument sets.
110: */
111: public TypeSet addedTo(TypeSet that) {
112: if (isUniverse() || that.isUniverse())
113: return getTypeSetEnvironment().getUniverseTypeSet();
114: if ((this instanceof EnumeratedTypeSet || this instanceof SingletonTypeSet)
115: && (that instanceof EnumeratedTypeSet || that instanceof SingletonTypeSet)) {
116: EnumeratedTypeSet result = enumerate();
117:
118: result.addAll(that);
119: return result;
120: }
121: return new TypeSetUnion(this , that);
122: }
123:
124: /**
125: * Returns a new TypeSet representing the set of all sub-types of the
126: * types in the receiver.
127: */
128: public TypeSet subTypes() {
129: if (isUniverse() || contains(getJavaLangObject()))
130: return getTypeSetEnvironment().getUniverseTypeSet();
131:
132: if (isSingleton())
133: return possiblyArraySubTypeSetFor(anyMember());
134:
135: return getTypeSetEnvironment().createSubTypesSet(this );
136: }
137:
138: private TypeSet possiblyArraySubTypeSetFor(TType t) {
139: // In Java, subTypes(x[]) == (subTypes(x))[]
140: // if (t.isArrayType()) {
141: // ArrayType at= (ArrayType) t;
142: //
143: // return new ArrayTypeSet(possiblyArraySubTypeSetFor(at.getArrayElementType()));
144: // } else
145:
146: return getTypeSetEnvironment().createSubTypesOfSingleton(t);
147: }
148:
149: private TypeSet possiblyArraySuperTypeSetFor(TType t) {
150: // In Java, superTypes(x[]) == (superTypes(x))[] union {Object}
151: // if (t.isArrayType()) {
152: // ArrayType at= (ArrayType) t;
153: //
154: // return new ArraySuperTypeSet(possiblyArraySuperTypeSetFor(at.getArrayElementType()));
155: // } else
156: return getTypeSetEnvironment().createSuperTypesOfSingleton(t);
157: }
158:
159: /**
160: * Returns a new TypeSet representing the set of all super-types of the
161: * types in the receiver.
162: */
163: public TypeSet super Types() {
164: if (isUniverse())
165: return getTypeSetEnvironment().getUniverseTypeSet();
166:
167: if (isSingleton())
168: return possiblyArraySuperTypeSetFor(anyMember());
169:
170: return getTypeSetEnvironment().createSuperTypesSet(this );
171: }
172:
173: /**
174: * Return true iff the type set contains no types.
175: */
176: abstract public boolean isEmpty();
177:
178: /**
179: * Returns the types in the upper bound of this set.
180: */
181: abstract public TypeSet upperBound();
182:
183: /**
184: * Returns the types in the lower bound of this set.
185: */
186: abstract public TypeSet lowerBound();
187:
188: /**
189: * Returns true iff this TypeSet has a unique lower bound.
190: */
191: abstract public boolean hasUniqueLowerBound();
192:
193: /**
194: * Returns true iff this TypeSet has a unique upper bound other than
195: * java.lang.Object.
196: */
197: abstract public boolean hasUniqueUpperBound();
198:
199: /**
200: * Returns the unique lower bound of this set of types, if it has one,
201: * or null otherwise.
202: */
203: abstract public TType uniqueLowerBound();
204:
205: /**
206: * Returns the unique upper bound of this set of types, if it has one,
207: * or null otherwise.
208: */
209: abstract public TType uniqueUpperBound();
210:
211: /**
212: * Returns true iff the type set contains the given type.
213: */
214: abstract public boolean contains(TType t);
215:
216: /**
217: * Returns true iff the type set contains all of the types in the given TypeSet.
218: */
219: abstract public boolean containsAll(TypeSet s);
220:
221: /**
222: * Returns an iterator over the types in the receiver.
223: */
224: abstract public Iterator iterator();
225:
226: /**
227: * Returns a new TypeSet enumerating the receiver's contents.
228: */
229: abstract public EnumeratedTypeSet enumerate();
230:
231: /**
232: * Returns true iff the given set has precisely one element
233: */
234: abstract public boolean isSingleton();
235:
236: /**
237: * Returns an arbitrary member of the given Typeset.
238: */
239: abstract public TType anyMember();
240: }
|