| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Robert M. Fuhrer (rfuhrer@watson.ibm.com), IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets; |
| |
| import java.util.Iterator; |
| |
| import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ArrayType; |
| import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; |
| import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TTypes; |
| |
| public class SuperTypesOfSingleton extends TypeSet { |
| /** |
| * The "base type" defining the lower bound of this set. |
| */ |
| private TType fLowerBound; |
| |
| SuperTypesOfSingleton(TType t, TypeSetEnvironment typeSetEnvironment) { |
| super(typeSetEnvironment); |
| fLowerBound= t; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isUniverse() |
| */ |
| @Override |
| public boolean isUniverse() { |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#makeClone() |
| */ |
| @Override |
| public TypeSet makeClone() { |
| return this; //new SuperTypesOfSingleton(fLowerBound, getTypeSetEnvironment()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#intersectedWith(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet) |
| */ |
| @Override |
| protected TypeSet specialCasesIntersectedWith(TypeSet other) { |
| if (other.isSingleton() && other.anyMember().equals(fLowerBound)) |
| return other; // xsect(superTypes(A),A) = A |
| |
| if (other instanceof SuperTypesOfSingleton) { |
| SuperTypesOfSingleton otherSuper= (SuperTypesOfSingleton) other; |
| |
| if (TTypes.canAssignTo(otherSuper.fLowerBound, fLowerBound)) |
| return this; |
| if (TTypes.canAssignTo(fLowerBound, otherSuper.fLowerBound)) |
| return otherSuper; |
| } else if (other.hasUniqueUpperBound()) { |
| TType otherUpper= other.uniqueUpperBound(); |
| |
| if (otherUpper.equals(fLowerBound)) |
| return new SingletonTypeSet(fLowerBound, getTypeSetEnvironment()); |
| if ((otherUpper != fLowerBound && TTypes.canAssignTo(otherUpper, fLowerBound)) || |
| ! TTypes.canAssignTo(fLowerBound, otherUpper)) |
| return getTypeSetEnvironment().getEmptyTypeSet(); |
| } |
| // else if (other instanceof SuperTypesSet) { |
| // SuperTypesSet otherSub= (SuperTypesSet) other; |
| // TypeSet otherLowers= otherSub.lowerBound(); |
| // |
| // for(Iterator iter= otherLowers.iterator(); iter.hasNext(); ) { |
| // TType t= (TType) iter.next(); |
| // |
| // if () |
| // } |
| // } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isEmpty() |
| */ |
| @Override |
| public boolean isEmpty() { |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#upperBound() |
| */ |
| @Override |
| public TypeSet upperBound() { |
| return new SingletonTypeSet(getJavaLangObject(), getTypeSetEnvironment()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#lowerBound() |
| */ |
| @Override |
| public TypeSet lowerBound() { |
| return new SingletonTypeSet(fLowerBound, getTypeSetEnvironment()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueLowerBound() |
| */ |
| @Override |
| public boolean hasUniqueLowerBound() { |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#hasUniqueUpperBound() |
| */ |
| @Override |
| public boolean hasUniqueUpperBound() { |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueLowerBound() |
| */ |
| @Override |
| public TType uniqueLowerBound() { |
| return fLowerBound; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#uniqueUpperBound() |
| */ |
| @Override |
| public TType uniqueUpperBound() { |
| return getJavaLangObject(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#superTypes() |
| */ |
| @Override |
| public TypeSet superTypes() { |
| return this; // makeClone(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#contains(TType) |
| */ |
| @Override |
| public boolean contains(TType t) { |
| if (t.equals(fLowerBound)) |
| return true; |
| if (t.equals(getJavaLangObject())) |
| return true; |
| return TTypes.canAssignTo(fLowerBound, t); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#containsAll(org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet) |
| */ |
| @Override |
| public boolean containsAll(TypeSet other) { |
| // Optimization: if other is also a SubTypeOfSingleton, just compare bounds |
| if (other instanceof SuperTypesOfSingleton) { |
| SuperTypesOfSingleton otherSuper= (SuperTypesOfSingleton) other; |
| return TTypes.canAssignTo(fLowerBound, otherSuper.fLowerBound); |
| } |
| // Optimization: if other is a SubTypesSet, just compare all its bounds to mine |
| if (other instanceof SuperTypesSet) { |
| SuperTypesSet otherSuper= (SuperTypesSet) other; |
| TypeSet otherLowerBounds= otherSuper.lowerBound(); |
| |
| for(Iterator<TType> iter= otherLowerBounds.iterator(); iter.hasNext(); ) { |
| TType t= iter.next(); |
| if (! TTypes.canAssignTo(fLowerBound, t)) |
| return false; |
| } |
| return true; |
| } |
| if (other.isUniverse()) { |
| return false; |
| } |
| // For now, no more tricks up my sleeve; get an iterator |
| for(Iterator<TType> iter= other.iterator(); iter.hasNext(); ) { |
| TType t= iter.next(); |
| |
| if (! TTypes.canAssignTo(fLowerBound, t)) |
| return false; |
| } |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#iterator() |
| */ |
| @Override |
| public Iterator<TType> iterator() { |
| return enumerate().iterator(); |
| // return new Iterator() { |
| // // First type returned is fLowerBound, then each of the supertypes, in turn |
| // // |
| // // If the lower bound is an array type, return the set of array types |
| // // { Array(superType(elementTypeOf(fUpperBound))) } |
| // boolean isArray= (fLowerBound instanceof ArrayType); |
| // private Set/*<TType>*/ superTypes= sTypeHierarchy.getAllSupertypes(getElementTypeOf(fLowerBound)); |
| // private Iterator/*<TType>*/ superTypeIter= superTypes.iterator(); |
| // private int nDims= getDimsOf(fLowerBound); |
| // private int idx= (isArray ? -2 : -1); |
| // public void remove() { /*do nothing*/ } |
| // public boolean hasNext() { return idx < superTypes.size(); } |
| // public Object next() { |
| // int i=idx++; |
| // if (i < -1) return sJavaLangObject; |
| // if (i < 0) return fLowerBound; |
| // return makePossiblyArrayTypeFor((TType) superTypeIter.next(), nDims); |
| // } |
| // }; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#isSingleton() |
| */ |
| @Override |
| public boolean isSingleton() { |
| // The only thing that doesn't have at least 1 proper supertype is java.lang.Object |
| return fLowerBound.equals(getJavaLangObject()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#anyMember() |
| */ |
| @Override |
| public TType anyMember() { |
| return fLowerBound; |
| } |
| |
| private EnumeratedTypeSet fEnumCache= null; |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints.typesets.TypeSet#enumerate() |
| */ |
| @Override |
| public EnumeratedTypeSet enumerate() { |
| if (fEnumCache == null) { |
| if (fLowerBound instanceof ArrayType) { |
| ArrayType at= (ArrayType) fLowerBound; |
| fEnumCache= EnumeratedTypeSet.makeArrayTypesForElements(TTypes.getAllSuperTypesIterator(at.getComponentType()), getTypeSetEnvironment()); |
| fEnumCache.add(getJavaLangObject()); |
| } else |
| fEnumCache= new EnumeratedTypeSet(TTypes.getAllSuperTypesIterator(fLowerBound), getTypeSetEnvironment()); |
| |
| fEnumCache.add(fLowerBound); |
| fEnumCache.initComplete(); |
| } |
| return fEnumCache; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof SuperTypesOfSingleton)) |
| return false; |
| SuperTypesOfSingleton other= (SuperTypesOfSingleton) o; |
| |
| return other.fLowerBound.equals(fLowerBound); |
| } |
| |
| @Override |
| public int hashCode() { |
| return fLowerBound.hashCode(); |
| } |
| |
| @Override |
| public String toString() { |
| return "<" + fID + ": superTypes(" + fLowerBound.getPrettySignature() + ")>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| } |