KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > lookup > BinaryTypeBinding


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 import java.util.ArrayList JavaDoc;
14
15 import org.eclipse.jdt.core.compiler.CharOperation;
16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17 import org.eclipse.jdt.internal.compiler.env.*;
18 import org.eclipse.jdt.internal.compiler.impl.Constant;
19 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
20 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
21
22 /*
23 Not all fields defined by this type are initialized when it is created.
24 Some are initialized only when needed.
25
26 Accessors have been provided for some public fields so all TypeBindings have the same API...
27 but access public fields directly whenever possible.
28 Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
29
30 null is NOT a valid value for a non-public field... it just means the field is not initialized.
31 */

32
33 public class BinaryTypeBinding extends ReferenceBinding {
34
35     // all of these fields are ONLY guaranteed to be initialized if accessed using their public accessor method
36
protected ReferenceBinding superclass;
37     protected ReferenceBinding enclosingType;
38     protected ReferenceBinding[] superInterfaces;
39     protected FieldBinding[] fields;
40     protected MethodBinding[] methods;
41     protected ReferenceBinding[] memberTypes;
42     protected TypeVariableBinding[] typeVariables;
43
44     // For the link with the principle structure
45
protected LookupEnvironment environment;
46
47     protected SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
48

49 static Object JavaDoc convertMemberValue(Object JavaDoc binaryValue, LookupEnvironment env) {
50     if (binaryValue == null) return null;
51     if (binaryValue instanceof Constant)
52         return binaryValue;
53     if (binaryValue instanceof ClassSignature)
54         return env.getTypeFromSignature(((ClassSignature) binaryValue).getTypeName(), 0, -1, false, null);
55     if (binaryValue instanceof IBinaryAnnotation)
56         return createAnnotation((IBinaryAnnotation) binaryValue, env);
57     if (binaryValue instanceof EnumConstantSignature) {
58         EnumConstantSignature ref = (EnumConstantSignature) binaryValue;
59         ReferenceBinding enumType =
60             (ReferenceBinding) env.getTypeFromSignature(ref.getTypeName(), 0, -1, false, null);
61         enumType = resolveType(enumType, env, false);
62         return enumType.getField(ref.getEnumConstantName(), false);
63     }
64     if (binaryValue instanceof Object JavaDoc[]) {
65         Object JavaDoc[] objects = (Object JavaDoc[]) binaryValue;
66         int length = objects.length;
67         if (length == 0) return objects;
68         Object JavaDoc[] values = new Object JavaDoc[length];
69         for (int i = 0; i < length; i++)
70             values[i] = convertMemberValue(objects[i], env);
71         return values;
72     }
73
74     // should never reach here.
75
throw new IllegalStateException JavaDoc();
76 }
77 static AnnotationBinding createAnnotation(IBinaryAnnotation annotationInfo, LookupEnvironment env) {
78     IBinaryElementValuePair[] binaryPairs = annotationInfo.getElementValuePairs();
79     int length = binaryPairs == null ? 0 : binaryPairs.length;
80     ElementValuePair[] pairs = length == 0 ? Binding.NO_ELEMENT_VALUE_PAIRS : new ElementValuePair[length];
81     for (int i = 0; i < length; i++)
82         pairs[i] = new ElementValuePair(binaryPairs[i].getName(), convertMemberValue(binaryPairs[i].getValue(), env), null);
83
84     char[] typeName = annotationInfo.getTypeName();
85     ReferenceBinding annotationType = env.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false);
86     return new UnresolvedAnnotationBinding(annotationType, pairs, env);
87 }
88 public static AnnotationBinding[] createAnnotations(IBinaryAnnotation[] annotationInfos, LookupEnvironment env) {
89     int length = annotationInfos == null ? 0 : annotationInfos.length;
90     AnnotationBinding[] result = length == 0 ? Binding.NO_ANNOTATIONS : new AnnotationBinding[length];
91     for (int i = 0; i < length; i++)
92         result[i] = createAnnotation(annotationInfos[i], env);
93     return result;
94 }
95 public static ReferenceBinding resolveType(ReferenceBinding type, LookupEnvironment environment, boolean convertGenericToRawType) {
96     if (type instanceof UnresolvedReferenceBinding)
97         return ((UnresolvedReferenceBinding) type).resolve(environment, convertGenericToRawType);
98     if (type.isParameterizedType())
99         return ((ParameterizedTypeBinding) type).resolve();
100     if (type.isWildcard())
101         return ((WildcardBinding) type).resolve();
102
103     if (convertGenericToRawType) // raw reference to generic ?
104
return (ReferenceBinding) environment.convertUnresolvedBinaryToRawType(type);
105     return type;
106 }
107 public static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, ParameterizedTypeBinding parameterizedType, int rank) {
108     switch (type.kind()) {
109         
110         case Binding.PARAMETERIZED_TYPE :
111             return ((ParameterizedTypeBinding) type).resolve();
112             
113         case Binding.WILDCARD_TYPE :
114             return ((WildcardBinding) type).resolve();
115             
116         case Binding.ARRAY_TYPE :
117             resolveType(((ArrayBinding) type).leafComponentType, environment, parameterizedType, rank);
118             break;
119             
120         case Binding.TYPE_PARAMETER :
121             ((TypeVariableBinding) type).resolve(environment);
122             break;
123                         
124         case Binding.GENERIC_TYPE :
125             if (parameterizedType == null) // raw reference to generic ?
126
return environment.convertUnresolvedBinaryToRawType(type);
127             break;
128             
129         default:
130             if (type instanceof UnresolvedReferenceBinding)
131                 return ((UnresolvedReferenceBinding) type).resolve(environment, parameterizedType == null);
132     }
133     return type;
134 }
135
136 /**
137  * Default empty constructor for subclasses only.
138  */

