/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
import org.eclipse.jdt.core.compiler.CharOperation;
/**
* Denote a raw type, i.e. a generic type referenced without any type arguments. e.g. X<T extends
* Exception> can be used a raw type 'X', in which case it will behave as X<Exception>
*/
public class RawTypeBinding extends ParameterizedTypeBinding {
/**
* Raw type arguments are erasure of respective parameter bounds. But we may not have resolved
* these bounds yet if creating raw types while supertype hierarchies are being connected.
* Therefore, use 'null' instead, and access these in a lazy way later on (when substituting).
*/
public RawTypeBinding(ReferenceBinding type, ReferenceBinding enclosingType, LookupEnvironment environment) {
super(type, null, enclosingType, environment);
if (enclosingType == null || (enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0)
this.modifiers&= ~ExtraCompilerModifiers.AccGenericSignature; // only need signature if enclosing needs one
}
public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer sig= new StringBuffer(10);
if (isMemberType() && enclosingType().isParameterizedType()) {
char[] typeSig= enclosingType().computeUniqueKey(false/*not a leaf*/);
sig.append(typeSig, 0, typeSig.length - 1); // copy all but trailing semicolon
sig.append('.').append(sourceName()).append('<').append('>').append(';');
} else {
sig.append(genericType().computeUniqueKey(false/*not a leaf*/));
sig.insert(sig.length() - 1, "<>"); //$NON-NLS-1$
}
int sigLength= sig.length();
char[] uniqueKey= new char[sigLength];
sig.getChars(0, sigLength, uniqueKey, 0);
return uniqueKey;
}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
*/
public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) {
if (originalMethod.typeVariables == Binding.NO_TYPE_VARIABLES || originalMethod.isStatic()) {
return super.createParameterizedMethod(originalMethod);
}
return this.environment.createParameterizedGenericMethod(originalMethod, this);
}
public int kind() {
return RAW_TYPE;
}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
*/
public String debugName() {
StringBuffer nameBuffer= new StringBuffer(10);
nameBuffer.append(actualType().sourceName()).append("#RAW"); //$NON-NLS-1$
return nameBuffer.toString();
}
/**
* Ltype<param1 ... paramN>; LY<TT;>;
*/
public char[] genericTypeSignature() {
if (this.genericTypeSignature == null) {
if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) {
this.genericTypeSignature= genericType().signature();
} else {
StringBuffer sig= new StringBuffer(10);
if (isMemberType()) {
ReferenceBinding enclosing= enclosingType();
char[] typeSig= enclosing.genericTypeSignature();
sig.append(typeSig, 0, typeSig.length - 1);// copy all but trailing semicolon
if ((enclosing.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
sig.append('.');
} else {
sig.append('$');
}
sig.append(sourceName());
} else {
char[] typeSig= genericType().signature();
sig.append(typeSig, 0, typeSig.length - 1);// copy all but trailing semicolon
}
sig.append(';');
int sigLength= sig.length();
this.genericTypeSignature= new char[sigLength];
sig.getChars(0, sigLength, this.genericTypeSignature, 0);
}
}
return this.genericTypeSignature;
}
public boolean isEquivalentTo(TypeBinding otherType) {
if (this == otherType)
return true;
if (otherType == null)
return false;
switch (otherType.kind()) {
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
return ((WildcardBinding)otherType).boundCheck(this);
case Binding.GENERIC_TYPE:
case Binding.PARAMETERIZED_TYPE:
case Binding.RAW_TYPE:
return erasure() == otherType.erasure();
}
return false;
}
public boolean isProvablyDistinct(TypeBinding otherType) {
if (this == otherType)
return false;
if (otherType == null)
return true;
switch (otherType.kind()) {
case Binding.GENERIC_TYPE:
case Binding.PARAMETERIZED_TYPE:
case Binding.RAW_TYPE:
return erasure() != otherType.erasure();
}
return true;
}
protected void initializeArguments() {
TypeVariableBinding[] typeVariables= genericType().typeVariables();
int length= typeVariables.length;
TypeBinding[] typeArguments= new TypeBinding[length];
for (int i= 0; i < length; i++) {
// perform raw conversion on variable upper bound - could cause infinite regression if arguments were initialized lazily
typeArguments[i]= this.environment.convertToRawType(typeVariables[i].erasure(), false /*do not force conversion of enclosing types*/);
}
this.arguments= typeArguments;
}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
*/
public char[] readableName() /*java.lang.Object, p.X<T> */{
char[] readableName;
if (isMemberType()) {
readableName= CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
} else {
readableName= CharOperation.concatWith(actualType().compoundName, '.');
}
return readableName;
}
/**
* @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
*/
public char[] shortReadableName() /*Object*/{
char[] shortReadableName;
if (isMemberType()) {
shortReadableName= CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.');
} else {
shortReadableName= actualType().sourceName;
}
return shortReadableName;
}
}