KickJava   Java API By Example, From Geeks To Geeks.

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


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.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.jdt.core.compiler.CharOperation;
17 import org.eclipse.jdt.internal.compiler.ClassFilePool;
18 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
19 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
20 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
21 import org.eclipse.jdt.internal.compiler.env.*;
22 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
23 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
24 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
25 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
26 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
27
28 public class LookupEnvironment implements ProblemReasons, TypeConstants {
29     
30     final static int BUILD_FIELDS_AND_METHODS = 4;
31     final static int BUILD_TYPE_HIERARCHY = 1;
32     final static int CHECK_AND_SET_IMPORTS = 2;
33     final static int CONNECT_TYPE_HIERARCHY = 3;
34     static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
35     static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, null, NotFound);
36     
37     /**
38      * Map from typeBinding -> accessRestriction rule
39      */

40     private Map JavaDoc accessRestrictions;
41     ImportBinding[] defaultImports;
42
43     public PackageBinding defaultPackage;
44     HashtableOfPackage knownPackages;
45     private int lastCompletedUnitIndex = -1;
46     private int lastUnitIndex = -1;
47
48     public INameEnvironment nameEnvironment;
49     public CompilerOptions globalOptions;
50     public ProblemReporter problemReporter;
51
52     public ClassFilePool classFilePool;
53
54     // indicate in which step on the compilation we are.
55
// step 1 : build the reference binding
56
// step 2 : conect the hierarchy (connect bindings)
57
// step 3 : build fields and method bindings.
58
private int stepCompleted;
59     public ITypeRequestor typeRequestor;
60     private ArrayBinding[][] uniqueArrayBindings;
61     private SimpleLookupTable uniqueParameterizedTypeBindings;
62     private SimpleLookupTable uniqueRawTypeBindings;
63     private SimpleLookupTable uniqueWildcardBindings;
64     private SimpleLookupTable uniqueParameterizedGenericMethodBindings;
65     
66     public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
67
public Object JavaDoc missingClassFileLocation = null; // only set when resolving certain references, to help locating problems
68

69     private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
70     private MethodVerifier verifier;
71
72 public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
73     this.typeRequestor = typeRequestor;
74     this.globalOptions = globalOptions;
75     this.problemReporter = problemReporter;
76     this.defaultPackage = new PackageBinding(this); // assume the default package always exists
77
this.defaultImports = null;
78     this.nameEnvironment = nameEnvironment;
79     this.knownPackages = new HashtableOfPackage();
80     this.uniqueArrayBindings = new ArrayBinding[5][];
81     this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
82
this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
83     this.uniqueRawTypeBindings = new SimpleLookupTable(3);
84     this.uniqueWildcardBindings = new SimpleLookupTable(3);
85     this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
86     this.accessRestrictions = new HashMap JavaDoc(3);
87     this.classFilePool = ClassFilePool.newInstance();
88 }
89
90 /**
91  * Ask the name environment for a type which corresponds to the compoundName.
92  * Answer null if the name cannot be found.
93  */

94
95 public ReferenceBinding askForType(char[][] compoundName) {
96     NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName);
97     if (answer == null)
98         return null;
99
100     if (answer.isBinaryType())
101         // the type was found as a .class file
102
typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName), answer.getAccessRestriction());
103     else if (answer.isCompilationUnit())
104         // the type was found as a .java file, try to build it then search the cache
105
typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction());
106     else if (answer.isSourceType())
107         // the type was found as a source model
108
typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName), answer.getAccessRestriction());
109
110     return getCachedType(compoundName);
111 }
112 /* Ask the oracle for a type named name in the packageBinding.
113 * Answer null if the name cannot be found.
114 */

115
116 ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
117     if (packageBinding == null) {
118         if (defaultPackage == null)
119             return null;
120         packageBinding = defaultPackage;
121     }
122     NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName);
123     if (answer == null)
124         return null;
125
126     if (answer.isBinaryType())
127         // the type was found as a .class file
128
typeRequestor.accept(answer.getBinaryType(), packageBinding, answer.getAccessRestriction());
129     else if (answer.isCompilationUnit())
130         // the type was found as a .java file, try to build it then search the cache
131
typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction());
132     else if (answer.isSourceType())
133         // the type was found as a source model
134
typeRequestor.accept(answer.getSourceTypes(), packageBinding, answer.getAccessRestriction());
135
136     return packageBinding.getType0(name);
137 }
138 /* Create the initial type bindings for the compilation unit.
139 *
140 * See completeTypeBindings() for a description of the remaining steps
141 *
142 * NOTE: This method can be called multiple times as additional source files are needed
143 */

144
145 public void buildTypeBindings(CompilationUnitDeclaration unit, AccessRestriction accessRestriction) {
146     CompilationUnitScope scope = new CompilationUnitScope(unit, this);
147     scope.buildTypeBindings(accessRestriction);
148
149     int unitsLength = units.length;
150     if (++lastUnitIndex >= unitsLength)
151         System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
152     units[lastUnitIndex] = unit;
153 }
154 /* Cache the binary type since we know it is needed during this compile.
155 *
156 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
157 */

158
159 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, AccessRestriction accessRestriction) {
160     return cacheBinaryType(binaryType, true, accessRestriction);
161 }
162 /* Cache the binary type since we know it is needed during this compile.
163 *
164 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
165 */