139 protected BinaryTypeBinding() {
140     // only for subclasses
141
}
142
143 /**
144  * Standard constructor for creating binary type bindings from binary models (classfiles)
145  * @param packageBinding
146  * @param binaryType
147  * @param environment
148  */

149 public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType binaryType, LookupEnvironment environment) {
150     this.compoundName = CharOperation.splitOn('/', binaryType.getName());
151     computeId();
152
153     this.tagBits |= TagBits.IsBinaryBinding;
154     this.environment = environment;
155     this.fPackage = packageBinding;
156     this.fileName = binaryType.getFileName();
157
158     char[] typeSignature = environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null;
159     this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<'
160         ? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
161
: Binding.NO_TYPE_VARIABLES;
162
163     this.sourceName = binaryType.getSourceName();
164     this.modifiers = binaryType.getModifiers();
165
166     if ((binaryType.getTagBits() & TagBits.HasInconsistentHierarchy) != 0)
167         this.tagBits |= TagBits.HierarchyHasProblems;
168         
169     if (binaryType.isAnonymous()) {
170         this.tagBits |= TagBits.AnonymousTypeMask;
171     } else if (binaryType.isLocal()) {
172         this.tagBits |= TagBits.LocalTypeMask;
173     } else if (binaryType.isMember()) {
174         this.tagBits |= TagBits.MemberTypeMask;
175     }
176     // need enclosing type to access type variables
177
char[] enclosingTypeName = binaryType.getEnclosingTypeName();
178     if (enclosingTypeName != null) {
179         // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
180
this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true); // pretend parameterized to avoid raw
181
this.tagBits |= TagBits.MemberTypeMask; // must be a member type not a top-level or local type
182
this.tagBits |= TagBits.HasUnresolvedEnclosingType;
183         if (this.enclosingType().isStrictfp())
184             this.modifiers |= ClassFileConstants.AccStrictfp;
185         if (this.enclosingType().isDeprecated())
186             this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
187     }
188 }
189
190 /**
191  * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
192  */

193 public FieldBinding[] availableFields() {
194     if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
195         return fields;
196
197     // lazily sort fields
198
if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
199         int length = this.fields.length;
200         if (length > 1)
201             ReferenceBinding.sortFields(this.fields, 0, length);
202         this.tagBits |= TagBits.AreFieldsSorted;
203     }
204     FieldBinding[] availableFields = new FieldBinding[fields.length];
205     int count = 0;
206     for (int i = 0; i < fields.length; i++) {
207         try {
208             availableFields[count] = resolveTypeFor(fields[i]);
209             count++;
210         } catch (AbortCompilation a){
211             // silent abort
212
}
213     }
214     if (count < availableFields.length)
215         System.arraycopy(availableFields, 0, availableFields = new FieldBinding[count], 0, count);
216     return availableFields;
217 }
218
219 /**
220  * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
221  */

