0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.lookup;
0011:
0012: import org.eclipse.jdt.core.compiler.CharOperation;
0013: import org.eclipse.jdt.internal.compiler.ast.Wildcard;
0014:
0015: /*
0016: * Not all fields defined by this type (& its subclasses) are initialized when it is created.
0017: * Some are initialized only when needed.
0018: *
0019: * Accessors have been provided for some public fields so all TypeBindings have the same API...
0020: * but access public fields directly whenever possible.
0021: * Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
0022: *
0023: * null is NOT a valid value for a non-public field... it just means the field is not initialized.
0024: */
0025: abstract public class TypeBinding extends Binding {
0026:
0027: public int id = TypeIds.NoId;
0028: public long tagBits = 0; // See values in the interface TagBits below
0029:
0030: /** Base type definitions */
0031: public final static BaseTypeBinding INT = new BaseTypeBinding(
0032: TypeIds.T_int, TypeConstants.INT, new char[] { 'I' });
0033:
0034: public final static BaseTypeBinding BYTE = new BaseTypeBinding(
0035: TypeIds.T_byte, TypeConstants.BYTE, new char[] { 'B' });
0036:
0037: public final static BaseTypeBinding SHORT = new BaseTypeBinding(
0038: TypeIds.T_short, TypeConstants.SHORT, new char[] { 'S' });
0039:
0040: public final static BaseTypeBinding CHAR = new BaseTypeBinding(
0041: TypeIds.T_char, TypeConstants.CHAR, new char[] { 'C' });
0042:
0043: public final static BaseTypeBinding LONG = new BaseTypeBinding(
0044: TypeIds.T_long, TypeConstants.LONG, new char[] { 'J' });
0045:
0046: public final static BaseTypeBinding FLOAT = new BaseTypeBinding(
0047: TypeIds.T_float, TypeConstants.FLOAT, new char[] { 'F' });
0048:
0049: public final static BaseTypeBinding DOUBLE = new BaseTypeBinding(
0050: TypeIds.T_double, TypeConstants.DOUBLE, new char[] { 'D' });
0051:
0052: public final static BaseTypeBinding BOOLEAN = new BaseTypeBinding(
0053: TypeIds.T_boolean, TypeConstants.BOOLEAN,
0054: new char[] { 'Z' });
0055:
0056: public final static BaseTypeBinding NULL = new BaseTypeBinding(
0057: TypeIds.T_null, TypeConstants.NULL, new char[] { 'N' }); //N stands for null even if it is never internally used
0058:
0059: public final static BaseTypeBinding VOID = new BaseTypeBinding(
0060: TypeIds.T_void, TypeConstants.VOID, new char[] { 'V' });
0061:
0062: /**
0063: * Match a well-known type id to its binding
0064: */
0065: public static final TypeBinding wellKnownType(Scope scope, int id) {
0066: switch (id) {
0067: case TypeIds.T_boolean:
0068: return TypeBinding.BOOLEAN;
0069: case TypeIds.T_byte:
0070: return TypeBinding.BYTE;
0071: case TypeIds.T_char:
0072: return TypeBinding.CHAR;
0073: case TypeIds.T_short:
0074: return TypeBinding.SHORT;
0075: case TypeIds.T_double:
0076: return TypeBinding.DOUBLE;
0077: case TypeIds.T_float:
0078: return TypeBinding.FLOAT;
0079: case TypeIds.T_int:
0080: return TypeBinding.INT;
0081: case TypeIds.T_long:
0082: return TypeBinding.LONG;
0083: case TypeIds.T_JavaLangObject:
0084: return scope.getJavaLangObject();
0085: case TypeIds.T_JavaLangString:
0086: return scope.getJavaLangString();
0087: default:
0088: return null;
0089: }
0090: }
0091:
0092: /* Answer true if the receiver can be instantiated
0093: */
0094: public boolean canBeInstantiated() {
0095: return !isBaseType();
0096: }
0097:
0098: /**
0099: * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
0100: */
0101: public TypeBinding capture(Scope scope, int position) {
0102: return this ;
0103: }
0104:
0105: /**
0106: * Collect the substitutes into a map for certain type variables inside the receiver type
0107: * e.g. Collection<T>.findSubstitute(T, Collection<List<X>>): T --> List<X>
0108: * Constraints:
0109: * A << F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
0110: * A = F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
0111: * A >> F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
0112: */
0113: public void collectSubstitutes(Scope scope, TypeBinding actualType,
0114: InferenceContext inferenceContext, int constraint) {
0115: // no substitute by default
0116: }
0117:
0118: /**
0119: * Answer the receiver's constant pool name.
0120: * NOTE: This method should only be used during/after code gen.
0121: * e.g. 'java/lang/Object'
0122: */
0123: public abstract char[] constantPoolName();
0124:
0125: public String debugName() {
0126: return new String(readableName());
0127: }
0128:
0129: /*
0130: * Answer the receiver's dimensions - 0 for non-array types
0131: */
0132: public int dimensions() {
0133: return 0;
0134: }
0135:
0136: /* Answer the receiver's enclosing type... null if the receiver is a top level type.
0137: */
0138: public ReferenceBinding enclosingType() {
0139: return null;
0140: }
0141:
0142: public TypeBinding erasure() {
0143: return this ;
0144: }
0145:
0146: /**
0147: * Find supertype which erases to a given well-known type, or null if not found
0148: * (using id avoids triggering the load of well-known type: 73740)
0149: * NOTE: only works for erasures of well-known types, as random other types may share
0150: * same id though being distincts.
0151: *
0152: */
0153: public ReferenceBinding findSuperTypeErasingTo(
0154: int wellKnownErasureID, boolean erasureIsClass) {
0155:
0156: if (!(this instanceof ReferenceBinding))
0157: return null;
0158: ReferenceBinding reference = (ReferenceBinding) this ;
0159:
0160: // do not allow type variables to match with erasures for free
0161: if (reference.id == wellKnownErasureID
0162: || (!isTypeVariable() && !isIntersectionType() && erasure().id == wellKnownErasureID))
0163: return reference;
0164:
0165: ReferenceBinding currentType = reference;
0166: // iterate superclass to avoid recording interfaces if searched supertype is class
0167: if (erasureIsClass) {
0168: while ((currentType = currentType.super class()) != null) {
0169: if (currentType.id == wellKnownErasureID)
0170: return currentType;
0171: switch (currentType.kind()) {
0172: case Binding.PARAMETERIZED_TYPE:
0173: case Binding.RAW_TYPE:
0174: case Binding.ARRAY_TYPE:
0175: if (currentType.erasure().id == wellKnownErasureID)
0176: return currentType;
0177: }
0178: }
0179: return null;
0180: }
0181: ReferenceBinding[] interfacesToVisit = null;
0182: int nextPosition = 0;
0183: do {
0184: ReferenceBinding[] itsInterfaces = currentType
0185: .super Interfaces();
0186: if (itsInterfaces != null
0187: && itsInterfaces != Binding.NO_SUPERINTERFACES) {
0188: if (interfacesToVisit == null) {
0189: interfacesToVisit = itsInterfaces;
0190: nextPosition = interfacesToVisit.length;
0191: } else {
0192: int itsLength = itsInterfaces.length;
0193: if (nextPosition + itsLength >= interfacesToVisit.length)
0194: System
0195: .arraycopy(
0196: interfacesToVisit,
0197: 0,
0198: interfacesToVisit = new ReferenceBinding[nextPosition
0199: + itsLength + 5], 0,
0200: nextPosition);
0201: nextInterface: for (int a = 0; a < itsLength; a++) {
0202: ReferenceBinding next = itsInterfaces[a];
0203: for (int b = 0; b < nextPosition; b++)
0204: if (next == interfacesToVisit[b])
0205: continue nextInterface;
0206: interfacesToVisit[nextPosition++] = next;
0207: }
0208: }
0209: }
0210: } while ((currentType = currentType.super class()) != null);
0211:
0212: for (int i = 0; i < nextPosition; i++) {
0213: currentType = interfacesToVisit[i];
0214: if (currentType.id == wellKnownErasureID)
0215: return currentType;
0216: switch (currentType.kind()) {
0217: case Binding.PARAMETERIZED_TYPE:
0218: case Binding.RAW_TYPE:
0219: case Binding.ARRAY_TYPE:
0220: if (currentType.erasure().id == wellKnownErasureID)
0221: return currentType;
0222: }
0223: ReferenceBinding[] itsInterfaces = currentType
0224: .super Interfaces();
0225: if (itsInterfaces != null
0226: && itsInterfaces != Binding.NO_SUPERINTERFACES) {
0227: int itsLength = itsInterfaces.length;
0228: if (nextPosition + itsLength >= interfacesToVisit.length)
0229: System
0230: .arraycopy(
0231: interfacesToVisit,
0232: 0,
0233: interfacesToVisit = new ReferenceBinding[nextPosition
0234: + itsLength + 5], 0,
0235: nextPosition);
0236: nextInterface: for (int a = 0; a < itsLength; a++) {
0237: ReferenceBinding next = itsInterfaces[a];
0238: for (int b = 0; b < nextPosition; b++)
0239: if (next == interfacesToVisit[b])
0240: continue nextInterface;
0241: interfacesToVisit[nextPosition++] = next;
0242: }
0243: }
0244: }
0245: return null;
0246: }
0247:
0248: /**
0249: * Find supertype which erases to a given type, or null if not found
0250: */
0251: public TypeBinding findSuperTypeWithSameErasure(
0252: TypeBinding otherType) {
0253: if (this == otherType)
0254: return this ;
0255: if (otherType == null)
0256: return null;
0257: int kind;
0258: switch (kind = kind()) {
0259: case Binding.ARRAY_TYPE:
0260: ArrayBinding arrayType = (ArrayBinding) this ;
0261: int otherDim = otherType.dimensions();
0262: if (arrayType.dimensions != otherDim) {
0263: switch (otherType.id) {
0264: case TypeIds.T_JavaLangObject:
0265: case TypeIds.T_JavaIoSerializable:
0266: case TypeIds.T_JavaLangCloneable:
0267: return otherType;
0268: }
0269: if (otherDim < arrayType.dimensions
0270: && otherType.leafComponentType().id == TypeIds.T_JavaLangObject) {
0271: return otherType; // X[][] has Object[] as an implicit supertype
0272: }
0273: return null;
0274: }
0275: if (!(arrayType.leafComponentType instanceof ReferenceBinding))
0276: return null;
0277: TypeBinding leafSuperType = arrayType.leafComponentType
0278: .findSuperTypeWithSameErasure(otherType
0279: .leafComponentType());
0280: if (leafSuperType == null)
0281: return null;
0282: return arrayType.environment().createArrayType(
0283: leafSuperType, arrayType.dimensions);
0284:
0285: case Binding.TYPE_PARAMETER:
0286: if (isCapture()) {
0287: CaptureBinding capture = (CaptureBinding) this ;
0288: TypeBinding captureBound = capture.firstBound;
0289: if (captureBound instanceof ArrayBinding) {
0290: TypeBinding match = captureBound
0291: .findSuperTypeWithSameErasure(otherType);
0292: if (match != null)
0293: return match;
0294: }
0295: }
0296: // fall-through
0297: case Binding.TYPE:
0298: case Binding.PARAMETERIZED_TYPE:
0299: case Binding.GENERIC_TYPE:
0300: case Binding.RAW_TYPE:
0301: case Binding.WILDCARD_TYPE:
0302: // do not allow type variables/intersection types to match with erasures for free
0303: switch (otherType.kind()) {
0304: case Binding.PARAMETERIZED_TYPE:
0305: case Binding.RAW_TYPE:
0306: case Binding.ARRAY_TYPE:
0307: otherType = otherType.erasure();
0308: }
0309: if (this == otherType)
0310: return this ;
0311: switch (kind) {
0312: case Binding.PARAMETERIZED_TYPE:
0313: case Binding.RAW_TYPE:
0314: case Binding.ARRAY_TYPE:
0315: if (erasure() == otherType)
0316: return this ;
0317: }
0318:
0319: ReferenceBinding currentType = (ReferenceBinding) this ;
0320: if (!otherType.isInterface()) {
0321: while ((currentType = currentType.super class()) != null) {
0322: if (currentType == otherType)
0323: return currentType;
0324: switch (currentType.kind()) {
0325: case Binding.PARAMETERIZED_TYPE:
0326: case Binding.RAW_TYPE:
0327: case Binding.ARRAY_TYPE:
0328: if (currentType.erasure() == otherType)
0329: return currentType;
0330: }
0331: }
0332: return null;
0333: }
0334: ReferenceBinding[] interfacesToVisit = null;
0335: int nextPosition = 0;
0336: do {
0337: ReferenceBinding[] itsInterfaces = currentType
0338: .super Interfaces();
0339: if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
0340: if (interfacesToVisit == null) {
0341: interfacesToVisit = itsInterfaces;
0342: nextPosition = interfacesToVisit.length;
0343: } else {
0344: int itsLength = itsInterfaces.length;
0345: if (nextPosition + itsLength >= interfacesToVisit.length)
0346: System
0347: .arraycopy(
0348: interfacesToVisit,
0349: 0,
0350: interfacesToVisit = new ReferenceBinding[nextPosition
0351: + itsLength + 5],
0352: 0, nextPosition);
0353: nextInterface: for (int a = 0; a < itsLength; a++) {
0354: ReferenceBinding next = itsInterfaces[a];
0355: for (int b = 0; b < nextPosition; b++)
0356: if (next == interfacesToVisit[b])
0357: continue nextInterface;
0358: interfacesToVisit[nextPosition++] = next;
0359: }
0360: }
0361: }
0362: } while ((currentType = currentType.super class()) != null);
0363:
0364: for (int i = 0; i < nextPosition; i++) {
0365: currentType = interfacesToVisit[i];
0366: if (currentType == otherType)
0367: return currentType;
0368: switch (currentType.kind()) {
0369: case Binding.PARAMETERIZED_TYPE:
0370: case Binding.RAW_TYPE:
0371: case Binding.ARRAY_TYPE:
0372: if (currentType.erasure() == otherType)
0373: return currentType;
0374: }
0375: ReferenceBinding[] itsInterfaces = currentType
0376: .super Interfaces();
0377: if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
0378: int itsLength = itsInterfaces.length;
0379: if (nextPosition + itsLength >= interfacesToVisit.length)
0380: System
0381: .arraycopy(
0382: interfacesToVisit,
0383: 0,
0384: interfacesToVisit = new ReferenceBinding[nextPosition
0385: + itsLength + 5], 0,
0386: nextPosition);
0387: nextInterface: for (int a = 0; a < itsLength; a++) {
0388: ReferenceBinding next = itsInterfaces[a];
0389: for (int b = 0; b < nextPosition; b++)
0390: if (next == interfacesToVisit[b])
0391: continue nextInterface;
0392: interfacesToVisit[nextPosition++] = next;
0393: }
0394: }
0395: }
0396: }
0397: return null;
0398: }
0399:
0400: /**
0401: * Returns the type to use for generic cast, or null if none required
0402: */
0403: public TypeBinding genericCast(TypeBinding otherType) {
0404: if (this == otherType)
0405: return null;
0406: TypeBinding otherErasure = otherType.erasure();
0407: if (otherErasure == this .erasure())
0408: return null;
0409: return otherErasure;
0410: }
0411:
0412: /**
0413: * Answer the receiver classfile signature.
0414: * Arrays & base types do not distinguish between signature() & constantPoolName().
0415: * NOTE: This method should only be used during/after code gen.
0416: */
0417: public char[] genericTypeSignature() {
0418: return signature();
0419: }
0420:
0421: public abstract PackageBinding getPackage();
0422:
0423: public boolean isAnnotationType() {
0424: return false;
0425: }
0426:
0427: public final boolean isAnonymousType() {
0428: return (this .tagBits & TagBits.IsAnonymousType) != 0;
0429: }
0430:
0431: /* Answer true if the receiver is an array
0432: */
0433: public final boolean isArrayType() {
0434: return (this .tagBits & TagBits.IsArrayType) != 0;
0435: }
0436:
0437: /* Answer true if the receiver is a base type
0438: */
0439: public final boolean isBaseType() {
0440: return (this .tagBits & TagBits.IsBaseType) != 0;
0441: }
0442:
0443: /**
0444: * Returns true if parameterized type AND not of the form List<?>
0445: */
0446: public boolean isBoundParameterizedType() {
0447: return (this .tagBits & TagBits.IsBoundParameterizedType) != 0;
0448: }
0449:
0450: /**
0451: * Returns true if the type is the capture of some wildcard
0452: */
0453: public boolean isCapture() {
0454: return false;
0455: }
0456:
0457: public boolean isClass() {
0458: return false;
0459: }
0460:
0461: /* Answer true if the receiver type can be assigned to the argument type (right)
0462: */
0463: public abstract boolean isCompatibleWith(TypeBinding right);
0464:
0465: public boolean isEnum() {
0466: return false;
0467: }
0468:
0469: /**
0470: * Returns true if a type is identical to another one,
0471: * or for generic types, true if compared to its raw type.
0472: */
0473: public boolean isEquivalentTo(TypeBinding otherType) {
0474: if (this == otherType)
0475: return true;
0476: if (otherType == null)
0477: return false;
0478: if (otherType.isWildcard()) // wildcard
0479: return ((WildcardBinding) otherType).boundCheck(this );
0480: return false;
0481: }
0482:
0483: public boolean isGenericType() {
0484: return false;
0485: }
0486:
0487: /* Answer true if the receiver's hierarchy has problems (always false for arrays & base types)
0488: */
0489: public final boolean isHierarchyInconsistent() {
0490: return (this .tagBits & TagBits.HierarchyHasProblems) != 0;
0491: }
0492:
0493: public boolean isInterface() {
0494: return false;
0495: }
0496:
0497: /**
0498: * Returns true if a type is intersecting with another one,
0499: */
0500: public boolean isIntersectingWith(TypeBinding otherType) {
0501: return this == otherType;
0502: }
0503:
0504: /**
0505: * Returns true if the current type denotes an intersection type: Number & Comparable<?>
0506: */
0507: public boolean isIntersectionType() {
0508: return false;
0509: }
0510:
0511: public final boolean isLocalType() {
0512: return (this .tagBits & TagBits.IsLocalType) != 0;
0513: }
0514:
0515: public final boolean isMemberType() {
0516: return (this .tagBits & TagBits.IsMemberType) != 0;
0517: }
0518:
0519: public final boolean isNestedType() {
0520: return (this .tagBits & TagBits.IsNestedType) != 0;
0521: }
0522:
0523: public final boolean isNumericType() {
0524: switch (id) {
0525: case TypeIds.T_int:
0526: case TypeIds.T_float:
0527: case TypeIds.T_double:
0528: case TypeIds.T_short:
0529: case TypeIds.T_byte:
0530: case TypeIds.T_long:
0531: case TypeIds.T_char:
0532: return true;
0533: default:
0534: return false;
0535: }
0536: }
0537:
0538: /**
0539: * Returns true if the type is parameterized, e.g. List<String>
0540: */
0541: public boolean isParameterizedType() {
0542: return false;
0543: }
0544:
0545: /**
0546: * Returns true if the type is parameterized using its own type variables as arguments
0547: */
0548: public boolean isParameterizedWithOwnVariables() {
0549: if (this .kind() != Binding.PARAMETERIZED_TYPE)
0550: return false;
0551: ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this ;
0552: if (paramType.arguments == null)
0553: return false;
0554: TypeVariableBinding[] variables = this .erasure()
0555: .typeVariables();
0556: for (int i = 0, length = variables.length; i < length; i++) {
0557: if (variables[i] != paramType.arguments[i])
0558: return false;
0559: }
0560: ReferenceBinding enclosing = paramType.enclosingType();
0561: if (enclosing != null && enclosing.erasure().isGenericType()
0562: && !enclosing.isParameterizedWithOwnVariables()) {
0563: return false;
0564: }
0565: return true;
0566: }
0567:
0568: /**
0569: * Returns true if the two types are statically known to be different at compile-time,
0570: * e.g. a type variable is not provably known to be distinct from another type
0571: */
0572: public boolean isProvablyDistinctFrom(TypeBinding otherType,
0573: int depth) {
0574: if (this == otherType)
0575: return false;
0576: if (depth > 1)
0577: return true;
0578: switch (otherType.kind()) {
0579: case Binding.TYPE_PARAMETER:
0580: case Binding.WILDCARD_TYPE:
0581: return false;
0582: }
0583: switch (kind()) {
0584: case Binding.TYPE_PARAMETER:
0585: case Binding.WILDCARD_TYPE:
0586: return false;
0587:
0588: case Binding.PARAMETERIZED_TYPE:
0589: ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) this ;
0590: if (parameterizedType.genericType().isProvablyDistinctFrom(
0591: otherType.erasure(), depth))
0592: return true;
0593: switch (otherType.kind()) {
0594: case Binding.GENERIC_TYPE:
0595: case Binding.RAW_TYPE:
0596: return false;
0597: case Binding.PARAMETERIZED_TYPE:
0598: TypeBinding[] arguments = parameterizedType.arguments;
0599: if (arguments == null)
0600: return false;
0601: ParameterizedTypeBinding otherParameterizedType = (ParameterizedTypeBinding) otherType;
0602: TypeBinding[] otherArguments = otherParameterizedType.arguments;
0603: if (otherArguments == null)
0604: return false;
0605: for (int i = 0, length = arguments.length; i < length; i++) {
0606: if (arguments[i].isProvablyDistinctFrom(
0607: otherArguments[i], depth + 1))
0608: return true;
0609: }
0610: return false;
0611:
0612: }
0613: break;
0614:
0615: case Binding.RAW_TYPE:
0616: if (depth > 0)
0617: return true;
0618: return this .erasure().isProvablyDistinctFrom(
0619: otherType.erasure(), 0);
0620:
0621: case Binding.GENERIC_TYPE:
0622: if (depth > 0)
0623: return true;
0624: return this != otherType.erasure();
0625: }
0626: return this != otherType;
0627: }
0628:
0629: public boolean isRawType() {
0630: return false;
0631: }
0632:
0633: /**
0634: * JLS(3) 4.7.
0635: * Note: Foo<?>.Bar is also reifiable
0636: */
0637: public boolean isReifiable() {
0638:
0639: TypeBinding leafType = leafComponentType();
0640: if (!(leafType instanceof ReferenceBinding))
0641: return true;
0642: ReferenceBinding current = (ReferenceBinding) leafType;
0643: do {
0644: switch (current.kind()) {
0645:
0646: case Binding.TYPE_PARAMETER:
0647: case Binding.WILDCARD_TYPE:
0648: case Binding.GENERIC_TYPE:
0649: return false;
0650:
0651: case Binding.PARAMETERIZED_TYPE:
0652: if (current.isBoundParameterizedType())
0653: return false;
0654: break;
0655:
0656: case Binding.RAW_TYPE:
0657: return true;
0658: }
0659: if (current.isStatic())
0660: return true;
0661: if (current.isLocalType()) {
0662: NestedTypeBinding nestedType = (NestedTypeBinding) current
0663: .erasure();
0664: if (nestedType.scope.methodScope().isStatic)
0665: return true;
0666: }
0667: } while ((current = current.enclosingType()) != null);
0668: return true;
0669: }
0670:
0671: /**
0672: * Returns true if a given type may be thrown
0673: */
0674: public boolean isThrowable() {
0675: return false;
0676: }
0677:
0678: // JLS3: 4.5.1.1
0679: public boolean isTypeArgumentContainedBy(TypeBinding otherType) {
0680: if (this == otherType)
0681: return true;
0682: switch (otherType.kind()) {
0683: // allow wildcard containment
0684: case Binding.WILDCARD_TYPE:
0685: TypeBinding lowerBound = this ;
0686: TypeBinding upperBound = this ;
0687: switch (this .kind()) {
0688: case Binding.WILDCARD_TYPE:
0689: WildcardBinding wildcard = (WildcardBinding) this ;
0690: switch (wildcard.boundKind) {
0691: case Wildcard.EXTENDS:
0692: if (wildcard.otherBounds != null) // intersection type
0693: break;
0694: upperBound = wildcard.bound;
0695: lowerBound = null;
0696: break;
0697: case Wildcard.SUPER:
0698: upperBound = wildcard;
0699: lowerBound = wildcard.bound;
0700: break;
0701: case Wildcard.UNBOUND:
0702: upperBound = wildcard;
0703: lowerBound = null;
0704: }
0705: break;
0706: case Binding.TYPE_PARAMETER:
0707: if (this .isCapture()) {
0708: CaptureBinding capture = (CaptureBinding) this ;
0709: if (capture.lowerBound != null)
0710: lowerBound = capture.lowerBound;
0711: }
0712: }
0713: WildcardBinding otherWildcard = (WildcardBinding) otherType;
0714: if (otherWildcard.otherBounds != null)
0715: return false; // not a true wildcard (intersection type)
0716: TypeBinding otherBound = otherWildcard.bound;
0717: switch (otherWildcard.boundKind) {
0718: case Wildcard.EXTENDS:
0719: if (otherBound == this )
0720: return true; // ? extends T <= ? extends ? extends T
0721: if (upperBound == null)
0722: return false;
0723: TypeBinding match = upperBound
0724: .findSuperTypeWithSameErasure(otherBound);
0725: if (match != null
0726: && (match = match.leafComponentType())
0727: .isRawType()) {
0728: return match == otherBound.leafComponentType(); // forbide: Collection <= ? extends Collection<?>
0729: // forbide: Collection[] <= ? extends Collection<?>[]
0730: }
0731: return upperBound.isCompatibleWith(otherBound);
0732:
0733: case Wildcard.SUPER:
0734: if (otherBound == this )
0735: return true; // ? super T <= ? super ? super T
0736: if (lowerBound == null)
0737: return false;
0738: match = otherBound
0739: .findSuperTypeWithSameErasure(lowerBound);
0740: if (match != null
0741: && (match = match.leafComponentType())
0742: .isRawType()) {
0743: return match == lowerBound.leafComponentType(); // forbide: Collection <= ? super Collection<?>
0744: // forbide: Collection[] <= ? super Collection<?>[]
0745: }
0746: return otherBound.isCompatibleWith(lowerBound);
0747:
0748: case Wildcard.UNBOUND:
0749: default:
0750: return true;
0751: }
0752: // allow List<?> to match List<? extends Object> (and reciprocally)
0753: case Binding.PARAMETERIZED_TYPE:
0754: if (!this .isParameterizedType())
0755: return false;
0756: ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this ;
0757: ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
0758: if (paramType.actualType() != otherParamType.actualType())
0759: return false;
0760: if (!paramType.isStatic()) { // static member types do not compare their enclosing
0761: ReferenceBinding enclosing = enclosingType();
0762: if (enclosing != null) {
0763: ReferenceBinding otherEnclosing = otherParamType
0764: .enclosingType();
0765: if (otherEnclosing == null)
0766: return false;
0767: if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
0768: if (enclosing != otherEnclosing)
0769: return false;
0770: } else {
0771: if (!enclosing.isEquivalentTo(otherParamType
0772: .enclosingType()))
0773: return false;
0774: }
0775: }
0776: }
0777: int length = paramType.arguments == null ? 0
0778: : paramType.arguments.length;
0779: TypeBinding[] otherArguments = otherParamType.arguments;
0780: int otherLength = otherArguments == null ? 0
0781: : otherArguments.length;
0782: if (otherLength != length)
0783: return false;
0784: nextArgument: for (int i = 0; i < length; i++) {
0785: TypeBinding argument = paramType.arguments[i];
0786: TypeBinding otherArgument = otherArguments[i];
0787: if (argument == otherArgument)
0788: continue nextArgument;
0789: int kind = argument.kind();
0790: if (otherArgument.kind() != kind)
0791: return false;
0792: switch (kind) {
0793: case Binding.PARAMETERIZED_TYPE:
0794: if (argument
0795: .isTypeArgumentContainedBy(otherArgument)) // recurse
0796: continue nextArgument;
0797: break;
0798: case Binding.WILDCARD_TYPE:
0799: WildcardBinding wildcard = (WildcardBinding) argument;
0800: otherWildcard = (WildcardBinding) otherArgument;
0801: switch (wildcard.boundKind) {
0802: case Wildcard.EXTENDS:
0803: // match "? extends <upperBound>" with "?"
0804: if (otherWildcard.boundKind == Wildcard.UNBOUND
0805: && wildcard.bound == wildcard
0806: .typeVariable().upperBound())
0807: continue nextArgument;
0808: break;
0809: case Wildcard.SUPER:
0810: break;
0811: case Wildcard.UNBOUND:
0812: // match "?" with "? extends <upperBound>"
0813: if (otherWildcard.boundKind == Wildcard.EXTENDS
0814: && otherWildcard.bound == otherWildcard
0815: .typeVariable().upperBound())
0816: continue nextArgument;
0817: break;
0818: }
0819: break;
0820: }
0821: return false;
0822: }
0823: return true;
0824: }
0825: return false;
0826: }
0827:
0828: /**
0829: * Returns false if two given types could not intersect as argument types:
0830: * List<Throwable> & List<Runnable> --> false
0831: * List<? extends Throwable> & List<? extends Runnable> --> true
0832: * List<? extends String> & List<? extends Runnable> --> false
0833: */
0834: public boolean isTypeArgumentIntersecting(TypeBinding otherArgument) {
0835: if (this == otherArgument)
0836: return true;
0837: switch (kind()) {
0838:
0839: // TYPE_PARAM & ANY TYPE
0840: case Binding.TYPE_PARAMETER:
0841: return true;
0842:
0843: case Binding.WILDCARD_TYPE:
0844: switch (otherArgument.kind()) {
0845:
0846: // WILDCARD & TYPE_PARAM
0847: case Binding.TYPE_PARAMETER:
0848: return true;
0849:
0850: // WILDCARD & WILDCARD
0851: case Binding.WILDCARD_TYPE:
0852: TypeBinding lowerBound1 = null;
0853: TypeBinding upperBound1 = null;
0854: WildcardBinding wildcard = (WildcardBinding) this ;
0855: switch (wildcard.boundKind) {
0856: case Wildcard.EXTENDS:
0857: upperBound1 = wildcard.bound;
0858: break;
0859: case Wildcard.SUPER:
0860: lowerBound1 = wildcard.bound;
0861: break;
0862: case Wildcard.UNBOUND:
0863: }
0864:
0865: TypeBinding lowerBound2 = null;
0866: TypeBinding upperBound2 = null;
0867: WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
0868: switch (otherWildcard.boundKind) {
0869: case Wildcard.EXTENDS:
0870: upperBound2 = otherWildcard.bound;
0871: break;
0872: case Wildcard.SUPER:
0873: lowerBound2 = otherWildcard.bound;
0874: break;
0875: case Wildcard.UNBOUND:
0876: }
0877: if (lowerBound1 != null) {
0878: if (lowerBound2 != null) {
0879: return true; // Object could always be a candidate
0880:
0881: } else if (upperBound2 != null) {
0882: return lowerBound1
0883: .isCompatibleWith(upperBound2);
0884: } else {
0885: return true;
0886: }
0887: } else if (upperBound1 != null) {
0888: if (upperBound1.isTypeVariable())
0889: return true;
0890: if (lowerBound2 != null) {
0891: return lowerBound2
0892: .isCompatibleWith(upperBound1);
0893:
0894: } else if (upperBound2 != null) {
0895: if (upperBound1.isInterface()) {
0896: if (upperBound2.isInterface())
0897: return true;
0898: if (upperBound2.isArrayType()
0899: || ((upperBound2 instanceof ReferenceBinding) && ((ReferenceBinding) upperBound2)
0900: .isFinal())) {
0901: return upperBound2
0902: .isCompatibleWith(upperBound1);
0903: }
0904: return true;
0905: } else {
0906: if (upperBound2.isInterface()) {
0907: if (upperBound1.isArrayType()
0908: || ((upperBound1 instanceof ReferenceBinding) && ((ReferenceBinding) upperBound1)
0909: .isFinal())) {
0910: return upperBound1
0911: .isCompatibleWith(upperBound2);
0912: }
0913: } else {
0914: return upperBound1
0915: .isCompatibleWith(upperBound2);
0916: }
0917: }
0918: return true;
0919: } else {
0920: return true;
0921: }
0922: } else {
0923: return true;
0924: }
0925:
0926: // WILDCARD & OTHER TYPE
0927: default:
0928: wildcard = (WildcardBinding) this ;
0929: switch (wildcard.boundKind) {
0930: case Wildcard.EXTENDS:
0931: return otherArgument
0932: .isCompatibleWith(wildcard.bound);
0933: case Wildcard.SUPER:
0934: return wildcard.bound
0935: .isCompatibleWith(otherArgument);
0936: case Wildcard.UNBOUND:
0937: default:
0938: return true;
0939: }
0940: }
0941:
0942: default:
0943: switch (otherArgument.kind()) {
0944:
0945: // OTHER TYPE & TYPE_PARAM
0946: case Binding.TYPE_PARAMETER:
0947: return true;
0948:
0949: // OTHER TYPE & WILDCARD
0950: case Binding.WILDCARD_TYPE:
0951: WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
0952: switch (otherWildcard.boundKind) {
0953: case Wildcard.EXTENDS:
0954: return this .isCompatibleWith(otherWildcard.bound);
0955: case Wildcard.SUPER:
0956: return otherWildcard.bound.isCompatibleWith(this );
0957: case Wildcard.UNBOUND:
0958: default:
0959: return true;
0960: }
0961:
0962: // OTHER TYPE & OTHER TYPE
0963: default:
0964: return false;
0965: }
0966: }
0967: }
0968:
0969: /**
0970: * Returns true if the type was declared as a type variable
0971: */
0972: public boolean isTypeVariable() {
0973: return false;
0974: }
0975:
0976: /**
0977: * Returns true if wildcard type of the form '?' (no bound)
0978: */
0979: public boolean isUnboundWildcard() {
0980: return false;
0981: }
0982:
0983: /**
0984: * Returns true if the type is a subclass of java.lang.Error or java.lang.RuntimeException
0985: */
0986: public boolean isUncheckedException(boolean includeSupertype) {
0987: return false;
0988: }
0989:
0990: /**
0991: * Returns true if the type is a wildcard
0992: */
0993: public boolean isWildcard() {
0994: return false;
0995: }
0996:
0997: /* API
0998: * Answer the receiver's binding type from Binding.BindingID.
0999: */
1000: public int kind() {
1001: return Binding.TYPE;
1002: }
1003:
1004: public TypeBinding leafComponentType() {
1005: return this ;
1006: }
1007:
1008: /**
1009: * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
1010: */
1011: public boolean needsUncheckedConversion(TypeBinding targetType) {
1012:
1013: if (this == targetType)
1014: return false;
1015: targetType = targetType.leafComponentType();
1016: if (!(targetType instanceof ReferenceBinding))
1017: return false;
1018:
1019: TypeBinding currentType = this .leafComponentType();
1020: TypeBinding match = currentType
1021: .findSuperTypeWithSameErasure(targetType);
1022: if (!(match instanceof ReferenceBinding))
1023: return false;
1024: ReferenceBinding compatible = (ReferenceBinding) match;
1025: while (compatible.isRawType()) {
1026: if (targetType.isBoundParameterizedType())
1027: return true;
1028: if (compatible.isStatic())
1029: break;
1030: if ((compatible = compatible.enclosingType()) == null)
1031: break;
1032: if ((targetType = targetType.enclosingType()) == null)
1033: break;
1034: }
1035: return false;
1036: }
1037:
1038: /**
1039: * Answer the qualified name of the receiver's package separated by periods
1040: * or an empty string if its the default package.
1041: *
1042: * For example, {java.util}.
1043: */
1044:
1045: public char[] qualifiedPackageName() {
1046: PackageBinding packageBinding = getPackage();
1047: return packageBinding == null
1048: || packageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? CharOperation.NO_CHAR
1049: : packageBinding.readableName();
1050: }
1051:
1052: /**
1053: * Answer the source name for the type.
1054: * In the case of member types, as the qualified name from its top level type.
1055: * For example, for a member type N defined inside M & A: "A.M.N".
1056: */
1057:
1058: public abstract char[] qualifiedSourceName();
1059:
1060: /**
1061: * Answer the receiver classfile signature.
1062: * Arrays & base types do not distinguish between signature() & constantPoolName().
1063: * NOTE: This method should only be used during/after code gen.
1064: */
1065: public char[] signature() {
1066: return constantPoolName();
1067: }
1068:
1069: public abstract char[] sourceName();
1070:
1071: public void swapUnresolved(
1072: UnresolvedReferenceBinding unresolvedType,
1073: ReferenceBinding resolvedType, LookupEnvironment environment) {
1074: // subclasses must override if they wrap another type binding
1075: }
1076:
1077: public TypeVariableBinding[] typeVariables() {
1078: return Binding.NO_TYPE_VARIABLES;
1079: }
1080: }
|