Makefile fixup
[org.ibex.tool.git] / repo / org.ibex.tool / src / org / eclipse / jdt / internal / compiler / lookup / LookupEnvironment.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
15 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
16 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
17 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
18 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
19 import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
20 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
21 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
22 import org.eclipse.jdt.internal.compiler.util.Util;
23
24 public class LookupEnvironment implements BaseTypes, ProblemReasons, TypeConstants {
25         public CompilerOptions options;
26         public ProblemReporter problemReporter;
27         public ITypeRequestor typeRequestor;
28
29         PackageBinding defaultPackage;
30         ImportBinding[] defaultImports;
31         HashtableOfPackage knownPackages;
32         static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
33         static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, NotFound);
34
35         private INameEnvironment nameEnvironment;
36         private MethodVerifier verifier;
37         private ArrayBinding[][] uniqueArrayBindings;
38
39         private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
40         private int lastUnitIndex = -1;
41         private int lastCompletedUnitIndex = -1;
42         public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
43
44         // indicate in which step on the compilation we are.
45         // step 1 : build the reference binding
46         // step 2 : conect the hierarchy (connect bindings)
47         // step 3 : build fields and method bindings.
48         private int stepCompleted;
49         final static int BUILD_TYPE_HIERARCHY = 1;
50         final static int CHECK_AND_SET_IMPORTS = 2;
51         final static int CONNECT_TYPE_HIERARCHY = 3;
52         final static int BUILD_FIELDS_AND_METHODS = 4;
53
54         // shared byte[]'s used by ClassFile to avoid allocating MBs during a build
55         public boolean sharedArraysUsed = true; // set to false once actual arrays are allocated
56         public byte[] sharedClassFileHeader = null;
57         public byte[] sharedClassFileContents = null;
58
59 public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions options, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
60         this.typeRequestor = typeRequestor;
61         this.options = options;
62         this.problemReporter = problemReporter;
63         this.defaultPackage = new PackageBinding(this); // assume the default package always exists
64         this.defaultImports = null;
65         this.nameEnvironment = nameEnvironment;
66         this.knownPackages = new HashtableOfPackage();
67         this.uniqueArrayBindings = new ArrayBinding[5][];
68         this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
69 }
70 /* Ask the oracle for a type which corresponds to the compoundName.
71 * Answer null if the name cannot be found.
72 */
73
74 public ReferenceBinding askForType(char[][] compoundName) {
75         NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName);
76         if (answer == null)
77                 return null;
78
79         if (answer.isBinaryType())
80                 // the type was found as a .class file
81                 typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName));
82         else if (answer.isCompilationUnit())
83                 // the type was found as a .java file, try to build it then search the cache
84                 typeRequestor.accept(answer.getCompilationUnit());
85         else if (answer.isSourceType())
86                 // the type was found as a source model
87                 typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName));
88
89         return getCachedType(compoundName);
90 }
91 /* Ask the oracle for a type named name in the packageBinding.
92 * Answer null if the name cannot be found.
93 */
94
95 ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
96         if (packageBinding == null) {
97                 if (defaultPackage == null)
98                         return null;
99                 packageBinding = defaultPackage;
100         }
101         NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName);
102         if (answer == null)
103                 return null;
104
105         if (answer.isBinaryType())
106                 // the type was found as a .class file
107                 typeRequestor.accept(answer.getBinaryType(), packageBinding);
108         else if (answer.isCompilationUnit())
109                 // the type was found as a .java file, try to build it then search the cache
110                 typeRequestor.accept(answer.getCompilationUnit());
111         else if (answer.isSourceType())
112                 // the type was found as a source model
113                 typeRequestor.accept(answer.getSourceTypes(), packageBinding);
114
115         return packageBinding.getType0(name);
116 }
117 /* Create the initial type bindings for the compilation unit.
118 *
119 * See completeTypeBindings() for a description of the remaining steps
120 *
121 * NOTE: This method can be called multiple times as additional source files are needed
122 */
123
124 public void buildTypeBindings(CompilationUnitDeclaration unit) {
125         CompilationUnitScope scope = new CompilationUnitScope(unit, this);
126         scope.buildTypeBindings();
127
128         int unitsLength = units.length;
129         if (++lastUnitIndex >= unitsLength)
130                 System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
131         units[lastUnitIndex] = unit;
132 }
133 /* Cache the binary type since we know it is needed during this compile.
134 *
135 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
136 */
137
138 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType) {
139         return cacheBinaryType(binaryType, true);
140 }
141 /* Cache the binary type since we know it is needed during this compile.
142 *
143 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
144 */
145
146 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods) {
147         char[][] compoundName = CharOperation.splitOn('/', binaryType.getName());
148         ReferenceBinding existingType = getCachedType(compoundName);
149
150         if (existingType == null || existingType instanceof UnresolvedReferenceBinding)
151                 // only add the binary type if its not already in the cache
152                 return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods);
153         return null; // the type already exists & can be retrieved from the cache
154 }
155 /*
156 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
157 * 2. Create the field bindings
158 * 3. Create the method bindings
159 */
160
161 /* We know each known compilationUnit is free of errors at this point...
162 *
163 * Each step will create additional bindings unless a problem is detected, in which
164 * case either the faulty import/superinterface/field/method will be skipped or a
165 * suitable replacement will be substituted (such as Object for a missing superclass)
166 */
167
168 public void completeTypeBindings() {
169         stepCompleted = BUILD_TYPE_HIERARCHY;
170         
171         for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
172             (this.unitBeingCompleted = this.units[i]).scope.checkAndSetImports();
173         }
174         stepCompleted = CHECK_AND_SET_IMPORTS;
175
176         for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
177             (this.unitBeingCompleted = this.units[i]).scope.connectTypeHierarchy();
178         }
179         stepCompleted = CONNECT_TYPE_HIERARCHY;
180
181         for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
182                 (this.unitBeingCompleted = this.units[i]).scope.buildFieldsAndMethods();
183                 this.units[i] = null; // release unnecessary reference to the parsed unit
184         }
185         stepCompleted = BUILD_FIELDS_AND_METHODS;
186         this.lastCompletedUnitIndex = this.lastUnitIndex;
187         this.unitBeingCompleted = null;
188 }
189 /*
190 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
191 * 2. Create the field bindings
192 * 3. Create the method bindings
193 */
194
195 /*
196 * Each step will create additional bindings unless a problem is detected, in which
197 * case either the faulty import/superinterface/field/method will be skipped or a
198 * suitable replacement will be substituted (such as Object for a missing superclass)
199 */
200
201 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
202         if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
203                 // This can only happen because the original set of units are completely built and
204                 // are now being processed, so we want to treat all the additional units as a group
205                 // until they too are completely processed.
206                 completeTypeBindings();
207         } else {
208                 if (parsedUnit.scope == null) return; // parsing errors were too severe
209                 
210                 if (stepCompleted >= CHECK_AND_SET_IMPORTS)
211                         (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
212
213                 if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
214                         (this.unitBeingCompleted = parsedUnit).scope.connectTypeHierarchy();
215                 
216                 this.unitBeingCompleted = null;
217         }
218 }
219 /*
220 * Used by other compiler tools which do not start by calling completeTypeBindings().
221 *
222 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
223 * 2. Create the field bindings
224 * 3. Create the method bindings
225 */
226
227 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) {
228         if (parsedUnit.scope == null) return; // parsing errors were too severe
229
230         (this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
231         parsedUnit.scope.connectTypeHierarchy();
232         if (buildFieldsAndMethods)
233                 parsedUnit.scope.buildFieldsAndMethods();
234         this.unitBeingCompleted = null;
235 }
236 private PackageBinding computePackageFrom(char[][] constantPoolName) {
237         if (constantPoolName.length == 1)
238                 return defaultPackage;
239
240         PackageBinding packageBinding = getPackage0(constantPoolName[0]);
241         if (packageBinding == null || packageBinding == TheNotFoundPackage) {
242                 packageBinding = new PackageBinding(constantPoolName[0], this);
243                 knownPackages.put(constantPoolName[0], packageBinding);
244         }
245
246         for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
247                 PackageBinding parent = packageBinding;
248                 if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) {
249                         packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this);
250                         parent.addPackage(packageBinding);
251                 }
252         }
253         return packageBinding;
254 }
255 /* Used to guarantee array type identity.
256 */
257
258 ArrayBinding createArrayType(TypeBinding type, int dimensionCount) {
259         if (type instanceof LocalTypeBinding) // cache local type arrays with the local type itself
260                 return ((LocalTypeBinding) type).createArrayType(dimensionCount);
261
262         // find the array binding cache for this dimension
263         int dimIndex = dimensionCount - 1;
264         int length = uniqueArrayBindings.length;
265         ArrayBinding[] arrayBindings;
266         if (dimIndex < length) {
267                 if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
268                         uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
269         } else {
270                 System.arraycopy(
271                         uniqueArrayBindings, 0, 
272                         uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0, 
273                         length); 
274                 uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
275         }
276
277         // find the cached array binding for this leaf component type (if any)
278         int index = -1;
279         length = arrayBindings.length;
280         while (++index < length) {
281                 ArrayBinding currentBinding = arrayBindings[index];
282                 if (currentBinding == null) // no matching array, but space left
283                         return arrayBindings[index] = new ArrayBinding(type, dimensionCount);
284                 if (currentBinding.leafComponentType == type)
285                         return currentBinding;
286         }
287
288         // no matching array, no space left
289         System.arraycopy(
290                 arrayBindings, 0,
291                 (arrayBindings = new ArrayBinding[length * 2]), 0,
292                 length); 
293         uniqueArrayBindings[dimIndex] = arrayBindings;
294         return arrayBindings[length] = new ArrayBinding(type, dimensionCount);
295 }
296 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding) {
297         return createBinaryTypeFrom(binaryType, packageBinding, true);
298 }
299 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods) {
300         BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this);
301
302         // resolve any array bindings which reference the unresolvedType
303         ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
304         if (cachedType != null) {
305                 if (cachedType.isBinaryBinding()) // sanity check before the cast... at this point the cache should ONLY contain unresolved types
306                         return (BinaryTypeBinding) cachedType;
307
308                 UnresolvedReferenceBinding unresolvedType = (UnresolvedReferenceBinding) cachedType;
309                 unresolvedType.resolvedType = binaryBinding;
310                 updateArrayCache(unresolvedType, binaryBinding);
311         }
312
313         packageBinding.addType(binaryBinding);
314         binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
315         return binaryBinding;
316 }
317 /* Used to create packages from the package statement.
318 */
319
320 PackageBinding createPackage(char[][] compoundName) {
321         PackageBinding packageBinding = getPackage0(compoundName[0]);
322         if (packageBinding == null || packageBinding == TheNotFoundPackage) {
323                 packageBinding = new PackageBinding(compoundName[0], this);
324                 knownPackages.put(compoundName[0], packageBinding);
325         }
326
327         for (int i = 1, length = compoundName.length; i < length; i++) {
328                 // check to see if it collides with a known type...
329                 // this case can only happen if the package does not exist as a directory in the file system
330                 // otherwise when the source type was defined, the correct error would have been reported
331                 // unless its an unresolved type which is referenced from an inconsistent class file
332                 ReferenceBinding type = packageBinding.getType0(compoundName[i]);
333                 if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding))
334                         return null;
335
336                 PackageBinding parent = packageBinding;
337                 if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) {
338                         // if the package is unknown, check to see if a type exists which would collide with the new package
339                         // catches the case of a package statement of: package java.lang.Object;
340                         // since the package can be added after a set of source files have already been compiled, we need
341                         // whenever a package statement is encountered
342                         if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null)
343                                 return null;
344
345                         packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this);
346                         parent.addPackage(packageBinding);
347                 }
348         }
349         return packageBinding;
350 }
351 /* Answer the type for the compoundName if it exists in the cache.
352 * Answer theNotFoundType if it could not be resolved the first time
353 * it was looked up, otherwise answer null.
354 *
355 * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
356 * assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
357 */
358
359 public ReferenceBinding getCachedType(char[][] compoundName) {
360         if (compoundName.length == 1) {
361                 if (defaultPackage == null)
362                         return null;
363                 return defaultPackage.getType0(compoundName[0]);
364         }
365
366         PackageBinding packageBinding = getPackage0(compoundName[0]);
367         if (packageBinding == null || packageBinding == TheNotFoundPackage)
368                 return null;
369
370         for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
371                 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage)
372                         return null;
373         return packageBinding.getType0(compoundName[compoundName.length - 1]);
374 }
375 /* Answer the top level package named name if it exists in the cache.
376 * Answer theNotFoundPackage if it could not be resolved the first time
377 * it was looked up, otherwise answer null.
378 *
379 * NOTE: Senders must convert theNotFoundPackage into a real problem
380 * package if its to returned.
381 */
382
383 PackageBinding getPackage0(char[] name) {
384         return knownPackages.get(name);
385 }
386 /* Answer the top level package named name.
387 * Ask the oracle for the package if its not in the cache.
388 * Answer null if the package cannot be found.
389 */
390
391 PackageBinding getTopLevelPackage(char[] name) {
392         PackageBinding packageBinding = getPackage0(name);
393         if (packageBinding != null) {
394                 if (packageBinding == TheNotFoundPackage)
395                         return null;
396                 return packageBinding;
397         }
398
399         if (nameEnvironment.isPackage(null, name)) {
400                 knownPackages.put(name, packageBinding = new PackageBinding(name, this));
401                 return packageBinding;
402         }
403
404         knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
405         return null;
406 }
407 /* Answer the type corresponding to the compoundName.
408 * Ask the oracle for the type if its not in the cache.
409 * Answer null if the type cannot be found... likely a fatal error.
410 */
411
412 public ReferenceBinding getType(char[][] compoundName) {
413         ReferenceBinding referenceBinding;
414
415         if (compoundName.length == 1) {
416                 if (defaultPackage == null)
417                         return null;
418
419                 if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) {
420                         PackageBinding packageBinding = getPackage0(compoundName[0]);
421                         if (packageBinding != null && packageBinding != TheNotFoundPackage)
422                                 return null; // collides with a known package... should not call this method in such a case
423                         referenceBinding = askForType(defaultPackage, compoundName[0]);
424                 }
425         } else {
426                 PackageBinding packageBinding = getPackage0(compoundName[0]);
427                 if (packageBinding == TheNotFoundPackage)
428                         return null;
429
430                 if (packageBinding != null) {
431                         for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
432                                 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null)
433                                         break;
434                                 if (packageBinding == TheNotFoundPackage)
435                                         return null;
436                         }
437                 }
438
439                 if (packageBinding == null)
440                         referenceBinding = askForType(compoundName);
441                 else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null)
442                         referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]);
443         }
444
445         if (referenceBinding == null || referenceBinding == TheNotFoundType)
446                 return null;
447         if (referenceBinding instanceof UnresolvedReferenceBinding)
448                 referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this);
449
450         // compoundName refers to a nested type incorrectly (for example, package1.A$B)
451         if (referenceBinding.isNestedType())
452                 return new ProblemReferenceBinding(compoundName, InternalNameProvided);
453         return referenceBinding;
454 }
455 /* Answer the type corresponding to the name from the binary file.
456 * Does not ask the oracle for the type if its not found in the cache... instead an
457 * unresolved type is returned which must be resolved before used.
458 *
459 * NOTE: Does NOT answer base types nor array types!
460 *
461 * NOTE: Aborts compilation if the class file cannot be found.
462 */
463
464 ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end) {
465         if (end == -1)
466                 end = signature.length;
467
468         char[][] compoundName = CharOperation.splitOn('/', signature, start, end);
469         ReferenceBinding binding = getCachedType(compoundName);
470         if (binding == null) {
471                 PackageBinding packageBinding = computePackageFrom(compoundName);
472                 binding = new UnresolvedReferenceBinding(compoundName, packageBinding);
473                 packageBinding.addType(binding);
474         } else if (binding == TheNotFoundType) {
475                 problemReporter.isClassPathCorrect(compoundName, null);
476                 return null; // will not get here since the above error aborts the compilation
477         }
478         return binding;
479 }
480 /* Answer the type corresponding to the signature from the binary file.
481 * Does not ask the oracle for the type if its not found in the cache... instead an
482 * unresolved type is returned which must be resolved before used.
483 *
484 * NOTE: Does answer base types & array types.
485 *
486 * NOTE: Aborts compilation if the class file cannot be found.
487 */
488
489 TypeBinding getTypeFromSignature(char[] signature, int start, int end) {
490         int dimension = 0;
491         while (signature[start] == '[') {
492                 start++;
493                 dimension++;
494         }
495         if (end == -1)
496                 end = signature.length - 1;
497
498         // Just switch on signature[start] - the L case is the else
499         TypeBinding binding = null;
500         if (start == end) {
501                 switch (signature[start]) {
502                         case 'I' :
503                                 binding = IntBinding;
504                                 break;
505                         case 'Z' :
506                                 binding = BooleanBinding;
507                                 break;
508                         case 'V' :
509                                 binding = VoidBinding;
510                                 break;
511                         case 'C' :
512                                 binding = CharBinding;
513                                 break;
514                         case 'D' :
515                                 binding = DoubleBinding;
516                                 break;
517                         case 'B' :
518                                 binding = ByteBinding;
519                                 break;
520                         case 'F' :
521                                 binding = FloatBinding;
522                                 break;
523                         case 'J' :
524                                 binding = LongBinding;
525                                 break;
526                         case 'S' :
527                                 binding = ShortBinding;
528                                 break;
529                         default :
530                                 throw new Error(Util.bind("error.undefinedBaseType",String.valueOf(signature[start]))); //$NON-NLS-1$
531                 }
532         } else {
533                 binding = getTypeFromConstantPoolName(signature, start + 1, end);
534         }
535
536         if (dimension == 0)
537                 return binding;
538         return createArrayType(binding, dimension);
539 }
540 /* Ask the oracle if a package exists named name in the package named compoundName.
541 */
542
543 boolean isPackage(char[][] compoundName, char[] name) {
544         if (compoundName == null || compoundName.length == 0)
545                 return nameEnvironment.isPackage(null, name);
546         return nameEnvironment.isPackage(compoundName, name);
547 }
548 // The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
549
550 public MethodVerifier methodVerifier() {
551         if (verifier == null)
552                 verifier = new MethodVerifier(this);
553         return verifier;
554 }
555 public void reset() {
556         this.defaultPackage = new PackageBinding(this); // assume the default package always exists
557         this.defaultImports = null;
558         this.knownPackages = new HashtableOfPackage();
559
560         this.verifier = null;
561         for (int i = this.uniqueArrayBindings.length; --i >= 0;)
562                 this.uniqueArrayBindings[i] = null;
563         this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
564
565         for (int i = this.units.length; --i >= 0;)
566                 this.units[i] = null;
567         this.lastUnitIndex = -1;
568         this.lastCompletedUnitIndex = -1;
569         this.unitBeingCompleted = null; // in case AbortException occurred
570         
571         // name environment has a longer life cycle, and must be reset in
572         // the code which created it.
573 }
574 void updateArrayCache(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
575         nextDimension : for (int i = 0, length = uniqueArrayBindings.length; i < length; i++) {
576                 ArrayBinding[] arrayBindings = uniqueArrayBindings[i];
577                 if (arrayBindings != null) {
578                         for (int j = 0, max = arrayBindings.length; j < max; j++) {
579                                 ArrayBinding currentBinding = arrayBindings[j];
580                                 if (currentBinding == null)
581                                         continue nextDimension;
582                                 if (currentBinding.leafComponentType == unresolvedType) {
583                                         currentBinding.leafComponentType = resolvedType;
584                                         continue nextDimension;
585                                 }
586                         }
587                 }
588         }
589 }
590 }