166
167 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
168     char[][] compoundName = CharOperation.splitOn('/', binaryType.getName());
169     ReferenceBinding existingType = getCachedType(compoundName);
170
171     if (existingType == null || existingType instanceof UnresolvedReferenceBinding)
172         // only add the binary type if its not already in the cache
173
return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods, accessRestriction);
174     return null; // the type already exists & can be retrieved from the cache
175
}
176 public BinaryTypeBinding cacheMissingBinaryType(char[][] compoundName, CompilationUnitDeclaration unit) {
177     // report the missing class file first
178
problemReporter.isClassPathCorrect(
179         compoundName,
180         unit == null ? this.unitBeingCompleted : unit,
181         this.missingClassFileLocation);
182
183     PackageBinding packageBinding = computePackageFrom(compoundName);
184     // create a proxy for the missing BinaryType
185
MissingBinaryTypeBinding type = new MissingBinaryTypeBinding(packageBinding, compoundName, this);
186     if (type.id != TypeIds.T_JavaLangObject) {
187         // make Object be its superclass - it could in turn be missing as well
188
ReferenceBinding objectType = getType(TypeConstants.JAVA_LANG_OBJECT);
189         if (objectType == null)
190             objectType = cacheMissingBinaryType(TypeConstants.JAVA_LANG_OBJECT, unit); // create a proxy for the missing Object type
191
type.setMissingSuperclass(objectType);
192     }
193     packageBinding.addType(type);
194     return type;
195 }
196 /*
197 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
198 * 2. Create the field bindings
199 * 3. Create the method bindings
200 */

201
202 /* We know each known compilationUnit is free of errors at this point...
203 *
204 * Each step will create additional bindings unless a problem is detected, in which
205 * case either the faulty import/superinterface/field/method will be skipped or a
206 * suitable replacement will be substituted (such as Object for a missing superclass)
207 */

208
209 public void completeTypeBindings() {
210     stepCompleted = BUILD_TYPE_HIERARCHY;
211     
212     for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
213         (this.unitBeingCompleted = this.units[i]).scope.checkAndSetImports();
214     }
215     stepCompleted = CHECK_AND_SET_IMPORTS;
216
217     for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
218         (this.unitBeingCompleted = this.units[i]).scope.connectTypeHierarchy();
219     }
220     stepCompleted = CONNECT_TYPE_HIERARCHY;
221
222     for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
223         CompilationUnitScope unitScope = (this.unitBeingCompleted = this.units[i]).scope;
224         unitScope.checkParameterizedTypes();
225         unitScope.buildFieldsAndMethods();
226         this.units[i] = null; // release unnecessary reference to the parsed unit
227
}
228     stepCompleted = BUILD_FIELDS_AND_METHODS;
229     this.lastCompletedUnitIndex = this.lastUnitIndex;
230     this.unitBeingCompleted = null;
231 }
232 /*
233 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
234 * 2. Create the field bindings
235 * 3. Create the method bindings
236 */

237
238 /*
239 * Each step will create additional bindings unless a problem is detected, in which
240 * case either the faulty import/superinterface/field/method will be skipped or a
241 * suitable replacement will be substituted (such as Object for a missing superclass)
242 */

243
244 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
245     if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
246         // This can only happen because the original set of units are completely built and
247
// are now being processed, so we want to treat all the additional units as a group
248
// until they too are completely processed.
249
completeTypeBindings();
250     } else {
251         if (parsedUnit.scope == null) return; // parsing errors were too severe
252

253         if (stepCompleted >= CHECK_AND_SET_IMPORTS)
254             (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
255
256         if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
257             (this.unitBeingCompleted = parsedUnit).scope.connectTypeHierarchy();
258         
259         this.unitBeingCompleted = null;
260     }
261 }
262 /*
263 * Used by other compiler tools which do not start by calling completeTypeBindings().
264 *
265 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
266 * 2. Create the field bindings
267 * 3. Create the method bindings
268 */