222 public MethodBinding[] availableMethods() {
223     if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
224         return methods;
225
226     // lazily sort methods
227
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
228         int length = this.methods.length;
229         if (length > 1)
230             ReferenceBinding.sortMethods(this.methods, 0, length);
231         this.tagBits |= TagBits.AreMethodsSorted;
232     }
233     MethodBinding[] availableMethods = new MethodBinding[methods.length];
234     int count = 0;
235     for (int i = 0; i < methods.length; i++) {
236         try {
237             availableMethods[count] = resolveTypesFor(methods[i]);
238             count++;
239         } catch (AbortCompilation a){
240             // silent abort
241
}
242     }
243     if (count < availableMethods.length)
244         System.arraycopy(availableMethods, 0, availableMethods = new MethodBinding[count], 0, count);
245     return availableMethods;
246 }
247 void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) {
248     // default initialization for super-interfaces early, in case some aborting compilation error occurs,
249
// and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
250
this.typeVariables = Binding.NO_TYPE_VARIABLES;
251     this.superInterfaces = Binding.NO_SUPERINTERFACES;
252
253     // must retrieve member types in case superclass/interfaces need them
254
this.memberTypes = Binding.NO_MEMBER_TYPES;
255     IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes();
256     if (memberTypeStructures != null) {
257         int size = memberTypeStructures.length;
258         if (size > 0) {
259             this.memberTypes = new ReferenceBinding[size];
260             for (int i = 0; i < size; i++)
261                 // attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
262
this.memberTypes[i] = environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false);
263             this.tagBits |= TagBits.HasUnresolvedMemberTypes;
264         }
265     }
266
267     long sourceLevel = environment.globalOptions.sourceLevel;
268     char[] typeSignature = null;
269     if (sourceLevel >= ClassFileConstants.JDK1_5) {
270         typeSignature = binaryType.getGenericSignature();
271         this.tagBits |= binaryType.getTagBits();
272     }
273     if (typeSignature == null) {
274         char[] superclassName = binaryType.getSuperclassName();
275         if (superclassName != null) {
276             // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
277
this.superclass = environment.getTypeFromConstantPoolName(superclassName, 0, -1, false);
278             this.tagBits |= TagBits.HasUnresolvedSuperclass;
279         }
280
281         this.superInterfaces = Binding.NO_SUPERINTERFACES;
282         char[][] interfaceNames = binaryType.getInterfaceNames();
283         if (interfaceNames != null) {
284             int size = interfaceNames.length;
285             if (size > 0) {
286                 this.superInterfaces = new ReferenceBinding[size];
287                 for (int i = 0; i < size; i++)
288                     // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
289
this.superInterfaces[i] = environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false);
290                 this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
291             }
292         }
293     } else {
294         // ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature
295
SignatureWrapper wrapper = new SignatureWrapper(typeSignature);
296         if (wrapper.signature[wrapper.start] == '<') {
297             // ParameterPart = '<' ParameterSignature(s) '>'
298
wrapper.start++; // skip '<'
299
this.typeVariables = createTypeVariables(wrapper, true);
300             wrapper.start++; // skip '>'
301
this.tagBits |= TagBits.HasUnresolvedTypeVariables;
302             this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
303         }
304
305         // attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
306
this.superclass = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES, this);
307         this.tagBits |= TagBits.HasUnresolvedSuperclass;
308
309         this.superInterfaces = Binding.NO_SUPERINTERFACES;
310         if (!wrapper.atEnd()) {
311             // attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
312
java.util.ArrayList JavaDoc types = new java.util.ArrayList JavaDoc(2);
313             do {
314                 types.add(environment.getTypeFromTypeSignature(wrapper, Binding.NO_TYPE_VARIABLES, this));
315             } while (!wrapper.atEnd());
316             this.superInterfaces = new ReferenceBinding[types.size()];
317             types.toArray(this.superInterfaces);
318             this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
319         }
320     }
321
322     if (needFieldsAndMethods) {
323         createFields(binaryType.getFields(), sourceLevel);
324         createMethods(binaryType.getMethods(), sourceLevel);
325     } else { // protect against incorrect use of the needFieldsAndMethods flag, see 48459
326
this.fields = Binding.NO_FIELDS;
327         this.methods = Binding.NO_METHODS;
328     }
329     if (this.environment.globalOptions.storeAnnotations)
330         setAnnotations(createAnnotations(binaryType.getAnnotations(), this.environment));
331 }
332 private void createFields(IBinaryField[] iFields, long sourceLevel) {
333     this.fields = Binding.NO_FIELDS;
334     if (iFields != null) {
335         int size = iFields.length;
336         if (size > 0) {
337             this.fields = new FieldBinding[size];
338             boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
339             boolean isViewedAsDeprecated = isViewedAsDeprecated();
340             boolean hasRestrictedAccess = hasRestrictedAccess();
341             int firstAnnotatedFieldIndex = -1;
342             for (int i = 0; i < size; i++) {
343                 IBinaryField binaryField = iFields[i];
344                 char[] fieldSignature = use15specifics ? binaryField.getGenericSignature() : null;
345                 TypeBinding type = fieldSignature == null
346                     ? environment.getTypeFromSignature(binaryField.getTypeName(), 0, -1, false, this)
347                     : environment.getTypeFromTypeSignature(new SignatureWrapper(fieldSignature), Binding.NO_TYPE_VARIABLES, this);
348                 FieldBinding field =
349                     new FieldBinding(
350                         binaryField.getName(),
351                         type,
352                         binaryField.getModifiers() | ExtraCompilerModifiers.AccUnresolved,
353                         this,
354                         binaryField.getConstant());
355                 if (firstAnnotatedFieldIndex < 0
356                         && this.environment.globalOptions.storeAnnotations
357                         && binaryField.getAnnotations() != null) {
358                     firstAnnotatedFieldIndex = i;
359                 }
360                 field.id = i; // ordinal
361
if (use15specifics)
362                     field.tagBits |= binaryField.getTagBits();
363                 if (isViewedAsDeprecated && !field.isDeprecated())
364                     field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
365                 if (hasRestrictedAccess)
366                     field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
367                 if (fieldSignature != null)
368                     field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
369                 this.fields[i] = field;
370             }
371             // second pass for reifying annotations, since may refer to fields being constructed (147875)
372
if (firstAnnotatedFieldIndex >= 0) {
373                 for (int i = firstAnnotatedFieldIndex; i <size; i++) {
374                     this.fields[i].setAnnotations(createAnnotations(iFields[i].getAnnotations(), this.environment));
375                 }
376             }
377         }
378     }
379 }
380 private MethodBinding createMethod(IBinaryMethod method, long sourceLevel) {
381     int methodModifiers = method.getModifiers() | ExtraCompilerModifiers.AccUnresolved;
382     if (sourceLevel < ClassFileConstants.JDK1_5)
383         methodModifiers &= ~ClassFileConstants.AccVarargs; // vararg methods are not recognized until 1.5
384
ReferenceBinding[] exceptions = Binding.NO_EXCEPTIONS;
385     TypeBinding[] parameters = Binding.NO_PARAMETERS;
386     TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
387     AnnotationBinding[][] paramAnnotations = null;
388     TypeBinding returnType = null;
389
390     final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
391     char[] methodSignature = use15specifics ? method.getGenericSignature() : null;
392     if (methodSignature == null) { // no generics
393
char[] methodDescriptor = method.getMethodDescriptor(); // of the form (I[Ljava/jang/String;)V
394
int numOfParams = 0;
395         char nextChar;
396         int index = 0; // first character is always '(' so skip it
397
while ((nextChar = methodDescriptor[++index]) != ')') {
398             if (nextChar != '[') {
399                 numOfParams++;
400                 if (nextChar == 'L')
401                     while ((nextChar = methodDescriptor[++index]) != ';'){/*empty*/}
402             }
403         }
404
405         // Ignore synthetic argument for member types.
406
int startIndex = (method.isConstructor() && isMemberType() && !isStatic()) ? 1 : 0;
407         int size = numOfParams - startIndex;
408         if (size > 0) {
409             parameters = new TypeBinding[size];
410             if (this.environment.globalOptions.storeAnnotations)
411                 paramAnnotations = new AnnotationBinding[size][];
412             index = 1;
413             int end = 0; // first character is always '(' so skip it
414
for (int i = 0; i < numOfParams; i++) {
415                 while ((nextChar = methodDescriptor[++end]) == '['){/*empty*/}
416                 if (nextChar == 'L')
417                     while ((nextChar = methodDescriptor[++end]) != ';'){/*empty*/}
418
419                 if (i >= startIndex) { // skip the synthetic arg if necessary
420
parameters[i - startIndex] = environment.getTypeFromSignature(methodDescriptor, index, end, false, this);
421                     // 'paramAnnotations' line up with 'parameters'
422
// int parameter to method.getParameterAnnotations() include the synthetic arg
423
if (paramAnnotations != null)
424                         paramAnnotations[i - startIndex] = createAnnotations(method.getParameterAnnotations(i), this.environment);
425                 }
426                 index = end + 1;
427             }
428         }
429
430         char[][] exceptionTypes = method.getExceptionTypeNames();
431         if (exceptionTypes != null) {
432             size = exceptionTypes.length;
433             if (size > 0) {
434                 exceptions = new ReferenceBinding[size];
435                 for (int i = 0; i < size; i++)
436                     exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false);
437             }
438         }
439
440         if (!method.isConstructor())
441             returnType = environment.getTypeFromSignature(methodDescriptor, index + 1, -1, false, this); // index is currently pointing at the ')'
442
} else {
443         methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
444         // MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
445
SignatureWrapper wrapper = new SignatureWrapper(methodSignature);
446         if (wrapper.signature[wrapper.start] == '<') {
447             // <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
448
// ParameterPart = '<' ParameterSignature(s) '>'
449
wrapper.start++; // skip '<'
450
typeVars = createTypeVariables(wrapper, false);
451             wrapper.start++; // skip '>'
452
}
453
454         if (wrapper.signature[wrapper.start] == '(') {
455             wrapper.start++; // skip '('
456
if (wrapper.signature[wrapper.start] == ')') {
457                 wrapper.start++; // skip ')'
458
} else {
459                 java.util.ArrayList JavaDoc types = new java.util.ArrayList JavaDoc(2);
460                 while (wrapper.signature[wrapper.start] != ')')
461                     types.add(environment.getTypeFromTypeSignature(wrapper, typeVars, this));
462                 wrapper.start++; // skip ')'
463
int numParam = types.size();
464                 parameters = new TypeBinding[numParam];
465                 types.toArray(parameters);
466                 if (this.environment.globalOptions.storeAnnotations) {
467                     paramAnnotations = new AnnotationBinding[numParam][];
468                     for (int i = 0; i < numParam; i++)
469                         paramAnnotations[i] = createAnnotations(method.getParameterAnnotations(i), this.environment);
470                 }
471             }
472         }
473
474         // always retrieve return type (for constructors, its V for void - will be ignored)
475
returnType = environment.getTypeFromTypeSignature(wrapper, typeVars, this);
476
477         if (!wrapper.atEnd() && wrapper.signature[wrapper.start] == '^') {
478             // attempt to find each exception if it exists in the cache (otherwise - resolve it when requested)
479
java.util.ArrayList JavaDoc types = new java.util.ArrayList JavaDoc(2);
480             do {
481                 wrapper.start++; // skip '^'
482
types.add(environment.getTypeFromTypeSignature(wrapper, typeVars, this));
483             } while (!wrapper.atEnd() && wrapper.signature[wrapper.start] == '^');
484             exceptions = new ReferenceBinding[types.size()];
485             types.toArray(exceptions);
486         } else { // get the exceptions the old way
487
char[][] exceptionTypes = method.getExceptionTypeNames();
488             if (exceptionTypes != null) {
489                 int size = exceptionTypes.length;
490                 if (size > 0) {
491                     exceptions = new ReferenceBinding[size];
492                     for (int i = 0; i < size; i++)
493                         exceptions[i] = environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false);
494                 }
495             }
496         }
497     }
498
499     MethodBinding result = method.isConstructor()
500         ? new MethodBinding(methodModifiers, parameters, exceptions, this)
501         : new MethodBinding(methodModifiers, method.getSelector(), returnType, parameters, exceptions, this);
502     if (this.environment.globalOptions.storeAnnotations)
503         result.setAnnotations(
504             createAnnotations(method.getAnnotations(), this.environment),
505             paramAnnotations,
506             isAnnotationType() ? convertMemberValue(method.getDefaultValue(), this.environment) : null);
507
508     if (use15specifics)
509         result.tagBits |= method.getTagBits();
510     result.typeVariables = typeVars;
511     // fixup the declaring element of the type variable
512
for (int i = 0, length = typeVars.length; i < length; i++)
513         typeVars[i].declaringElement = result;
514     return result;
515 }
516 /**
517  * Create method bindings for binary type, filtering out <clinit> and synthetics
518  */

