KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > lookup > ArrayBinding


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
15 import org.eclipse.jdt.internal.compiler.impl.Constant;
16
17 public final class ArrayBinding extends TypeBinding {
18     // creation and initialization of the length field
19
// the declaringClass of this field is intentionally set to null so it can be distinguished.
20
public static final FieldBinding ArrayLength = new FieldBinding(TypeConstants.LENGTH, TypeBinding.INT, ClassFileConstants.AccPublic | ClassFileConstants.AccFinal, null, Constant.NotAConstant);
21
22     public TypeBinding leafComponentType;
23     public int dimensions;
24     LookupEnvironment environment;
25     char[] constantPoolName;
26     char[] genericTypeSignature;
27     
28 public ArrayBinding(TypeBinding type, int dimensions, LookupEnvironment environment) {
29     this.tagBits |= TagBits.IsArrayType;
30     this.leafComponentType = type;
31     this.dimensions = dimensions;
32     this.environment = environment;
33     if (type instanceof UnresolvedReferenceBinding)
34         ((UnresolvedReferenceBinding) type).addWrapper(this, environment);
35     else
36         this.tagBits |= type.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard);
37 }
38
39 /**
40  * Collect the substitutes into a map for certain type variables inside the receiver type
41  * e.g. Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
42  * Constraints:
43  * A << F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
44  * A = F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
45  * A >> F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
46 */

47 public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
48     
49     if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
50     if (actualType == TypeBinding.NULL) return;
51     
52     switch(actualType.kind()) {
53         case Binding.ARRAY_TYPE :
54             int actualDim = actualType.dimensions();
55             if (actualDim == this.dimensions) {
56                 this.leafComponentType.collectSubstitutes(scope, actualType.leafComponentType(), inferenceContext, constraint);
57             } else if (actualDim > this.dimensions) {
58                 ArrayBinding actualReducedType = this.environment.createArrayType(actualType.leafComponentType(), actualDim - this.dimensions);
59                 this.leafComponentType.collectSubstitutes(scope, actualReducedType, inferenceContext, constraint);
60             }
61             break;
62         case Binding.TYPE_PARAMETER :
63             //TypeVariableBinding variable = (TypeVariableBinding) otherType;
64
// TODO (philippe) should consider array bounds, and recurse
65
break;
66     }
67 }
68
69 /*
70  * brakets leafUniqueKey
71  * p.X[][] --> [[Lp/X;
72  */

73 public char[] computeUniqueKey(boolean isLeaf) {
74     char[] brackets = new char[dimensions];
75     for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
76     return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey(isLeaf));
77  }
78     
79 /**
80  * Answer the receiver's constant pool name.
81  * NOTE: This method should only be used during/after code gen.
82  * e.g. '[Ljava/lang/Object;'
83  */

84 public char[] constantPoolName() {
85     if (constantPoolName != null)
86         return constantPoolName;
87
88     char[] brackets = new char[dimensions];
89     for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
90     return constantPoolName = CharOperation.concat(brackets, leafComponentType.signature());
91 }
92 public String JavaDoc debugName() {
93     StringBuffer JavaDoc brackets = new StringBuffer JavaDoc(dimensions * 2);
94     for (int i = dimensions; --i >= 0;)
95         brackets.append("[]"); //$NON-NLS-1$
96
return leafComponentType.debugName() + brackets.toString();
97 }
98 public int dimensions() {
99     return this.dimensions;
100 }
101
102 /* Answer an array whose dimension size is one less than the receiver.
103 *
104 * When the receiver's dimension size is one then answer the leaf component type.
105 */

106
107 public TypeBinding elementsType() {
108     if (this.dimensions == 1) return this.leafComponentType;
109     return this.environment.createArrayType(this.leafComponentType, this.dimensions - 1);
110 }
111 /**
112  * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
113  */