269
270 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) {
271     if (parsedUnit.scope == null) return; // parsing errors were too severe
272

273     (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
274     parsedUnit.scope.connectTypeHierarchy();
275     parsedUnit.scope.checkParameterizedTypes();
276     if (buildFieldsAndMethods)
277         parsedUnit.scope.buildFieldsAndMethods();
278     this.unitBeingCompleted = null;
279 }
280 public TypeBinding computeBoxingType(TypeBinding type) {
281     TypeBinding boxedType;
282     switch (type.id) {
283         case TypeIds.T_JavaLangBoolean :
284             return TypeBinding.BOOLEAN;
285         case TypeIds.T_JavaLangByte :
286             return TypeBinding.BYTE;
287         case TypeIds.T_JavaLangCharacter :
288             return TypeBinding.CHAR;
289         case TypeIds.T_JavaLangShort :
290             return TypeBinding.SHORT;
291         case TypeIds.T_JavaLangDouble :
292             return TypeBinding.DOUBLE;
293         case TypeIds.T_JavaLangFloat :
294             return TypeBinding.FLOAT;
295         case TypeIds.T_JavaLangInteger :
296             return TypeBinding.INT;
297         case TypeIds.T_JavaLangLong :
298             return TypeBinding.LONG;
299
300         case TypeIds.T_int :
301             boxedType = getType(JAVA_LANG_INTEGER);
302             if (boxedType != null) return boxedType;
303             return new ProblemReferenceBinding(JAVA_LANG_INTEGER, null, NotFound);
304         case TypeIds.T_byte :
305             boxedType = getType(JAVA_LANG_BYTE);
306             if (boxedType != null) return boxedType;
307             return new ProblemReferenceBinding(JAVA_LANG_BYTE, null, NotFound);
308         case TypeIds.T_short :
309             boxedType = getType(JAVA_LANG_SHORT);
310             if (boxedType != null) return boxedType;
311             return new ProblemReferenceBinding(JAVA_LANG_SHORT, null, NotFound);
312         case TypeIds.T_char :
313             boxedType = getType(JAVA_LANG_CHARACTER);
314             if (boxedType != null) return boxedType;
315             return new ProblemReferenceBinding(JAVA_LANG_CHARACTER, null, NotFound);
316         case TypeIds.T_long :
317             boxedType = getType(JAVA_LANG_LONG);
318             if (boxedType != null) return boxedType;
319             return new ProblemReferenceBinding(JAVA_LANG_LONG, null, NotFound);
320         case TypeIds.T_float :
321             boxedType = getType(JAVA_LANG_FLOAT);
322             if (boxedType != null) return boxedType;
323             return new ProblemReferenceBinding(JAVA_LANG_FLOAT, null, NotFound);
324         case TypeIds.T_double :
325             boxedType = getType(JAVA_LANG_DOUBLE);
326             if (boxedType != null) return boxedType;
327             return new ProblemReferenceBinding(JAVA_LANG_DOUBLE, null, NotFound);
328         case TypeIds.T_boolean :
329             boxedType = getType(JAVA_LANG_BOOLEAN);
330             if (boxedType != null) return boxedType;
331             return new ProblemReferenceBinding(JAVA_LANG_BOOLEAN, null, NotFound);
332 // case TypeIds.T_int :
333
// return getResolvedType(JAVA_LANG_INTEGER, null);
334
// case TypeIds.T_byte :
335
// return getResolvedType(JAVA_LANG_BYTE, null);
336
// case TypeIds.T_short :
337
// return getResolvedType(JAVA_LANG_SHORT, null);
338
// case TypeIds.T_char :
339
// return getResolvedType(JAVA_LANG_CHARACTER, null);
340
// case TypeIds.T_long :
341
// return getResolvedType(JAVA_LANG_LONG, null);
342
// case TypeIds.T_float :
343
// return getResolvedType(JAVA_LANG_FLOAT, null);
344
// case TypeIds.T_double :
345
// return getResolvedType(JAVA_LANG_DOUBLE, null);
346
// case TypeIds.T_boolean :
347
// return getResolvedType(JAVA_LANG_BOOLEAN, null);
348
}
349     // allow indirect unboxing conversion for wildcards and type parameters
350
switch (type.kind()) {
351         case Binding.WILDCARD_TYPE :
352         case Binding.TYPE_PARAMETER :
353             switch (type.erasure().id) {
354                 case TypeIds.T_JavaLangBoolean :
355                     return TypeBinding.BOOLEAN;
356                 case TypeIds.T_JavaLangByte :
357                     return TypeBinding.BYTE;
358                 case TypeIds.T_JavaLangCharacter :
359                     return TypeBinding.CHAR;
360                 case TypeIds.T_JavaLangShort :
361                     return TypeBinding.SHORT;
362                 case TypeIds.T_JavaLangDouble :
363                     return TypeBinding.DOUBLE;
364                 case TypeIds.T_JavaLangFloat :
365                     return TypeBinding.FLOAT;
366                 case TypeIds.T_JavaLangInteger :
367                     return TypeBinding.INT;
368                 case TypeIds.T_JavaLangLong :
369                     return TypeBinding.LONG;
370             }
371     }
372     return type;
373 }
374 private PackageBinding computePackageFrom(char[][] constantPoolName) {
375     if (constantPoolName.length == 1)
376         return defaultPackage;
377
378     PackageBinding packageBinding = getPackage0(constantPoolName[0]);
379     if (packageBinding == null || packageBinding == TheNotFoundPackage) {
380         packageBinding = new PackageBinding(constantPoolName[0], this);
381         knownPackages.put(constantPoolName[0], packageBinding);
382     }
383
384     for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
385         PackageBinding parent = packageBinding;
386         if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) {
387             packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this);
388             parent.addPackage(packageBinding);
389         }
390     }
391     return packageBinding;
392 }
393
394 /**
395  * Convert a given source type into a parameterized form if generic.
396  * generic X<E> --> param X<E>
397  */

398 public ReferenceBinding convertToParameterizedType(ReferenceBinding originalType) {
399     if (originalType != null) {
400         boolean isGeneric = originalType.isGenericType();
401         ReferenceBinding originalEnclosingType = originalType.enclosingType();
402         ReferenceBinding convertedEnclosingType = originalEnclosingType;
403         boolean needToConvert = isGeneric;
404         if (originalEnclosingType != null) {
405             convertedEnclosingType = originalType.isStatic()
406                 ? (ReferenceBinding) convertToRawType(originalEnclosingType)
407                 : convertToParameterizedType(originalEnclosingType);
408             needToConvert |= originalEnclosingType != convertedEnclosingType;
409         }
410         if (needToConvert) {
411             return createParameterizedType(originalType, isGeneric ? originalType.typeVariables() : null, convertedEnclosingType);
412         }
413     }
414     return originalType;
415 }
416
417 public TypeBinding convertToRawType(TypeBinding type) {
418     int dimension;
419     TypeBinding originalType;
420     switch(type.kind()) {
421         case Binding.BASE_TYPE :
422         case Binding.TYPE_PARAMETER:
423         case Binding.WILDCARD_TYPE:
424         case Binding.RAW_TYPE:
425             return type;
426         case Binding.ARRAY_TYPE:
427             dimension = type.dimensions();
428             originalType = type.leafComponentType();
429             break;
430         default:
431             if (type.id == TypeIds.T_JavaLangObject)
432                 return type; // Object is not generic
433
dimension = 0;
434             originalType = type;
435     }
436     boolean needToConvert;
437     switch (originalType.kind()) {
438         case Binding.BASE_TYPE :
439             return type;
440         case Binding.GENERIC_TYPE :
441             needToConvert = true;
442             break;
443         case Binding.PARAMETERIZED_TYPE :
444             ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
445             needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
446
break;
447         default :
448             needToConvert = false;
449             break;
450     }
451     ReferenceBinding originalEnclosing = originalType.enclosingType();
452     TypeBinding convertedType;
453     if (originalEnclosing == null) {
454         convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
455     } else {
456         ReferenceBinding convertedEnclosing;
457         if (originalEnclosing.kind() == Binding.RAW_TYPE) {
458             needToConvert |= !((ReferenceBinding)originalType).isStatic();
459             convertedEnclosing = originalEnclosing;
460         } else if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
461             convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
462         } else {
463             convertedEnclosing = convertToParameterizedType(originalEnclosing);
464         }
465         if (needToConvert) {
466             convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
467         } else if (originalEnclosing != convertedEnclosing) {
468             convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
469         } else {
470             convertedType = originalType;
471         }
472     }
473     if (originalType != convertedType) {
474         return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
475     }
476     return type;
477 }
478
479 // variation for unresolved types in binaries (consider generic type as raw)
480
public TypeBinding convertUnresolvedBinaryToRawType(TypeBinding type) {
481     int dimension;
482     TypeBinding originalType;
483     switch(type.kind()) {
484         case Binding.BASE_TYPE :
485         case Binding.TYPE_PARAMETER:
486         case Binding.WILDCARD_TYPE:
487         case Binding.RAW_TYPE:
488             return type;
489         case Binding.ARRAY_TYPE:
490             dimension = type.dimensions();
491             originalType = type.leafComponentType();
492             break;
493         default:
494             if (type.id == TypeIds.T_JavaLangObject)
495                 return type; // Object is not generic
496
dimension = 0;
497             originalType = type;
498     }
499     boolean needToConvert;
500     switch (originalType.kind()) {
501         case Binding.BASE_TYPE :
502             return type;
503         case Binding.GENERIC_TYPE :
504             needToConvert = true;
505             break;
506         case Binding.PARAMETERIZED_TYPE :
507             ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
508             needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
509
break;
510         default :
511             needToConvert = false;
512             break;
513     }
514     ReferenceBinding originalEnclosing = originalType.enclosingType();
515     TypeBinding convertedType;
516     if (originalEnclosing == null) {
517         convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
518     } else {
519         ReferenceBinding convertedEnclosing = (ReferenceBinding) convertUnresolvedBinaryToRawType(originalEnclosing);
520         if (convertedEnclosing != originalEnclosing) {
521             needToConvert |= !((ReferenceBinding)originalType).isStatic();
522         }
523         if (needToConvert) {
524             convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
525         } else if (originalEnclosing != convertedEnclosing) {
526             convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
527         } else {
528             convertedType = originalType;
529         }
530     }
531     if (originalType != convertedType) {
532         return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
533     }
534     return type;
535 }
536 /*
537  * Used to guarantee annotation identity.
538  */

