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.TTypes;
016:
017: public class TypeSetIntersection extends TypeSet {
018: private TypeSet fLHS;
019: private TypeSet fRHS;
020:
021: public TypeSetIntersection(TypeSet lhs, TypeSet rhs) {
022: super (lhs.getTypeSetEnvironment());
023: fLHS = lhs;
024: fRHS = rhs;
025: }
026:
027: /**
028: * @return Returns the LHS.
029: */
030: public TypeSet getLHS() {
031: return fLHS;
032: }
033:
034: /**
035: * @return Returns the RHS.
036: */
037: public TypeSet getRHS() {
038: return fRHS;
039: }
040:
041: /* (non-Javadoc)
042: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse()
043: */
044: public boolean isUniverse() {
045: return fLHS.isUniverse() && fRHS.isUniverse();
046: }
047:
048: /* (non-Javadoc)
049: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone()
050: */
051: public TypeSet makeClone() {
052: return this ; //new TypeSetIntersection(fLHS.makeClone(), fRHS.makeClone());
053: }
054:
055: /* (non-Javadoc)
056: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty()
057: */
058: public boolean isEmpty() {
059: if (fLHS.isEmpty() || fRHS.isEmpty())
060: return true;
061: if (fLHS.isUniverse() || fRHS.isUniverse())
062: return false;
063: // Another quick check we can make before jumping to the expensive stuff
064: if (fLHS.contains(getJavaLangObject())
065: && fRHS.contains(getJavaLangObject()))
066: return false;
067:
068: // TypeSet lhsLB= fLHS.lowerBound();
069: // TypeSet rhsUB= fRHS.upperBound();
070: //
071: // // Avoid the infinite recursion that will occur if lhsLB == fLHS && rhsUB == fRHS
072: // if ((!lhsLB.equals(fLHS) || !rhsUB.equals(fRHS)) &&
073: // !lhsLB.intersectedWith(rhsUB).isEmpty())
074: // return false;
075: //
076: // if (areAllSuperTypesOf(lhsLB, rhsUB))
077: // return true;
078: //
079: // TypeSet lhsUB= fLHS.upperBound();
080: // TypeSet rhsLB= fRHS.lowerBound();
081: //
082: // if (!lhsUB.intersectedWith(rhsLB).isEmpty())
083: // return false;
084: //
085: // if (areAllSuperTypesOf(rhsLB, lhsUB))
086: // return true;
087:
088: return false;
089: }
090:
091: /* (non-Javadoc)
092: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType)
093: */
094: public boolean contains(TType t) {
095: return fLHS.contains(t) && fRHS.contains(t);
096: }
097:
098: /* (non-Javadoc)
099: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet)
100: */
101: public boolean containsAll(TypeSet s) {
102: return fLHS.containsAll(s) && fRHS.containsAll(s);
103: }
104:
105: /* (non-Javadoc)
106: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#subTypes()
107: */
108: public TypeSet subTypes() {
109: if (isUniverse() || contains(getJavaLangObject()))
110: return getTypeSetEnvironment().getUniverseTypeSet();
111: // sub(xsect(sub(a),sub(b))) == xsect(sub(a),sub(b))
112: if ((fLHS instanceof SubTypesSet || fLHS instanceof SubTypesOfSingleton)
113: && (fRHS instanceof SubTypesSet || fRHS instanceof SubTypesOfSingleton))
114: return this ;
115: return getTypeSetEnvironment().createSubTypesSet(this );
116: }
117:
118: /* (non-Javadoc)
119: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes()
120: */
121: public TypeSet super Types() {
122: // super(xsect(super(a),super(b))) == xsect(super(a),super(b))
123: if ((fLHS instanceof SuperTypesSet || fLHS instanceof SuperTypesOfSingleton)
124: && (fRHS instanceof SuperTypesSet || fRHS instanceof SuperTypesOfSingleton))
125: return this ;
126: return getTypeSetEnvironment().createSuperTypesSet(this );
127: }
128:
129: /* (non-Javadoc)
130: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound()
131: */
132: public TypeSet upperBound() {
133: if (fLHS.contains(getJavaLangObject())
134: && fRHS.contains(getJavaLangObject()))
135: return new SingletonTypeSet(getTypeSetEnvironment()
136: .getJavaLangObject(), getTypeSetEnvironment());
137:
138: if (fEnumCache != null)
139: return fEnumCache.upperBound();
140:
141: EnumeratedTypeSet lhsSet = fLHS.enumerate();
142: EnumeratedTypeSet rhsSet = fRHS.enumerate();
143: TypeSet xsect = lhsSet.intersectedWith(rhsSet);
144:
145: return xsect.upperBound();
146: }
147:
148: /* (non-Javadoc)
149: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound()
150: */
151: public TypeSet lowerBound() {
152: if (fLHS.hasUniqueLowerBound() && fRHS.hasUniqueLowerBound()) {
153: TType lhsBound = fLHS.uniqueLowerBound();
154: TType rhsBound = fRHS.uniqueLowerBound();
155:
156: if (lhsBound.equals(rhsBound))
157: return new SingletonTypeSet(lhsBound,
158: getTypeSetEnvironment());
159: else if (TTypes.canAssignTo(lhsBound, rhsBound))
160: return new SingletonTypeSet(rhsBound,
161: getTypeSetEnvironment());
162: else if (TTypes.canAssignTo(rhsBound, lhsBound))
163: return new SingletonTypeSet(lhsBound,
164: getTypeSetEnvironment());
165: }
166: if (fEnumCache != null)
167: return fEnumCache.lowerBound();
168:
169: EnumeratedTypeSet lhsSet = fLHS.enumerate();
170: EnumeratedTypeSet rhsSet = fRHS.enumerate();
171: TypeSet xsect = lhsSet.intersectedWith(rhsSet);
172:
173: return xsect.lowerBound();
174: }
175:
176: protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
177: if (s2.equals(fLHS)) // xsect(s2,xsect(s2,?)) = xsect(s2,?)
178: return this ;
179: if (s2.equals(fRHS)) // xsect(s2,xsect(?,s2)) = xsect(?,s2)
180: return this ;
181: if (s2 instanceof TypeSetIntersection) {
182: TypeSetIntersection x2 = (TypeSetIntersection) s2;
183: //
184: // The following should use a "quick equals()" guaranteed to be constant-time
185: //
186: // xsect(xsect(A,B),xsect(A,C)) = xsect(xsect(A,B),C)
187: if (fLHS.equals(x2.fLHS))
188: return new TypeSetIntersection(this , x2.fRHS);
189: // xsect(xsect(A,B),xsect(C,A)) = xsect(xsect(A,B),C)
190: if (fLHS.equals(x2.fRHS))
191: return new TypeSetIntersection(this , x2.fLHS);
192: // xsect(xsect(A,B),xsect(B,C)) = xsect(xsect(A,B),C)
193: if (fRHS.equals(x2.fLHS))
194: return new TypeSetIntersection(this , x2.fRHS);
195: // xsect(xsect(A,B),xsect(C,B)) = xsect(xsect(A,B),C)
196: if (fRHS.equals(x2.fRHS))
197: return new TypeSetIntersection(this , x2.fLHS);
198: }
199: return null;
200: }
201:
202: /* (non-Javadoc)
203: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton()
204: */
205: public boolean isSingleton() {
206: if (fEnumCache != null)
207: return fEnumCache.isSingleton();
208:
209: int count = 0;
210: for (Iterator lhsIter = fLHS.iterator(); lhsIter.hasNext();) {
211: TType t = (TType) lhsIter.next();
212: if (fRHS.contains(t))
213: count++;
214: if (count > 1)
215: return false;
216: }
217: return (count == 1);
218: }
219:
220: /* (non-Javadoc)
221: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember()
222: */
223: public TType anyMember() {
224: if (fEnumCache != null)
225: return fEnumCache.anyMember();
226:
227: for (Iterator lhsIter = fLHS.iterator(); lhsIter.hasNext();) {
228: TType t = (TType) lhsIter.next();
229: if (fRHS.contains(t))
230: return t;
231: }
232: return null;
233: }
234:
235: /* (non-Javadoc)
236: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator()
237: */
238: public Iterator iterator() {
239: return enumerate().iterator();
240:
241: // return new Iterator() {
242: // private Iterator fLHSIter= fLHS.iterator();
243: // private TType fNext= null;
244: // public void remove() {
245: // throw new IllegalStateException("Unimplemented");
246: // }
247: // private void advance() {
248: // for(; fLHSIter.hasNext(); ) {
249: // TType t= (TType) fLHSIter.next();
250: // if (fRHS.contains(t)) {
251: // fNext= t;
252: // break;
253: // }
254: // }
255: // }
256: // public boolean hasNext() {
257: // if (fNext == null)
258: // advance();
259: // return fNext != null;
260: // }
261: // public Object next() {
262: // if (fNext == null)
263: // advance();
264: // if (fNext == null)
265: // throw new NoSuchElementException("No more elements in TypeSetIntersection");
266: // TType result= fNext;
267: // fNext= null;
268: // return result;
269: // }
270: // };
271: }
272:
273: /* (non-Javadoc)
274: * @see java.lang.Object#equals(java.lang.Object)
275: */
276: public boolean equals(Object o) {
277: if (o instanceof TypeSetIntersection) {
278: TypeSetIntersection other = (TypeSetIntersection) o;
279: return other.fLHS.equals(fLHS) && other.fRHS.equals(fRHS);
280: } else
281: return false;
282: }
283:
284: public String toString() {
285: return "<" + fID + ": intersect(" + fLHS + "," + fRHS + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
286: }
287:
288: /* (non-Javadoc)
289: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound()
290: */
291: public boolean hasUniqueLowerBound() {
292: return false;
293: }
294:
295: /* (non-Javadoc)
296: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound()
297: */
298: public boolean hasUniqueUpperBound() {
299: return false;
300: }
301:
302: /* (non-Javadoc)
303: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound()
304: */
305: public TType uniqueLowerBound() {
306: return null;
307: }
308:
309: /* (non-Javadoc)
310: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound()
311: */
312: public TType uniqueUpperBound() {
313: return null;
314: }
315:
316: private EnumeratedTypeSet fEnumCache = null;
317:
318: /* (non-Javadoc)
319: * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate()
320: */
321: public EnumeratedTypeSet enumerate() {
322: if (fEnumCache == null) {
323: EnumeratedTypeSet lhsSet = fLHS.enumerate();
324: EnumeratedTypeSet rhsSet = fRHS.enumerate();
325: fEnumCache = lhsSet.intersectedWith(rhsSet).enumerate();
326: }
327:
328: return fEnumCache;
329: }
330: }
|