001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.typeconstraints.types;
011:
012: import org.eclipse.core.runtime.Assert;
013:
014: import org.eclipse.jdt.core.dom.ITypeBinding;
015:
016: public final class ArrayType extends TType {
017: private TType fElementType;
018: private int fDimensions;
019:
020: private TType fErasure;
021:
022: protected ArrayType(TypeEnvironment environment) {
023: super (environment);
024: }
025:
026: protected ArrayType(TypeEnvironment environment, String key) {
027: super (environment, key);
028: }
029:
030: protected void initialize(ITypeBinding binding, TType elementType) {
031: Assert.isTrue(binding.isArray());
032: super .initialize(binding);
033: fElementType = elementType;
034: fDimensions = binding.getDimensions();
035: if (fElementType.isStandardType()
036: || fElementType.isGenericType()
037: || fElementType.isPrimitiveType()) {
038: fErasure = this ;
039: } else {
040: fErasure = getEnvironment().create(binding.getErasure());
041: }
042: }
043:
044: protected void initialize(TType elementType, int dimensions) {
045: fElementType = elementType;
046: fDimensions = dimensions;
047: if (fElementType.isStandardType()
048: || fElementType.isGenericType()
049: || fElementType.isPrimitiveType()) {
050: fErasure = this ;
051: } else {
052: fErasure = getEnvironment().createArrayType(
053: elementType.getErasure(), dimensions);
054: }
055: }
056:
057: public TType getElementType() {
058: return fElementType;
059: }
060:
061: /**
062: * Returns the component type of this array.
063: * If getDimensions() is 1, the component type is the element type.
064: * If getDimensions() is > 1, the component type is an array type
065: * with element type getElementType() and dimensions getDimensions() - 1.
066: *
067: * @return the component type
068: */
069: public TType getComponentType() {
070: if (fDimensions > 1)
071: return getEnvironment().createArrayType(fElementType,
072: fDimensions - 1);
073: else
074: return fElementType;
075: }
076:
077: public int getDimensions() {
078: return fDimensions;
079: }
080:
081: public int getKind() {
082: return ARRAY_TYPE;
083: }
084:
085: public TType[] getSubTypes() {
086: TType[] subTypes = fElementType.getSubTypes();
087: TType[] result = new TType[subTypes.length];
088: for (int i = 0; i < subTypes.length; i++) {
089: result[i] = getEnvironment().createArrayType(subTypes[i],
090: fDimensions);
091: }
092: return result;
093: }
094:
095: public TType getErasure() {
096: return fErasure;
097: }
098:
099: public boolean doEquals(TType other) {
100: ArrayType arrayType = (ArrayType) other;
101: return fElementType.equals(arrayType.fElementType)
102: && fDimensions == arrayType.fDimensions;
103: }
104:
105: public int hashCode() {
106: return fElementType.hashCode() << ARRAY_TYPE_SHIFT;
107: }
108:
109: protected boolean doCanAssignTo(TType lhs) {
110: switch (lhs.getKind()) {
111: case NULL_TYPE:
112: return false;
113: case VOID_TYPE:
114: return false;
115: case PRIMITIVE_TYPE:
116: return false;
117:
118: case ARRAY_TYPE:
119: return canAssignToArrayType((ArrayType) lhs);
120:
121: case GENERIC_TYPE:
122: return false;
123: case STANDARD_TYPE:
124: return isArrayLhsCompatible(lhs);
125: case PARAMETERIZED_TYPE:
126: return false;
127: case RAW_TYPE:
128: return false;
129:
130: case UNBOUND_WILDCARD_TYPE:
131: case EXTENDS_WILDCARD_TYPE:
132: case SUPER_WILDCARD_TYPE:
133: return ((WildcardType) lhs).checkAssignmentBound(this );
134:
135: case TYPE_VARIABLE:
136: return false;
137: case CAPTURE_TYPE:
138: return ((CaptureType) lhs).checkLowerBound(lhs);
139: }
140: return false;
141: }
142:
143: private boolean canAssignToArrayType(ArrayType lhs) {
144: if (fDimensions == lhs.fDimensions) {
145: // primitive type don't have any conversion for arrays.
146: if (fElementType.getKind() == PRIMITIVE_TYPE
147: || lhs.fElementType.getKind() == PRIMITIVE_TYPE)
148: return fElementType
149: .isTypeEquivalentTo(lhs.fElementType);
150: return fElementType.canAssignTo(lhs.fElementType);
151: }
152: if (fDimensions < lhs.fDimensions)
153: return false;
154: return isArrayLhsCompatible(lhs.fElementType);
155: }
156:
157: private boolean isArrayLhsCompatible(TType lhsElementType) {
158: return lhsElementType.isJavaLangObject()
159: || lhsElementType.isJavaLangCloneable()
160: || lhsElementType.isJavaIoSerializable();
161: }
162:
163: protected String getPlainPrettySignature() {
164: StringBuffer result = new StringBuffer(fElementType
165: .getPlainPrettySignature());
166: for (int i = 0; i < fDimensions; i++) {
167: result.append("[]"); //$NON-NLS-1$
168: }
169: return result.toString();
170: }
171:
172: public String getName() {
173: StringBuffer result = new StringBuffer(fElementType.getName());
174: for (int i = 0; i < fDimensions; i++) {
175: result.append("[]"); //$NON-NLS-1$
176: }
177: return result.toString();
178: }
179:
180: }
|