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 java.util.ArrayList;
0013:
0014: import org.eclipse.jdt.core.compiler.CharOperation;
0015: import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0016: import org.eclipse.jdt.internal.compiler.env.*;
0017: import org.eclipse.jdt.internal.compiler.impl.Constant;
0018: import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
0019: import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
0020:
0021: /*
0022: Not all fields defined by this type are initialized when it is created.
0023: Some are initialized only when needed.
0024:
0025: Accessors have been provided for some public fields so all TypeBindings have the same API...
0026: but access public fields directly whenever possible.
0027: Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
0028:
0029: null is NOT a valid value for a non-public field... it just means the field is not initialized.
0030: */
0031:
0032: public class BinaryTypeBinding extends ReferenceBinding {
0033:
0034: // all of these fields are ONLY guaranteed to be initialized if accessed using their public accessor method
0035: protected ReferenceBinding super class;
0036: protected ReferenceBinding enclosingType;
0037: protected ReferenceBinding[] super Interfaces;
0038: protected FieldBinding[] fields;
0039: protected MethodBinding[] methods;
0040: protected ReferenceBinding[] memberTypes;
0041: protected TypeVariableBinding[] typeVariables;
0042:
0043: // For the link with the principle structure
0044: protected LookupEnvironment environment;
0045:
0046: protected SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
0047:
0048: static Object convertMemberValue(Object binaryValue,
0049: LookupEnvironment env) {
0050: if (binaryValue == null)
0051: return null;
0052: if (binaryValue instanceof Constant)
0053: return binaryValue;
0054: if (binaryValue instanceof ClassSignature)
0055: return env.getTypeFromSignature(
0056: ((ClassSignature) binaryValue).getTypeName(), 0,
0057: -1, false, null);
0058: if (binaryValue instanceof IBinaryAnnotation)
0059: return createAnnotation((IBinaryAnnotation) binaryValue,
0060: env);
0061: if (binaryValue instanceof EnumConstantSignature) {
0062: EnumConstantSignature ref = (EnumConstantSignature) binaryValue;
0063: ReferenceBinding enumType = (ReferenceBinding) env
0064: .getTypeFromSignature(ref.getTypeName(), 0, -1,
0065: false, null);
0066: enumType = resolveType(enumType, env, false);
0067: return enumType.getField(ref.getEnumConstantName(), false);
0068: }
0069: if (binaryValue instanceof Object[]) {
0070: Object[] objects = (Object[]) binaryValue;
0071: int length = objects.length;
0072: if (length == 0)
0073: return objects;
0074: Object[] values = new Object[length];
0075: for (int i = 0; i < length; i++)
0076: values[i] = convertMemberValue(objects[i], env);
0077: return values;
0078: }
0079:
0080: // should never reach here.
0081: throw new IllegalStateException();
0082: }
0083:
0084: static AnnotationBinding createAnnotation(
0085: IBinaryAnnotation annotationInfo, LookupEnvironment env) {
0086: IBinaryElementValuePair[] binaryPairs = annotationInfo
0087: .getElementValuePairs();
0088: int length = binaryPairs == null ? 0 : binaryPairs.length;
0089: ElementValuePair[] pairs = length == 0 ? Binding.NO_ELEMENT_VALUE_PAIRS
0090: : new ElementValuePair[length];
0091: for (int i = 0; i < length; i++)
0092: pairs[i] = new ElementValuePair(binaryPairs[i].getName(),
0093: convertMemberValue(binaryPairs[i].getValue(), env),
0094: null);
0095:
0096: char[] typeName = annotationInfo.getTypeName();
0097: ReferenceBinding annotationType = env
0098: .getTypeFromConstantPoolName(typeName, 1,
0099: typeName.length - 1, false);
0100: return new UnresolvedAnnotationBinding(annotationType, pairs,
0101: env);
0102: }
0103:
0104: public static AnnotationBinding[] createAnnotations(
0105: IBinaryAnnotation[] annotationInfos, LookupEnvironment env) {
0106: int length = annotationInfos == null ? 0
0107: : annotationInfos.length;
0108: AnnotationBinding[] result = length == 0 ? Binding.NO_ANNOTATIONS
0109: : new AnnotationBinding[length];
0110: for (int i = 0; i < length; i++)
0111: result[i] = createAnnotation(annotationInfos[i], env);
0112: return result;
0113: }
0114:
0115: public static ReferenceBinding resolveType(ReferenceBinding type,
0116: LookupEnvironment environment,
0117: boolean convertGenericToRawType) {
0118: if (type instanceof UnresolvedReferenceBinding)
0119: return ((UnresolvedReferenceBinding) type).resolve(
0120: environment, convertGenericToRawType);
0121: if (type.isParameterizedType())
0122: return ((ParameterizedTypeBinding) type).resolve();
0123: if (type.isWildcard())
0124: return ((WildcardBinding) type).resolve();
0125:
0126: if (convertGenericToRawType) // raw reference to generic ?
0127: return (ReferenceBinding) environment
0128: .convertUnresolvedBinaryToRawType(type);
0129: return type;
0130: }
0131:
0132: public static TypeBinding resolveType(TypeBinding type,
0133: LookupEnvironment environment,
0134: ParameterizedTypeBinding parameterizedType, int rank) {
0135: switch (type.kind()) {
0136:
0137: case Binding.PARAMETERIZED_TYPE:
0138: return ((ParameterizedTypeBinding) type).resolve();
0139:
0140: case Binding.WILDCARD_TYPE:
0141: return ((WildcardBinding) type).resolve();
0142:
0143: case Binding.ARRAY_TYPE:
0144: resolveType(((ArrayBinding) type).leafComponentType,
0145: environment, parameterizedType, rank);
0146: break;
0147:
0148: case Binding.TYPE_PARAMETER:
0149: ((TypeVariableBinding) type).resolve(environment);
0150: break;
0151:
0152: case Binding.GENERIC_TYPE:
0153: if (parameterizedType == null) // raw reference to generic ?
0154: return environment
0155: .convertUnresolvedBinaryToRawType(type);
0156: break;
0157:
0158: default:
0159: if (type instanceof UnresolvedReferenceBinding)
0160: return ((UnresolvedReferenceBinding) type).resolve(
0161: environment, parameterizedType == null);
0162: }
0163: return type;
0164: }
0165:
0166: /**
0167: * Default empty constructor for subclasses only.
0168: */
0169: protected BinaryTypeBinding() {
0170: // only for subclasses
0171: }
0172:
0173: /**
0174: * Standard constructor for creating binary type bindings from binary models (classfiles)
0175: * @param packageBinding
0176: * @param binaryType
0177: * @param environment
0178: */
0179: public BinaryTypeBinding(PackageBinding packageBinding,
0180: IBinaryType binaryType, LookupEnvironment environment) {
0181: this .compoundName = CharOperation.splitOn('/', binaryType
0182: .getName());
0183: computeId();
0184:
0185: this .tagBits |= TagBits.IsBinaryBinding;
0186: this .environment = environment;
0187: this .fPackage = packageBinding;
0188: this .fileName = binaryType.getFileName();
0189:
0190: char[] typeSignature = environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5 ? binaryType
0191: .getGenericSignature()
0192: : null;
0193: this .typeVariables = typeSignature != null
0194: && typeSignature.length > 0 && typeSignature[0] == '<' ? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
0195: : Binding.NO_TYPE_VARIABLES;
0196:
0197: this .sourceName = binaryType.getSourceName();
0198: this .modifiers = binaryType.getModifiers();
0199:
0200: if ((binaryType.getTagBits() & TagBits.HasInconsistentHierarchy) != 0)
0201: this .tagBits |= TagBits.HierarchyHasProblems;
0202:
0203: if (binaryType.isAnonymous()) {
0204: this .tagBits |= TagBits.AnonymousTypeMask;
0205: } else if (binaryType.isLocal()) {
0206: this .tagBits |= TagBits.LocalTypeMask;
0207: } else if (binaryType.isMember()) {
0208: this .tagBits |= TagBits.MemberTypeMask;
0209: }
0210: // need enclosing type to access type variables
0211: char[] enclosingTypeName = binaryType.getEnclosingTypeName();
0212: if (enclosingTypeName != null) {
0213: // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
0214: this .enclosingType = environment
0215: .getTypeFromConstantPoolName(enclosingTypeName, 0,
0216: -1, true); // pretend parameterized to avoid raw
0217: this .tagBits |= TagBits.MemberTypeMask; // must be a member type not a top-level or local type
0218: this .tagBits |= TagBits.HasUnresolvedEnclosingType;
0219: if (this .enclosingType().isStrictfp())
0220: this .modifiers |= ClassFileConstants.AccStrictfp;
0221: if (this .enclosingType().isDeprecated())
0222: this .modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
0223: }
0224: }
0225:
0226: /**
0227: * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
0228: */
0229: public FieldBinding[] availableFields() {
0230: if ((this .tagBits & TagBits.AreFieldsComplete) != 0)
0231: return fields;
0232:
0233: // lazily sort fields
0234: if ((this .tagBits & TagBits.AreFieldsSorted) == 0) {
0235: int length = this .fields.length;
0236: if (length > 1)
0237: ReferenceBinding.sortFields(this .fields, 0, length);
0238: this .tagBits |= TagBits.AreFieldsSorted;
0239: }
0240: FieldBinding[] availableFields = new FieldBinding[fields.length];
0241: int count = 0;
0242: for (int i = 0; i < fields.length; i++) {
0243: try {
0244: availableFields[count] = resolveTypeFor(fields[i]);
0245: count++;
0246: } catch (AbortCompilation a) {
0247: // silent abort
0248: }
0249: }
0250: if (count < availableFields.length)
0251: System
0252: .arraycopy(availableFields, 0,
0253: availableFields = new FieldBinding[count],
0254: 0, count);
0255: return availableFields;
0256: }
0257:
0258: /**
0259: * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
0260: */
0261: public MethodBinding[] availableMethods() {
0262: if ((this .tagBits & TagBits.AreMethodsComplete) != 0)
0263: return methods;
0264:
0265: // lazily sort methods
0266: if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0267: int length = this .methods.length;
0268: if (length > 1)
0269: ReferenceBinding.sortMethods(this .methods, 0, length);
0270: this .tagBits |= TagBits.AreMethodsSorted;
0271: }
0272: MethodBinding[] availableMethods = new MethodBinding[methods.length];
0273: int count = 0;
0274: for (int i = 0; i < methods.length; i++) {
0275: try {
0276: availableMethods[count] = resolveTypesFor(methods[i]);
0277: count++;
0278: } catch (AbortCompilation a) {
0279: // silent abort
0280: }
0281: }
0282: if (count < availableMethods.length)
0283: System.arraycopy(availableMethods, 0,
0284: availableMethods = new MethodBinding[count], 0,
0285: count);
0286: return availableMethods;
0287: }
0288:
0289: void cachePartsFrom(IBinaryType binaryType,
0290: boolean needFieldsAndMethods) {
0291: // default initialization for super-interfaces early, in case some aborting compilation error occurs,
0292: // and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
0293: this .typeVariables = Binding.NO_TYPE_VARIABLES;
0294: this .super Interfaces = Binding.NO_SUPERINTERFACES;
0295:
0296: // must retrieve member types in case superclass/interfaces need them
0297: this .memberTypes = Binding.NO_MEMBER_TYPES;
0298: IBinaryNestedType[] memberTypeStructures = binaryType
0299: .getMemberTypes();
0300: if (memberTypeStructures != null) {
0301: int size = memberTypeStructures.length;
0302: if (size > 0) {
0303: this .memberTypes = new ReferenceBinding[size];
0304: for (int i = 0; i < size; i++)
0305: // attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
0306: this .memberTypes[i] = environment
0307: .getTypeFromConstantPoolName(
0308: memberTypeStructures[i].getName(),
0309: 0, -1, false);
0310: this .tagBits |= TagBits.HasUnresolvedMemberTypes;
0311: }
0312: }
0313:
0314: long sourceLevel = environment.globalOptions.sourceLevel;
0315: char[] typeSignature = null;
0316: if (sourceLevel >= ClassFileConstants.JDK1_5) {
0317: typeSignature = binaryType.getGenericSignature();
0318: this .tagBits |= binaryType.getTagBits();
0319: }
0320: if (typeSignature == null) {
0321: char[] super className = binaryType.getSuperclassName();
0322: if (super className != null) {
0323: // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
0324: this .super class = environment
0325: .getTypeFromConstantPoolName(super className, 0,
0326: -1, false);
0327: this .tagBits |= TagBits.HasUnresolvedSuperclass;
0328: }
0329:
0330: this .super Interfaces = Binding.NO_SUPERINTERFACES;
0331: char[][] interfaceNames = binaryType.getInterfaceNames();
0332: if (interfaceNames != null) {
0333: int size = interfaceNames.length;
0334: if (size > 0) {
0335: this .super Interfaces = new ReferenceBinding[size];
0336: for (int i = 0; i < size; i++)
0337: // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
0338: this .super Interfaces[i] = environment
0339: .getTypeFromConstantPoolName(
0340: interfaceNames[i], 0, -1, false);
0341: this .tagBits |= TagBits.HasUnresolvedSuperinterfaces;
0342: }
0343: }
0344: } else {
0345: // ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature
0346: SignatureWrapper wrapper = new SignatureWrapper(
0347: typeSignature);
0348: if (wrapper.signature[wrapper.start] == '<') {
0349: // ParameterPart = '<' ParameterSignature(s) '>'
0350: wrapper.start++; // skip '<'
0351: this .typeVariables = createTypeVariables(wrapper, true);
0352: wrapper.start++; // skip '>'
0353: this .tagBits |= TagBits.HasUnresolvedTypeVariables;
0354: this .modifiers |= ExtraCompilerModifiers.AccGenericSignature;
0355: }
0356:
0357: // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
0358: this .super class = (ReferenceBinding) environment
0359: .getTypeFromTypeSignature(wrapper,
0360: Binding.NO_TYPE_VARIABLES, this );
0361: this .tagBits |= TagBits.HasUnresolvedSuperclass;
0362:
0363: this .super Interfaces = Binding.NO_SUPERINTERFACES;
0364: if (!wrapper.atEnd()) {
0365: // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
0366: java.util.ArrayList types = new java.util.ArrayList(2);
0367: do {
0368: types.add(environment.getTypeFromTypeSignature(
0369: wrapper, Binding.NO_TYPE_VARIABLES, this ));
0370: } while (!wrapper.atEnd());
0371: this .super Interfaces = new ReferenceBinding[types
0372: .size()];
0373: types.toArray(this .super Interfaces);
0374: this .tagBits |= TagBits.HasUnresolvedSuperinterfaces;
0375: }
0376: }
0377:
0378: if (needFieldsAndMethods) {
0379: createFields(binaryType.getFields(), sourceLevel);
0380: createMethods(binaryType.getMethods(), sourceLevel);
0381: } else { // protect against incorrect use of the needFieldsAndMethods flag, see 48459
0382: this .fields = Binding.NO_FIELDS;
0383: this .methods = Binding.NO_METHODS;
0384: }
0385: if (this .environment.globalOptions.storeAnnotations)
0386: setAnnotations(createAnnotations(binaryType
0387: .getAnnotations(), this .environment));
0388: }
0389:
0390: private void createFields(IBinaryField[] iFields, long sourceLevel) {
0391: this .fields = Binding.NO_FIELDS;
0392: if (iFields != null) {
0393: int size = iFields.length;
0394: if (size > 0) {
0395: this .fields = new FieldBinding[size];
0396: boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
0397: boolean isViewedAsDeprecated = isViewedAsDeprecated();
0398: boolean hasRestrictedAccess = hasRestrictedAccess();
0399: int firstAnnotatedFieldIndex = -1;
0400: for (int i = 0; i < size; i++) {
0401: IBinaryField binaryField = iFields[i];
0402: char[] fieldSignature = use15specifics ? binaryField
0403: .getGenericSignature()
0404: : null;
0405: TypeBinding type = fieldSignature == null ? environment
0406: .getTypeFromSignature(binaryField
0407: .getTypeName(), 0, -1, false, this )
0408: : environment
0409: .getTypeFromTypeSignature(
0410: new SignatureWrapper(
0411: fieldSignature),
0412: Binding.NO_TYPE_VARIABLES,
0413: this );
0414: FieldBinding field = new FieldBinding(binaryField
0415: .getName(), type, binaryField
0416: .getModifiers()
0417: | ExtraCompilerModifiers.AccUnresolved,
0418: this , binaryField.getConstant());
0419: if (firstAnnotatedFieldIndex < 0
0420: && this .environment.globalOptions.storeAnnotations
0421: && binaryField.getAnnotations() != null) {
0422: firstAnnotatedFieldIndex = i;
0423: }
0424: field.id = i; // ordinal
0425: if (use15specifics)
0426: field.tagBits |= binaryField.getTagBits();
0427: if (isViewedAsDeprecated && !field.isDeprecated())
0428: field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
0429: if (hasRestrictedAccess)
0430: field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
0431: if (fieldSignature != null)
0432: field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
0433: this .fields[i] = field;
0434: }
0435: // second pass for reifying annotations, since may refer to fields being constructed (147875)
0436: if (firstAnnotatedFieldIndex >= 0) {
0437: for (int i = firstAnnotatedFieldIndex; i < size; i++) {
0438: this .fields[i]
0439: .setAnnotations(createAnnotations(
0440: iFields[i].getAnnotations(),
0441: this .environment));
0442: }
0443: }
0444: }
0445: }
0446: }
0447:
0448: private MethodBinding createMethod(IBinaryMethod method,
0449: long sourceLevel) {
0450: int methodModifiers = method.getModifiers()
0451: | ExtraCompilerModifiers.AccUnresolved;
0452: if (sourceLevel < ClassFileConstants.JDK1_5)
0453: methodModifiers &= ~ClassFileConstants.AccVarargs; // vararg methods are not recognized until 1.5
0454: ReferenceBinding[] exceptions = Binding.NO_EXCEPTIONS;
0455: TypeBinding[] parameters = Binding.NO_PARAMETERS;
0456: TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
0457: AnnotationBinding[][] paramAnnotations = null;
0458: TypeBinding returnType = null;
0459:
0460: final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
0461: char[] methodSignature = use15specifics ? method
0462: .getGenericSignature() : null;
0463: if (methodSignature == null) { // no generics
0464: char[] methodDescriptor = method.getMethodDescriptor(); // of the form (I[Ljava/jang/String;)V
0465: int numOfParams = 0;
0466: char nextChar;
0467: int index = 0; // first character is always '(' so skip it
0468: while ((nextChar = methodDescriptor[++index]) != ')') {
0469: if (nextChar != '[') {
0470: numOfParams++;
0471: if (nextChar == 'L')
0472: while ((nextChar = methodDescriptor[++index]) != ';') {/*empty*/
0473: }
0474: }
0475: }
0476:
0477: // Ignore synthetic argument for member types.
0478: int startIndex = (method.isConstructor() && isMemberType() && !isStatic()) ? 1
0479: : 0;
0480: int size = numOfParams - startIndex;
0481: if (size > 0) {
0482: parameters = new TypeBinding[size];
0483: if (this .environment.globalOptions.storeAnnotations)
0484: paramAnnotations = new AnnotationBinding[size][];
0485: index = 1;
0486: int end = 0; // first character is always '(' so skip it
0487: for (int i = 0; i < numOfParams; i++) {
0488: while ((nextChar = methodDescriptor[++end]) == '[') {/*empty*/
0489: }
0490: if (nextChar == 'L')
0491: while ((nextChar = methodDescriptor[++end]) != ';') {/*empty*/
0492: }
0493:
0494: if (i >= startIndex) { // skip the synthetic arg if necessary
0495: parameters[i - startIndex] = environment
0496: .getTypeFromSignature(methodDescriptor,
0497: index, end, false, this );
0498: // 'paramAnnotations' line up with 'parameters'
0499: // int parameter to method.getParameterAnnotations() include the synthetic arg
0500: if (paramAnnotations != null)
0501: paramAnnotations[i - startIndex] = createAnnotations(
0502: method.getParameterAnnotations(i),
0503: this .environment);
0504: }
0505: index = end + 1;
0506: }
0507: }
0508:
0509: char[][] exceptionTypes = method.getExceptionTypeNames();
0510: if (exceptionTypes != null) {
0511: size = exceptionTypes.length;
0512: if (size > 0) {
0513: exceptions = new ReferenceBinding[size];
0514: for (int i = 0; i < size; i++)
0515: exceptions[i] = environment
0516: .getTypeFromConstantPoolName(
0517: exceptionTypes[i], 0, -1, false);
0518: }
0519: }
0520:
0521: if (!method.isConstructor())
0522: returnType = environment.getTypeFromSignature(
0523: methodDescriptor, index + 1, -1, false, this ); // index is currently pointing at the ')'
0524: } else {
0525: methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
0526: // MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
0527: SignatureWrapper wrapper = new SignatureWrapper(
0528: methodSignature);
0529: if (wrapper.signature[wrapper.start] == '<') {
0530: // <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
0531: // ParameterPart = '<' ParameterSignature(s) '>'
0532: wrapper.start++; // skip '<'
0533: typeVars = createTypeVariables(wrapper, false);
0534: wrapper.start++; // skip '>'
0535: }
0536:
0537: if (wrapper.signature[wrapper.start] == '(') {
0538: wrapper.start++; // skip '('
0539: if (wrapper.signature[wrapper.start] == ')') {
0540: wrapper.start++; // skip ')'
0541: } else {
0542: java.util.ArrayList types = new java.util.ArrayList(
0543: 2);
0544: while (wrapper.signature[wrapper.start] != ')')
0545: types.add(environment.getTypeFromTypeSignature(
0546: wrapper, typeVars, this ));
0547: wrapper.start++; // skip ')'
0548: int numParam = types.size();
0549: parameters = new TypeBinding[numParam];
0550: types.toArray(parameters);
0551: if (this .environment.globalOptions.storeAnnotations) {
0552: paramAnnotations = new AnnotationBinding[numParam][];
0553: for (int i = 0; i < numParam; i++)
0554: paramAnnotations[i] = createAnnotations(
0555: method.getParameterAnnotations(i),
0556: this .environment);
0557: }
0558: }
0559: }
0560:
0561: // always retrieve return type (for constructors, its V for void - will be ignored)
0562: returnType = environment.getTypeFromTypeSignature(wrapper,
0563: typeVars, this );
0564:
0565: if (!wrapper.atEnd()
0566: && wrapper.signature[wrapper.start] == '^') {
0567: // attempt to find each exception if it exists in the cache (otherwise - resolve it when requested)
0568: java.util.ArrayList types = new java.util.ArrayList(2);
0569: do {
0570: wrapper.start++; // skip '^'
0571: types.add(environment.getTypeFromTypeSignature(
0572: wrapper, typeVars, this ));
0573: } while (!wrapper.atEnd()
0574: && wrapper.signature[wrapper.start] == '^');
0575: exceptions = new ReferenceBinding[types.size()];
0576: types.toArray(exceptions);
0577: } else { // get the exceptions the old way
0578: char[][] exceptionTypes = method
0579: .getExceptionTypeNames();
0580: if (exceptionTypes != null) {
0581: int size = exceptionTypes.length;
0582: if (size > 0) {
0583: exceptions = new ReferenceBinding[size];
0584: for (int i = 0; i < size; i++)
0585: exceptions[i] = environment
0586: .getTypeFromConstantPoolName(
0587: exceptionTypes[i], 0, -1,
0588: false);
0589: }
0590: }
0591: }
0592: }
0593:
0594: MethodBinding result = method.isConstructor() ? new MethodBinding(
0595: methodModifiers, parameters, exceptions, this )
0596: : new MethodBinding(methodModifiers, method
0597: .getSelector(), returnType, parameters,
0598: exceptions, this );
0599: if (this .environment.globalOptions.storeAnnotations)
0600: result.setAnnotations(createAnnotations(method
0601: .getAnnotations(), this .environment),
0602: paramAnnotations,
0603: isAnnotationType() ? convertMemberValue(method
0604: .getDefaultValue(), this .environment)
0605: : null);
0606:
0607: if (use15specifics)
0608: result.tagBits |= method.getTagBits();
0609: result.typeVariables = typeVars;
0610: // fixup the declaring element of the type variable
0611: for (int i = 0, length = typeVars.length; i < length; i++)
0612: typeVars[i].declaringElement = result;
0613: return result;
0614: }
0615:
0616: /**
0617: * Create method bindings for binary type, filtering out <clinit> and synthetics
0618: */
0619: private void createMethods(IBinaryMethod[] iMethods,
0620: long sourceLevel) {
0621: int total = 0, initialTotal = 0, iClinit = -1;
0622: int[] toSkip = null;
0623: if (iMethods != null) {
0624: total = initialTotal = iMethods.length;
0625: boolean keepBridgeMethods = sourceLevel < ClassFileConstants.JDK1_5
0626: && this .environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5;
0627: for (int i = total; --i >= 0;) {
0628: IBinaryMethod method = iMethods[i];
0629: if ((method.getModifiers() & ClassFileConstants.AccSynthetic) != 0) {
0630: if (keepBridgeMethods
0631: && (method.getModifiers() & ClassFileConstants.AccBridge) != 0)
0632: continue; // want to see bridge methods as real methods
0633: // discard synthetics methods
0634: if (toSkip == null)
0635: toSkip = new int[iMethods.length];
0636: toSkip[i] = -1;
0637: total--;
0638: } else if (iClinit == -1) {
0639: char[] methodName = method.getSelector();
0640: if (methodName.length == 8 && methodName[0] == '<') {
0641: // discard <clinit>
0642: iClinit = i;
0643: total--;
0644: }
0645: }
0646: }
0647: }
0648: if (total == 0) {
0649: this .methods = Binding.NO_METHODS;
0650: return;
0651: }
0652:
0653: boolean isViewedAsDeprecated = isViewedAsDeprecated();
0654: boolean hasRestrictedAccess = hasRestrictedAccess();
0655: this .methods = new MethodBinding[total];
0656: if (total == initialTotal) {
0657: for (int i = 0; i < initialTotal; i++) {
0658: MethodBinding method = createMethod(iMethods[i],
0659: sourceLevel);
0660: if (isViewedAsDeprecated && !method.isDeprecated())
0661: method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
0662: if (hasRestrictedAccess)
0663: method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
0664: this .methods[i] = method;
0665: }
0666: } else {
0667: for (int i = 0, index = 0; i < initialTotal; i++) {
0668: if (iClinit != i && (toSkip == null || toSkip[i] != -1)) {
0669: MethodBinding method = createMethod(iMethods[i],
0670: sourceLevel);
0671: if (isViewedAsDeprecated && !method.isDeprecated())
0672: method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
0673: if (hasRestrictedAccess)
0674: method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
0675: this .methods[index++] = method;
0676: }
0677: }
0678: }
0679: }
0680:
0681: private TypeVariableBinding[] createTypeVariables(
0682: SignatureWrapper wrapper, boolean assignVariables) {
0683: // detect all type variables first
0684: char[] typeSignature = wrapper.signature;
0685: int depth = 0, length = typeSignature.length;
0686: int rank = 0;
0687: ArrayList variables = new ArrayList(1);
0688: depth = 0;
0689: boolean pendingVariable = true;
0690: createVariables: {
0691: for (int i = 1; i < length; i++) {
0692: switch (typeSignature[i]) {
0693: case '<':
0694: depth++;
0695: break;
0696: case '>':
0697: if (--depth < 0)
0698: break createVariables;
0699: break;
0700: case ';':
0701: if ((depth == 0) && (i + 1 < length)
0702: && (typeSignature[i + 1] != ':'))
0703: pendingVariable = true;
0704: break;
0705: default:
0706: if (pendingVariable) {
0707: pendingVariable = false;
0708: int colon = CharOperation.indexOf(':',
0709: typeSignature, i);
0710: char[] variableName = CharOperation.subarray(
0711: typeSignature, i, colon);
0712: variables.add(new TypeVariableBinding(
0713: variableName, this , rank++));
0714: }
0715: }
0716: }
0717: }
0718: // initialize type variable bounds - may refer to forward variables
0719: TypeVariableBinding[] result;
0720: variables.toArray(result = new TypeVariableBinding[rank]);
0721: // when creating the type variables for a type, the type must remember them before initializing each variable
0722: // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=163680
0723: if (assignVariables)
0724: this .typeVariables = result;
0725: for (int i = 0; i < rank; i++) {
0726: initializeTypeVariable(result[i], result, wrapper);
0727: }
0728: return result;
0729: }
0730:
0731: /* Answer the receiver's enclosing type... null if the receiver is a top level type.
0732: *
0733: * NOTE: enclosingType of a binary type is resolved when needed
0734: */
0735: public ReferenceBinding enclosingType() {
0736: if ((this .tagBits & TagBits.HasUnresolvedEnclosingType) == 0)
0737: return this .enclosingType;
0738:
0739: // finish resolving the type
0740: this .enclosingType = resolveType(this .enclosingType,
0741: this .environment, false);
0742: this .tagBits &= ~TagBits.HasUnresolvedEnclosingType;
0743: return this .enclosingType;
0744: }
0745:
0746: // NOTE: the type of each field of a binary type is resolved when needed
0747: public FieldBinding[] fields() {
0748: if ((this .tagBits & TagBits.AreFieldsComplete) != 0)
0749: return fields;
0750:
0751: // lazily sort fields
0752: if ((this .tagBits & TagBits.AreFieldsSorted) == 0) {
0753: int length = this .fields.length;
0754: if (length > 1)
0755: ReferenceBinding.sortFields(this .fields, 0, length);
0756: this .tagBits |= TagBits.AreFieldsSorted;
0757: }
0758: for (int i = fields.length; --i >= 0;)
0759: resolveTypeFor(fields[i]);
0760: this .tagBits |= TagBits.AreFieldsComplete;
0761: return fields;
0762: }
0763:
0764: /**
0765: * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
0766: */
0767: public char[] genericTypeSignature() {
0768: return computeGenericTypeSignature(this .typeVariables);
0769: }
0770:
0771: //NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
0772: public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
0773:
0774: // lazily sort methods
0775: if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0776: int length = this .methods.length;
0777: if (length > 1)
0778: ReferenceBinding.sortMethods(this .methods, 0, length);
0779: this .tagBits |= TagBits.AreMethodsSorted;
0780: }
0781: int argCount = argumentTypes.length;
0782: long range;
0783: if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT,
0784: this .methods)) >= 0) {
0785: nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
0786: MethodBinding method = methods[imethod];
0787: if (method.parameters.length == argCount) {
0788: resolveTypesFor(method);
0789: TypeBinding[] toMatch = method.parameters;
0790: for (int iarg = 0; iarg < argCount; iarg++)
0791: if (toMatch[iarg] != argumentTypes[iarg])
0792: continue nextMethod;
0793: return method;
0794: }
0795: }
0796: }
0797: return null;
0798: }
0799:
0800: //NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
0801: //searches up the hierarchy as long as no potential (but not exact) match was found.
0802: public MethodBinding getExactMethod(char[] selector,
0803: TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
0804: // sender from refScope calls recordTypeReference(this)
0805:
0806: // lazily sort methods
0807: if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0808: int length = this .methods.length;
0809: if (length > 1)
0810: ReferenceBinding.sortMethods(this .methods, 0, length);
0811: this .tagBits |= TagBits.AreMethodsSorted;
0812: }
0813:
0814: int argCount = argumentTypes.length;
0815: boolean foundNothing = true;
0816:
0817: long range;
0818: if ((range = ReferenceBinding.binarySearch(selector,
0819: this .methods)) >= 0) {
0820: nextMethod: for (int imethod = (int) range, end = (int) (range >> 32); imethod <= end; imethod++) {
0821: MethodBinding method = methods[imethod];
0822: foundNothing = false; // inner type lookups must know that a method with this name exists
0823: if (method.parameters.length == argCount) {
0824: resolveTypesFor(method);
0825: TypeBinding[] toMatch = method.parameters;
0826: for (int iarg = 0; iarg < argCount; iarg++)
0827: if (toMatch[iarg] != argumentTypes[iarg])
0828: continue nextMethod;
0829: return method;
0830: }
0831: }
0832: }
0833: if (foundNothing) {
0834: if (isInterface()) {
0835: if (super Interfaces().length == 1) { // ensure superinterfaces are resolved before checking
0836: if (refScope != null)
0837: refScope
0838: .recordTypeReference(super Interfaces[0]);
0839: return super Interfaces[0].getExactMethod(selector,
0840: argumentTypes, refScope);
0841: }
0842: } else if (super class() != null) { // ensure superclass is resolved before checking
0843: if (refScope != null)
0844: refScope.recordTypeReference(super class);
0845: return super class.getExactMethod(selector,
0846: argumentTypes, refScope);
0847: }
0848: }
0849: return null;
0850: }
0851:
0852: //NOTE: the type of a field of a binary type is resolved when needed
0853: public FieldBinding getField(char[] fieldName, boolean needResolve) {
0854: // lazily sort fields
0855: if ((this .tagBits & TagBits.AreFieldsSorted) == 0) {
0856: int length = this .fields.length;
0857: if (length > 1)
0858: ReferenceBinding.sortFields(this .fields, 0, length);
0859: this .tagBits |= TagBits.AreFieldsSorted;
0860: }
0861: FieldBinding field = ReferenceBinding.binarySearch(fieldName,
0862: this .fields);
0863: return needResolve && field != null ? resolveTypeFor(field)
0864: : field;
0865: }
0866:
0867: /**
0868: * Rewrite of default getMemberType to avoid resolving eagerly all member types when one is requested
0869: */
0870: public ReferenceBinding getMemberType(char[] typeName) {
0871: for (int i = this .memberTypes.length; --i >= 0;) {
0872: ReferenceBinding memberType = this .memberTypes[i];
0873: if (memberType instanceof UnresolvedReferenceBinding) {
0874: char[] name = memberType.sourceName; // source name is qualified with enclosing type name
0875: int prefixLength = this .compoundName[this .compoundName.length - 1].length + 1; // enclosing$
0876: if (name.length == (prefixLength + typeName.length)) // enclosing $ typeName
0877: if (CharOperation.fragmentEquals(typeName, name,
0878: prefixLength, true)) // only check trailing portion
0879: return this .memberTypes[i] = resolveType(
0880: memberType, this .environment, false); // no raw conversion for now
0881: } else if (CharOperation.equals(typeName,
0882: memberType.sourceName)) {
0883: return memberType;
0884: }
0885: }
0886: return null;
0887: }
0888:
0889: // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
0890: public MethodBinding[] getMethods(char[] selector) {
0891: if ((this .tagBits & TagBits.AreMethodsComplete) != 0) {
0892: long range;
0893: if ((range = ReferenceBinding.binarySearch(selector,
0894: this .methods)) >= 0) {
0895: int start = (int) range, end = (int) (range >> 32);
0896: int length = end - start + 1;
0897: if ((this .tagBits & TagBits.AreMethodsComplete) != 0) {
0898: // simply clone method subset
0899: MethodBinding[] result;
0900: System.arraycopy(this .methods, start,
0901: result = new MethodBinding[length], 0,
0902: length);
0903: return result;
0904: }
0905: }
0906: return Binding.NO_METHODS;
0907: }
0908: // lazily sort methods
0909: if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
0910: int length = this .methods.length;
0911: if (length > 1)
0912: ReferenceBinding.sortMethods(this .methods, 0, length);
0913: this .tagBits |= TagBits.AreMethodsSorted;
0914: }
0915: long range;
0916: if ((range = ReferenceBinding.binarySearch(selector,
0917: this .methods)) >= 0) {
0918: int start = (int) range, end = (int) (range >> 32);
0919: int length = end - start + 1;
0920: MethodBinding[] result = new MethodBinding[length];
0921: // iterate methods to resolve them
0922: for (int i = start, index = 0; i <= end; i++, index++)
0923: result[index] = resolveTypesFor(methods[i]);
0924: return result;
0925: }
0926: return Binding.NO_METHODS;
0927: }
0928:
0929: public boolean hasMemberTypes() {
0930: return this .memberTypes.length > 0;
0931: }
0932:
0933: // NOTE: member types of binary types are resolved when needed
0934: public TypeVariableBinding getTypeVariable(char[] variableName) {
0935: TypeVariableBinding variable = super
0936: .getTypeVariable(variableName);
0937: variable.resolve(this .environment);
0938: return variable;
0939: }
0940:
0941: private void initializeTypeVariable(TypeVariableBinding variable,
0942: TypeVariableBinding[] existingVariables,
0943: SignatureWrapper wrapper) {
0944: // ParameterSignature = Identifier ':' TypeSignature
0945: // or Identifier ':' TypeSignature(optional) InterfaceBound(s)
0946: // InterfaceBound = ':' TypeSignature
0947: int colon = CharOperation.indexOf(':', wrapper.signature,
0948: wrapper.start);
0949: wrapper.start = colon + 1; // skip name + ':'
0950: ReferenceBinding type, firstBound = null;
0951: if (wrapper.signature[wrapper.start] == ':') {
0952: type = environment.getResolvedType(
0953: TypeConstants.JAVA_LANG_OBJECT, null);
0954: } else {
0955: type = (ReferenceBinding) environment
0956: .getTypeFromTypeSignature(wrapper,
0957: existingVariables, this );
0958: firstBound = type;
0959: }
0960:
0961: // variable is visible to its bounds
0962: variable.modifiers |= ExtraCompilerModifiers.AccUnresolved;
0963: variable.super class = type;
0964:
0965: ReferenceBinding[] bounds = null;
0966: if (wrapper.signature[wrapper.start] == ':') {
0967: java.util.ArrayList types = new java.util.ArrayList(2);
0968: do {
0969: wrapper.start++; // skip ':'
0970: types.add(environment.getTypeFromTypeSignature(wrapper,
0971: existingVariables, this ));
0972: } while (wrapper.signature[wrapper.start] == ':');
0973: bounds = new ReferenceBinding[types.size()];
0974: types.toArray(bounds);
0975: }
0976:
0977: variable.super Interfaces = bounds == null ? Binding.NO_SUPERINTERFACES
0978: : bounds;
0979: if (firstBound == null) {
0980: firstBound = variable.super Interfaces.length == 0 ? null
0981: : variable.super Interfaces[0];
0982: }
0983: variable.firstBound = firstBound;
0984: }
0985:
0986: /**
0987: * Returns true if a type is identical to another one,
0988: * or for generic types, true if compared to its raw type.
0989: */
0990: public boolean isEquivalentTo(TypeBinding otherType) {
0991: if (this == otherType)
0992: return true;
0993: if (otherType == null)
0994: return false;
0995: switch (otherType.kind()) {
0996: case Binding.WILDCARD_TYPE:
0997: return ((WildcardBinding) otherType).boundCheck(this );
0998: case Binding.RAW_TYPE:
0999: return otherType.erasure() == this ;
1000: }
1001: return false;
1002: }
1003:
1004: public boolean isGenericType() {
1005: return this .typeVariables != Binding.NO_TYPE_VARIABLES;
1006: }
1007:
1008: public int kind() {
1009: if (this .typeVariables != Binding.NO_TYPE_VARIABLES)
1010: return Binding.GENERIC_TYPE;
1011: return Binding.TYPE;
1012: }
1013:
1014: // NOTE: member types of binary types are resolved when needed
1015: public ReferenceBinding[] memberTypes() {
1016: if ((this .tagBits & TagBits.HasUnresolvedMemberTypes) == 0)
1017: return this .memberTypes;
1018:
1019: for (int i = this .memberTypes.length; --i >= 0;)
1020: this .memberTypes[i] = resolveType(this .memberTypes[i],
1021: this .environment, false); // no raw conversion for now
1022: this .tagBits &= ~TagBits.HasUnresolvedMemberTypes;
1023: return this .memberTypes;
1024: }
1025:
1026: // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
1027: public MethodBinding[] methods() {
1028: if ((this .tagBits & TagBits.AreMethodsComplete) != 0)
1029: return methods;
1030:
1031: // lazily sort methods
1032: if ((this .tagBits & TagBits.AreMethodsSorted) == 0) {
1033: int length = this .methods.length;
1034: if (length > 1)
1035: ReferenceBinding.sortMethods(this .methods, 0, length);
1036: this .tagBits |= TagBits.AreMethodsSorted;
1037: }
1038: for (int i = methods.length; --i >= 0;)
1039: resolveTypesFor(methods[i]);
1040: this .tagBits |= TagBits.AreMethodsComplete;
1041: return methods;
1042: }
1043:
1044: private FieldBinding resolveTypeFor(FieldBinding field) {
1045: if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
1046: return field;
1047:
1048: field.type = resolveType(field.type, this .environment, null, 0);
1049: field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
1050: return field;
1051: }
1052:
1053: MethodBinding resolveTypesFor(MethodBinding method) {
1054: if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
1055: return method;
1056:
1057: if (!method.isConstructor())
1058: method.returnType = resolveType(method.returnType,
1059: this .environment, null, 0);
1060: for (int i = method.parameters.length; --i >= 0;)
1061: method.parameters[i] = resolveType(method.parameters[i],
1062: this .environment, null, 0);
1063: for (int i = method.thrownExceptions.length; --i >= 0;)
1064: method.thrownExceptions[i] = resolveType(
1065: method.thrownExceptions[i], this .environment, true);
1066: for (int i = method.typeVariables.length; --i >= 0;)
1067: method.typeVariables[i].resolve(this .environment);
1068: method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
1069: return method;
1070: }
1071:
1072: AnnotationBinding[] retrieveAnnotations(Binding binding) {
1073: return AnnotationBinding.addStandardAnnotations(super
1074: .retrieveAnnotations(binding), binding
1075: .getAnnotationTagBits(), this .environment);
1076: }
1077:
1078: SimpleLookupTable storedAnnotations(boolean forceInitialize) {
1079: if (forceInitialize && this .storedAnnotations == null) {
1080: if (!this .environment.globalOptions.storeAnnotations)
1081: return null; // not supported during this compile
1082: this .storedAnnotations = new SimpleLookupTable(3);
1083: }
1084: return this .storedAnnotations;
1085: }
1086:
1087: /* Answer the receiver's superclass... null if the receiver is Object or an interface.
1088: *
1089: * NOTE: superclass of a binary type is resolved when needed
1090: */
1091: public ReferenceBinding super class() {
1092: if ((this .tagBits & TagBits.HasUnresolvedSuperclass) == 0)
1093: return this .super class;
1094:
1095: // finish resolving the type
1096: this .super class = resolveType(this .super class,
1097: this .environment, true);
1098: this .tagBits &= ~TagBits.HasUnresolvedSuperclass;
1099: if (this .super class.problemId() == ProblemReasons.NotFound)
1100: this .tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1101: return this .super class;
1102: }
1103:
1104: // NOTE: superInterfaces of binary types are resolved when needed
1105: public ReferenceBinding[] super Interfaces() {
1106: if ((this .tagBits & TagBits.HasUnresolvedSuperinterfaces) == 0)
1107: return this .super Interfaces;
1108:
1109: for (int i = this .super Interfaces.length; --i >= 0;) {
1110: this .super Interfaces[i] = resolveType(
1111: this .super Interfaces[i], this .environment, true);
1112: if (this .super Interfaces[i].problemId() == ProblemReasons.NotFound)
1113: this .tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
1114: }
1115: this .tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
1116: return this .super Interfaces;
1117: }
1118:
1119: public TypeVariableBinding[] typeVariables() {
1120: if ((this .tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
1121: return this .typeVariables;
1122:
1123: for (int i = this .typeVariables.length; --i >= 0;)
1124: this .typeVariables[i].resolve(this .environment);
1125: this .tagBits &= ~TagBits.HasUnresolvedTypeVariables;
1126: return this .typeVariables;
1127: }
1128:
1129: public String toString() {
1130: StringBuffer buffer = new StringBuffer();
1131:
1132: if (isDeprecated())
1133: buffer.append("deprecated "); //$NON-NLS-1$
1134: if (isPublic())
1135: buffer.append("public "); //$NON-NLS-1$
1136: if (isProtected())
1137: buffer.append("protected "); //$NON-NLS-1$
1138: if (isPrivate())
1139: buffer.append("private "); //$NON-NLS-1$
1140: if (isAbstract() && isClass())
1141: buffer.append("abstract "); //$NON-NLS-1$
1142: if (isStatic() && isNestedType())
1143: buffer.append("static "); //$NON-NLS-1$
1144: if (isFinal())
1145: buffer.append("final "); //$NON-NLS-1$
1146:
1147: if (isEnum())
1148: buffer.append("enum "); //$NON-NLS-1$
1149: else if (isAnnotationType())
1150: buffer.append("@interface "); //$NON-NLS-1$
1151: else if (isClass())
1152: buffer.append("class "); //$NON-NLS-1$
1153: else
1154: buffer.append("interface "); //$NON-NLS-1$
1155: buffer.append((compoundName != null) ? CharOperation
1156: .toString(compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
1157:
1158: buffer.append("\n\textends "); //$NON-NLS-1$
1159: buffer.append((super class != null) ? super class.debugName()
1160: : "NULL TYPE"); //$NON-NLS-1$
1161:
1162: if (super Interfaces != null) {
1163: if (super Interfaces != Binding.NO_SUPERINTERFACES) {
1164: buffer.append("\n\timplements : "); //$NON-NLS-1$
1165: for (int i = 0, length = super Interfaces.length; i < length; i++) {
1166: if (i > 0)
1167: buffer.append(", "); //$NON-NLS-1$
1168: buffer
1169: .append((super Interfaces[i] != null) ? super Interfaces[i]
1170: .debugName()
1171: : "NULL TYPE"); //$NON-NLS-1$
1172: }
1173: }
1174: } else {
1175: buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
1176: }
1177:
1178: if (enclosingType != null) {
1179: buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
1180: buffer.append(enclosingType.debugName());
1181: }
1182:
1183: if (fields != null) {
1184: if (fields != Binding.NO_FIELDS) {
1185: buffer.append("\n/* fields */"); //$NON-NLS-1$
1186: for (int i = 0, length = fields.length; i < length; i++)
1187: buffer
1188: .append((fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"); //$NON-NLS-1$ //$NON-NLS-2$
1189: }
1190: } else {
1191: buffer.append("NULL FIELDS"); //$NON-NLS-1$
1192: }
1193:
1194: if (methods != null) {
1195: if (methods != Binding.NO_METHODS) {
1196: buffer.append("\n/* methods */"); //$NON-NLS-1$
1197: for (int i = 0, length = methods.length; i < length; i++)
1198: buffer
1199: .append((methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"); //$NON-NLS-1$ //$NON-NLS-2$
1200: }
1201: } else {
1202: buffer.append("NULL METHODS"); //$NON-NLS-1$
1203: }
1204:
1205: if (memberTypes != null) {
1206: if (memberTypes != Binding.NO_MEMBER_TYPES) {
1207: buffer.append("\n/* members */"); //$NON-NLS-1$
1208: for (int i = 0, length = memberTypes.length; i < length; i++)
1209: buffer
1210: .append((memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"); //$NON-NLS-1$ //$NON-NLS-2$
1211: }
1212: } else {
1213: buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
1214: }
1215:
1216: buffer.append("\n\n\n"); //$NON-NLS-1$
1217: return buffer.toString();
1218: }
1219:
1220: MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
1221: return methods;
1222: }
1223: }
|