539 public AnnotationBinding createAnnotation(ReferenceBinding annotationType, ElementValuePair[] pairs) {
540     if (pairs.length != 0) {
541         AnnotationBinding.setMethodBindings(annotationType, pairs);
542     }
543     return new AnnotationBinding(annotationType, pairs);
544 }
545
546 /*
547  * Used to guarantee array type identity.
548  */

549 public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount) {
550     if (leafComponentType instanceof LocalTypeBinding) // cache local type arrays with the local type itself
551
return ((LocalTypeBinding) leafComponentType).createArrayType(dimensionCount, this);
552
553     // find the array binding cache for this dimension
554
int dimIndex = dimensionCount - 1;
555     int length = uniqueArrayBindings.length;
556     ArrayBinding[] arrayBindings;
557     if (dimIndex < length) {
558         if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
559             uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
560     } else {
561         System.arraycopy(
562             uniqueArrayBindings, 0,
563             uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0,
564             length);
565         uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
566     }
567
568     // find the cached array binding for this leaf component type (if any)
569
int index = -1;
570     length = arrayBindings.length;
571     while (++index < length) {
572         ArrayBinding currentBinding = arrayBindings[index];
573         if (currentBinding == null) // no matching array, but space left
574
return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this);
575         if (currentBinding.leafComponentType == leafComponentType)
576             return currentBinding;
577     }
578
579     // no matching array, no space left
580
System.arraycopy(
581         arrayBindings, 0,
582         (arrayBindings = new ArrayBinding[length * 2]), 0,
583         length);
584     uniqueArrayBindings[dimIndex] = arrayBindings;
585     return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this);
586 }
587 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
588     return createBinaryTypeFrom(binaryType, packageBinding, true, accessRestriction);
589 }
590 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
591     BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this);
592     
593     // resolve any array bindings which reference the unresolvedType
594
ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
595     if (cachedType != null) { // update reference to unresolved binding after having read classfile (knows whether generic for raw conversion)
596
if (cachedType instanceof UnresolvedReferenceBinding) {
597             ((UnresolvedReferenceBinding) cachedType).setResolvedType(binaryBinding, this);
598         } else {
599             if (cachedType.isBinaryBinding()) // sanity check... at this point the cache should ONLY contain unresolved types
600
return (BinaryTypeBinding) cachedType;
601             // it is possible with a large number of source files (exceeding AbstractImageBuilder.MAX_AT_ONCE) that a member type can be in the cache as an UnresolvedType,
602
// but because its enclosingType is resolved while its created (call to BinaryTypeBinding constructor), its replaced with a source type
603
return null;
604         }
605     }
606
607     packageBinding.addType(binaryBinding);
608     setAccessRestriction(binaryBinding, accessRestriction);
609     binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
610     return binaryBinding;
611 }
612 /* Used to create packages from the package statement.
613 */