114 public TypeBinding erasure() {
115     TypeBinding erasedType = this.leafComponentType.erasure();
116     if (this.leafComponentType != erasedType)
117         return this.environment.createArrayType(erasedType, this.dimensions);
118     return this;
119 }
120 public LookupEnvironment environment() {
121     return this.environment;
122 }
123
124 public char[] genericTypeSignature() {
125     
126     if (this.genericTypeSignature == null) {
127         char[] brackets = new char[dimensions];
128         for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
129         this.genericTypeSignature = CharOperation.concat(brackets, leafComponentType.genericTypeSignature());
130     }
131     return this.genericTypeSignature;
132 }
133
134 public PackageBinding getPackage() {
135     return leafComponentType.getPackage();
136 }
137
138 public int hashCode() {
139     return this.leafComponentType == null ? super.hashCode() : this.leafComponentType.hashCode();
140 }
141
142 /* Answer true if the receiver type can be assigned to the argument type (right)
143 */

144 public boolean isCompatibleWith(TypeBinding otherType) {
145     if (this == otherType)
146         return true;
147
148     switch (otherType.kind()) {
149         case Binding.ARRAY_TYPE :
150             ArrayBinding otherArray = (ArrayBinding) otherType;
151             if (otherArray.leafComponentType.isBaseType())
152                 return false; // relying on the fact that all equal arrays are identical
153
if (dimensions == otherArray.dimensions)
154                 return leafComponentType.isCompatibleWith(otherArray.leafComponentType);
155             if (dimensions < otherArray.dimensions)
156                 return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
157
break;
158         case Binding.BASE_TYPE :
159             return false;
160         case Binding.WILDCARD_TYPE :
161             return ((WildcardBinding) otherType).boundCheck(this);
162             
163         case Binding.TYPE_PARAMETER :
164             // check compatibility with capture of ? super X
165
if (otherType.isCapture()) {
166                 CaptureBinding otherCapture = (CaptureBinding) otherType;
167                 TypeBinding otherLowerBound;
168                 if ((otherLowerBound = otherCapture.lowerBound) != null) {
169                     if (!otherLowerBound.isArrayType()) return false;
170                     return this.isCompatibleWith(otherLowerBound);
171                 }
172             }
173             return false;
174
175     }
176     //Check dimensions - Java does not support explicitly sized dimensions for types.
177
//However, if it did, the type checking support would go here.
178
switch (otherType.leafComponentType().id) {
179         case TypeIds.T_JavaLangObject :
180         case TypeIds.T_JavaLangCloneable :
181         case TypeIds.T_JavaIoSerializable :
182             return true;
183     }
184     return false;
185 }
186
187 public int kind() {
188     return ARRAY_TYPE;
189 }
190
191 public TypeBinding leafComponentType(){
192     return leafComponentType;
193 }
194
195 /* API
196 * Answer the problem id associated with the receiver.
197 * NoError if the receiver is a valid binding.
198 */

199 public int problemId() {
200     return leafComponentType.problemId();
201 }
202 /**
203 * Answer the source name for the type.
204 * In the case of member types, as the qualified name from its top level type.
205 * For example, for a member type N defined inside M & A: "A.M.N".
206 */

207
208 public char[] qualifiedSourceName() {
209     char[] brackets = new char[dimensions * 2];
210     for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
211         brackets[i] = ']';
212         brackets[i - 1] = '[';
213     }
214     return CharOperation.concat(leafComponentType.qualifiedSourceName(), brackets);
215 }
216 public char[] readableName() /* java.lang.Object[] */ {
217     char[] brackets = new char[dimensions * 2];
218     for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
219         brackets[i] = ']';
220         brackets[i - 1] = '[';
221     }
222     return CharOperation.concat(leafComponentType.readableName(), brackets);
223 }
224 public char[] shortReadableName(){
225     char[] brackets = new char[dimensions * 2];
226     for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
227         brackets[i] = ']';
228         brackets[i - 1] = '[';
229     }
230     return CharOperation.concat(leafComponentType.shortReadableName(), brackets);
231 }
232 public char[] sourceName() {
233     char[] brackets = new char[dimensions * 2];
234     for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
235         brackets[i] = ']';
236         brackets[i - 1] = '[';
237     }
238     return CharOperation.concat(leafComponentType.sourceName(), brackets);
239 }
240 public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
241     if (this.leafComponentType == unresolvedType) {
242         this.leafComponentType = env.convertUnresolvedBinaryToRawType(resolvedType);
243         this.tagBits |= this.leafComponentType.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard);
244     }
245 }
246 public String JavaDoc toString() {
247     return leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
248
}
249 }
250
Popular Tags