001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.compiler.lookup;
011:
012: import org.eclipse.jdt.core.compiler.CharOperation;
013:
014: /**
015: * Denote a raw type, i.e. a generic type referenced without any type arguments.
016: * e.g. X<T extends Exception> can be used a raw type 'X', in which case it
017: * will behave as X<Exception>
018: */
019: public class RawTypeBinding extends ParameterizedTypeBinding {
020:
021: /**
022: * Raw type arguments are erasure of respective parameter bounds. But we may not have resolved
023: * these bounds yet if creating raw types while supertype hierarchies are being connected.
024: * Therefore, use 'null' instead, and access these in a lazy way later on (when substituting).
025: */
026: public RawTypeBinding(ReferenceBinding type,
027: ReferenceBinding enclosingType,
028: LookupEnvironment environment) {
029: super (type, null, enclosingType, environment);
030: if (enclosingType == null
031: || (enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0)
032: this .modifiers &= ~ExtraCompilerModifiers.AccGenericSignature; // only need signature if enclosing needs one
033: }
034:
035: public char[] computeUniqueKey(boolean isLeaf) {
036: StringBuffer sig = new StringBuffer(10);
037: if (isMemberType() && enclosingType().isParameterizedType()) {
038: char[] typeSig = enclosingType()
039: .computeUniqueKey(false/*not a leaf*/);
040: sig.append(typeSig, 0, typeSig.length - 1); // copy all but trailing semicolon
041: sig.append('.').append(sourceName()).append('<')
042: .append('>').append(';');
043: } else {
044: sig.append(genericType()
045: .computeUniqueKey(false/*not a leaf*/));
046: sig.insert(sig.length() - 1, "<>"); //$NON-NLS-1$
047: }
048:
049: int sigLength = sig.length();
050: char[] uniqueKey = new char[sigLength];
051: sig.getChars(0, sigLength, uniqueKey, 0);
052: return uniqueKey;
053: }
054:
055: /**
056: * @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
057: */
058: public ParameterizedMethodBinding createParameterizedMethod(
059: MethodBinding originalMethod) {
060: if (originalMethod.typeVariables == Binding.NO_TYPE_VARIABLES
061: || originalMethod.isStatic()) {
062: return super .createParameterizedMethod(originalMethod);
063: }
064: return this .environment.createParameterizedGenericMethod(
065: originalMethod, this );
066: }
067:
068: public int kind() {
069: return RAW_TYPE;
070: }
071:
072: /**
073: * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
074: */
075: public String debugName() {
076: StringBuffer nameBuffer = new StringBuffer(10);
077: nameBuffer.append(actualType().sourceName()).append("#RAW"); //$NON-NLS-1$
078: return nameBuffer.toString();
079: }
080:
081: /**
082: * Ltype<param1 ... paramN>;
083: * LY<TT;>;
084: */
085: public char[] genericTypeSignature() {
086: if (this .genericTypeSignature == null) {
087: if ((this .modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) {
088: this .genericTypeSignature = genericType().signature();
089: } else {
090: StringBuffer sig = new StringBuffer(10);
091: if (this .isMemberType()) {
092: ReferenceBinding enclosing = enclosingType();
093: boolean hasParameterizedEnclosing = enclosing
094: .isParameterizedType();
095: char[] typeSig = hasParameterizedEnclosing ? enclosing
096: .genericTypeSignature()
097: : enclosing.signature();
098: sig.append(typeSig, 0, typeSig.length - 1);// copy all but trailing semicolon
099: if (hasParameterizedEnclosing
100: && (enclosing.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
101: sig.append('.');
102: } else {
103: sig.append('$');
104: }
105: sig.append(this .sourceName());
106: } else {
107: char[] typeSig = genericType().signature();
108: sig.append(typeSig, 0, typeSig.length - 1);// copy all but trailing semicolon
109: }
110: sig.append(';');
111: int sigLength = sig.length();
112: this .genericTypeSignature = new char[sigLength];
113: sig
114: .getChars(0, sigLength,
115: this .genericTypeSignature, 0);
116: }
117: }
118: return this .genericTypeSignature;
119: }
120:
121: public boolean isEquivalentTo(TypeBinding otherType) {
122: if (this == otherType)
123: return true;
124: if (otherType == null)
125: return false;
126: switch (otherType.kind()) {
127:
128: case Binding.WILDCARD_TYPE:
129: return ((WildcardBinding) otherType).boundCheck(this );
130:
131: case Binding.GENERIC_TYPE:
132: case Binding.PARAMETERIZED_TYPE:
133: case Binding.RAW_TYPE:
134: return erasure() == otherType.erasure();
135: }
136: return false;
137: }
138:
139: public boolean isIntersectingWith(TypeBinding otherType) {
140: if (this == otherType)
141: return true;
142: if (otherType == null)
143: return false;
144: switch (otherType.kind()) {
145:
146: case Binding.GENERIC_TYPE:
147: case Binding.PARAMETERIZED_TYPE:
148: case Binding.RAW_TYPE:
149: return erasure() == otherType.erasure();
150: }
151: return false;
152: }
153:
154: /**
155: * Raw type is not treated as a standard parameterized type
156: * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isParameterizedType()
157: */
158: public boolean isParameterizedType() {
159: return false;
160: }
161:
162: public boolean isRawType() {
163: return true;
164: }
165:
166: protected void initializeArguments() {
167: TypeVariableBinding[] typeVariables = genericType()
168: .typeVariables();
169: int length = typeVariables.length;
170: TypeBinding[] typeArguments = new TypeBinding[length];
171: for (int i = 0; i < length; i++) {
172: // perform raw conversion on variable upper bound - could cause infinite regression if arguments were initialized lazily
173: typeArguments[i] = this .environment
174: .convertToRawType(typeVariables[i].erasure());
175: }
176: this .arguments = typeArguments;
177: }
178:
179: /**
180: * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
181: */
182: public char[] readableName() /*java.lang.Object, p.X<T> */{
183: char[] readableName;
184: if (isMemberType()) {
185: readableName = CharOperation.concat(enclosingType()
186: .readableName(), sourceName, '.');
187: } else {
188: readableName = CharOperation.concatWith(
189: actualType().compoundName, '.');
190: }
191: return readableName;
192: }
193:
194: /**
195: * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
196: */
197: public char[] shortReadableName() /*Object*/{
198: char[] shortReadableName;
199: if (isMemberType()) {
200: shortReadableName = CharOperation.concat(enclosingType()
201: .shortReadableName(), sourceName, '.');
202: } else {
203: shortReadableName = actualType().sourceName;
204: }
205: return shortReadableName;
206: }
207: }
|