blob: 2befebc5cccced8592c89fd3d4f4d08a306a580c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.structure.constraints;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet;
/**
* Optimized type sets for supertype constraint problems.
*/
public abstract class SuperTypeSet implements ITypeSet {
/** Implementation of an empty set */
private static class SuperTypeEmptySet extends SuperTypeSet {
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType()
*/
public final TType chooseSingleType() {
return null;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty()
*/
public final boolean isEmpty() {
return true;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet)
*/
public final ITypeSet restrictedTo(final ITypeSet set) {
return this;
}
/*
* @see java.lang.Object#toString()
*/
public final String toString() {
return "EMPTY"; //$NON-NLS-1$
}
}
/** Implementation of a singleton */
private static class SuperTypeSingletonSet extends SuperTypeSet {
/** The type */
private final TType fType;
/**
* Creates a new super type singleton set.
*
* @param type the type
*/
private SuperTypeSingletonSet(final TType type) {
fType= type;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType()
*/
public final TType chooseSingleType() {
return fType;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty()
*/
public final boolean isEmpty() {
return false;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet)
*/
public final ITypeSet restrictedTo(final ITypeSet set) {
final TType leftErasure= fType.getErasure();
if (set instanceof SuperTypeUniverse) {
return this;
} else if (set instanceof SuperTypeSingletonSet) {
if (this == set)
return this;
if (fType.isNullType())
return this;
final SuperTypeSingletonSet singleton= (SuperTypeSingletonSet) set;
final TType rightErasure= singleton.fType.getErasure();
if (leftErasure.isGenericType() || rightErasure.isGenericType()) {
if (rightErasure.equals(leftErasure) || ((HierarchyType) leftErasure).isSubType((HierarchyType) rightErasure))
return this;
}
if (rightErasure.isJavaLangObject())
return this;
if (leftErasure.canAssignTo(rightErasure))
return this;
return SuperTypeSet.getEmpty();
} else if (set instanceof SuperTypeTuple) {
if (fType.isNullType())
return this;
final SuperTypeTuple tuple= (SuperTypeTuple) set;
final TType rightErasure= tuple.fSuperType.getErasure();
if (leftErasure.isGenericType() || rightErasure.isGenericType()) {
if (rightErasure.equals(leftErasure) || ((HierarchyType) leftErasure).isSubType((HierarchyType) rightErasure))
return this;
}
if (rightErasure.isJavaLangObject())
return this;
if (leftErasure.canAssignTo(rightErasure))
return this;
return SuperTypeSet.createTypeSet(tuple.fSubType);
} else if (set instanceof SuperTypeEmptySet) {
return set;
} else
Assert.isTrue(false);
return null;
}
/*
* @see java.lang.Object#toString()
*/
public final String toString() {
return fType.getPrettySignature();
}
}
/** Implementation of a tuple */
private static class SuperTypeTuple extends SuperTypeSet {
/** The other type */
private final TType fSubType;
/** The super type */
private final TType fSuperType;
/**
* Creates a new super type tuple.
*
* @param subType the sub type
* @param superType the super type
*/
private SuperTypeTuple(final TType subType, final TType superType) {
fSubType= subType;
fSuperType= superType;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType()
*/
public final TType chooseSingleType() {
return fSuperType;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty()
*/
public final boolean isEmpty() {
return false;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet)
*/
public final ITypeSet restrictedTo(final ITypeSet set) {
if (set instanceof SuperTypeUniverse) {
return this;
} else if (set instanceof SuperTypeSingletonSet) {
final SuperTypeSingletonSet singleton= (SuperTypeSingletonSet) set;
final TType rightErasure= singleton.fType.getErasure();
final TType subErasure= fSubType.getErasure();
final TType superErasure= fSuperType.getErasure();
if (subErasure.isGenericType() || superErasure.isGenericType() || rightErasure.isGenericType()) {
if ((rightErasure.equals(subErasure) || ((HierarchyType) subErasure).isSubType((HierarchyType) rightErasure)) && (rightErasure.equals(superErasure) || ((HierarchyType) superErasure).isSubType((HierarchyType) rightErasure)))
return this;
}
if (rightErasure.isJavaLangObject())
return this;
if (subErasure.canAssignTo(rightErasure) && superErasure.canAssignTo(rightErasure))
return this;
return SuperTypeSet.createTypeSet(fSubType);
} else if (set instanceof SuperTypeTuple) {
return this;
} else if (set instanceof SuperTypeEmptySet) {
return set;
} else
Assert.isTrue(false);
return null;
}
/*
* @see java.lang.Object#toString()
*/
public final String toString() {
return "[" + fSubType.getPrettySignature() + ", " + fSuperType.getPrettySignature() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
/** Implementation of the type universe */
private static class SuperTypeUniverse extends SuperTypeSet {
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#chooseSingleType()
*/
public final TType chooseSingleType() {
return null;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#isEmpty()
*/
public final boolean isEmpty() {
return false;
}
/*
* @see org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet#restrictedTo(org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet)
*/
public final ITypeSet restrictedTo(final ITypeSet set) {
return set;
}
/*
* @see java.lang.Object#toString()
*/
public final String toString() {
return "UNIVERSE"; //$NON-NLS-1$
}
}
/** The empty set */
private static final ITypeSet fgEmpty= new SuperTypeEmptySet();
/** The universe */
private static final ITypeSet fgUniverse= new SuperTypeUniverse();
/**
* Creates a new type set.
*
* @param type the type to contain, or <code>null</code>
* @return the type set, or the universe if <code>type</code> is <code>null</code>
*/
public static ITypeSet createTypeSet(final TType type) {
if (type == null)
return fgUniverse;
return new SuperTypeSingletonSet(type);
}
/**
* Creates a new type set.
*
* @param subType the sub type
* @param superType the super type
* @return the type set, or the universe if <code>type</code> is <code>null</code>
*/
public static ITypeSet createTypeSet(final TType subType, final TType superType) {
if (subType == null || superType == null)
return fgUniverse;
return new SuperTypeTuple(subType, superType);
}
/**
* Returns the empty set.
*
* @return the empty set
*/
public static ITypeSet getEmpty() {
return fgEmpty;
}
/**
* Returns the universe set.
*
* @return the universe set
*/
public static ITypeSet getUniverse() {
return fgUniverse;
}
}