519 private void createMethods(IBinaryMethod[] iMethods, long sourceLevel) {
520     int total = 0, initialTotal = 0, iClinit = -1;
521     int[] toSkip = null;
522     if (iMethods != null) {
523         total = initialTotal = iMethods.length;
524         boolean keepBridgeMethods = sourceLevel < ClassFileConstants.JDK1_5
525             && this.environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5;
526         for (int i = total; --i >= 0;) {
527             IBinaryMethod method = iMethods[i];
528             if ((method.getModifiers() & ClassFileConstants.AccSynthetic) != 0) {
529                 if (keepBridgeMethods && (method.getModifiers() & ClassFileConstants.AccBridge) != 0)
530                     continue; // want to see bridge methods as real methods
531
// discard synthetics methods
532
if (toSkip == null) toSkip = new int[iMethods.length];
533                 toSkip[i] = -1;
534                 total--;
535             } else if (iClinit == -1) {
536                 char[] methodName = method.getSelector();
537                 if (methodName.length == 8 && methodName[0] == '<') {
538                     // discard <clinit>
539
iClinit = i;
540                     total--;
541                 }
542             }
543         }
544     }
545     if (total == 0) {
546         this.methods = Binding.NO_METHODS;
547         return;
548     }
549
550     boolean isViewedAsDeprecated = isViewedAsDeprecated();
551     boolean hasRestrictedAccess = hasRestrictedAccess();
552     this.methods = new MethodBinding[total];
553     if (total == initialTotal) {
554         for (int i = 0; i < initialTotal; i++) {
555             MethodBinding method = createMethod(iMethods[i], sourceLevel);
556             if (isViewedAsDeprecated && !method.isDeprecated())
557                 method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
558             if (hasRestrictedAccess)
559                 method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
560             this.methods[i] = method;
561         }
562     } else {
563         for (int i = 0, index = 0; i < initialTotal; i++) {
564             if (iClinit != i && (toSkip == null || toSkip[i] != -1)) {
565                 MethodBinding method = createMethod(iMethods[i], sourceLevel);
566                 if (isViewedAsDeprecated && !method.isDeprecated())
567                     method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
568                 if (hasRestrictedAccess)
569                     method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
570                 this.methods[index++] = method;
571             }
572         }
573     }
574 }
575 private TypeVariableBinding[] createTypeVariables(SignatureWrapper wrapper, boolean assignVariables) {
576     // detect all type variables first
577
char[] typeSignature = wrapper.signature;
578     int depth = 0, length = typeSignature.length;
579     int rank = 0;
580     ArrayList JavaDoc variables = new ArrayList JavaDoc(1);
581     depth = 0;
582     boolean pendingVariable = true;
583     createVariables: {
584         for (int i = 1; i < length; i++) {
585             switch(typeSignature[i]) {
586                 case '<' :
587                     depth++;
588                     break;
589                 case '>' :
590                     if (--depth < 0)
591                         break createVariables;
592                     break;
593                 case ';' :
594                     if ((depth == 0) && (i +1 < length) && (typeSignature[i+1] != ':'))
595                         pendingVariable = true;
596                     break;
597                 default:
598                     if (pendingVariable) {
599                         pendingVariable = false;
600                         int colon = CharOperation.indexOf(':', typeSignature, i);
601                         char[] variableName = CharOperation.subarray(typeSignature, i, colon);
602                         variables.add(new TypeVariableBinding(variableName, this, rank++));
603                     }
604             }
605         }
606     }
607     // initialize type variable bounds - may refer to forward variables
608
TypeVariableBinding[] result;
609     variables.toArray(result = new TypeVariableBinding[rank]);
610     // when creating the type variables for a type, the type must remember them before initializing each variable
611
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=163680
612
if (assignVariables)
613         this.typeVariables = result;
614     for (int i = 0; i < rank; i++) {
615         initializeTypeVariable(result[i], result, wrapper);
616     }
617     return result;
618 }
619 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
620 *
621 * NOTE: enclosingType of a binary type is resolved when needed
622 */