614
615 public PackageBinding createPackage(char[][] compoundName) {
616     PackageBinding packageBinding = getPackage0(compoundName[0]);
617     if (packageBinding == null || packageBinding == TheNotFoundPackage) {
618         packageBinding = new PackageBinding(compoundName[0], this);
619         knownPackages.put(compoundName[0], packageBinding);
620     }
621
622     for (int i = 1, length = compoundName.length; i < length; i++) {
623         // check to see if it collides with a known type...
624
// this case can only happen if the package does not exist as a directory in the file system
625
// otherwise when the source type was defined, the correct error would have been reported
626
// unless its an unresolved type which is referenced from an inconsistent class file
627
// NOTE: empty packages are not packages according to changes in JLS v2, 7.4.3
628
// so not all types cause collision errors when they're created even though the package did exist
629
ReferenceBinding type = packageBinding.getType0(compoundName[i]);
630         if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding))
631             return null;
632
633         PackageBinding parent = packageBinding;
634         if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) {
635             // if the package is unknown, check to see if a type exists which would collide with the new package
636
// catches the case of a package statement of: package java.lang.Object;
637
// since the package can be added after a set of source files have already been compiled,
638
// we need to check whenever a package is created
639
if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null)
640                 return null;
641
642             packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this);
643             parent.addPackage(packageBinding);
644         }
645     }
646     return packageBinding;
647 }
648
649 public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, RawTypeBinding rawType) {
650
651     // cached info is array of already created parameterized types for this type
652
ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod);
653     boolean needToGrow = false;
654     int index = 0;
655     if (cachedInfo != null){
656         nextCachedMethod :
657             // iterate existing parameterized for reusing one with same type arguments if any
658
for (int max = cachedInfo.length; index < max; index++){
659                 ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
660                 if (cachedMethod == null) break nextCachedMethod;
661                 if (!cachedMethod.isRaw) continue nextCachedMethod;
662                 if (cachedMethod.declaringClass != (rawType == null ? genericMethod.declaringClass : rawType)) continue nextCachedMethod;
663                 return cachedMethod;
664         }
665         needToGrow = true;
666     } else {
667         cachedInfo = new ParameterizedGenericMethodBinding[5];
668         this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
669     }
670     // grow cache ?
671
int length = cachedInfo.length;
672     if (needToGrow && index == length){
673         System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
674         this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
675     }
676     // add new binding
677
ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, rawType, this);
678     cachedInfo[index] = parameterizedGenericMethod;
679     return parameterizedGenericMethod;
680 }
681
682 public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, TypeBinding[] typeArguments) {
683
684     // cached info is array of already created parameterized types for this type
685
ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod);
686     int argLength = typeArguments == null ? 0: typeArguments.length;
687     boolean needToGrow = false;
688     int index = 0;
689     if (cachedInfo != null){
690         nextCachedMethod :
691             // iterate existing parameterized for reusing one with same type arguments if any
692
for (int max = cachedInfo.length; index < max; index++){
693                 ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
694                 if (cachedMethod == null) break nextCachedMethod;
695                 if (cachedMethod.isRaw) continue nextCachedMethod;
696                 TypeBinding[] cachedArguments = cachedMethod.typeArguments;
697                 int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
698                 if (argLength != cachedArgLength) continue nextCachedMethod;
699                 for (int j = 0; j < cachedArgLength; j++){
700                     if (typeArguments[j] != cachedArguments[j]) continue nextCachedMethod;
701                 }
702                 // all arguments match, reuse current
703
return cachedMethod;
704         }
705         needToGrow = true;
706     } else {
707         cachedInfo = new ParameterizedGenericMethodBinding[5];
708         this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
709     }
710     // grow cache ?
711
int length = cachedInfo.length;
712     if (needToGrow && index == length){
713         System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
714         this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
715     }
716     // add new binding
717
ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, typeArguments, this);
718     cachedInfo[index] = parameterizedGenericMethod;
719     return parameterizedGenericMethod;
720 }
721
722 public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType) {
723
724     // cached info is array of already created parameterized types for this type
725
ParameterizedTypeBinding[] cachedInfo = (ParameterizedTypeBinding[])this.uniqueParameterizedTypeBindings.get(genericType);
726     int argLength = typeArguments == null ? 0: typeArguments.length;
727     boolean needToGrow = false;
728     int index = 0;
729     if (cachedInfo != null){
730         nextCachedType :
731             // iterate existing parameterized for reusing one with same type arguments if any
732
for (int max = cachedInfo.length; index < max; index++){
733                 ParameterizedTypeBinding cachedType = cachedInfo[index];
734                 if (cachedType == null) break nextCachedType;
735                 if (cachedType.actualType() != genericType) continue nextCachedType; // remain of unresolved type
736
if (cachedType.enclosingType() != enclosingType) continue nextCachedType;
737                 TypeBinding[] cachedArguments = cachedType.arguments;
738                 int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
739                 if (argLength != cachedArgLength) continue nextCachedType; // would be an error situation (from unresolved binaries)
740
for (int j = 0; j < cachedArgLength; j++){
741                     if (typeArguments[j] != cachedArguments[j]) continue nextCachedType;
742                 }
743                 // all arguments match, reuse current
744
return cachedType;
745         }
746         needToGrow = true;
747     } else {
748         cachedInfo = new ParameterizedTypeBinding[5];
749         this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo);
750     }
751     // grow cache ?
752
int length = cachedInfo.length;
753     if (needToGrow && index == length){
754         System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedTypeBinding[length*2], 0, length);
755         this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo);
756     }
757     // add new binding
758
ParameterizedTypeBinding parameterizedType = new ParameterizedTypeBinding(genericType,typeArguments, enclosingType, this);
759     cachedInfo[index] = parameterizedType;
760     return parameterizedType;
761 }
762
763 public RawTypeBinding createRawType(ReferenceBinding genericType, ReferenceBinding enclosingType) {
764     // cached info is array of already created raw types for this type
765
RawTypeBinding[] cachedInfo = (RawTypeBinding[])this.uniqueRawTypeBindings.get(genericType);
766     boolean needToGrow = false;
767     int index = 0;
768     if (cachedInfo != null){
769         nextCachedType :
770             // iterate existing parameterized for reusing one with same type arguments if any
771
for (int max = cachedInfo.length; index < max; index++){
772                 RawTypeBinding cachedType = cachedInfo[index];
773                 if (cachedType == null) break nextCachedType;
774                 if (cachedType.actualType() != genericType) continue nextCachedType; // remain of unresolved type
775
if (cachedType.enclosingType() != enclosingType) continue nextCachedType;
776                 // all enclosing type match, reuse current
777
return cachedType;
778         }
779         needToGrow = true;
780     } else {
781         cachedInfo = new RawTypeBinding[1];
782         this.uniqueRawTypeBindings.put(genericType, cachedInfo);
783     }
784     // grow cache ?
785
int length = cachedInfo.length;
786     if (needToGrow && index == length){
787         System.arraycopy(cachedInfo, 0, cachedInfo = new RawTypeBinding[length*2], 0, length);
788         this.uniqueRawTypeBindings.put(genericType, cachedInfo);
789     }
790     // add new binding
791
RawTypeBinding rawType = new RawTypeBinding(genericType, enclosingType, this);
792     cachedInfo[index] = rawType;
793     return rawType;
794     
795 }
796
797 public WildcardBinding createWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind) {
798     
799     // cached info is array of already created wildcard types for this type
800
if (genericType == null) // pseudo wildcard denoting composite bounds for lub computation
801
genericType = ReferenceBinding.LUB_GENERIC;
802     WildcardBinding[] cachedInfo = (WildcardBinding[])this.uniqueWildcardBindings.get(genericType);
803     boolean needToGrow = false;
804     int index = 0;
805     if (cachedInfo != null){
806         nextCachedType :
807             // iterate existing wildcards for reusing one with same information if any
808
for (int max = cachedInfo.length; index < max; index++){
809                 WildcardBinding cachedType = cachedInfo[index];
810                 if (cachedType == null) break nextCachedType;
811                 if (cachedType.genericType != genericType) continue nextCachedType; // remain of unresolved type
812
if (cachedType.rank != rank) continue nextCachedType;
813                 if (cachedType.boundKind != boundKind) continue nextCachedType;
814                 if (cachedType.bound != bound) continue nextCachedType;
815                 if (cachedType.otherBounds != otherBounds) {
816                     int cachedLength = cachedType.otherBounds == null ? 0 : cachedType.otherBounds.length;
817                     int length = otherBounds == null ? 0 : otherBounds.length;
818                     if (cachedLength != length) continue nextCachedType;
819                     for (int j = 0; j < length; j++) {
820                         if (cachedType.otherBounds[j] != otherBounds[j]) continue nextCachedType;
821                     }
822                 }
823                 // all match, reuse current
824
return cachedType;
825         }
826         needToGrow = true;
827     } else {
828         cachedInfo = new WildcardBinding[10];
829         this.uniqueWildcardBindings.put(genericType, cachedInfo);
830     }
831     // grow cache ?
832
int length = cachedInfo.length;
833     if (needToGrow && index == length){
834         System.arraycopy(cachedInfo, 0, cachedInfo = new WildcardBinding[length*2], 0, length);
835         this.uniqueWildcardBindings.put(genericType, cachedInfo);
836     }
837     // add new binding
838
WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, otherBounds, boundKind, this);
839     cachedInfo[index] = wildcard;
840     return wildcard;
841 }
842
843 /**
844  * Returns the access restriction associated to a given type, or null if none
845  */

846 public AccessRestriction getAccessRestriction(TypeBinding type) {
847     return (AccessRestriction) this.accessRestrictions.get(type);
848 }
849
850 /**
851  * Answer the type for the compoundName if it exists in the cache.
852  * Answer theNotFoundType if it could not be resolved the first time
853  * it was looked up, otherwise answer null.
854  *
855  * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
856  * assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
857  */

858
859 public ReferenceBinding getCachedType(char[][] compoundName) {
860     if (compoundName.length == 1) {
861         if (defaultPackage == null)
862             return null;
863         return defaultPackage.getType0(compoundName[0]);
864     }
865
866     PackageBinding packageBinding = getPackage0(compoundName[0]);
867     if (packageBinding == null || packageBinding == TheNotFoundPackage)
868         return null;
869
870     for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
871         if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage)
872             return null;
873     return packageBinding.getType0(compoundName[compoundName.length - 1]);
874 }
875 /* Answer the top level package named name if it exists in the cache.
876 * Answer theNotFoundPackage if it could not be resolved the first time
877 * it was looked up, otherwise answer null.
878 *
879 * NOTE: Senders must convert theNotFoundPackage into a real problem
880 * package if its to returned.
881 */

882
883 PackageBinding getPackage0(char[] name) {
884     return knownPackages.get(name);
885 }
886 /* Answer the type corresponding to the compoundName.
887 * Ask the name environment for the type if its not in the cache.
888 * Fail with a classpath error if the type cannot be found.
889 */

890 public ReferenceBinding getResolvedType(char[][] compoundName, Scope scope) {
891     ReferenceBinding type = getType(compoundName);
892     if (type != null) return type;
893
894     // create a proxy for the missing BinaryType
895
return cacheMissingBinaryType(
896         compoundName,
897         scope == null ? this.unitBeingCompleted : scope.referenceCompilationUnit());
898 }
899 /* Answer the top level package named name.
900 * Ask the oracle for the package if its not in the cache.
901 * Answer null if the package cannot be found.
902 */

903
904 PackageBinding getTopLevelPackage(char[] name) {
905     PackageBinding packageBinding = getPackage0(name);
906     if (packageBinding != null) {
907         if (packageBinding == TheNotFoundPackage)
908             return null;
909         return packageBinding;
910     }
911
912     if (nameEnvironment.isPackage(null, name)) {
913         knownPackages.put(name, packageBinding = new PackageBinding(name, this));
914         return packageBinding;
915     }
916
917     knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
918
return null;
919 }
920 /* Answer the type corresponding to the compoundName.
921 * Ask the name environment for the type if its not in the cache.
922 * Answer null if the type cannot be found.
923 */

924
925 public ReferenceBinding getType(char[][] compoundName) {
926     ReferenceBinding referenceBinding;
927
928     if (compoundName.length == 1) {
929         if (defaultPackage == null)
930             return null;
931
932         if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) {
933             PackageBinding packageBinding = getPackage0(compoundName[0]);
934             if (packageBinding != null && packageBinding != TheNotFoundPackage)
935                 return null; // collides with a known package... should not call this method in such a case
936
referenceBinding = askForType(defaultPackage, compoundName[0]);
937         }
938     } else {
939         PackageBinding packageBinding = getPackage0(compoundName[0]);
940         if (packageBinding == TheNotFoundPackage)
941             return null;
942
943         if (packageBinding != null) {
944             for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
945                 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null)
946                     break;
947                 if (packageBinding == TheNotFoundPackage)
948                     return null;
949             }
950         }
951
952         if (packageBinding == null)
953             referenceBinding = askForType(compoundName);
954         else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null)
955             referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]);
956     }
957
958     if (referenceBinding == null || referenceBinding == TheNotFoundType)
959         return null;
960     referenceBinding = BinaryTypeBinding.resolveType(referenceBinding, this, false); // no raw conversion for now
961

962     // compoundName refers to a nested type incorrectly (for example, package1.A$B)
963
if (referenceBinding.isNestedType())
964         return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided);
965     return referenceBinding;
966 }
967 private TypeBinding[] getTypeArgumentsFromSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType, ReferenceBinding genericType) {
968     java.util.ArrayList JavaDoc args = new java.util.ArrayList JavaDoc(2);
969     int rank = 0;
970     do {
971         args.add(getTypeFromVariantTypeSignature(wrapper, staticVariables, enclosingType, genericType, rank++));
972     } while (wrapper.signature[wrapper.start] != '>');
973     wrapper.start++; // skip '>'
974
TypeBinding[] typeArguments = new TypeBinding[args.size()];
975     args.toArray(typeArguments);
976     return typeArguments;
977 }
978 /* Answer the type corresponding to the compound name.
979 * Does not ask the oracle for the type if its not found in the cache... instead an
980 * unresolved type is returned which must be resolved before used.
981 *
982 * NOTE: Does NOT answer base types nor array types!
983 */

984
985 ReferenceBinding getTypeFromCompoundName(char[][] compoundName, boolean isParameterized) {
986     ReferenceBinding binding = getCachedType(compoundName);
987     if (binding == null) {
988         PackageBinding packageBinding = computePackageFrom(compoundName);
989         binding = new UnresolvedReferenceBinding(compoundName, packageBinding);
990         packageBinding.addType(binding);
991     } else if (binding == TheNotFoundType) {
992         // create a proxy for the missing BinaryType
993
binding = cacheMissingBinaryType(compoundName, this.unitBeingCompleted);
994     } else if (!isParameterized) {
995         // check raw type, only for resolved types
996
binding = (ReferenceBinding) convertUnresolvedBinaryToRawType(binding);
997     }
998     return binding;
999 }
1000/* Answer the type corresponding to the name from the binary file.
1001* Does not ask the oracle for the type if its not found in the cache... instead an
1002* unresolved type is returned which must be resolved before used.
1003*
1004* NOTE: Does NOT answer base types nor array types!
1005*/

1006
1007ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end, boolean isParameterized) {
1008    if (end == -1)
1009        end = signature.length;
1010
1011    char[][] compoundName = CharOperation.splitOn('/', signature, start, end);
1012    return getTypeFromCompoundName(compoundName, isParameterized);
1013}
1014/* Answer the type corresponding to the signature from the binary file.
1015* Does not ask the oracle for the type if its not found in the cache... instead an
1016* unresolved type is returned which must be resolved before used.
1017*
1018* NOTE: Does answer base types & array types.
1019*/

1020
1021TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean isParameterized, TypeBinding enclosingType) {
1022    int dimension = 0;
1023    while (signature[start] == '[') {
1024        start++;
1025        dimension++;
1026    }
1027    if (end == -1)
1028        end = signature.length - 1;
1029
1030    // Just switch on signature[start] - the L case is the else
1031
TypeBinding binding = null;
1032    if (start == end) {
1033        switch (signature[start]) {
1034            case 'I' :
1035                binding = TypeBinding.INT;
1036                break;
1037            case 'Z' :
1038                binding = TypeBinding.BOOLEAN;
1039                break;
1040            case 'V' :
1041                binding = TypeBinding.VOID;
1042                break;
1043            case 'C' :
1044                binding = TypeBinding.CHAR;
1045                break;
1046            case 'D' :
1047                binding = TypeBinding.DOUBLE;
1048                break;
1049            case 'B' :
1050                binding = TypeBinding.BYTE;
1051                break;
1052            case 'F' :
1053                binding = TypeBinding.FLOAT;
1054                break;
1055            case 'J' :
1056                binding = TypeBinding.LONG;
1057                break;
1058            case 'S' :
1059                binding = TypeBinding.SHORT;
1060                break;
1061            default :
1062                problemReporter.corruptedSignature(enclosingType, signature, start);
1063                // will never reach here, since error will cause abort
1064
}
1065    } else {
1066        binding = getTypeFromConstantPoolName(signature, start + 1, end, isParameterized); // skip leading 'L' or 'T'
1067
}
1068
1069    if (dimension == 0)
1070        return binding;
1071    return createArrayType(binding, dimension);
1072}
1073TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType) {
1074    // TypeVariableSignature = 'T' Identifier ';'
1075
// ArrayTypeSignature = '[' TypeSignature
1076
// ClassTypeSignature = 'L' Identifier TypeArgs(optional) ';'
1077
// or ClassTypeSignature '.' 'L' Identifier TypeArgs(optional) ';'
1078
// TypeArgs = '<' VariantTypeSignature VariantTypeSignatures '>'
1079
int dimension = 0;
1080    while (wrapper.signature[wrapper.start] == '[') {
1081        wrapper.start++;
1082        dimension++;
1083    }
1084
1085    if (wrapper.signature[wrapper.start] == 'T') {
1086        int varStart = wrapper.start + 1;
1087        int varEnd = wrapper.computeEnd();
1088        for (int i = staticVariables.length; --i >= 0;)
1089            if (CharOperation.equals(staticVariables[i].sourceName, wrapper.signature, varStart, varEnd))
1090                return dimension == 0 ? (TypeBinding) staticVariables[i] : createArrayType(staticVariables[i], dimension);
1091        ReferenceBinding initialType = enclosingType;
1092        do {
1093            if (enclosingType instanceof BinaryTypeBinding) { // per construction can only be binary type binding
1094
TypeVariableBinding[] enclosingVariables = ((BinaryTypeBinding)enclosingType).typeVariables; // do not trigger resolution of variables
1095
for (int i = enclosingVariables.length; --i >= 0;)
1096                    if (CharOperation.equals(enclosingVariables[i].sourceName, wrapper.signature, varStart, varEnd))
1097                        return dimension == 0 ? (TypeBinding) enclosingVariables[i] : createArrayType(enclosingVariables[i], dimension);
1098            }
1099        } while ((enclosingType = enclosingType.enclosingType()) != null);
1100        problemReporter.undefinedTypeVariableSignature(CharOperation.subarray(wrapper.signature, varStart, varEnd), initialType);
1101        return null; // cannot reach this, since previous problem will abort compilation
1102
}
1103    boolean isParameterized;
1104    TypeBinding type = getTypeFromSignature(wrapper.signature, wrapper.start, wrapper.computeEnd(), isParameterized = (wrapper.end == wrapper.bracket), enclosingType);
1105    if (!isParameterized)
1106        return dimension == 0 ? type : createArrayType(type, dimension);
1107
1108    // type must be a ReferenceBinding at this point, cannot be a BaseTypeBinding or ArrayTypeBinding
1109
ReferenceBinding actualType = (ReferenceBinding) type;
1110    TypeBinding[] typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, actualType);
1111    ReferenceBinding actualEnclosing = actualType.enclosingType();
1112    if (actualEnclosing != null) { // convert needed if read some static member type
1113
actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing);
1114    }
1115    ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, actualEnclosing);
1116
1117    while (wrapper.signature[wrapper.start] == '.') {
1118        wrapper.start++; // skip '.'
1119
char[] memberName = wrapper.nextWord();
1120        BinaryTypeBinding.resolveType(parameterizedType, this, false);
1121        ReferenceBinding memberType = parameterizedType.genericType().getMemberType(memberName);
1122        if (wrapper.signature[wrapper.start] == '<') {
1123            wrapper.start++; // skip '<'
1124
typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, memberType);
1125        } else {
1126            typeArguments = null;
1127        }
1128        parameterizedType = createParameterizedType(memberType, typeArguments, parameterizedType);
1129    }
1130    wrapper.start++; // skip ';'
1131
return dimension == 0 ? (TypeBinding) parameterizedType : createArrayType(parameterizedType, dimension);
1132}
1133TypeBinding getTypeFromVariantTypeSignature(
1134    SignatureWrapper wrapper,
1135    TypeVariableBinding[] staticVariables,
1136    ReferenceBinding enclosingType,
1137    ReferenceBinding genericType,
1138    int rank) {
1139    // VariantTypeSignature = '-' TypeSignature
1140
// or '+' TypeSignature
1141
// or TypeSignature
1142
// or '*'
1143
switch (wrapper.signature[wrapper.start]) {
1144        case '-' :
1145            // ? super aType
1146
wrapper.start++;
1147            TypeBinding bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
1148            return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.SUPER);
1149        case '+' :
1150            // ? extends aType
1151
wrapper.start++;
1152            bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
1153            return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.EXTENDS);
1154        case '*' :
1155            // ?
1156
wrapper.start++;
1157            return createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
1158        default :
1159            return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
1160    }
1161}
1162
1163/* Ask the oracle if a package exists named name in the package named compoundName.
1164*/

