blob: a914c8984340baf243123c6f1ed7aed56a5a501b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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.TType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet;
public abstract class TypeSet implements ITypeSet {
public TType chooseSingleType() {
return null;
}
public ITypeSet restrictedTo(ITypeSet restrictionSet) {
throw new UnsupportedOperationException();
}
protected TType getJavaLangObject() {
return fTypeSetEnvironment.getJavaLangObject();
}
protected TypeSetEnvironment getTypeSetEnvironment() {
return fTypeSetEnvironment;
}
static private int sID= 0;
static public int getCount() { return sID; }
static public void resetCount() { sID= 0; }
/**
* An ID unique to this EnumeratedTypeSet instance, to aid in debugging the sharing
* of TypeSets across ConstraintVariables in a TypeEstimateEnvironment.
*/
protected final int fID;
private final TypeSetEnvironment fTypeSetEnvironment;
protected TypeSet(TypeSetEnvironment typeSetEnvironment) {
fTypeSetEnvironment= typeSetEnvironment;
fID= sID++;
}
/**
* @return <code>true</code> iff this set represents the universe of TTypes
*/
abstract public boolean isUniverse();
abstract public TypeSet makeClone();
protected TypeSet specialCasesIntersectedWith(TypeSet s2) {
return null;
}
/**
* Computes and returns a <em>new</em> TypeSet representing the intersection of the
* receiver with s2. Does not modify the receiver or argument sets.
* @param s2
* @return the new TypeSet
*/
public TypeSet intersectedWith(TypeSet s2) {
if (s2.isUniverse())
return makeClone();
else if (isUniverse())
return s2.makeClone();
else if (isEmpty() || s2.isEmpty())
return getTypeSetEnvironment().getEmptyTypeSet();
else if (isSingleton()) {
if (s2.contains(anyMember()))
return makeClone();
else
return getTypeSetEnvironment().getEmptyTypeSet();
} else if (s2.isSingleton()) {
if (contains(s2.anyMember()))
return s2.makeClone();
else
return getTypeSetEnvironment().getEmptyTypeSet();
} else if (s2 instanceof TypeSetIntersection) {
TypeSetIntersection x= (TypeSetIntersection) s2;
// xsect(A,xsect(A,B)) = xsect(A,B) and
// xsect(B,xsect(A,B)) = xsect(A,B)
if (x.getLHS().equals(this) || x.getRHS().equals(this))
return x;
}
TypeSet result= specialCasesIntersectedWith(s2);
if (result != null)
return result;
else
return new TypeSetIntersection(this, s2);
}
/**
* Returns the TypeSet resulting from union'ing the receiver with the argument.
* Does not modify the receiver or the argument sets.
*/
public TypeSet addedTo(TypeSet that) {
if (isUniverse() || that.isUniverse())
return getTypeSetEnvironment().getUniverseTypeSet();
if ((this instanceof EnumeratedTypeSet || this instanceof SingletonTypeSet) &&
(that instanceof EnumeratedTypeSet || that instanceof SingletonTypeSet)) {
EnumeratedTypeSet result= enumerate();
result.addAll(that);
return result;
}
return new TypeSetUnion(this, that);
}
/**
* Returns a new TypeSet representing the set of all sub-types of the
* types in the receiver.
*/
public TypeSet subTypes() {
if (isUniverse() || contains(getJavaLangObject()))
return getTypeSetEnvironment().getUniverseTypeSet();
if (isSingleton())
return possiblyArraySubTypeSetFor(anyMember());
return getTypeSetEnvironment().createSubTypesSet(this);
}
private TypeSet possiblyArraySubTypeSetFor(TType t) {
// In Java, subTypes(x[]) == (subTypes(x))[]
// if (t.isArrayType()) {
// ArrayType at= (ArrayType) t;
//
// return new ArrayTypeSet(possiblyArraySubTypeSetFor(at.getArrayElementType()));
// } else
return getTypeSetEnvironment().createSubTypesOfSingleton(t);
}
private TypeSet possiblyArraySuperTypeSetFor(TType t) {
// In Java, superTypes(x[]) == (superTypes(x))[] union {Object}
// if (t.isArrayType()) {
// ArrayType at= (ArrayType) t;
//
// return new ArraySuperTypeSet(possiblyArraySuperTypeSetFor(at.getArrayElementType()));
// } else
return getTypeSetEnvironment().createSuperTypesOfSingleton(t);
}
/**
* Returns a new TypeSet representing the set of all super-types of the
* types in the receiver.
*/
public TypeSet superTypes() {
if (isUniverse())
return getTypeSetEnvironment().getUniverseTypeSet();
if (isSingleton())
return possiblyArraySuperTypeSetFor(anyMember());
return getTypeSetEnvironment().createSuperTypesSet(this);
}
/**
* Return true iff the type set contains no types.
*/
abstract public boolean isEmpty();
/**
* Returns the types in the upper bound of this set.
*/
abstract public TypeSet upperBound();
/**
* Returns the types in the lower bound of this set.
*/
abstract public TypeSet lowerBound();
/**
* Returns true iff this TypeSet has a unique lower bound.
*/
abstract public boolean hasUniqueLowerBound();
/**
* Returns true iff this TypeSet has a unique upper bound other than
* java.lang.Object.
*/
abstract public boolean hasUniqueUpperBound();
/**
* Returns the unique lower bound of this set of types, if it has one,
* or null otherwise.
*/
abstract public TType uniqueLowerBound();
/**
* Returns the unique upper bound of this set of types, if it has one,
* or null otherwise.
*/
abstract public TType uniqueUpperBound();
/**
* Returns true iff the type set contains the given type.
*/
abstract public boolean contains(TType t);
/**
* Returns true iff the type set contains all of the types in the given TypeSet.
*/
abstract public boolean containsAll(TypeSet s);
/**
* Returns an iterator over the types in the receiver.
*/
abstract public Iterator iterator();
/**
* Returns a new TypeSet enumerating the receiver's contents.
*/
abstract public EnumeratedTypeSet enumerate();
/**
* Returns true iff the given set has precisely one element
*/
abstract public boolean isSingleton();
/**
* Returns an arbitrary member of the given Typeset.
*/
abstract public TType anyMember();
}