623 public ReferenceBinding enclosingType() {
624     if ((this.tagBits & TagBits.HasUnresolvedEnclosingType) == 0)
625         return this.enclosingType;
626
627     // finish resolving the type
628
this.enclosingType = resolveType(this.enclosingType, this.environment, false);
629     this.tagBits &= ~TagBits.HasUnresolvedEnclosingType;
630     return this.enclosingType;
631 }
632 // NOTE: the type of each field of a binary type is resolved when needed
633
public FieldBinding[] fields() {
634     if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
635         return fields;
636
637     // lazily sort fields
638
if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
639         int length = this.fields.length;
640         if (length > 1)
641             ReferenceBinding.sortFields(this.fields, 0, length);
642         this.tagBits |= TagBits.AreFieldsSorted;
643     }
644     for (int i = fields.length; --i >= 0;)
645         resolveTypeFor(fields[i]);
646     this.tagBits |= TagBits.AreFieldsComplete;
647     return fields;
648 }
649 /**
650  * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
651  */

652 public char[] genericTypeSignature() {
653     return computeGenericTypeSignature(this.typeVariables);
654 }
655 //NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
656
public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
657
658     // lazily sort methods
659
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
660         int length = this.methods.length;
661         if (length > 1)
662             ReferenceBinding.sortMethods(this.methods, 0, length);
663         this.tagBits |= TagBits.AreMethodsSorted;
664     }
665     int argCount = argumentTypes.length;
666     long range;
667     if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
668         nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
669             MethodBinding method = methods[imethod];
670             if (method.parameters.length == argCount) {
671                 resolveTypesFor(method);
672                 TypeBinding[] toMatch = method.parameters;
673                 for (int iarg = 0; iarg < argCount; iarg++)
674                     if (toMatch[iarg] != argumentTypes[iarg])
675                         continue nextMethod;
676                 return method;
677             }
678         }
679     }
680     return null;
681 }
682
683 //NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
684
//searches up the hierarchy as long as no potential (but not exact) match was found.
685
public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
686     // sender from refScope calls recordTypeReference(this)
687