1165boolean isPackage(char[][] compoundName, char[] name) {
1166    if (compoundName == null || compoundName.length == 0)
1167        return nameEnvironment.isPackage(null, name);
1168    return nameEnvironment.isPackage(compoundName, name);
1169}
1170// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
1171

1172public MethodVerifier methodVerifier() {
1173    if (verifier == null)
1174        verifier = this.globalOptions.sourceLevel < ClassFileConstants.JDK1_5
1175            ? new MethodVerifier(this)
1176            : new MethodVerifier15(this); // covariance only if sourceLevel is >= 1.5
1177
return verifier;
1178}
1179public void reset() {
1180    this.defaultPackage = new PackageBinding(this); // assume the default package always exists
1181
this.defaultImports = null;
1182    this.knownPackages = new HashtableOfPackage();
1183    this.accessRestrictions = new HashMap JavaDoc(3);
1184
1185    this.verifier = null;
1186    for (int i = this.uniqueArrayBindings.length; --i >= 0;) {
1187        ArrayBinding[] arrayBindings = this.uniqueArrayBindings[i];
1188        if (arrayBindings != null)
1189            for (int j = arrayBindings.length; --j >= 0;)
1190                arrayBindings[j] = null;
1191    }
1192    this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
1193    this.uniqueRawTypeBindings = new SimpleLookupTable(3);
1194    this.uniqueWildcardBindings = new SimpleLookupTable(3);
1195    this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
1196    
1197    for (int i = this.units.length; --i >= 0;)
1198        this.units[i] = null;
1199    this.lastUnitIndex = -1;
1200    this.lastCompletedUnitIndex = -1;
1201    this.unitBeingCompleted = null; // in case AbortException occurred
1202

1203    this.classFilePool.reset();
1204    // name environment has a longer life cycle, and must be reset in
1205
// the code which created it.
1206
}
1207/**
1208 * Associate a given type with some access restriction
1209 * (did not store the restriction directly into binding, since sparse information)
1210 */

1211public void setAccessRestriction(ReferenceBinding type, AccessRestriction accessRestriction) {
1212    if (accessRestriction == null) return;
1213    type.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
1214    this.accessRestrictions.put(type, accessRestriction);
1215}
1216
1217void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
1218    // walk all the unique collections & replace the unresolvedType with the resolvedType
1219
// must prevent 2 entries so == still works (1 containing the unresolvedType and the other containing the resolvedType)
1220
if (this.uniqueParameterizedTypeBindings.get(unresolvedType) != null) { // update the key
1221
Object JavaDoc[] keys = this.uniqueParameterizedTypeBindings.keyTable;
1222        for (int i = 0, l = keys.length; i < l; i++) {
1223            if (keys[i] == unresolvedType) {
1224                keys[i] = resolvedType; // hashCode is based on compoundName so this works - cannot be raw since type of parameterized type
1225
break;
1226            }
1227        }
1228    }
1229
1230    if (this.uniqueWildcardBindings.get(unresolvedType) != null) { // update the key
1231
Object JavaDoc[] keys = this.uniqueWildcardBindings.keyTable;
1232        for (int i = 0, l = keys.length; i < l; i++) {
1233            if (keys[i] == unresolvedType) {
1234                keys[i] = resolvedType; // hashCode is based on compoundName so this works
1235
break;
1236            }
1237        }
1238    }
1239}
1240}
1241
Popular Tags