001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.typeconstraints2;
011:
012: import java.util.Iterator;
013: import java.util.Stack;
014:
015: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.AbstractTypeVariable;
016: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType;
017: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
018: import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeVariable;
019:
020: public class TTypes {
021:
022: private static class AllSupertypesIterator implements Iterator {
023: private final Stack fWorklist;
024:
025: public AllSupertypesIterator(TType type) {
026: fWorklist = new Stack();
027: pushSupertypes(type);
028: }
029:
030: public boolean hasNext() {
031: return !fWorklist.empty();
032: }
033:
034: public Object next() {
035: TType result = (TType) fWorklist.pop();
036: pushSupertypes(result);
037: return result;
038: }
039:
040: private void pushSupertypes(TType type) {
041: if (type.isJavaLangObject())
042: return;
043:
044: if (type.isTypeVariable() || type.isCaptureType()) {
045: TType[] bounds = ((AbstractTypeVariable) type)
046: .getBounds();
047: for (int i = 0; i < bounds.length; i++)
048: fWorklist.push(bounds[i].getTypeDeclaration());
049:
050: } else {
051: TType super class = type.getSuperclass();
052: if (super class == null) {
053: if (type.isInterface())
054: fWorklist.push(type.getEnvironment()
055: .getJavaLangObject());
056: } else {
057: fWorklist.push(super class.getTypeDeclaration());
058: }
059: TType[] interfaces = type.getInterfaces();
060: for (int i = 0; i < interfaces.length; i++)
061: fWorklist.push(interfaces[i].getTypeDeclaration());
062: }
063: }
064:
065: public void remove() {
066: throw new UnsupportedOperationException();
067: }
068: }
069:
070: private static class AllSubtypesIterator implements Iterator {
071: private final Stack fWorklist;
072:
073: public AllSubtypesIterator(TType type) {
074: fWorklist = new Stack();
075: fWorklist.push(type.getTypeDeclaration());
076: }
077:
078: public boolean hasNext() {
079: return !fWorklist.empty();
080: }
081:
082: public Object next() {
083: TType result = (TType) fWorklist.pop();
084: TType[] subTypes = result.getSubTypes();
085: for (int i = 0; i < subTypes.length; i++)
086: fWorklist.push(subTypes[i].getTypeDeclaration());
087:
088: return result;
089: }
090:
091: public void remove() {
092: throw new UnsupportedOperationException();
093: }
094: }
095:
096: private TTypes() {
097: // no instances
098: }
099:
100: public static TType createArrayType(TType elementType,
101: int dimensions) {
102: return elementType.getEnvironment().createArrayType(
103: elementType, dimensions);
104: }
105:
106: /**
107: * @return all subtypes of this type (including this type)
108: */
109: public static Iterator getAllSubTypesIterator(TType type) {
110: return new AllSubtypesIterator(type);
111: }
112:
113: /**
114: * @return all proper supertypes of this type
115: */
116: public static Iterator getAllSuperTypesIterator(TType type) {
117: return new AllSupertypesIterator(type);
118: }
119:
120: /**
121: * @param rhs
122: * @param lhs
123: * @return <code>true</code> iff an expression of type 'rhs' can be assigned to a variable of type 'lhs'.
124: * Type arguments of generic / raw / parameterized types are <b>not</b> considered.
125: */
126: public static boolean canAssignTo(TType rhs, TType lhs) {
127: if (rhs.isHierarchyType() && lhs.isHierarchyType()) {
128: HierarchyType rhsGeneric = (HierarchyType) rhs
129: .getTypeDeclaration();
130: HierarchyType lhsGeneric = (HierarchyType) lhs
131: .getTypeDeclaration();
132: return lhs.isJavaLangObject()
133: || rhsGeneric.equals(lhsGeneric)
134: || rhsGeneric.isSubType(lhsGeneric);
135:
136: } else if (rhs.isTypeVariable()) {
137: if (rhs.canAssignTo(lhs))
138: return true;
139: TType[] bounds = ((TypeVariable) rhs).getBounds();
140: for (int i = 0; i < bounds.length; i++) {
141: if (canAssignTo(bounds[i], lhs))
142: return true;
143: }
144: return lhs.isJavaLangObject();
145:
146: } else {
147: return rhs.canAssignTo(lhs);
148: }
149: }
150:
151: }
|