1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.lookup;
14 import org.eclipse.jdt.core.compiler.CharOperation;
15 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
18 * Not all fields defined by this type (& its subclasses) are initialized when it is created.
19 * Some are initialized only when needed.
21 * Accessors have been provided for some public fields so all TypeBindings have the same API...
22 * but access public fields directly whenever possible.
23 * Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
25 * null is NOT a valid value for a non-public field... it just means the field is not initialized.
27 abstract public class TypeBinding extends Binding implements BaseTypes, TagBits, TypeConstants, TypeIds {
29 public long tagBits = 0; // See values in the interface TagBits below
31 * Match a well-known type id to its binding
33 public static final TypeBinding wellKnownType(Scope scope, int id) {
36 return BooleanBinding;
51 case T_JavaLangObject :
52 return scope.getJavaLangObject();
53 case T_JavaLangString :
54 return scope.getJavaLangString();
60 * Answer the receiver's binding type from Binding.BindingID.
66 /* Answer true if the receiver can be instantiated
68 public boolean canBeInstantiated() {
72 * Collect the substitutes into a map for certain type variables inside the receiver type
73 * e.g. Collection<T>.findSubstitute(T, Collection<List<X>>): T --> List<X>
75 public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
76 // no substitute by default
79 * genericTypeSignature
81 public char[] computeUniqueKey() {
82 return genericTypeSignature();
85 * Answer the receiver's constant pool name.
86 * NOTE: This method should only be used during/after code gen.
87 * e.g. 'java/lang/Object'
89 public abstract char[] constantPoolName();
91 public String debugName() {
92 return new String(readableName());
95 * Answer the receiver's dimensions - 0 for non-array types
97 public int dimensions(){
100 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
103 public ReferenceBinding enclosingType() {
106 public TypeBinding erasure() {
110 * Returns the type to use for generic cast, or null if none required
112 public TypeBinding genericCast(TypeBinding otherType) {
113 if (this == otherType) return null;
114 if (otherType.isWildcard() && ((WildcardBinding)otherType).kind != Wildcard.EXTENDS) return null;
115 TypeBinding otherErasure = otherType.erasure();
116 if (otherErasure == this.erasure()) return null;
121 * Answer the receiver classfile signature.
122 * Arrays & base types do not distinguish between signature() & constantPoolName().
123 * NOTE: This method should only be used during/after code gen.
125 public char[] genericTypeSignature() {
128 public abstract PackageBinding getPackage();
129 public boolean isAnnotationType() {
132 /* Answer true if the receiver is an array
134 public final boolean isArrayType() {
135 return (tagBits & IsArrayType) != 0;
137 /* Answer true if the receiver is a base type
139 public final boolean isBaseType() {
140 return (tagBits & IsBaseType) != 0;
145 * Returns true if parameterized type AND not of the form List<?>
147 public boolean isBoundParameterizedType() {
148 return (this.tagBits & TagBits.IsBoundParameterizedType) != 0;
150 public boolean isClass() {
153 /* Answer true if the receiver type can be assigned to the argument type (right)
155 public abstract boolean isCompatibleWith(TypeBinding right);
157 public boolean isEnum() {
161 * Returns true if a type is identical to another one,
162 * or for generic types, true if compared to its raw type.
164 public boolean isEquivalentTo(TypeBinding otherType) {
165 if (this == otherType) return true;
166 if (otherType == null) return false;
167 if (otherType.isWildcard()) // wildcard
168 return ((WildcardBinding) otherType).boundCheck(this);
172 public boolean isGenericType() {
176 /* Answer true if the receiver's hierarchy has problems (always false for arrays & base types)
178 public final boolean isHierarchyInconsistent() {
179 return (tagBits & HierarchyHasProblems) != 0;
181 public boolean isInterface() {
184 public final boolean isLocalType() {
185 return (tagBits & IsLocalType) != 0;
188 public final boolean isMemberType() {
189 return (tagBits & IsMemberType) != 0;
192 public final boolean isNestedType() {
193 return (tagBits & IsNestedType) != 0;
195 public final boolean isNumericType() {
211 * Returns true if the type is parameterized, e.g. List<String>
213 public boolean isParameterizedType() {
217 public boolean isPartOfRawType() {
218 TypeBinding current = this;
220 if (current.isRawType())
222 } while ((current = current.enclosingType()) != null);
227 * Returns true if the two types are statically known to be different at compile-time,
228 * e.g. a type variable is not probably known to be distinct from another type
230 public boolean isProvablyDistinctFrom(TypeBinding otherType, int depth) {
231 if (this == otherType) return false;
232 if (depth > 1) return true;
233 switch (otherType.kind()) {
234 case Binding.TYPE_PARAMETER :
235 case Binding.WILDCARD_TYPE :
240 case Binding.TYPE_PARAMETER :
241 case Binding.WILDCARD_TYPE :
244 case Binding.PARAMETERIZED_TYPE :
245 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) this;
246 if (parameterizedType.type.isProvablyDistinctFrom(otherType.erasure(), depth)) return true;
247 switch (otherType.kind()) {
248 case Binding.GENERIC_TYPE :
249 case Binding.RAW_TYPE :
251 case Binding.PARAMETERIZED_TYPE :
252 TypeBinding[] arguments = parameterizedType.arguments;
253 if (arguments == null) return false;
254 ParameterizedTypeBinding otherParameterizedType = (ParameterizedTypeBinding) otherType;
255 TypeBinding[] otherArguments = otherParameterizedType.arguments;
256 if (otherArguments == null) return false;
257 for (int i = 0, length = arguments.length; i < length; i++) {
258 if (arguments[i].isProvablyDistinctFrom(otherArguments[i], depth+1)) return true;
265 case Binding.RAW_TYPE :
266 return this.erasure().isProvablyDistinctFrom(otherType.erasure(), 0);
268 case Binding.GENERIC_TYPE :
269 return this != otherType.erasure();
271 return this != otherType;
274 public boolean isRawType() {
281 public boolean isReifiable() {
283 TypeBinding leafType = leafComponentType();
284 if (!(leafType instanceof ReferenceBinding))
286 ReferenceBinding current = (ReferenceBinding) leafType;
288 switch(current.kind()) {
290 case Binding.TYPE_PARAMETER :
291 case Binding.WILDCARD_TYPE :
292 case Binding.GENERIC_TYPE :
295 case Binding.PARAMETERIZED_TYPE :
296 if (isBoundParameterizedType())
300 case Binding.RAW_TYPE :
303 if (current.isStatic())
305 } while ((current = current.enclosingType()) != null);
310 public boolean isTypeArgumentContainedBy(TypeBinding otherArgument) {
311 if (this == otherArgument)
313 TypeBinding lowerBound = this;
314 TypeBinding upperBound = this;
316 WildcardBinding wildcard = (WildcardBinding) this;
317 switch(wildcard.kind) {
318 case Wildcard.EXTENDS :
319 upperBound = wildcard.bound;
322 case Wildcard. SUPER :
323 upperBound = wildcard.typeVariable();
324 lowerBound = wildcard.bound;
326 case Wildcard.UNBOUND :
327 upperBound = wildcard.typeVariable();
331 if (otherArgument.isWildcard()) {
332 WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
333 switch(otherWildcard.kind) {
334 case Wildcard.EXTENDS:
335 return upperBound != null && upperBound.isCompatibleWith(otherWildcard.bound);
337 case Wildcard.SUPER :
338 return lowerBound != null && otherWildcard.bound.isCompatibleWith(lowerBound);
340 case Wildcard.UNBOUND :
348 * Returns true if the type was declared as a type variable
350 public boolean isTypeVariable() {
354 * Returns true if wildcard type of the form '?' (no bound)
356 public boolean isUnboundWildcard() {
361 * Returns true if the type is a wildcard
363 public boolean isWildcard() {
368 * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
370 public boolean needsUncheckedConversion(TypeBinding targetType) {
374 public TypeBinding leafComponentType(){
379 * Answer the qualified name of the receiver's package separated by periods
380 * or an empty string if its the default package.
382 * For example, {java.util.Hashtable}.
385 public char[] qualifiedPackageName() {
386 PackageBinding packageBinding = getPackage();
387 return packageBinding == null || packageBinding.compoundName == CharOperation.NO_CHAR_CHAR
388 ? CharOperation.NO_CHAR
389 : packageBinding.readableName();
392 * Answer the source name for the type.
393 * In the case of member types, as the qualified name from its top level type.
394 * For example, for a member type N defined inside M & A: "A.M.N".
397 public abstract char[] qualifiedSourceName();
400 * Answer the receiver classfile signature.
401 * Arrays & base types do not distinguish between signature() & constantPoolName().
402 * NOTE: This method should only be used during/after code gen.
404 public char[] signature() {
405 return constantPoolName();
408 public abstract char[] sourceName();
410 public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment environment) {
411 // subclasses must override if they wrap another type binding
413 public TypeVariableBinding[] typeVariables() {
414 return NoTypeVariables;