Revision: 8405
Author: [email protected]
Date: Thu Jul 22 05:27:33 2010
Log: Adds BinaryTypeBinding from JDT 3.4.2 in preparation for changes.
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8405
Added:
/trunk/dev/core/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
=======================================
--- /dev/null
+++
/trunk/dev/core/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
Thu Jul 22 05:27:33 2010
@@ -0,0 +1,1079 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+
*******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+/*
+Not all fields defined by this type are initialized when it is created.
+Some are initialized only when needed.
+
+Accessors have been provided for some public fields so all TypeBindings
have the same API...
+but access public fields directly whenever possible.
+Non-public fields have accessors which should be used everywhere you
expect the field to be initialized.
+
+null is NOT a valid value for a non-public field... it just means the
field is not initialized.
+*/
+
+public class BinaryTypeBinding extends ReferenceBinding {
+
+ // all of these fields are ONLY guaranteed to be initialized if accessed
using their public accessor method
+ protected ReferenceBinding superclass;
+ protected ReferenceBinding enclosingType;
+ protected ReferenceBinding[] superInterfaces;
+ protected FieldBinding[] fields;
+ protected MethodBinding[] methods;
+ protected ReferenceBinding[] memberTypes;
+ protected TypeVariableBinding[] typeVariables;
+
+ // For the link with the principle structure
+ protected LookupEnvironment environment;
+
+ protected SimpleLookupTable storedAnnotations = null; // keys are this
ReferenceBinding & its fields and methods, value is an AnnotationHolder
+
+static Object convertMemberValue(Object binaryValue, LookupEnvironment
env, char[][][] missingTypeNames) {
+ if (binaryValue == null) return null;
+ if (binaryValue instanceof Constant)
+ return binaryValue;
+ if (binaryValue instanceof ClassSignature) {
+ TypeBinding typeFromSignature =
env.getTypeFromSignature(((ClassSignature) binaryValue).getTypeName(), 0,
-1, false, null, missingTypeNames);
+ if (typeFromSignature.isBaseType()) {
+ return typeFromSignature;
+ }
+ return resolveType((ReferenceBinding) typeFromSignature, env,
false);
+ }
+ if (binaryValue instanceof IBinaryAnnotation)
+ return createAnnotation((IBinaryAnnotation) binaryValue, env,
missingTypeNames);
+ if (binaryValue instanceof EnumConstantSignature) {
+ EnumConstantSignature ref = (EnumConstantSignature) binaryValue;
+ ReferenceBinding enumType = (ReferenceBinding)
env.getTypeFromSignature(ref.getTypeName(), 0, -1, false, null,
missingTypeNames);
+ enumType = resolveType(enumType, env, false);
+ return enumType.getField(ref.getEnumConstantName(), false);
+ }
+ if (binaryValue instanceof Object[]) {
+ Object[] objects = (Object[]) binaryValue;
+ int length = objects.length;
+ if (length == 0) return objects;
+ Object[] values = new Object[length];
+ for (int i = 0; i < length; i++)
+ values[i] = convertMemberValue(objects[i], env,
missingTypeNames);
+ return values;
+ }
+
+ // should never reach here.
+ throw new IllegalStateException();
+}
+static AnnotationBinding createAnnotation(IBinaryAnnotation
annotationInfo, LookupEnvironment env, char[][][] missingTypeNames) {
+ IBinaryElementValuePair[] binaryPairs =
annotationInfo.getElementValuePairs();
+ int length = binaryPairs == null ? 0 : binaryPairs.length;
+ ElementValuePair[] pairs = length == 0 ? Binding.NO_ELEMENT_VALUE_PAIRS :
new ElementValuePair[length];
+ for (int i = 0; i < length; i++)
+ pairs[i] = new ElementValuePair(binaryPairs[i].getName(),
convertMemberValue(binaryPairs[i].getValue(), env, missingTypeNames), null);
+
+ char[] typeName = annotationInfo.getTypeName();
+ ReferenceBinding annotationType =
env.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false,
missingTypeNames);
+ return new UnresolvedAnnotationBinding(annotationType, pairs, env);
+}
+public static AnnotationBinding[] createAnnotations(IBinaryAnnotation[]
annotationInfos, LookupEnvironment env, char[][][] missingTypeNames) {
+ int length = annotationInfos == null ? 0 : annotationInfos.length;
+ AnnotationBinding[] result = length == 0 ? Binding.NO_ANNOTATIONS : new
AnnotationBinding[length];
+ for (int i = 0; i < length; i++)
+ result[i] = createAnnotation(annotationInfos[i], env,
missingTypeNames);
+ return result;
+}
+public static ReferenceBinding resolveType(ReferenceBinding type,
LookupEnvironment environment, boolean convertGenericToRawType) {
+ if (type instanceof UnresolvedReferenceBinding)
+ return ((UnresolvedReferenceBinding) type).resolve(environment,
convertGenericToRawType);
+ switch (type.kind()) {
+ case Binding.PARAMETERIZED_TYPE :
+ return ((ParameterizedTypeBinding) type).resolve();
+ case Binding.WILDCARD_TYPE :
+ case Binding.INTERSECTION_TYPE :
+ return ((WildcardBinding) type).resolve();
+ }
+ if (convertGenericToRawType) // raw reference to generic ?
+ return (ReferenceBinding)
environment.convertUnresolvedBinaryToRawType(type);
+ return type;
+}
+public static TypeBinding resolveType(TypeBinding type, LookupEnvironment
environment, ParameterizedTypeBinding parameterizedType, int rank) {
+ switch (type.kind()) {
+
+ case Binding.PARAMETERIZED_TYPE :
+ return ((ParameterizedTypeBinding) type).resolve();
+
+ case Binding.WILDCARD_TYPE :
+ case Binding.INTERSECTION_TYPE :
+ return ((WildcardBinding) type).resolve();
+
+ case Binding.ARRAY_TYPE :
+ resolveType(((ArrayBinding) type).leafComponentType, environment,
parameterizedType, rank);
+ break;
+
+ case Binding.TYPE_PARAMETER :
+ ((TypeVariableBinding) type).resolve(environment);
+ break;
+
+ case Binding.GENERIC_TYPE :
+ if (parameterizedType == null) // raw reference to
generic ?
+ return
environment.convertUnresolvedBinaryToRawType(type);
+ break;
+
+ default:
+ if (type instanceof UnresolvedReferenceBinding)
+ return ((UnresolvedReferenceBinding) type).resolve(environment,
parameterizedType == null);
+ }
+ return type;
+}
+
+/**
+ * Default empty constructor for subclasses only.
+ */
+protected BinaryTypeBinding() {
+ // only for subclasses
+}
+
+/**
+ * Standard constructor for creating binary type bindings from binary
models (classfiles)
+ * @param packageBinding
+ * @param binaryType
+ * @param environment
+ */
+public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType
binaryType, LookupEnvironment environment) {
+ this.compoundName = CharOperation.splitOn('/', binaryType.getName());
+ computeId();
+
+ this.tagBits |= TagBits.IsBinaryBinding;
+ this.environment = environment;
+ this.fPackage = packageBinding;
+ this.fileName = binaryType.getFileName();
+
+ char[] typeSignature = environment.globalOptions.sourceLevel >=
ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null;
+ this.typeVariables = typeSignature != null && typeSignature.length > 0 &&
typeSignature[0] == '<'
+ ? null // is initialized in cachePartsFrom (called from
LookupEnvironment.createBinaryTypeFrom())... must set to null so
isGenericType() answers true
+ : Binding.NO_TYPE_VARIABLES;
+
+ this.sourceName = binaryType.getSourceName();
+ this.modifiers = binaryType.getModifiers();
+
+ if ((binaryType.getTagBits() & TagBits.HierarchyHasProblems) != 0)
+ this.tagBits |= TagBits.HierarchyHasProblems;
+
+ if (binaryType.isAnonymous()) {
+ this.tagBits |= TagBits.AnonymousTypeMask;
+ } else if (binaryType.isLocal()) {
+ this.tagBits |= TagBits.LocalTypeMask;
+ } else if (binaryType.isMember()) {
+ this.tagBits |= TagBits.MemberTypeMask;
+ }
+ // need enclosing type to access type variables
+ char[] enclosingTypeName = binaryType.getEnclosingTypeName();
+ if (enclosingTypeName != null) {
+ // attempt to find the enclosing type if it exists in the cache
(otherwise - resolve it when requested)
+ this.enclosingType =
environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true,
null /* could not be missing */); // pretend parameterized to avoid raw
+ this.tagBits |= TagBits.MemberTypeMask; // must be a member type not a
top-level or local type
+ this.tagBits |= TagBits.HasUnresolvedEnclosingType;
+ if (this.enclosingType().isStrictfp())
+ this.modifiers |= ClassFileConstants.AccStrictfp;
+ if (this.enclosingType().isDeprecated())
+ this.modifiers |=
ExtraCompilerModifiers.AccDeprecatedImplicitly;
+ }
+}
+
+/**
+ * @see
org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
+ */
+public FieldBinding[] availableFields() {
+ if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+ return fields;
+
+ // lazily sort fields
+ if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+ int length = this.fields.length;
+ if (length > 1)
+ ReferenceBinding.sortFields(this.fields, 0, length);
+ this.tagBits |= TagBits.AreFieldsSorted;
+ }
+ FieldBinding[] availableFields = new FieldBinding[fields.length];
+ int count = 0;
+ for (int i = 0; i < fields.length; i++) {
+ try {
+ availableFields[count] = resolveTypeFor(fields[i]);
+ count++;
+ } catch (AbortCompilation a){
+ // silent abort
+ }
+ }
+ if (count < availableFields.length)
+ System.arraycopy(availableFields, 0, availableFields = new
FieldBinding[count], 0, count);
+ return availableFields;
+}
+
+/**
+ * @see
org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
+ */
+public MethodBinding[] availableMethods() {
+ if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+ return methods;
+
+ // lazily sort methods
+ if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+ int length = this.methods.length;
+ if (length > 1)
+ ReferenceBinding.sortMethods(this.methods, 0, length);
+ this.tagBits |= TagBits.AreMethodsSorted;
+ }
+ MethodBinding[] availableMethods = new MethodBinding[methods.length];
+ int count = 0;
+ for (int i = 0; i < methods.length; i++) {
+ try {
+ availableMethods[count] = resolveTypesFor(methods[i]);
+ count++;
+ } catch (AbortCompilation a){
+ // silent abort
+ }
+ }
+ if (count < availableMethods.length)
+ System.arraycopy(availableMethods, 0, availableMethods = new
MethodBinding[count], 0, count);
+ return availableMethods;
+}
+void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) {
+ // default initialization for super-interfaces early, in case some
aborting compilation error occurs,
+ // and still want to use binaries passed that point (e.g. type hierarchy
resolver, see bug 63748).
+ this.typeVariables = Binding.NO_TYPE_VARIABLES;
+ this.superInterfaces = Binding.NO_SUPERINTERFACES;
+
+ // must retrieve member types in case superclass/interfaces need them
+ this.memberTypes = Binding.NO_MEMBER_TYPES;
+ IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes();
+ if (memberTypeStructures != null) {
+ int size = memberTypeStructures.length;
+ if (size > 0) {
+ this.memberTypes = new ReferenceBinding[size];
+ for (int i = 0; i < size; i++)
+ // attempt to find each member type if it exists in the cache
(otherwise - resolve it when requested)
+ this.memberTypes[i] =
environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(),
0, -1, false, null /* could not be missing */);
+ this.tagBits |=
TagBits.HasUnresolvedMemberTypes;
+ }
+ }
+
+
+ long sourceLevel = environment.globalOptions.sourceLevel;
+ char[] typeSignature = null;
+ if (sourceLevel >= ClassFileConstants.JDK1_5) {
+ typeSignature = binaryType.getGenericSignature();
+ this.tagBits |= binaryType.getTagBits();
+ }
+ char[][][] missingTypeNames = binaryType.getMissingTypeNames();
+ if (typeSignature == null) {
+ char[] superclassName = binaryType.getSuperclassName();
+ if (superclassName != null) {
+ // attempt to find the superclass if it exists in the cache (otherwise
- resolve it when requested)
+ this.superclass =
environment.getTypeFromConstantPoolName(superclassName, 0, -1, false,
missingTypeNames);
+ this.tagBits |= TagBits.HasUnresolvedSuperclass;
+ }
+
+ this.superInterfaces = Binding.NO_SUPERINTERFACES;
+ char[][] interfaceNames = binaryType.getInterfaceNames();
+ if (interfaceNames != null) {
+ int size = interfaceNames.length;
+ if (size > 0) {
+ this.superInterfaces = new
ReferenceBinding[size];
+ for (int i = 0; i < size; i++)
+ // attempt to find each superinterface if it exists in the cache
(otherwise - resolve it when requested)
+ this.superInterfaces[i] =
environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false,
missingTypeNames);
+ this.tagBits |=
TagBits.HasUnresolvedSuperinterfaces;
+ }
+ }
+ } else {
+ // ClassSignature = ParameterPart(optional) super_TypeSignature
interface_signature
+ SignatureWrapper wrapper = new SignatureWrapper(typeSignature);
+ if (wrapper.signature[wrapper.start] == '<') {
+ // ParameterPart = '<' ParameterSignature(s) '>'
+ wrapper.start++; // skip '<'
+ this.typeVariables = createTypeVariables(wrapper, true,
missingTypeNames);
+ wrapper.start++; // skip '>'
+ this.tagBits |= TagBits.HasUnresolvedTypeVariables;
+ this.modifiers |=
ExtraCompilerModifiers.AccGenericSignature;
+ }
+
+ // attempt to find the superclass if it exists in the cache (otherwise -
resolve it when requested)
+ this.superclass = (ReferenceBinding)
environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES,
this, missingTypeNames);
+ this.tagBits |= TagBits.HasUnresolvedSuperclass;
+
+ this.superInterfaces = Binding.NO_SUPERINTERFACES;
+ if (!wrapper.atEnd()) {
+ // attempt to find each superinterface if it exists in the cache
(otherwise - resolve it when requested)
+ java.util.ArrayList types = new java.util.ArrayList(2);
+ do {
+ types.add(environment.getTypeFromTypeSignature(wrapper,
Binding.NO_TYPE_VARIABLES, this, missingTypeNames));
+ } while (!wrapper.atEnd());
+ this.superInterfaces = new
ReferenceBinding[types.size()];
+ types.toArray(this.superInterfaces);
+ this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+ }
+ }
+
+ if (needFieldsAndMethods) {
+ createFields(binaryType.getFields(), sourceLevel,
missingTypeNames);
+ createMethods(binaryType.getMethods(), sourceLevel,
missingTypeNames);
+ } else { // protect against incorrect use of the needFieldsAndMethods
flag, see 48459
+ this.fields = Binding.NO_FIELDS;
+ this.methods = Binding.NO_METHODS;
+ }
+ if (this.environment.globalOptions.storeAnnotations)
+ setAnnotations(createAnnotations(binaryType.getAnnotations(),
this.environment, missingTypeNames));
+}
+private void createFields(IBinaryField[] iFields, long sourceLevel,
char[][][] missingTypeNames) {
+ this.fields = Binding.NO_FIELDS;
+ if (iFields != null) {
+ int size = iFields.length;
+ if (size > 0) {
+ this.fields = new FieldBinding[size];
+ boolean use15specifics = sourceLevel >=
ClassFileConstants.JDK1_5;
+ boolean isViewedAsDeprecated = isViewedAsDeprecated();
+ boolean hasRestrictedAccess = hasRestrictedAccess();
+ int firstAnnotatedFieldIndex = -1;
+ for (int i = 0; i < size; i++) {
+ IBinaryField binaryField = iFields[i];
+ char[] fieldSignature = use15specifics ?
binaryField.getGenericSignature() : null;
+ TypeBinding type = fieldSignature == null
+ ? environment.getTypeFromSignature(binaryField.getTypeName(), 0, -1,
false, this, missingTypeNames)
+ : environment.getTypeFromTypeSignature(new
SignatureWrapper(fieldSignature), Binding.NO_TYPE_VARIABLES, this,
missingTypeNames);
+ FieldBinding field =
+ new FieldBinding(
+ binaryField.getName(),
+ type,
+ binaryField.getModifiers() |
ExtraCompilerModifiers.AccUnresolved,
+ this,
+ binaryField.getConstant());
+ if (firstAnnotatedFieldIndex < 0
+ &&
this.environment.globalOptions.storeAnnotations
+ && binaryField.getAnnotations()
!= null) {
+ firstAnnotatedFieldIndex = i;
+ }
+ field.id = i; // ordinal
+ if (use15specifics)
+ field.tagBits |=
binaryField.getTagBits();
+ if (isViewedAsDeprecated &&
!field.isDeprecated())
+ field.modifiers |=
ExtraCompilerModifiers.AccDeprecatedImplicitly;
+ if (hasRestrictedAccess)
+ field.modifiers |=
ExtraCompilerModifiers.AccRestrictedAccess;
+ if (fieldSignature != null)
+ field.modifiers |=
ExtraCompilerModifiers.AccGenericSignature;
+ this.fields[i] = field;
+ }
+ // second pass for reifying annotations, since may refer to fields
being constructed (147875)
+ if (firstAnnotatedFieldIndex >= 0) {
+ for (int i = firstAnnotatedFieldIndex; i <size;
i++) {
+ IBinaryField binaryField = iFields[i];
+
this.fields[i].setAnnotations(createAnnotations(binaryField.getAnnotations(),
this.environment, missingTypeNames));
+ }
+ }
+ }
+ }
+}
+private MethodBinding createMethod(IBinaryMethod method, long sourceLevel,
char[][][] missingTypeNames) {
+ int methodModifiers = method.getModifiers() |
ExtraCompilerModifiers.AccUnresolved;
+ if (sourceLevel < ClassFileConstants.JDK1_5)
+ methodModifiers &= ~ClassFileConstants.AccVarargs; // vararg methods are
not recognized until 1.5
+ ReferenceBinding[] exceptions = Binding.NO_EXCEPTIONS;
+ TypeBinding[] parameters = Binding.NO_PARAMETERS;
+ TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
+ AnnotationBinding[][] paramAnnotations = null;
+ TypeBinding returnType = null;
+
+ final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
+ char[] methodSignature = use15specifics ? method.getGenericSignature() :
null;
+ if (methodSignature == null) { // no generics
+ char[] methodDescriptor = method.getMethodDescriptor(); // of the form
(I[Ljava/jang/String;)V
+ int numOfParams = 0;
+ char nextChar;
+ int index = 0; // first character is always '(' so skip it
+ while ((nextChar = methodDescriptor[++index]) != ')') {
+ if (nextChar != '[') {
+ numOfParams++;
+ if (nextChar == 'L')
+ while ((nextChar =
methodDescriptor[++index]) != ';'){/*empty*/}
+ }
+ }
+
+ // Ignore synthetic argument for member types.
+ int startIndex = (method.isConstructor() && isMemberType()
&& !isStatic()) ? 1 : 0;
+ int size = numOfParams - startIndex;
+ if (size > 0) {
+ parameters = new TypeBinding[size];
+ if (this.environment.globalOptions.storeAnnotations)
+ paramAnnotations = new
AnnotationBinding[size][];
+ index = 1;
+ int end = 0; // first character is always '(' so skip
it
+ for (int i = 0; i < numOfParams; i++) {
+ while ((nextChar = methodDescriptor[++end]) ==
'['){/*empty*/}
+ if (nextChar == 'L')
+ while ((nextChar =
methodDescriptor[++end]) != ';'){/*empty*/}
+
+ if (i >= startIndex) { // skip the synthetic
arg if necessary
+ parameters[i - startIndex] =
environment.getTypeFromSignature(methodDescriptor, index, end, false, this,
missingTypeNames);
+ // 'paramAnnotations' line up with
'parameters'
+ // int parameter to method.getParameterAnnotations() include the
synthetic arg
+ if (paramAnnotations != null)
+ paramAnnotations[i - startIndex] =
createAnnotations(method.getParameterAnnotations(i), this.environment,
missingTypeNames);
+ }
+ index = end + 1;
+ }
+ }
+
+ char[][] exceptionTypes = method.getExceptionTypeNames();
+ if (exceptionTypes != null) {
+ size = exceptionTypes.length;
+ if (size > 0) {
+ exceptions = new ReferenceBinding[size];
+ for (int i = 0; i < size; i++)
+ exceptions[i] =
environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false,
missingTypeNames);
+ }
+ }
+
+ if (!method.isConstructor())
+ returnType = environment.getTypeFromSignature(methodDescriptor, index +
1, -1, false, this, missingTypeNames); // index is currently pointing at
the ')'
+ } else {
+ methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
+ // MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')'
return_typeSignature ['^' TypeSignature (optional)]
+ SignatureWrapper wrapper = new
SignatureWrapper(methodSignature);
+ if (wrapper.signature[wrapper.start] == '<') {
+ //
<A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
+ // ParameterPart = '<' ParameterSignature(s) '>'
+ wrapper.start++; // skip '<'
+ typeVars = createTypeVariables(wrapper, false,
missingTypeNames);
+ wrapper.start++; // skip '>'
+ }
+
+ if (wrapper.signature[wrapper.start] == '(') {
+ wrapper.start++; // skip '('
+ if (wrapper.signature[wrapper.start] == ')') {
+ wrapper.start++; // skip ')'
+ } else {
+ java.util.ArrayList types = new
java.util.ArrayList(2);
+ while (wrapper.signature[wrapper.start] != ')')
+ types.add(environment.getTypeFromTypeSignature(wrapper, typeVars,
this, missingTypeNames));
+ wrapper.start++; // skip ')'
+ int numParam = types.size();
+ parameters = new TypeBinding[numParam];
+ types.toArray(parameters);
+ if
(this.environment.globalOptions.storeAnnotations) {
+ paramAnnotations = new
AnnotationBinding[numParam][];
+ for (int i = 0; i < numParam; i++)
+ paramAnnotations[i] =
createAnnotations(method.getParameterAnnotations(i), this.environment,
missingTypeNames);
+ }
+ }
+ }
+
+ // always retrieve return type (for constructors, its V for void - will
be ignored)
+ returnType = environment.getTypeFromTypeSignature(wrapper, typeVars,
this, missingTypeNames);
+
+ if (!wrapper.atEnd() && wrapper.signature[wrapper.start] ==
'^') {
+ // attempt to find each exception if it exists in the cache (otherwise
- resolve it when requested)
+ java.util.ArrayList types = new java.util.ArrayList(2);
+ do {
+ wrapper.start++; // skip '^'
+ types.add(environment.getTypeFromTypeSignature(wrapper, typeVars,
this, missingTypeNames));
+ } while (!wrapper.atEnd() &&
wrapper.signature[wrapper.start] == '^');
+ exceptions = new ReferenceBinding[types.size()];
+ types.toArray(exceptions);
+ } else { // get the exceptions the old way
+ char[][] exceptionTypes =
method.getExceptionTypeNames();
+ if (exceptionTypes != null) {
+ int size = exceptionTypes.length;
+ if (size > 0) {
+ exceptions = new ReferenceBinding[size];
+ for (int i = 0; i < size; i++)
+ exceptions[i] =
environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false,
missingTypeNames);
+ }
+ }
+ }
+ }
+
+ MethodBinding result = method.isConstructor()
+ ? new MethodBinding(methodModifiers, parameters, exceptions,
this)
+ : new MethodBinding(methodModifiers, method.getSelector(), returnType,
parameters, exceptions, this);
+ if (this.environment.globalOptions.storeAnnotations)
+ result.setAnnotations(
+ createAnnotations(method.getAnnotations(), this.environment,
missingTypeNames),
+ paramAnnotations,
+ isAnnotationType() ? convertMemberValue(method.getDefaultValue(),
this.environment, missingTypeNames) : null);
+
+ if (use15specifics)
+ result.tagBits |= method.getTagBits();
+ result.typeVariables = typeVars;
+ // fixup the declaring element of the type variable
+ for (int i = 0, length = typeVars.length; i < length; i++)
+ typeVars[i].declaringElement = result;
+ return result;
+}
+/**
+ * Create method bindings for binary type, filtering out <clinit> and
synthetics
+ */
+private void createMethods(IBinaryMethod[] iMethods, long sourceLevel,
char[][][] missingTypeNames) {
+ int total = 0, initialTotal = 0, iClinit = -1;
+ int[] toSkip = null;
+ if (iMethods != null) {
+ total = initialTotal = iMethods.length;
+ boolean keepBridgeMethods = sourceLevel <
ClassFileConstants.JDK1_5
+ && this.environment.globalOptions.complianceLevel >=
ClassFileConstants.JDK1_5;
+ for (int i = total; --i >= 0;) {
+ IBinaryMethod method = iMethods[i];
+ if ((method.getModifiers() &
ClassFileConstants.AccSynthetic) != 0) {
+ if (keepBridgeMethods && (method.getModifiers() &
ClassFileConstants.AccBridge) != 0)
+ continue; // want to see bridge methods
as real methods
+ // discard synthetics methods
+ if (toSkip == null) toSkip = new
int[iMethods.length];
+ toSkip[i] = -1;
+ total--;
+ } else if (iClinit == -1) {
+ char[] methodName = method.getSelector();
+ if (methodName.length == 8 && methodName[0] ==
'<') {
+ // discard <clinit>
+ iClinit = i;
+ total--;
+ }
+ }
+ }
+ }
+ if (total == 0) {
+ this.methods = Binding.NO_METHODS;
+ return;
+ }
+
+ boolean isViewedAsDeprecated = isViewedAsDeprecated();
+ boolean hasRestrictedAccess = hasRestrictedAccess();
+ this.methods = new MethodBinding[total];
+ if (total == initialTotal) {
+ for (int i = 0; i < initialTotal; i++) {
+ MethodBinding method = createMethod(iMethods[i], sourceLevel,
missingTypeNames);
+ if (isViewedAsDeprecated && !method.isDeprecated())
+ method.modifiers |=
ExtraCompilerModifiers.AccDeprecatedImplicitly;
+ if (hasRestrictedAccess)
+ method.modifiers |=
ExtraCompilerModifiers.AccRestrictedAccess;
+ this.methods[i] = method;
+ }
+ } else {
+ for (int i = 0, index = 0; i < initialTotal; i++) {
+ if (iClinit != i && (toSkip == null || toSkip[i] !=
-1)) {
+ MethodBinding method = createMethod(iMethods[i], sourceLevel,
missingTypeNames);
+ if (isViewedAsDeprecated &&
!method.isDeprecated())
+ method.modifiers |=
ExtraCompilerModifiers.AccDeprecatedImplicitly;
+ if (hasRestrictedAccess)
+ method.modifiers |=
ExtraCompilerModifiers.AccRestrictedAccess;
+ this.methods[index++] = method;
+ }
+ }
+ }
+}
+private TypeVariableBinding[] createTypeVariables(SignatureWrapper
wrapper, boolean assignVariables, char[][][] missingTypeNames) {
+ // detect all type variables first
+ char[] typeSignature = wrapper.signature;
+ int depth = 0, length = typeSignature.length;
+ int rank = 0;
+ ArrayList variables = new ArrayList(1);
+ depth = 0;
+ boolean pendingVariable = true;
+ createVariables: {
+ for (int i = 1; i < length; i++) {
+ switch(typeSignature[i]) {
+ case '<' :
+ depth++;
+ break;
+ case '>' :
+ if (--depth < 0)
+ break createVariables;
+ break;
+ case ';' :
+ if ((depth == 0) && (i +1 < length) &&
(typeSignature[i+1] != ':'))
+ pendingVariable = true;
+ break;
+ default:
+ if (pendingVariable) {
+ pendingVariable = false;
+ int colon =
CharOperation.indexOf(':', typeSignature, i);
+ char[] variableName = CharOperation.subarray(typeSignature, i,
colon);
+ variables.add(new
TypeVariableBinding(variableName, this, rank++));
+ }
+ }
+ }
+ }
+ // initialize type variable bounds - may refer to forward variables
+ TypeVariableBinding[] result;
+ variables.toArray(result = new TypeVariableBinding[rank]);
+ // when creating the type variables for a type, the type must remember
them before initializing each variable
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=163680
+ if (assignVariables)
+ this.typeVariables = result;
+ for (int i = 0; i < rank; i++) {
+ initializeTypeVariable(result[i], result, wrapper,
missingTypeNames);
+ }
+ return result;
+}
+/* Answer the receiver's enclosing type... null if the receiver is a top
level type.
+*
+* NOTE: enclosingType of a binary type is resolved when needed
+*/
+public ReferenceBinding enclosingType() {
+ if ((this.tagBits & TagBits.HasUnresolvedEnclosingType) == 0)
+ return this.enclosingType;
+
+ // finish resolving the type
+ this.enclosingType = resolveType(this.enclosingType, this.environment,
false);
+ this.tagBits &= ~TagBits.HasUnresolvedEnclosingType;
+ return this.enclosingType;
+}
+// NOTE: the type of each field of a binary type is resolved when needed
+public FieldBinding[] fields() {
+ if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+ return fields;
+
+ // lazily sort fields
+ if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+ int length = this.fields.length;
+ if (length > 1)
+ ReferenceBinding.sortFields(this.fields, 0, length);
+ this.tagBits |= TagBits.AreFieldsSorted;
+ }
+ for (int i = fields.length; --i >= 0;)
+ resolveTypeFor(fields[i]);
+ this.tagBits |= TagBits.AreFieldsComplete;
+ return fields;
+}
+/**
+ * @see
org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
+ */
+public char[] genericTypeSignature() {
+ return computeGenericTypeSignature(this.typeVariables);
+}
+//NOTE: the return type, arg & exception types of each method of a binary
type are resolved when needed
+public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
+
+ // lazily sort methods
+ if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+ int length = this.methods.length;
+ if (length > 1)
+ ReferenceBinding.sortMethods(this.methods, 0, length);
+ this.tagBits |= TagBits.AreMethodsSorted;
+ }
+ int argCount = argumentTypes.length;
+ long range;
+ if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT,
this.methods)) >= 0) {
+ nextMethod: for (int imethod = (int)range, end = (int)(range >> 32);
imethod <= end; imethod++) {
+ MethodBinding method = methods[imethod];
+ if (method.parameters.length == argCount) {
+ resolveTypesFor(method);
+ TypeBinding[] toMatch = method.parameters;
+ for (int iarg = 0; iarg < argCount; iarg++)
+ if (toMatch[iarg] !=
argumentTypes[iarg])
+ continue nextMethod;
+ return method;
+ }
+ }
+ }
+ return null;
+}
+
+//NOTE: the return type, arg & exception types of each method of a binary
type are resolved when needed
+//searches up the hierarchy as long as no potential (but not exact) match
was found.
+public MethodBinding getExactMethod(char[] selector, TypeBinding[]
argumentTypes, CompilationUnitScope refScope) {
+ // sender from refScope calls recordTypeReference(this)
+
+ // lazily sort methods
+ if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+ int length = this.methods.length;
+ if (length > 1)
+ ReferenceBinding.sortMethods(this.methods, 0, length);
+ this.tagBits |= TagBits.AreMethodsSorted;
+ }
+
+ int argCount = argumentTypes.length;
+ boolean foundNothing = true;
+
+ long range;
+ if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0)
{
+ nextMethod: for (int imethod = (int)range, end = (int)(range >> 32);
imethod <= end; imethod++) {
+ MethodBinding method = methods[imethod];
+ foundNothing = false; // inner type lookups must know that a method
with this name exists
+ if (method.parameters.length == argCount) {
+ resolveTypesFor(method);
+ TypeBinding[] toMatch = method.parameters;
+ for (int iarg = 0; iarg < argCount; iarg++)
+ if (toMatch[iarg] !=
argumentTypes[iarg])
+ continue nextMethod;
+ return method;
+ }
+ }
+ }
+ if (foundNothing) {
+ if (isInterface()) {
+ if (superInterfaces().length == 1) { // ensure superinterfaces are
resolved before checking
+ if (refScope != null)
+
refScope.recordTypeReference(superInterfaces[0]);
+ return superInterfaces[0].getExactMethod(selector, argumentTypes,
refScope);
+ }
+ } else if (superclass() != null) { // ensure superclass is resolved
before checking
+ if (refScope != null)
+ refScope.recordTypeReference(superclass);
+ return superclass.getExactMethod(selector,
argumentTypes, refScope);
+ }
+ }
+ return null;
+}
+//NOTE: the type of a field of a binary type is resolved when needed
+public FieldBinding getField(char[] fieldName, boolean needResolve) {
+ // lazily sort fields
+ if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+ int length = this.fields.length;
+ if (length > 1)
+ ReferenceBinding.sortFields(this.fields, 0, length);
+ this.tagBits |= TagBits.AreFieldsSorted;
+ }
+ FieldBinding field = ReferenceBinding.binarySearch(fieldName,
this.fields);
+ return needResolve && field != null ? resolveTypeFor(field) : field;
+}
+/**
+ * Rewrite of default getMemberType to avoid resolving eagerly all member
types when one is requested
+ */
+public ReferenceBinding getMemberType(char[] typeName) {
+ for (int i = this.memberTypes.length; --i >= 0;) {
+ ReferenceBinding memberType = this.memberTypes[i];
+ if (memberType instanceof UnresolvedReferenceBinding) {
+ char[] name = memberType.sourceName; // source name is qualified with
enclosing type name
+ int prefixLength = this.compoundName[this.compoundName.length -
1].length + 1; // enclosing$
+ if (name.length == (prefixLength + typeName.length)) // enclosing $
typeName
+ if (CharOperation.fragmentEquals(typeName, name, prefixLength, true))
// only check trailing portion
+ return this.memberTypes[i] = resolveType(memberType,
this.environment, false); // no raw conversion for now
+ } else if (CharOperation.equals(typeName, memberType.sourceName)) {
+ return memberType;
+ }
+ }
+ return null;
+}
+// NOTE: the return type, arg & exception types of each method of a binary
type are resolved when needed
+public MethodBinding[] getMethods(char[] selector) {
+ if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+ long range;
+ if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >=
0) {
+ int start = (int) range, end = (int) (range >> 32);
+ int length = end - start + 1;
+ if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+ // simply clone method subset
+ MethodBinding[] result;
+ System.arraycopy(this.methods, start, result = new
MethodBinding[length], 0, length);
+ return result;
+ }
+ }
+ return Binding.NO_METHODS;
+ }
+ // lazily sort methods
+ if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+ int length = this.methods.length;
+ if (length > 1)
+ ReferenceBinding.sortMethods(this.methods, 0, length);
+ this.tagBits |= TagBits.AreMethodsSorted;
+ }
+ long range;
+ if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0)
{
+ int start = (int) range, end = (int) (range >> 32);
+ int length = end - start + 1;
+ MethodBinding[] result = new MethodBinding[length];
+ // iterate methods to resolve them
+ for (int i = start, index = 0; i <= end; i++, index++)
+ result[index] = resolveTypesFor(methods[i]);
+ return result;
+ }
+ return Binding.NO_METHODS;
+}
+public boolean hasMemberTypes() {
+ return this.memberTypes.length > 0;
+}
+// NOTE: member types of binary types are resolved when needed
+public TypeVariableBinding getTypeVariable(char[] variableName) {
+ TypeVariableBinding variable = super.getTypeVariable(variableName);
+ variable.resolve(this.environment);
+ return variable;
+}
+private void initializeTypeVariable(TypeVariableBinding variable,
TypeVariableBinding[] existingVariables, SignatureWrapper wrapper,
char[][][] missingTypeNames) {
+ // ParameterSignature = Identifier ':' TypeSignature
+ // or Identifier ':' TypeSignature(optional) InterfaceBound(s)
+ // InterfaceBound = ':' TypeSignature
+ int colon = CharOperation.indexOf(':', wrapper.signature,
wrapper.start);
+ wrapper.start = colon + 1; // skip name + ':'
+ ReferenceBinding type, firstBound = null;
+ if (wrapper.signature[wrapper.start] == ':') {
+ type =
environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+ } else {
+ type = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper,
existingVariables, this, missingTypeNames);
+ firstBound = type;
+ }
+
+ // variable is visible to its bounds
+ variable.modifiers |= ExtraCompilerModifiers.AccUnresolved;
+ variable.superclass = type;
+
+ ReferenceBinding[] bounds = null;
+ if (wrapper.signature[wrapper.start] == ':') {
+ java.util.ArrayList types = new java.util.ArrayList(2);
+ do {
+ wrapper.start++; // skip ':'
+ types.add(environment.getTypeFromTypeSignature(wrapper,
existingVariables, this, missingTypeNames));
+ } while (wrapper.signature[wrapper.start] == ':');
+ bounds = new ReferenceBinding[types.size()];
+ types.toArray(bounds);
+ }
+
+ variable.superInterfaces = bounds == null ? Binding.NO_SUPERINTERFACES :
bounds;
+ if (firstBound == null) {
+ firstBound = variable.superInterfaces.length == 0 ? null :
variable.superInterfaces[0];
+ }
+ variable.firstBound = firstBound;
+}
+/**
+ * Returns true if a type is identical to another one,
+ * or for generic types, true if compared to its raw type.
+ */
+public boolean isEquivalentTo(TypeBinding otherType) {
+ if (this == otherType) return true;
+ if (otherType == null) return false;
+ switch(otherType.kind()) {
+ case Binding.WILDCARD_TYPE :
+ case Binding.INTERSECTION_TYPE :
+ return ((WildcardBinding) otherType).boundCheck(this);
+ case Binding.RAW_TYPE :
+ return otherType.erasure() == this;
+ }
+ return false;
+}
+public boolean isGenericType() {
+ return this.typeVariables != Binding.NO_TYPE_VARIABLES;
+}
+public int kind() {
+ if (this.typeVariables != Binding.NO_TYPE_VARIABLES)
+ return Binding.GENERIC_TYPE;
+ return Binding.TYPE;
+}
+// NOTE: member types of binary types are resolved when needed
+public ReferenceBinding[] memberTypes() {
+ if ((this.tagBits & TagBits.HasUnresolvedMemberTypes) == 0)
+ return this.memberTypes;
+
+ for (int i = this.memberTypes.length; --i >= 0;)
+ this.memberTypes[i] = resolveType(this.memberTypes[i], this.environment,
false); // no raw conversion for now
+ this.tagBits &= ~TagBits.HasUnresolvedMemberTypes;
+ return this.memberTypes;
+}
+// NOTE: the return type, arg & exception types of each method of a binary
type are resolved when needed
+public MethodBinding[] methods() {
+ if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+ return methods;
+
+ // lazily sort methods
+ if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+ int length = this.methods.length;
+ if (length > 1)
+ ReferenceBinding.sortMethods(this.methods, 0, length);
+ this.tagBits |= TagBits.AreMethodsSorted;
+ }
+ for (int i = methods.length; --i >= 0;)
+ resolveTypesFor(methods[i]);
+ this.tagBits |= TagBits.AreMethodsComplete;
+ return methods;
+}
+private FieldBinding resolveTypeFor(FieldBinding field) {
+ if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+ return field;
+
+ TypeBinding resolvedType = resolveType(field.type, this.environment,
null, 0);
+ field.type = resolvedType;
+ if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+ field.tagBits |= TagBits.HasMissingType;
+ }
+ field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+ return field;
+}
+MethodBinding resolveTypesFor(MethodBinding method) {
+ if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+ return method;
+
+ if (!method.isConstructor()) {
+ TypeBinding resolvedType = resolveType(method.returnType,
this.environment, null, 0);
+ method.returnType = resolvedType;
+ if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+ method.tagBits |= TagBits.HasMissingType;
+ }
+ }
+ for (int i = method.parameters.length; --i >= 0;) {
+ TypeBinding resolvedType = resolveType(method.parameters[i],
this.environment, null, 0);
+ method.parameters[i] = resolvedType;
+ if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+ method.tagBits |= TagBits.HasMissingType;
+ }
+ }
+ for (int i = method.thrownExceptions.length; --i >= 0;) {
+ ReferenceBinding resolvedType = resolveType(method.thrownExceptions[i],
this.environment, true);
+ method.thrownExceptions[i] = resolvedType;
+ if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+ method.tagBits |= TagBits.HasMissingType;
+ }
+ }
+ for (int i = method.typeVariables.length; --i >= 0;) {
+ method.typeVariables[i].resolve(this.environment);
+ }
+ method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+ return method;
+}
+AnnotationBinding[] retrieveAnnotations(Binding binding) {
+ return
AnnotationBinding.addStandardAnnotations(super.retrieveAnnotations(binding),
binding.getAnnotationTagBits(), this.environment);
+}
+SimpleLookupTable storedAnnotations(boolean forceInitialize) {
+ if (forceInitialize && this.storedAnnotations == null) {
+ if (!this.environment.globalOptions.storeAnnotations)
+ return null; // not supported during this compile
+ this.storedAnnotations = new SimpleLookupTable(3);
+ }
+ return this.storedAnnotations;
+}
+/* Answer the receiver's superclass... null if the receiver is Object or
an interface.
+*
+* NOTE: superclass of a binary type is resolved when needed
+*/
+public ReferenceBinding superclass() {
+ if ((this.tagBits & TagBits.HasUnresolvedSuperclass) == 0)
+ return this.superclass;
+
+ // finish resolving the type
+ this.superclass = resolveType(this.superclass, this.environment, true);
+ this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
+ if (this.superclass.problemId() == ProblemReasons.NotFound)
+ this.tagBits |= TagBits.HierarchyHasProblems; // propagate type
inconsistency
+ return this.superclass;
+}
+// NOTE: superInterfaces of binary types are resolved when needed
+public ReferenceBinding[] superInterfaces() {
+ if ((this.tagBits & TagBits.HasUnresolvedSuperinterfaces) == 0)
+ return this.superInterfaces;
+
+ for (int i = this.superInterfaces.length; --i >= 0;) {
+ this.superInterfaces[i] = resolveType(this.superInterfaces[i],
this.environment, true);
+ if (this.superInterfaces[i].problemId() ==
ProblemReasons.NotFound)
+ this.tagBits |= TagBits.HierarchyHasProblems; // propagate type
inconsistency
+ }
+ this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
+ return this.superInterfaces;
+}
+public TypeVariableBinding[] typeVariables() {
+ if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
+ return this.typeVariables;
+
+ for (int i = this.typeVariables.length; --i >= 0;)
+ this.typeVariables[i].resolve(this.environment);
+ this.tagBits &= ~TagBits.HasUnresolvedTypeVariables;
+ return this.typeVariables;
+}
+public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
+ if (isPublic()) buffer.append("public "); //$NON-NLS-1$
+ if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
+ if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
+ if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
+ if (isStatic() && isNestedType()) buffer.append("static ");
//$NON-NLS-1$
***The diff for this file has been truncated for email.***
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors