/******************************************************************************* * Copyright (c) 2000, 2009 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.wst.jsdt.internal.corext.refactoring.typeconstraints2; import java.util.Iterator; import java.util.Stack; import org.eclipse.wst.jsdt.internal.corext.refactoring.typeconstraints.types.AbstractTypeVariable; import org.eclipse.wst.jsdt.internal.corext.refactoring.typeconstraints.types.HierarchyType; import org.eclipse.wst.jsdt.internal.corext.refactoring.typeconstraints.types.TType; 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; return lhs.isJavaLangObject(); } else { return rhs.canAssignTo(lhs); } } }