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
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;
13 import java.util.Iterator;
15 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
16 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes;
18 public class TypeSetIntersection extends TypeSet {
22 public TypeSetIntersection(TypeSet lhs, TypeSet rhs) {
23 super(lhs.getTypeSetEnvironment());
29 * @return Returns the LHS.
31 public TypeSet getLHS() {
36 * @return Returns the RHS.
38 public TypeSet getRHS() {
43 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse()
46 public boolean isUniverse() {
47 return fLHS.isUniverse() && fRHS.isUniverse();
51 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone()
54 public TypeSet makeClone() {
55 return this; //new TypeSetIntersection(fLHS.makeClone(), fRHS.makeClone());
59 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty()
62 public boolean isEmpty() {
63 if (fLHS.isEmpty() || fRHS.isEmpty())
65 if (fLHS.isUniverse() || fRHS.isUniverse())
67 // Another quick check we can make before jumping to the expensive stuff
68 if (fLHS.contains(getJavaLangObject()) && fRHS.contains(getJavaLangObject()))
71 // TypeSet lhsLB= fLHS.lowerBound();
72 // TypeSet rhsUB= fRHS.upperBound();
74 // // Avoid the infinite recursion that will occur if lhsLB == fLHS && rhsUB == fRHS
75 // if ((!lhsLB.equals(fLHS) || !rhsUB.equals(fRHS)) &&
76 // !lhsLB.intersectedWith(rhsUB).isEmpty())
79 // if (areAllSuperTypesOf(lhsLB, rhsUB))
82 // TypeSet lhsUB= fLHS.upperBound();
83 // TypeSet rhsLB= fRHS.lowerBound();
85 // if (!lhsUB.intersectedWith(rhsLB).isEmpty())
88 // if (areAllSuperTypesOf(rhsLB, lhsUB))
95 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType)
98 public boolean contains(TType t) {
99 return fLHS.contains(t) && fRHS.contains(t);
103 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet)
106 public boolean containsAll(TypeSet s) {
107 return fLHS.containsAll(s) && fRHS.containsAll(s);
111 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#subTypes()
114 public TypeSet subTypes() {
115 if (isUniverse() || contains(getJavaLangObject()))
116 return getTypeSetEnvironment().getUniverseTypeSet();
117 // sub(xsect(sub(a),sub(b))) == xsect(sub(a),sub(b))
118 if ((fLHS instanceof SubTypesSet || fLHS instanceof SubTypesOfSingleton) &&
119 (fRHS instanceof SubTypesSet || fRHS instanceof SubTypesOfSingleton))
121 return getTypeSetEnvironment().createSubTypesSet(this);
125 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes()
128 public TypeSet superTypes() {
129 // super(xsect(super(a),super(b))) == xsect(super(a),super(b))
130 if ((fLHS instanceof SuperTypesSet || fLHS instanceof SuperTypesOfSingleton) &&
131 (fRHS instanceof SuperTypesSet || fRHS instanceof SuperTypesOfSingleton))
133 return getTypeSetEnvironment().createSuperTypesSet(this);
137 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound()
140 public TypeSet upperBound() {
141 if (fLHS.contains(getJavaLangObject()) && fRHS.contains(getJavaLangObject()))
142 return new SingletonTypeSet(getTypeSetEnvironment().getJavaLangObject(), getTypeSetEnvironment());
144 if (fEnumCache != null) return fEnumCache.upperBound();
146 EnumeratedTypeSet lhsSet= fLHS.enumerate();
147 EnumeratedTypeSet rhsSet= fRHS.enumerate();
148 TypeSet xsect= lhsSet.intersectedWith(rhsSet);
150 return xsect.upperBound();
154 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound()
157 public TypeSet lowerBound() {
158 if (fLHS.hasUniqueLowerBound() && fRHS.hasUniqueLowerBound()) {
159 TType lhsBound= fLHS.uniqueLowerBound();
160 TType rhsBound= fRHS.uniqueLowerBound();
162 if (lhsBound.equals(rhsBound))
163 return new SingletonTypeSet(lhsBound, getTypeSetEnvironment());
164 else if (TTypes.canAssignTo(lhsBound, rhsBound))
165 return new SingletonTypeSet(rhsBound, getTypeSetEnvironment());
166 else if (TTypes.canAssignTo(rhsBound, lhsBound))
167 return new SingletonTypeSet(lhsBound, getTypeSetEnvironment());
169 if (fEnumCache != null) return fEnumCache.lowerBound();
171 EnumeratedTypeSet lhsSet= fLHS.enumerate();
172 EnumeratedTypeSet rhsSet= fRHS.enumerate();
173 TypeSet xsect= lhsSet.intersectedWith(rhsSet);
175 return xsect.lowerBound();
179 protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
180 if (s2.equals(fLHS)) // xsect(s2,xsect(s2,?)) = xsect(s2,?)
182 if (s2.equals(fRHS)) // xsect(s2,xsect(?,s2)) = xsect(?,s2)
184 if (s2 instanceof TypeSetIntersection) {
185 TypeSetIntersection x2= (TypeSetIntersection) s2;
187 // The following should use a "quick equals()" guaranteed to be constant-time
189 // xsect(xsect(A,B),xsect(A,C)) = xsect(xsect(A,B),C)
190 if (fLHS.equals(x2.fLHS))
191 return new TypeSetIntersection(this, x2.fRHS);
192 // xsect(xsect(A,B),xsect(C,A)) = xsect(xsect(A,B),C)
193 if (fLHS.equals(x2.fRHS))
194 return new TypeSetIntersection(this, x2.fLHS);
195 // xsect(xsect(A,B),xsect(B,C)) = xsect(xsect(A,B),C)
196 if (fRHS.equals(x2.fLHS))
197 return new TypeSetIntersection(this, x2.fRHS);
198 // xsect(xsect(A,B),xsect(C,B)) = xsect(xsect(A,B),C)
199 if (fRHS.equals(x2.fRHS))
200 return new TypeSetIntersection(this, x2.fLHS);
206 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton()
209 public boolean isSingleton() {
210 if (fEnumCache != null) return fEnumCache.isSingleton();
213 for(Iterator<TType> lhsIter= fLHS.iterator(); lhsIter.hasNext(); ) {
214 TType t= lhsIter.next();
215 if (fRHS.contains(t))
224 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember()
227 public TType anyMember() {
228 if (fEnumCache != null) return fEnumCache.anyMember();
230 for(Iterator<TType> lhsIter= fLHS.iterator(); lhsIter.hasNext(); ) {
231 TType t= lhsIter.next();
232 if (fRHS.contains(t))
239 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator()
242 public Iterator<TType> iterator() {
243 return enumerate().iterator();
245 // return new Iterator() {
246 // private Iterator fLHSIter= fLHS.iterator();
247 // private TType fNext= null;
248 // public void remove() {
249 // throw new IllegalStateException("Unimplemented");
251 // private void advance() {
252 // for(; fLHSIter.hasNext(); ) {
253 // TType t= (TType) fLHSIter.next();
254 // if (fRHS.contains(t)) {
260 // public boolean hasNext() {
261 // if (fNext == null)
263 // return fNext != null;
265 // public Object next() {
266 // if (fNext == null)
268 // if (fNext == null)
269 // throw new NoSuchElementException("No more elements in TypeSetIntersection");
270 // TType result= fNext;
278 * @see java.lang.Object#equals(java.lang.Object)
281 public boolean equals(Object o) {
282 if (o instanceof TypeSetIntersection) {
283 TypeSetIntersection other= (TypeSetIntersection) o;
284 return other.fLHS.equals(fLHS) && other.fRHS.equals(fRHS);
290 public int hashCode() {
291 return fLHS.hashCode() * 37 + fRHS.hashCode();
295 public String toString() {
296 return "<" + fID + ": intersect(" + fLHS + "," + fRHS + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
300 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound()
303 public boolean hasUniqueLowerBound() {
308 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound()
311 public boolean hasUniqueUpperBound() {
316 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound()
319 public TType uniqueLowerBound() {
324 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound()
327 public TType uniqueUpperBound() {
331 private EnumeratedTypeSet fEnumCache= null;
334 * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate()
337 public EnumeratedTypeSet enumerate() {
338 if (fEnumCache == null) {
339 EnumeratedTypeSet lhsSet= fLHS.enumerate();
340 EnumeratedTypeSet rhsSet= fRHS.enumerate();
341 fEnumCache= lhsSet.intersectedWith(rhsSet).enumerate();