688     // lazily sort methods
689
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
690         int length = this.methods.length;
691         if (length > 1)
692             ReferenceBinding.sortMethods(this.methods, 0, length);
693         this.tagBits |= TagBits.AreMethodsSorted;
694     }
695
696     int argCount = argumentTypes.length;
697     boolean foundNothing = true;
698
699     long range;
700     if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
701         nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
702             MethodBinding method = methods[imethod];
703             foundNothing = false; // inner type lookups must know that a method with this name exists
704
if (method.parameters.length == argCount) {
705                 resolveTypesFor(method);
706                 TypeBinding[] toMatch = method.parameters;
707                 for (int iarg = 0; iarg < argCount; iarg++)
708                     if (toMatch[iarg] != argumentTypes[iarg])
709                         continue nextMethod;
710                 return method;
711             }
712         }
713     }
714     if (foundNothing) {
715         if (isInterface()) {
716              if (superInterfaces().length == 1) { // ensure superinterfaces are resolved before checking
717
if (refScope != null)
718                     refScope.recordTypeReference(superInterfaces[0]);
719                 return superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
720              }
721         } else if (superclass() != null) { // ensure superclass is resolved before checking
722
if (refScope != null)
723                 refScope.recordTypeReference(superclass);
724             return superclass.getExactMethod(selector, argumentTypes, refScope);
725         }
726     }
727     return null;
728 }
729 //NOTE: the type of a field of a binary type is resolved when needed
730
public FieldBinding getField(char[] fieldName, boolean needResolve) {
731     // lazily sort fields
732
if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
733         int length = this.fields.length;
734         if (length > 1)
735             ReferenceBinding.sortFields(this.fields, 0, length);
736         this.tagBits |= TagBits.AreFieldsSorted;
737     }
738     FieldBinding field = ReferenceBinding.binarySearch(fieldName, this.fields);
739     return needResolve && field != null ? resolveTypeFor(field) : field;
740 }
741 /**
742  * Rewrite of default getMemberType to avoid resolving eagerly all member types when one is requested
743  */

