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