blob: 750e72806261c7af565929a17a3e809eddf60c46 [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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.typeconstraints2;
import java.util.Iterator;
import java.util.Stack;
import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.AbstractTypeVariable;
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.typeconstraints.types.TypeVariable;
public class TTypes {
private static class AllSupertypesIterator implements Iterator {
private final Stack fWorklist;
public AllSupertypesIterator(TType type) {
fWorklist= new Stack();
pushSupertypes(type);
}
public boolean hasNext() {
return ! fWorklist.empty();
}
public Object next() {
TType result= (TType) fWorklist.pop();
pushSupertypes(result);
return result;
}
private void pushSupertypes(TType type) {
if (type.isJavaLangObject())
return;
if (type.isTypeVariable() || type.isCaptureType()) {
TType[] bounds= ((AbstractTypeVariable) type).getBounds();
for (int i= 0; i < bounds.length; i++)
fWorklist.push(bounds[i].getTypeDeclaration());
} else {
TType superclass= type.getSuperclass();
if (superclass == null) {
if (type.isInterface())
fWorklist.push(type.getEnvironment().getJavaLangObject());
} else {
fWorklist.push(superclass.getTypeDeclaration());
}
TType[] interfaces= type.getInterfaces();
for (int i= 0; i < interfaces.length; i++)
fWorklist.push(interfaces[i].getTypeDeclaration());
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private static class AllSubtypesIterator implements Iterator {
private final Stack fWorklist;
public AllSubtypesIterator(TType type) {
fWorklist= new Stack();
fWorklist.push(type.getTypeDeclaration());
}
public boolean hasNext() {
return ! fWorklist.empty();
}
public Object next() {
TType result= (TType) fWorklist.pop();
TType[] subTypes= result.getSubTypes();
for (int i= 0; i < subTypes.length; i++)
fWorklist.push(subTypes[i].getTypeDeclaration());
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private TTypes() {
// no instances
}
public static TType createArrayType(TType elementType, int dimensions) {
return elementType.getEnvironment().createArrayType(elementType, dimensions);
}
/**
* @return all subtypes of this type (including this type)
*/
public static Iterator getAllSubTypesIterator(TType type) {
return new AllSubtypesIterator(type);
}
/**
* @return all proper supertypes of this type
*/
public static Iterator getAllSuperTypesIterator(TType type) {
return new AllSupertypesIterator(type);
}
/**
* @param rhs
* @param lhs
* @return <code>true</code> iff an expression of type 'rhs' can be assigned to a variable of type 'lhs'.
* Type arguments of generic / raw / parameterized types are <b>not</b> considered.
*/
public static boolean canAssignTo(TType rhs, TType lhs) {
if (rhs.isHierarchyType() && lhs.isHierarchyType()) {
HierarchyType rhsGeneric= (HierarchyType) rhs.getTypeDeclaration();
HierarchyType lhsGeneric= (HierarchyType) lhs.getTypeDeclaration();
return lhs.isJavaLangObject() || rhsGeneric.equals(lhsGeneric) || rhsGeneric.isSubType(lhsGeneric);
} else if (rhs.isTypeVariable()) {
if (rhs.canAssignTo(lhs))
return true;
TType[] bounds= ((TypeVariable) rhs).getBounds();
for (int i= 0; i < bounds.length; i++) {
if (canAssignTo(bounds[i], lhs))
return true;
}
return lhs.isJavaLangObject();
} else {
return rhs.canAssignTo(lhs);
}
}
}