744 public ReferenceBinding getMemberType(char[] typeName) {
745     for (int i = this.memberTypes.length; --i >= 0;) {
746         ReferenceBinding memberType = this.memberTypes[i];
747         if (memberType instanceof UnresolvedReferenceBinding) {
748             char[] name = memberType.sourceName; // source name is qualified with enclosing type name
749
int prefixLength = this.compoundName[this.compoundName.length - 1].length + 1; // enclosing$
750
if (name.length == (prefixLength + typeName.length)) // enclosing $ typeName
751
if (CharOperation.fragmentEquals(typeName, name, prefixLength, true)) // only check trailing portion
752
return this.memberTypes[i] = resolveType(memberType, this.environment, false); // no raw conversion for now
753
} else if (CharOperation.equals(typeName, memberType.sourceName)) {
754             return memberType;
755         }
756     }
757     return null;
758 }
759 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
760
public MethodBinding[] getMethods(char[] selector) {
761     if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
762         long range;
763         if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
764             int start = (int) range, end = (int) (range >> 32);
765             int length = end - start + 1;
766             if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
767                 // simply clone method subset
768
MethodBinding[] result;
769                 System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
770                 return result;
771             }
772         }
773         return Binding.NO_METHODS;
774     }
775     // lazily sort methods
776
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
777         int length = this.methods.length;
778         if (length > 1)
779             ReferenceBinding.sortMethods(this.methods, 0, length);
780         this.tagBits |= TagBits.AreMethodsSorted;
781     }
782     long range;
783     if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
784         int start = (int) range, end = (int) (range >> 32);
785         int length = end - start + 1;
786         MethodBinding[] result = new MethodBinding[length];
787         // iterate methods to resolve them
788
for (int i = start, index = 0; i <= end; i++, index++)
789             result[index] = resolveTypesFor(methods[i]);
790         return result;
791     }
792     return Binding.NO_METHODS;
793 }
794 public boolean hasMemberTypes() {
795     return this.memberTypes.length > 0;
796 }
797 // NOTE: member types of binary types are resolved when needed
798
public TypeVariableBinding getTypeVariable(char[] variableName) {
799     TypeVariableBinding variable = super.getTypeVariable(variableName);
800     variable.resolve(this.environment);
801     return variable;
802 }
803 private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper) {
804     // ParameterSignature = Identifier ':' TypeSignature
805
// or Identifier ':' TypeSignature(optional) InterfaceBound(s)
806
// InterfaceBound = ':' TypeSignature
807
int colon = CharOperation.indexOf(':', wrapper.signature, wrapper.start);
808     wrapper.start = colon + 1; // skip name + ':'
809
ReferenceBinding type, firstBound = null;
810     if (wrapper.signature[wrapper.start] == ':') {
811         type = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
812     } else {
813         type = (ReferenceBinding) environment.getTypeFromTypeSignature(wrapper, existingVariables, this);
814         firstBound = type;
815     }
816
817     // variable is visible to its bounds
818
variable.modifiers |= ExtraCompilerModifiers.AccUnresolved;
819     variable.superclass = type;
820
821     ReferenceBinding[] bounds = null;
822     if (wrapper.signature[wrapper.start] == ':') {
823         java.util.ArrayList JavaDoc types = new java.util.ArrayList JavaDoc(2);
824         do {
825             wrapper.start++; // skip ':'
826
types.add(environment.getTypeFromTypeSignature(wrapper, existingVariables, this));
827         } while (wrapper.signature[wrapper.start] == ':');
828         bounds = new ReferenceBinding[types.size()];
829         types.toArray(bounds);
830     }
831
832     variable.superInterfaces = bounds == null ? Binding.NO_SUPERINTERFACES : bounds;
833     if (firstBound == null) {
834         firstBound = variable.superInterfaces.length == 0 ? null : variable.superInterfaces[0];
835     }
836     variable.firstBound = firstBound;
837 }
838 /**
839  * Returns true if a type is identical to another one,
840  * or for generic types, true if compared to its raw type.
841  */

842 public boolean isEquivalentTo(TypeBinding otherType) {
843     if (this == otherType) return true;
844     if (otherType == null) return false;
845     switch(otherType.kind()) {
846         case Binding.WILDCARD_TYPE :
847             return ((WildcardBinding) otherType).boundCheck(this);
848         case Binding.RAW_TYPE :
849             return otherType.erasure() == this;
850     }
851     return false;
852 }
853 public boolean isGenericType() {
854     return this.typeVariables != Binding.NO_TYPE_VARIABLES;
855 }
856 public int kind() {
857     if (this.typeVariables != Binding.NO_TYPE_VARIABLES)
858         return Binding.GENERIC_TYPE;
859     return Binding.TYPE;
860 }
861 // NOTE: member types of binary types are resolved when needed
862
public ReferenceBinding[] memberTypes() {
863     if ((this.tagBits & TagBits.HasUnresolvedMemberTypes) == 0)
864         return this.memberTypes;
865
866     for (int i = this.memberTypes.length; --i >= 0;)
867         this.memberTypes[i] = resolveType(this.memberTypes[i], this.environment, false); // no raw conversion for now
868
this.tagBits &= ~TagBits.HasUnresolvedMemberTypes;
869     return this.memberTypes;
870 }
871 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
872
public MethodBinding[] methods() {
873     if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
874         return methods;
875
876     // lazily sort methods
877
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
878         int length = this.methods.length;
879         if (length > 1)
880             ReferenceBinding.sortMethods(this.methods, 0, length);
881         this.tagBits |= TagBits.AreMethodsSorted;
882     }
883     for (int i = methods.length; --i >= 0;)
884         resolveTypesFor(methods[i]);
885     this.tagBits |= TagBits.AreMethodsComplete;
886     return methods;
887 }
888 private FieldBinding resolveTypeFor(FieldBinding field) {
889     if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
890         return field;
891
892     field.type = resolveType(field.type, this.environment, null, 0);
893     field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
894     return field;
895 }
896 MethodBinding resolveTypesFor(MethodBinding method) {
897     if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
898         return method;
899
900     if (!method.isConstructor())
901         method.returnType = resolveType(method.returnType, this.environment, null, 0);
902     for (int i = method.parameters.length; --i >= 0;)
903         method.parameters[i] = resolveType(method.parameters[i], this.environment, null, 0);
904     for (int i = method.thrownExceptions.length; --i >= 0;)
905         method.thrownExceptions[i] = resolveType(method.thrownExceptions[i], this.environment, true);
906     for (int i = method.typeVariables.length; --i >= 0;)
907         method.typeVariables[i].resolve(this.environment);
908     method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
909     return method;
910 }
911 AnnotationBinding[] retrieveAnnotations(Binding binding) {
912     return AnnotationBinding.addStandardAnnotations(super.retrieveAnnotations(binding), binding.getAnnotationTagBits(), this.environment);
913 }
914 SimpleLookupTable storedAnnotations(boolean forceInitialize) {
915     if (forceInitialize && this.storedAnnotations == null) {
916         if (!this.environment.globalOptions.storeAnnotations)
917             return null; // not supported during this compile
918
this.storedAnnotations = new SimpleLookupTable(3);
919     }
920     return this.storedAnnotations;
921 }
922 /* Answer the receiver's superclass... null if the receiver is Object or an interface.
923 *
924 * NOTE: superclass of a binary type is resolved when needed
925 */

