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;
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
17 * Denote a raw type, i.e. a generic type referenced without any type arguments.
18 * e.g. X<T extends Exception> can be used a raw type 'X', in which case it
19 * will behave as X<Exception>
21 public class RawTypeBinding extends ParameterizedTypeBinding {
24 * Raw type arguments are erasure of respective parameter bounds. But we may not have resolved
25 * these bounds yet if creating raw types while supertype hierarchies are being connected.
26 * Therefore, use 'null' instead, and access these in a lazy way later on (when substituting).
28 public RawTypeBinding(ReferenceBinding type, ReferenceBinding enclosingType, LookupEnvironment environment){
29 super(type, null, enclosingType, environment);
30 if (enclosingType == null || (enclosingType.modifiers & AccGenericSignature) == 0)
31 this.modifiers &= ~AccGenericSignature; // only need signature if enclosing needs one
34 * @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
36 public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) {
37 if (originalMethod.typeVariables == NoTypeVariables || originalMethod.isStatic()) {
38 return super.createParameterizedMethod(originalMethod);
40 return new ParameterizedGenericMethodBinding(originalMethod, this, this.environment);
48 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
50 public String debugName() {
51 StringBuffer nameBuffer = new StringBuffer(10);
52 nameBuffer.append(this.type.sourceName()).append("#RAW"); //$NON-NLS-1$
53 return nameBuffer.toString();
57 * Ltype<param1 ... paramN>;
60 public char[] genericTypeSignature() {
62 if (this.genericTypeSignature == null) {
63 StringBuffer sig = new StringBuffer(10);
64 if (this.isMemberType() && this.enclosingType().isParameterizedType()) {
65 char[] typeSig = this.enclosingType().genericTypeSignature();
66 for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
67 sig.append('.').append(this.sourceName()).append(';');
68 int sigLength = sig.length();
69 this.genericTypeSignature = new char[sigLength];
70 sig.getChars(0, sigLength, this.genericTypeSignature, 0);
72 this.genericTypeSignature = this.type.signature(); // erasure
75 return this.genericTypeSignature;
78 public boolean isEquivalentTo(TypeBinding otherType) {
79 if (this == otherType) return true;
80 if (otherType == null) return false;
81 if (otherType.isWildcard()) // wildcard
82 return ((WildcardBinding) otherType).boundCheck(this);
83 return otherType.erasure() == this.erasure();
86 * Raw type is not treated as a standard parameterized type
87 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isParameterizedType()
89 public boolean isParameterizedType() {
92 public boolean isRawType() {
96 protected void initializeArguments() {
97 TypeVariableBinding[] typeVariables = this.type.typeVariables();
98 int length = typeVariables.length;
99 TypeBinding[] typeArguments = new TypeBinding[length];
100 for (int i = 0; i < length; i++) {
101 typeArguments[i] = typeVariables[i].erasure();
103 this.arguments = typeArguments;
106 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
108 public char[] readableName() /*java.lang.Object, p.X<T> */ {
110 if (isMemberType()) {
111 readableName = CharOperation.concat(enclosingType().readableName(), sourceName, '.');
113 readableName = CharOperation.concatWith(this.type.compoundName, '.');
119 * Returns a type, where original type was substituted using the receiver
121 * On raw types, all parameterized type denoting same original type are converted
126 * } when used in raw fashion, then type of both foo and bar is raw type X.
128 public TypeBinding substitute(TypeBinding originalType) {
130 switch (originalType.kind()) {
132 case Binding.TYPE_PARAMETER:
133 TypeVariableBinding originalVariable = (TypeVariableBinding) originalType;
134 ParameterizedTypeBinding currentType = this;
136 TypeVariableBinding[] typeVariables = currentType.type.typeVariables();
137 int length = typeVariables.length;
138 // check this variable can be substituted given parameterized type
139 if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) {
140 // lazy init, since cannot do so during binding creation if during supertype connection
141 if (currentType.arguments == null) currentType.initializeArguments();
142 if (currentType.arguments != null)
143 return currentType.arguments[originalVariable.rank];
145 // recurse on enclosing type, as it may hold more substitutions to perform
146 ReferenceBinding enclosing = currentType.enclosingType();
147 if (!(enclosing instanceof ParameterizedTypeBinding))
149 currentType = (ParameterizedTypeBinding) enclosing;
153 case Binding.PARAMETERIZED_TYPE:
154 ReferenceBinding substitutedEnclosing = originalType.enclosingType();
155 if (substitutedEnclosing != null) {
156 substitutedEnclosing = (ReferenceBinding) this.substitute(substitutedEnclosing);
158 ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
159 return this.environment.createRawType(originalParameterizedType.type, substitutedEnclosing);
161 case Binding.GENERIC_TYPE:
162 substitutedEnclosing = originalType.enclosingType();
163 if (substitutedEnclosing != null) {
164 substitutedEnclosing = (ReferenceBinding) this.substitute(substitutedEnclosing);
166 return this.environment.createRawType((ReferenceBinding)originalType, substitutedEnclosing);
168 case Binding.WILDCARD_TYPE:
169 WildcardBinding wildcard = (WildcardBinding) originalType;
170 if (wildcard.kind != Wildcard.UNBOUND) {
171 TypeBinding originalBound = wildcard.bound;
172 TypeBinding substitutedBound = substitute(originalBound);
173 if (substitutedBound != originalBound) {
174 return this.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, wildcard.kind);
179 case Binding.ARRAY_TYPE:
180 TypeBinding originalLeafComponentType = originalType.leafComponentType();
181 TypeBinding substitute = substitute(originalLeafComponentType); // substitute could itself be array type
182 if (substitute != originalLeafComponentType) {
183 return this.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
191 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
193 public char[] shortReadableName() /*Object*/ {
194 char[] shortReadableName;
195 if (isMemberType()) {
196 shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
198 shortReadableName = this.type.sourceName;
200 return shortReadableName;