package org.eclipse.jdt.internal.compiler.lookup;
import java.util.List;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
abstract public class TypeBinding extends Binding {
public int id = TypeIds.NoId;
public long tagBits = 0;
protected AnnotationBinding [] typeAnnotations = Binding.NO_ANNOTATIONS;
public static final ReferenceBinding TYPE_USE_BINDING = new ReferenceBinding() {
{ this.id = TypeIds.T_undefined; }
@Override
public int kind() { return Binding.TYPE_USE; }
@Override
public boolean hasTypeBit(int bit) { return false; }
};
public final static BaseTypeBinding INT = new BaseTypeBinding(
TypeIds.T_int, TypeConstants.INT, new char[] { 'I' });
public final static BaseTypeBinding BYTE = new BaseTypeBinding(
TypeIds.T_byte, TypeConstants.BYTE, new char[] { 'B' });
public final static BaseTypeBinding SHORT = new BaseTypeBinding(
TypeIds.T_short, TypeConstants.SHORT, new char[] { 'S' });
public final static BaseTypeBinding CHAR = new BaseTypeBinding(
TypeIds.T_char, TypeConstants.CHAR, new char[] { 'C' });
public final static BaseTypeBinding LONG = new BaseTypeBinding(
TypeIds.T_long, TypeConstants.LONG, new char[] { 'J' });
public final static BaseTypeBinding FLOAT = new BaseTypeBinding(
TypeIds.T_float, TypeConstants.FLOAT, new char[] { 'F' });
public final static BaseTypeBinding DOUBLE = new BaseTypeBinding(
TypeIds.T_double, TypeConstants.DOUBLE, new char[] { 'D' });
public final static BaseTypeBinding BOOLEAN = new BaseTypeBinding(
TypeIds.T_boolean, TypeConstants.BOOLEAN, new char[] { 'Z' });
public final static NullTypeBinding NULL = new NullTypeBinding();
public final static VoidTypeBinding VOID = new VoidTypeBinding();
public TypeBinding() {
super();
}
public TypeBinding(TypeBinding prototype) {
this.id = prototype.id;
this.tagBits = prototype.tagBits & ~TagBits.AnnotationNullMASK;
}
public static final TypeBinding wellKnownType(Scope scope, int id) {
switch (id) {
case TypeIds.T_boolean:
return TypeBinding.BOOLEAN;
case TypeIds.T_byte:
return TypeBinding.BYTE;
case TypeIds.T_char:
return TypeBinding.CHAR;
case TypeIds.T_short:
return TypeBinding.SHORT;
case TypeIds.T_double:
return TypeBinding.DOUBLE;
case TypeIds.T_float:
return TypeBinding.FLOAT;
case TypeIds.T_int:
return TypeBinding.INT;
case TypeIds.T_long:
return TypeBinding.LONG;
case TypeIds.T_JavaLangObject:
return scope.getJavaLangObject();
case TypeIds.T_JavaLangString:
return scope.getJavaLangString();
default:
return null;
}
}
public ReferenceBinding actualType() {
return null;
}
TypeBinding [] additionalBounds() {
return null;
}
public String annotatedDebugName() {
TypeBinding enclosingType = enclosingType();
StringBuffer buffer = new StringBuffer(16);
if (enclosingType != null) {
buffer.append(enclosingType.annotatedDebugName());
buffer.append('.');
}
AnnotationBinding [] annotations = getTypeAnnotations();
for (int i = 0, length = annotations == null ? 0 : annotations.length; i < length; i++) {
buffer.append(annotations[i]);
buffer.append(' ');
}
buffer.append(sourceName());
return buffer.toString();
}
TypeBinding bound() {
return null;
}
int boundKind() {
return -1;
}
int rank() {
return -1;
}
public ReferenceBinding containerAnnotationType() {
return null;
}
public boolean canBeInstantiated() {
return !isBaseType();
}
public TypeBinding capture(Scope scope, int start, int end) {
return this;
}
public TypeBinding uncapture(Scope scope) {
return this;
}
public TypeBinding closestMatch() {
return this;
}
public List<TypeBinding> collectMissingTypes(List<TypeBinding> missingTypes) {
return missingTypes;
}
public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
}
public TypeBinding clone(TypeBinding enclosingType) {
throw new IllegalStateException("TypeBinding#clone() should have been overridden");
}
public abstract char[] constantPoolName();
public String debugName() {
return this.hasTypeAnnotations() ? annotatedDebugName() : new String(readableName());
}
public int dimensions() {
return 0;
}
public int depth() {
return 0;
}
public MethodBinding enclosingMethod() {
return null;
}
public ReferenceBinding enclosingType() {
return null;
}
public TypeBinding erasure() {
return this;
}
public TypeBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}
public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
return this;
}
public ReferenceBinding findSuperTypeOriginatingFrom(int wellKnownOriginalID, boolean originalIsClass) {
if (!(this instanceof ReferenceBinding)) return null;
ReferenceBinding reference = (ReferenceBinding) this;
if (reference.id == wellKnownOriginalID || (original().id == wellKnownOriginalID)) return reference;
ReferenceBinding currentType = reference;
if (originalIsClass) {
while ((currentType = currentType.superclass()) != null) {
if (currentType.id == wellKnownOriginalID)
return currentType;
if (currentType.original().id == wellKnownOriginalID)
return currentType;
}
return null;
}
ReferenceBinding[] interfacesToVisit = null;
int nextPosition = 0;
do {
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (interfacesToVisit == null) {
interfacesToVisit = itsInterfaces;
nextPosition = interfacesToVisit.length;
} else {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
} while ((currentType = currentType.superclass()) != null);
for (int i = 0; i < nextPosition; i++) {
currentType = interfacesToVisit[i];
if (currentType.id == wellKnownOriginalID)
return currentType;
if (currentType.original().id == wellKnownOriginalID)
return currentType;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
return null;
}
public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType) {
if (equalsEquals(this, otherType)) return this;
if (otherType == null) return null;
switch(kind()) {
case Binding.ARRAY_TYPE :
ArrayBinding arrayType = (ArrayBinding) this;
int otherDim = otherType.dimensions();
if (arrayType.dimensions != otherDim) {
switch(otherType.id) {
case TypeIds.T_JavaLangObject :
case TypeIds.T_JavaIoSerializable :
case TypeIds.T_JavaLangCloneable :
return otherType;
}
if (otherDim < arrayType.dimensions && otherType.leafComponentType().id == TypeIds.T_JavaLangObject) {
return otherType;
}
return null;
}
if (!(arrayType.leafComponentType instanceof ReferenceBinding)) return null;
TypeBinding leafSuperType = arrayType.leafComponentType.findSuperTypeOriginatingFrom(otherType.leafComponentType());
if (leafSuperType == null) return null;
return arrayType.environment().createArrayType(leafSuperType, arrayType.dimensions);
case Binding.TYPE_PARAMETER :
if (isCapture()) {
CaptureBinding capture = (CaptureBinding) this;
TypeBinding captureBound = capture.firstBound;
if (captureBound instanceof ArrayBinding) {
TypeBinding match = captureBound.findSuperTypeOriginatingFrom(otherType);
if (match != null) return match;
}
}
case Binding.TYPE :
case Binding.PARAMETERIZED_TYPE :
case Binding.GENERIC_TYPE :
case Binding.RAW_TYPE :
case Binding.WILDCARD_TYPE :
case Binding.INTERSECTION_TYPE:
otherType = otherType.original();
if (equalsEquals(this, otherType))
return this;
if (equalsEquals(original(), otherType))
return this;
ReferenceBinding currentType = (ReferenceBinding)this;
if (!otherType.isInterface()) {
while ((currentType = currentType.superclass()) != null) {
if (equalsEquals(currentType, otherType))
return currentType;
if (equalsEquals(currentType.original(), otherType))
return currentType;
}
return null;
}
ReferenceBinding[] interfacesToVisit = null;
int nextPosition = 0;
do {
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
if (interfacesToVisit == null) {
interfacesToVisit = itsInterfaces;
nextPosition = interfacesToVisit.length;
} else {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
} while ((currentType = currentType.superclass()) != null);
for (int i = 0; i < nextPosition; i++) {
currentType = interfacesToVisit[i];
if (equalsEquals(currentType, otherType))
return currentType;
if (equalsEquals(currentType.original(), otherType))
return currentType;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
int itsLength = itsInterfaces.length;
if (nextPosition + itsLength >= interfacesToVisit.length)
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
nextInterface : for (int a = 0; a < itsLength; a++) {
ReferenceBinding next = itsInterfaces[a];
for (int b = 0; b < nextPosition; b++)
if (equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
interfacesToVisit[nextPosition++] = next;
}
}
}
break;
case Binding.INTERSECTION_TYPE18:
IntersectionTypeBinding18 itb18 = (IntersectionTypeBinding18) this;
ReferenceBinding[] intersectingTypes = itb18.getIntersectingTypes();
for (int i = 0, length = intersectingTypes.length; i < length; i++) {
TypeBinding superType = intersectingTypes[i].findSuperTypeOriginatingFrom(otherType);
if (superType != null)
return superType;
}
break;
}
return null;
}
public TypeBinding genericCast(TypeBinding targetType) {
if (TypeBinding.equalsEquals(this, targetType))
return null;
TypeBinding targetErasure = targetType.erasure();
if (erasure().findSuperTypeOriginatingFrom(targetErasure) != null)
return null;
return targetErasure;
}
public char[] genericTypeSignature() {
return signature();
}
public TypeBinding getErasureCompatibleType(TypeBinding declaringClass) {
switch(kind()) {
case Binding.TYPE_PARAMETER :
TypeVariableBinding variable = (TypeVariableBinding) this;
if (variable.erasure().findSuperTypeOriginatingFrom(declaringClass) != null) {
return this;
}
if (variable.superclass != null && variable.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
return variable.superclass.getErasureCompatibleType(declaringClass);
}
for (int i = 0, otherLength = variable.superInterfaces.length; i < otherLength; i++) {
ReferenceBinding superInterface = variable.superInterfaces[i];
if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
return superInterface.getErasureCompatibleType(declaringClass);
}
}
return this;
case Binding.INTERSECTION_TYPE :
WildcardBinding intersection = (WildcardBinding) this;
if (intersection.erasure().findSuperTypeOriginatingFrom(declaringClass) != null) {
return this;
}
if (intersection.superclass != null && intersection.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
return intersection.superclass.getErasureCompatibleType(declaringClass);
}
for (int i = 0, otherLength = intersection.superInterfaces.length; i < otherLength; i++) {
ReferenceBinding superInterface = intersection.superInterfaces[i];
if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
return superInterface.getErasureCompatibleType(declaringClass);
}
}
return this;
case Binding.INTERSECTION_TYPE18:
ReferenceBinding[] intersectingTypes = ((IntersectionTypeBinding18) this).getIntersectingTypes();
ReferenceBinding constantPoolType = intersectingTypes[0];
if (constantPoolType.id == TypeIds.T_JavaLangObject && intersectingTypes.length > 1)
constantPoolType = intersectingTypes[1];
if (constantPoolType.erasure().findSuperTypeOriginatingFrom(declaringClass) != null) {
return this;
}
for (ReferenceBinding superBinding : intersectingTypes) {
if (superBinding.findSuperTypeOriginatingFrom(declaringClass) != null) {
return superBinding.getErasureCompatibleType(declaringClass);
}
}
return this;
default :
return this;
}
}
public abstract PackageBinding getPackage();
void initializeForStaticImports() {
}
public final boolean isAnonymousType() {
return (this.tagBits & TagBits.IsAnonymousType) != 0;
}
public final boolean isArrayType() {
return (this.tagBits & TagBits.IsArrayType) != 0;
}
public final boolean isBaseType() {
return (this.tagBits & TagBits.IsBaseType) != 0;
}
public final boolean isPrimitiveType() {
return (this.tagBits & TagBits.IsBaseType) != 0 && this.id != TypeIds.T_void && this.id != TypeIds.T_null;
}
public final boolean isPrimitiveOrBoxedPrimitiveType() {
if (isPrimitiveType())
return true;
switch (this.id) {
case TypeIds.T_JavaLangBoolean :
case TypeIds.T_JavaLangByte :
case TypeIds.T_JavaLangCharacter :
case TypeIds.T_JavaLangShort :
case TypeIds.T_JavaLangDouble :
case TypeIds.T_JavaLangFloat :
case TypeIds.T_JavaLangInteger :
case TypeIds.T_JavaLangLong :
return true;
default:
return false;
}
}
public boolean isBoxedPrimitiveType() {
switch (this.id) {
case TypeIds.T_JavaLangBoolean :
case TypeIds.T_JavaLangByte :
case TypeIds.T_JavaLangCharacter :
case TypeIds.T_JavaLangShort :
case TypeIds.T_JavaLangDouble :
case TypeIds.T_JavaLangFloat :
case TypeIds.T_JavaLangInteger :
case TypeIds.T_JavaLangLong :
return true;
default:
return false;
}
}
public boolean isBoundParameterizedType() {
return false;
}
public boolean isCapture() {
return false;
}
public boolean isClass() {
return false;
}
public boolean isCompatibleWith(TypeBinding right) {
return isCompatibleWith(right, null);
}
public abstract boolean isCompatibleWith(TypeBinding right, Scope scope);
public boolean isPotentiallyCompatibleWith(TypeBinding right, Scope scope) {
return isCompatibleWith(right, scope);
}
public boolean isBoxingCompatibleWith(TypeBinding right, Scope scope) {
if (right == null)
return false;
if (TypeBinding.equalsEquals(this, right))
return true;
if (this.isCompatibleWith(right, scope))
return true;
if (this.isBaseType() != right.isBaseType()) {
TypeBinding convertedType = scope.environment().computeBoxingType(this);
if (TypeBinding.equalsEquals(convertedType, right) || convertedType.isCompatibleWith(right, scope))
return true;
}
return false;
}
public boolean isEnum() {
return false;
}
public boolean isEquivalentTo(TypeBinding otherType) {
if (equalsEquals(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);
}
return false;
}
public boolean isGenericType() {
return false;
}
public final boolean isHierarchyInconsistent() {
return (this.tagBits & TagBits.HierarchyHasProblems) != 0;
}
public boolean isInterface() {
return false;
}
public boolean isFunctionalInterface(Scope scope) {
return false;
}
public boolean isIntersectionType() {
return false;
}
public final boolean isLocalType() {
return (this.tagBits & TagBits.IsLocalType) != 0;
}
public final boolean isMemberType() {
return (this.tagBits & TagBits.IsMemberType) != 0;
}
public final boolean isNestedType() {
return (this.tagBits & TagBits.IsNestedType) != 0;
}
public final boolean isNumericType() {
switch (this.id) {
case TypeIds.T_int:
case TypeIds.T_float:
case TypeIds.T_double:
case TypeIds.T_short:
case TypeIds.T_byte:
case TypeIds.T_long:
case TypeIds.T_char:
return true;
default:
return false;
}
}
public boolean isParameterizedType() {
return false;
}
public boolean hasNullTypeAnnotations() {
return (this.tagBits & TagBits.HasNullTypeAnnotation) != 0;
}
public boolean acceptsNonNullDefault() {
return false;
}
public boolean isIntersectionType18() {
return false;
}
public final boolean isParameterizedTypeWithActualArguments() {
return (kind() == Binding.PARAMETERIZED_TYPE)
&& ((ParameterizedTypeBinding) this).arguments != null;
}
public boolean isParameterizedWithOwnVariables() {
if (kind() != Binding.PARAMETERIZED_TYPE)
return false;
ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
if (paramType.arguments == null)
return false;
TypeVariableBinding[] variables = erasure().typeVariables();
for (int i = 0, length = variables.length; i < length; i++) {
if (TypeBinding.notEquals(variables[i], paramType.arguments[i]))
return false;
}
ReferenceBinding enclosing = paramType.enclosingType();
if (enclosing != null && enclosing.erasure().isGenericType()
&& !enclosing.isParameterizedWithOwnVariables()) {
return false;
}
return true;
}
public boolean isProperType(boolean admitCapture18) {
return true;
}
public boolean isPolyType() {
return false;
}
TypeBinding substituteInferenceVariable(InferenceVariable var, TypeBinding substituteType) {
return this;
}
private boolean isProvableDistinctSubType(TypeBinding otherType) {
if (otherType.isInterface()) {
if (isInterface())
return false;
if (isArrayType()
|| ((this instanceof ReferenceBinding) && ((ReferenceBinding) this).isFinal())
|| (isTypeVariable() && ((TypeVariableBinding)this).superclass().isFinal())) {
return !isCompatibleWith(otherType);
}
return false;
} else {
if (isInterface()) {
if (otherType.isArrayType()
|| ((otherType instanceof ReferenceBinding) && ((ReferenceBinding) otherType).isFinal())
|| (otherType.isTypeVariable() && ((TypeVariableBinding)otherType).superclass().isFinal())) {
return !isCompatibleWith(otherType);
}
} else {
if (!isTypeVariable() && !otherType.isTypeVariable()) {
return !isCompatibleWith(otherType);
}
}
}
return false;
}
public boolean isProvablyDistinct(TypeBinding otherType) {
if (equalsEquals(this, otherType))
return false;
if (otherType == null)
return true;
switch (kind()) {
case Binding.PARAMETERIZED_TYPE :
ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
switch(otherType.kind()) {
case Binding.PARAMETERIZED_TYPE :
ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
if (notEquals(paramType.genericType(), otherParamType.genericType()))
return true;
if (!paramType.isStatic()) {
ReferenceBinding enclosing = enclosingType();
if (enclosing != null) {
ReferenceBinding otherEnclosing = otherParamType.enclosingType();
if (otherEnclosing == null) return true;
if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
if (enclosing.isProvablyDistinct(otherEnclosing)) return true;
} else {
if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return true;
}
}
}
int length = paramType.arguments == null ? 0 : paramType.arguments.length;
TypeBinding[] otherArguments = otherParamType.arguments;
int otherLength = otherArguments == null ? 0 : otherArguments.length;
if (otherLength != length)
return true;
for (int i = 0; i < length; i++) {
if (paramType.arguments[i].isProvablyDistinctTypeArgument(otherArguments[i], paramType, i))
return true;
}
return false;
case Binding.GENERIC_TYPE :
if (notEquals(paramType.genericType(), otherType))
return true;
if (!paramType.isStatic()) {
ReferenceBinding enclosing = enclosingType();
if (enclosing != null) {
ReferenceBinding otherEnclosing = otherType.enclosingType();
if (otherEnclosing == null) return true;
if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
if (notEquals(enclosing, otherEnclosing)) return true;
} else {
if (!enclosing.isEquivalentTo(otherType.enclosingType())) return true;
}
}
}
length = paramType.arguments == null ? 0 : paramType.arguments.length;
otherArguments = otherType.typeVariables();
otherLength = otherArguments == null ? 0 : otherArguments.length;
if (otherLength != length)
return true;
for (int i = 0; i < length; i++) {
if (paramType.arguments[i].isProvablyDistinctTypeArgument(otherArguments[i], paramType, i))
return true;
}
return false;
case Binding.RAW_TYPE :
return notEquals(erasure(), otherType.erasure());
case Binding.TYPE:
return notEquals(erasure(), otherType);
}
return true;
case Binding.RAW_TYPE :
switch(otherType.kind()) {
case Binding.GENERIC_TYPE :
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
case Binding.TYPE:
return notEquals(erasure(), otherType.erasure());
}
return true;
case Binding.TYPE:
switch(otherType.kind()) {
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
return notEquals(this, otherType.erasure());
}
break;
default :
break;
}
return true;
}
private boolean isProvablyDistinctTypeArgument(TypeBinding otherArgument, final ParameterizedTypeBinding paramType, final int rank) {
if (TypeBinding.equalsEquals(this, otherArgument))
return false;
TypeBinding upperBound1 = null;
TypeBinding lowerBound1 = null;
ReferenceBinding genericType = paramType.genericType();
switch (kind()) {
case Binding.WILDCARD_TYPE :
WildcardBinding wildcard = (WildcardBinding) this;
switch (wildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound1 = wildcard.bound;
break;
case Wildcard.SUPER:
lowerBound1 = wildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
break;
case Binding.INTERSECTION_TYPE :
break;
case Binding.TYPE_PARAMETER :
final TypeVariableBinding variable = (TypeVariableBinding) this;
if (variable.isCapture()) {
if (variable instanceof CaptureBinding18) {
CaptureBinding18 cb18 = (CaptureBinding18)variable;
upperBound1 = cb18.firstBound;
lowerBound1 = cb18.lowerBound;
} else {
CaptureBinding capture = (CaptureBinding) variable;
switch (capture.wildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound1 = capture.wildcard.bound;
break;
case Wildcard.SUPER:
lowerBound1 = capture.wildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
}
break;
}
if (variable.firstBound == null)
return false;
TypeBinding eliminatedType = Scope.convertEliminatingTypeVariables(variable, genericType, rank, null);
switch (eliminatedType.kind()) {
case Binding.WILDCARD_TYPE :
case Binding.INTERSECTION_TYPE :
wildcard = (WildcardBinding) eliminatedType;
switch (wildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound1 = wildcard.bound;
break;
case Wildcard.SUPER:
lowerBound1 = wildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
break;
}
break;
}
TypeBinding upperBound2 = null;
TypeBinding lowerBound2 = null;
switch (otherArgument.kind()) {
case Binding.WILDCARD_TYPE :
WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
switch (otherWildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound2 = otherWildcard.bound;
break;
case Wildcard.SUPER:
lowerBound2 = otherWildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
break;
case Binding.INTERSECTION_TYPE :
break;
case Binding.TYPE_PARAMETER :
TypeVariableBinding otherVariable = (TypeVariableBinding) otherArgument;
if (otherVariable.isCapture()) {
if (otherVariable instanceof CaptureBinding18) {
CaptureBinding18 cb18 = (CaptureBinding18)otherVariable;
upperBound2 = cb18.firstBound;
lowerBound2 = cb18.lowerBound;
} else {
CaptureBinding otherCapture = (CaptureBinding) otherVariable;
switch (otherCapture.wildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound2 = otherCapture.wildcard.bound;
break;
case Wildcard.SUPER:
lowerBound2 = otherCapture.wildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
}
break;
}
if (otherVariable.firstBound == null)
return false;
TypeBinding otherEliminatedType = Scope.convertEliminatingTypeVariables(otherVariable, genericType, rank, null);
switch (otherEliminatedType.kind()) {
case Binding.WILDCARD_TYPE :
case Binding.INTERSECTION_TYPE :
otherWildcard = (WildcardBinding) otherEliminatedType;
switch (otherWildcard.boundKind) {
case Wildcard.EXTENDS:
upperBound2 = otherWildcard.bound;
break;
case Wildcard.SUPER:
lowerBound2 = otherWildcard.bound;
break;
case Wildcard.UNBOUND:
return false;
}
break;
} break;
}
if (lowerBound1 != null) {
if (lowerBound2 != null) {
return false;
} else if (upperBound2 != null) {
if (lowerBound1.isTypeVariable() || upperBound2.isTypeVariable()) {
return false;
}
return !lowerBound1.isCompatibleWith(upperBound2);
} else {
if (lowerBound1.isTypeVariable() || otherArgument.isTypeVariable()) {
return false;
}
return !lowerBound1.isCompatibleWith(otherArgument);
}
} else if (upperBound1 != null) {
if (lowerBound2 != null) {
return !lowerBound2.isCompatibleWith(upperBound1);
} else if (upperBound2 != null) {
return upperBound1.isProvableDistinctSubType(upperBound2)
&& upperBound2.isProvableDistinctSubType(upperBound1);
} else {
return otherArgument.isProvableDistinctSubType(upperBound1);
}
} else {
if (lowerBound2 != null) {
if (lowerBound2.isTypeVariable() || isTypeVariable()) {
return false;
}
return !lowerBound2.isCompatibleWith(this);
} else if (upperBound2 != null) {
return isProvableDistinctSubType(upperBound2);
} else {
return true;
}
}
}
public boolean isRepeatableAnnotationType() {
return false;
}
public final boolean isRawType() {
return kind() == Binding.RAW_TYPE;
}
public boolean isReifiable() {
TypeBinding leafType = leafComponentType();
if (!(leafType instanceof ReferenceBinding))
return true;
ReferenceBinding current = (ReferenceBinding) leafType;
do {
switch (current.kind()) {
case Binding.TYPE_PARAMETER:
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
case Binding.GENERIC_TYPE:
return false;
case Binding.PARAMETERIZED_TYPE:
if (current.isBoundParameterizedType())
return false;
break;
case Binding.RAW_TYPE:
return true;
}
if (current.isStatic()) {
return true;
}
if (current.isLocalType()) {
LocalTypeBinding localTypeBinding = (LocalTypeBinding) current.erasure();
MethodBinding enclosingMethod = localTypeBinding.enclosingMethod;
if (enclosingMethod != null && enclosingMethod.isStatic()) {
return true;
}
}
} while ((current = current.enclosingType()) != null);
return true;
}
public boolean isStatic() {
return false;
}
public boolean isThrowable() {
return false;
}
public boolean isTypeArgumentContainedBy(TypeBinding otherType) {
if (TypeBinding.equalsEquals(this, otherType))
return true;
switch (otherType.kind()) {
case Binding.TYPE_PARAMETER: {
if (!isParameterizedType() || !otherType.isCapture()) {
return false;
}
CaptureBinding capture = (CaptureBinding) otherType;
if (capture instanceof CaptureBinding18) {
CaptureBinding18 cb18 = (CaptureBinding18) capture;
if (cb18.firstBound != null) {
if (cb18.lowerBound != null)
return false;
TypeBinding[] otherBounds = null;
int len = cb18.upperBounds.length;
if (len > 1)
System.arraycopy(cb18.upperBounds, 1, otherBounds = new TypeBinding[len-1], 0, len-1);
otherType = capture.environment.createWildcard(null, 0, cb18.firstBound, otherBounds, Wildcard.EXTENDS);
} else if (cb18.lowerBound != null) {
otherType = capture.environment.createWildcard(null, 0, cb18.lowerBound, null, Wildcard.SUPER);
} else {
return false;
}
} else {
TypeBinding upperBound = null;
TypeBinding [] otherBounds = null;
WildcardBinding wildcard = capture.wildcard;
switch (wildcard.boundKind) {
case Wildcard.SUPER:
return false;
case Wildcard.UNBOUND:
TypeVariableBinding variable = wildcard.genericType.typeVariables()[wildcard.rank];
upperBound = variable.upperBound();
otherBounds = variable.boundsCount() > 1 ? variable.otherUpperBounds() : null;
break;
case Wildcard.EXTENDS:
upperBound = wildcard.bound;
otherBounds = wildcard.otherBounds;
break;
}
if (upperBound.id == TypeIds.T_JavaLangObject && otherBounds == null) {
return false;
}
otherType = capture.environment.createWildcard(null, 0, upperBound, otherBounds, Wildcard.EXTENDS);
}
return isTypeArgumentContainedBy(otherType);
}
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
TypeBinding lowerBound = this;
TypeBinding upperBound = this;
switch (kind()) {
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
WildcardBinding wildcard = (WildcardBinding) this;
switch (wildcard.boundKind) {
case Wildcard.EXTENDS:
if (wildcard.otherBounds != null)
break;
upperBound = wildcard.bound;
lowerBound = null;
break;
case Wildcard.SUPER:
upperBound = wildcard;
lowerBound = wildcard.bound;
break;
case Wildcard.UNBOUND:
upperBound = wildcard;
lowerBound = null;
}
break;
case Binding.TYPE_PARAMETER:
if (isCapture()) {
CaptureBinding capture = (CaptureBinding) this;
if (capture.lowerBound != null)
lowerBound = capture.lowerBound;
}
}
WildcardBinding otherWildcard = (WildcardBinding) otherType;
if (otherWildcard.otherBounds != null)
return false;
TypeBinding otherBound = otherWildcard.bound;
switch (otherWildcard.boundKind) {
case Wildcard.EXTENDS:
if (otherBound instanceof IntersectionTypeBinding18) {
TypeBinding [] intersectingTypes = ((IntersectionTypeBinding18) otherBound).intersectingTypes;
for (int i = 0, length = intersectingTypes.length; i < length; i++)
if (TypeBinding.equalsEquals(intersectingTypes[i], this))
return true;
}
if (TypeBinding.equalsEquals(otherBound, this))
return true;
if (upperBound == null)
return false;
TypeBinding match = upperBound.findSuperTypeOriginatingFrom(otherBound);
if (match != null && (match = match.leafComponentType()).isRawType()) {
return TypeBinding.equalsEquals(match, otherBound.leafComponentType());
}
return upperBound.isCompatibleWith(otherBound);
case Wildcard.SUPER:
if (otherBound instanceof IntersectionTypeBinding18) {
TypeBinding [] intersectingTypes = ((IntersectionTypeBinding18) otherBound).intersectingTypes;
for (int i = 0, length = intersectingTypes.length; i < length; i++)
if (TypeBinding.equalsEquals(intersectingTypes[i], this))
return true;
}
if (TypeBinding.equalsEquals(otherBound, this))
return true;
if (lowerBound == null)
return false;
match = otherBound.findSuperTypeOriginatingFrom(lowerBound);
if (match != null && (match = match.leafComponentType()).isRawType()) {
return TypeBinding.equalsEquals(match, lowerBound.leafComponentType());
}
return otherBound.isCompatibleWith(lowerBound);
case Wildcard.UNBOUND:
default:
return true;
}
case Binding.PARAMETERIZED_TYPE:
if (!isParameterizedType())
return false;
ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
if (TypeBinding.notEquals(paramType.actualType(), otherParamType.actualType()))
return false;
if (!paramType.isStatic()) {
ReferenceBinding enclosing = enclosingType();
if (enclosing != null) {
ReferenceBinding otherEnclosing = otherParamType .enclosingType();
if (otherEnclosing == null)
return false;
if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
if (TypeBinding.notEquals(enclosing, otherEnclosing))
return false;
} else {
if (!enclosing.isTypeArgumentContainedBy(otherParamType.enclosingType()))
return false;
}
}
}
int length = paramType.arguments == null ? 0 : paramType.arguments.length;
TypeBinding[] otherArguments = otherParamType.arguments;
int otherLength = otherArguments == null ? 0 : otherArguments.length;
if (otherLength != length)
return false;
nextArgument: for (int i = 0; i < length; i++) {
TypeBinding argument = paramType.arguments[i];
TypeBinding otherArgument = otherArguments[i];
if (TypeBinding.equalsEquals(argument, otherArgument))
continue nextArgument;
int kind = argument.kind();
if (otherArgument.kind() != kind)
return false;
switch (kind) {
case Binding.PARAMETERIZED_TYPE:
if (argument.isTypeArgumentContainedBy(otherArgument))
continue nextArgument;
break;
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
WildcardBinding wildcard = (WildcardBinding) argument;
otherWildcard = (WildcardBinding) otherArgument;
switch (wildcard.boundKind) {
case Wildcard.EXTENDS:
if (otherWildcard.boundKind == Wildcard.UNBOUND
&& TypeBinding.equalsEquals(wildcard.bound, wildcard.typeVariable().upperBound()))
continue nextArgument;
break;
case Wildcard.SUPER:
break;
case Wildcard.UNBOUND:
if (otherWildcard.boundKind == Wildcard.EXTENDS
&& TypeBinding.equalsEquals(otherWildcard.bound, otherWildcard.typeVariable().upperBound()))
continue nextArgument;
break;
}
break;
}
return false;
}
return true;
}
if (otherType.id == TypeIds.T_JavaLangObject) {
switch (kind()) {
case Binding.WILDCARD_TYPE:
WildcardBinding wildcard = (WildcardBinding) this;
if (wildcard.boundKind == Wildcard.SUPER && wildcard.bound.id == TypeIds.T_JavaLangObject) {
return true;
}
break;
}
}
return false;
}
public boolean isTypeVariable() {
return false;
}
public boolean isUnboundWildcard() {
return false;
}
public boolean isUncheckedException(boolean includeSupertype) {
return false;
}
public boolean isWildcard() {
return false;
}
@Override
public int kind() {
return Binding.TYPE;
}
public TypeBinding leafComponentType() {
return this;
}
public boolean needsUncheckedConversion(TypeBinding targetType) {
if (TypeBinding.equalsEquals(this, targetType))
return false;
targetType = targetType.leafComponentType();
if (!(targetType instanceof ReferenceBinding))
return false;
TypeBinding currentType = leafComponentType();
TypeBinding match = currentType.findSuperTypeOriginatingFrom(targetType);
if (!(match instanceof ReferenceBinding))
return false;
ReferenceBinding compatible = (ReferenceBinding) match;
while (compatible.isRawType()) {
if (targetType.isBoundParameterizedType())
return true;
if (compatible.isStatic())
break;
if ((compatible = compatible.enclosingType()) == null)
break;
if ((targetType = targetType.enclosingType()) == null)
break;
}
return false;
}
public char[] nullAnnotatedReadableName(CompilerOptions options, boolean shortNames) {
if (shortNames)
return shortReadableName();
else
return readableName();
}
public TypeBinding original() {
switch(kind()) {
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
case Binding.ARRAY_TYPE :
return erasure().unannotated();
default :
return this.unannotated();
}
}
public TypeBinding unannotated() {
return this;
}
public TypeBinding withoutToplevelNullAnnotation() {
return this;
}
public final boolean hasTypeAnnotations() {
return (this.tagBits & TagBits.HasTypeAnnotations) != 0;
}
public char[] qualifiedPackageName() {
PackageBinding packageBinding = getPackage();
return packageBinding == null
|| packageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? CharOperation.NO_CHAR
: packageBinding.readableName();
}
public abstract char[] qualifiedSourceName();
final public AnnotationBinding[] getTypeAnnotations() {
return this.typeAnnotations;
}
public void setTypeAnnotations(AnnotationBinding[] annotations, boolean evalNullAnnotations) {
this.tagBits |= TagBits.HasTypeAnnotations;
if (annotations == null || annotations.length == 0)
return;
this.typeAnnotations = annotations;
if (evalNullAnnotations) {
for (int i = 0, length = annotations.length; i < length; i++) {
AnnotationBinding annotation = annotations[i];
if (annotation != null) {
if (annotation.type.hasNullBit(TypeIds.BitNullableAnnotation))
this.tagBits |= TagBits.AnnotationNullable | TagBits.HasNullTypeAnnotation;
else if (annotation.type.hasNullBit(TypeIds.BitNonNullAnnotation))
this.tagBits |= TagBits.AnnotationNonNull | TagBits.HasNullTypeAnnotation;
}
}
}
}
public char [] signableName() {
return readableName();
}
public char[] signature() {
return constantPoolName();
}
public abstract char[] sourceName();
public void swapUnresolved(UnresolvedReferenceBinding unresolvedType,
ReferenceBinding resolvedType, LookupEnvironment environment) {
}
TypeBinding [] typeArguments () {
return null;
}
public TypeVariableBinding[] typeVariables() {
return Binding.NO_TYPE_VARIABLES;
}
public MethodBinding getSingleAbstractMethod(Scope scope, boolean replaceWildcards) {
return null;
}
public ReferenceBinding[] getIntersectingTypes() {
return null;
}
public static boolean equalsEquals(TypeBinding that, TypeBinding other) {
if (that == other)
return true;
if (that == null || other == null)
return false;
if (that.id != TypeIds.NoId && that.id == other.id)
return true;
if (that instanceof LocalTypeBinding && other instanceof LocalTypeBinding) {
return ((LocalTypeBinding) that).sourceStart == ((LocalTypeBinding) other).sourceStart;
}
return false;
}
public static boolean notEquals(TypeBinding that, TypeBinding other) {
if (that == other)
return false;
if (that == null || other == null)
return true;
if (that.id != TypeIds.NoId && that.id == other.id)
return false;
return true;
}
public TypeBinding prototype() {
return null;
}
public boolean isUnresolvedType() {
return false;
}
public boolean mentionsAny(TypeBinding[] parameters, int idx) {
for (int i = 0; i < parameters.length; i++)
if (i != idx)
if (TypeBinding.equalsEquals(parameters[i], this))
return true;
return false;
}
void collectInferenceVariables(Set<InferenceVariable> variables) {
}
public boolean hasTypeBit(int bit) {
return false;
}
public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope scope) {
return s.isCompatibleWith(t, scope) && !s.needsUncheckedConversion(t);
}
public boolean isSubtypeOf(TypeBinding right, boolean simulatingBugJDK8026527) {
return isCompatibleWith(right);
}
public MethodBinding[] getMethods(char[] selector) {
return Binding.NO_METHODS;
}
public boolean canBeSeenBy(Scope scope) {
return true;
}
public ReferenceBinding superclass() {
return null;
}
public ReferenceBinding[] superInterfaces() {
return Binding.NO_SUPERINTERFACES;
}
public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
return null;
}
public boolean enterRecursiveFunction() {
return true;
}
public void exitRecursiveFunction() {
}
public boolean isFunctionalType() {
return false;
}
public long updateTagBits() {
return this.tagBits & TagBits.HasNullTypeAnnotation;
}
public boolean isFreeTypeVariable() {
return false;
}
}