926 public ReferenceBinding superclass() {
927     if ((this.tagBits & TagBits.HasUnresolvedSuperclass) == 0)
928         return this.superclass;
929
930     // finish resolving the type
931
this.superclass = resolveType(this.superclass, this.environment, true);
932     this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
933     if (this.superclass.problemId() == ProblemReasons.NotFound)
934         this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
935
return this.superclass;
936 }
937 // NOTE: superInterfaces of binary types are resolved when needed
938
public ReferenceBinding[] superInterfaces() {
939     if ((this.tagBits & TagBits.HasUnresolvedSuperinterfaces) == 0)
940         return this.superInterfaces;
941
942     for (int i = this.superInterfaces.length; --i >= 0;) {
943         this.superInterfaces[i] = resolveType(this.superInterfaces[i], this.environment, true);
944         if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound)
945             this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
946
}
947     this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
948     return this.superInterfaces;
949 }
950 public TypeVariableBinding[] typeVariables() {
951     if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
952         return this.typeVariables;
953
954     for (int i = this.typeVariables.length; --i >= 0;)
955         this.typeVariables[i].resolve(this.environment);
956     this.tagBits &= ~TagBits.HasUnresolvedTypeVariables;
957     return this.typeVariables;
958 }
959 public String JavaDoc toString() {
960     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
961
962     if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
963
if (isPublic()) buffer.append("public "); //$NON-NLS-1$
964
if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
965
if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
966
if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
967
if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
968
if (isFinal()) buffer.append("final "); //$NON-NLS-1$
969

970     if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
971
else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
972
else if (isClass()) buffer.append("class "); //$NON-NLS-1$
973
else buffer.append("interface "); //$NON-NLS-1$
974
buffer.append((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
975

976     buffer.append("\n\textends "); //$NON-NLS-1$
977
buffer.append((superclass != null) ? superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
978

979     if (superInterfaces != null) {
980         if (superInterfaces != Binding.NO_SUPERINTERFACES) {
981             buffer.append("\n\timplements : "); //$NON-NLS-1$
982
for (int i = 0, length = superInterfaces.length; i < length; i++) {
983                 if (i > 0)
984                     buffer.append(", "); //$NON-NLS-1$
985
buffer.append((superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
986
}
987         }
988     } else {
989         buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
990
}
991
992     if (enclosingType != null) {
993         buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
994
buffer.append(enclosingType.debugName());
995     }
996
997     if (fields != null) {
998         if (fields != Binding.NO_FIELDS) {
999             buffer.append("\n/* fields */"); //$NON-NLS-1$
1000
for (int i = 0, length = fields.length; i < length; i++)
1001                buffer.append((fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"); //$NON-NLS-1$ //$NON-NLS-2$
1002
}
1003    } else {
1004        buffer.append("NULL FIELDS"); //$NON-NLS-1$
1005
}
1006
1007    if (methods != null) {
1008        if (methods != Binding.NO_METHODS) {
1009            buffer.append("\n/* methods */"); //$NON-NLS-1$
1010
for (int i = 0, length = methods.length; i < length; i++)
1011                buffer.append((methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"); //$NON-NLS-1$ //$NON-NLS-2$
1012
}
1013    } else {
1014        buffer.append("NULL METHODS"); //$NON-NLS-1$
1015
}
1016
1017    if (memberTypes != null) {
1018        if (memberTypes != Binding.NO_MEMBER_TYPES) {
1019            buffer.append("\n/* members */"); //$NON-NLS-1$
1020
for (int i = 0, length = memberTypes.length; i < length; i++)
1021                buffer.append((memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"); //$NON-NLS-1$ //$NON-NLS-2$
1022
}
1023    } else {
1024        buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
1025
}
1026
1027    buffer.append("\n\n\n"); //$NON-NLS-1$
1028
return buffer.toString();
1029}
1030MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
1031
return methods;
1032}
1033}
1034
Popular Tags