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
 
   9  *     IBM Corporation - initial API and implementation
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpdt.internal.compiler.lookup;
 
  13 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  14 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
 
  15 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
 
  16 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
 
  17 import net.sourceforge.phpdt.internal.compiler.impl.ITypeRequestor;
 
  18 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  19 import net.sourceforge.phpdt.internal.compiler.util.HashtableOfPackage;
 
  20 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  21 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
 
  23 public class LookupEnvironment implements BaseTypes, ProblemReasons, TypeConstants {
 
  24 //      public CompilerOptions options;
 
  25         public ProblemReporter problemReporter;
 
  26         public ITypeRequestor typeRequestor;
 
  28         PackageBinding defaultPackage;
 
  29         ImportBinding[] defaultImports;
 
  30         HashtableOfPackage knownPackages;
 
  31         static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
 
  32         static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, NotFound);
 
  34         private INameEnvironment nameEnvironment;
 
  35         private MethodVerifier verifier;
 
  36         private ArrayBinding[][] uniqueArrayBindings;
 
  38         private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
 
  39         private int lastUnitIndex = -1;
 
  40         private int lastCompletedUnitIndex = -1;
 
  42         // indicate in which step on the compilation we are.
 
  43         // step 1 : build the reference binding
 
  44         // step 2 : conect the hierarchy (connect bindings)
 
  45         // step 3 : build fields and method bindings.
 
  46         private int stepCompleted;
 
  47         final static int BUILD_TYPE_HIERARCHY = 1;
 
  48         final static int CHECK_AND_SET_IMPORTS = 2;
 
  49         final static int CONNECT_TYPE_HIERARCHY = 3;
 
  50         final static int BUILD_FIELDS_AND_METHODS = 4;
 
  51 public LookupEnvironment(ITypeRequestor typeRequestor,ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
 
  52 // CompilerOptions options, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
 
  53         this.typeRequestor = typeRequestor;
 
  54 //      this.options = options;
 
  55         this.problemReporter = problemReporter;
 
  56         this.defaultPackage = new PackageBinding(this); // assume the default package always exists
 
  57         this.defaultImports = null;
 
  58         this.nameEnvironment = nameEnvironment;
 
  59         this.knownPackages = new HashtableOfPackage();
 
  60         this.uniqueArrayBindings = new ArrayBinding[5][];
 
  61         this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
 
  63 /* Ask the oracle for a type which corresponds to the compoundName.
 
  64 * Answer null if the name cannot be found.
 
  67 public ReferenceBinding askForType(char[][] compoundName) {
 
  68         NameEnvironmentAnswer answer = nameEnvironment.findType(compoundName);
 
  72         if (answer.isBinaryType())
 
  73                 // the type was found as a .class file
 
  74                 typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName));
 
  75         else if (answer.isCompilationUnit())
 
  76                 // the type was found as a .java file, try to build it then search the cache
 
  77                 typeRequestor.accept(answer.getCompilationUnit());
 
  78         else if (answer.isSourceType())
 
  79                 // the type was found as a source model
 
  80                 typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName));
 
  82         return getCachedType(compoundName);
 
  84 /* Ask the oracle for a type named name in the packageBinding.
 
  85 * Answer null if the name cannot be found.
 
  88 ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
 
  89         if (packageBinding == null) {
 
  90                 if (defaultPackage == null)
 
  92                 packageBinding = defaultPackage;
 
  94         NameEnvironmentAnswer answer = nameEnvironment.findType(name, packageBinding.compoundName);
 
  98         if (answer.isBinaryType())
 
  99                 // the type was found as a .class file
 
 100                 typeRequestor.accept(answer.getBinaryType(), packageBinding);
 
 101         else if (answer.isCompilationUnit())
 
 102                 // the type was found as a .java file, try to build it then search the cache
 
 103                 typeRequestor.accept(answer.getCompilationUnit());
 
 104         else if (answer.isSourceType())
 
 105                 // the type was found as a source model
 
 106                 typeRequestor.accept(answer.getSourceTypes(), packageBinding);
 
 108         return packageBinding.getType0(name);
 
 110 /* Create the initial type bindings for the compilation unit.
 
 112 * See completeTypeBindings() for a description of the remaining steps
 
 114 * NOTE: This method can be called multiple times as additional source files are needed
 
 117 public void buildTypeBindings(CompilationUnitDeclaration unit) {
 
 118         CompilationUnitScope scope = new CompilationUnitScope(unit, this);
 
 119         scope.buildTypeBindings();
 
 121         int unitsLength = units.length;
 
 122         if (++lastUnitIndex >= unitsLength)
 
 123                 System.arraycopy(units, 0, units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
 
 124         units[lastUnitIndex] = unit;
 
 126 /* Cache the binary type since we know it is needed during this compile.
 
 128 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
 
 131 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType) {
 
 132         return cacheBinaryType(binaryType, true);
 
 134 /* Cache the binary type since we know it is needed during this compile.
 
 136 * Answer the created BinaryTypeBinding or null if the type is already in the cache.
 
 139 public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods) {
 
 140         char[][] compoundName = CharOperation.splitOn('/', binaryType.getName());
 
 141         ReferenceBinding existingType = getCachedType(compoundName);
 
 143         if (existingType == null || existingType instanceof UnresolvedReferenceBinding)
 
 144                 // only add the binary type if its not already in the cache
 
 145                 return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName), needFieldsAndMethods);
 
 146         return null; // the type already exists & can be retrieved from the cache
 
 149 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
 
 150 * 2. Create the field bindings
 
 151 * 3. Create the method bindings
 
 154 /* We know each known compilationUnit is free of errors at this point...
 
 156 * Each step will create additional bindings unless a problem is detected, in which
 
 157 * case either the faulty import/superinterface/field/method will be skipped or a
 
 158 * suitable replacement will be substituted (such as Object for a missing superclass)
 
 161 public void completeTypeBindings() {
 
 162         stepCompleted = BUILD_TYPE_HIERARCHY;
 
 164 //      for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
 
 165 //              units[i].scope.checkAndSetImports();
 
 167         stepCompleted = CHECK_AND_SET_IMPORTS;
 
 169 //      for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
 
 170 //              units[i].scope.connectTypeHierarchy();
 
 172         stepCompleted = CONNECT_TYPE_HIERARCHY;
 
 174         for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
 
 175 //              units[i].scope.buildFieldsAndMethods();
 
 176                 units[i] = null; // release unnecessary reference to the parsed unit
 
 178         stepCompleted = BUILD_FIELDS_AND_METHODS;
 
 179         lastCompletedUnitIndex = lastUnitIndex;
 
 182 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
 
 183 * 2. Create the field bindings
 
 184 * 3. Create the method bindings
 
 188 * Each step will create additional bindings unless a problem is detected, in which
 
 189 * case either the faulty import/superinterface/field/method will be skipped or a
 
 190 * suitable replacement will be substituted (such as Object for a missing superclass)
 
 193 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
 
 194         if (stepCompleted == BUILD_FIELDS_AND_METHODS) {
 
 195                 // This can only happen because the original set of units are completely built and
 
 196                 // are now being processed, so we want to treat all the additional units as a group
 
 197                 // until they too are completely processed.
 
 198                 completeTypeBindings();
 
 200                 if (parsedUnit.scope == null) return; // parsing errors were too severe
 
 202 //              if (stepCompleted >= CHECK_AND_SET_IMPORTS)
 
 203 //                      parsedUnit.scope.checkAndSetImports();
 
 205                 if (stepCompleted >= CONNECT_TYPE_HIERARCHY)
 
 206                         parsedUnit.scope.connectTypeHierarchy();
 
 210 * Used by other compiler tools which do not start by calling completeTypeBindings().
 
 212 * 1. Connect the type hierarchy for the type bindings created for parsedUnits.
 
 213 * 2. Create the field bindings
 
 214 * 3. Create the method bindings
 
 217 public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) {
 
 218         if (parsedUnit.scope == null) return; // parsing errors were too severe
 
 220         parsedUnit.scope.checkAndSetImports();
 
 221         parsedUnit.scope.connectTypeHierarchy();
 
 223         if (buildFieldsAndMethods)
 
 224                 parsedUnit.scope.buildFieldsAndMethods();
 
 227 private PackageBinding computePackageFrom(char[][] constantPoolName) {
 
 228         if (constantPoolName.length == 1)
 
 229                 return defaultPackage;
 
 231         PackageBinding packageBinding = getPackage0(constantPoolName[0]);
 
 232         if (packageBinding == null || packageBinding == TheNotFoundPackage) {
 
 233                 packageBinding = new PackageBinding(constantPoolName[0], this);
 
 234                 knownPackages.put(constantPoolName[0], packageBinding);
 
 237         for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
 
 238                 PackageBinding parent = packageBinding;
 
 239                 if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) {
 
 240                         packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this);
 
 241                         parent.addPackage(packageBinding);
 
 244         return packageBinding;
 
 246 /* Used to guarantee array type identity.
 
 249 ArrayBinding createArrayType(TypeBinding type, int dimensionCount) {
 
 250         if (type instanceof LocalTypeBinding) // cache local type arrays with the local type itself
 
 251                 return ((LocalTypeBinding) type).createArrayType(dimensionCount);
 
 253         // find the array binding cache for this dimension
 
 254         int dimIndex = dimensionCount - 1;
 
 255         int length = uniqueArrayBindings.length;
 
 256         ArrayBinding[] arrayBindings;
 
 257         if (dimIndex < length) {
 
 258                 if ((arrayBindings = uniqueArrayBindings[dimIndex]) == null)
 
 259                         uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
 
 262                         uniqueArrayBindings, 0, 
 
 263                         uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0, 
 
 265                 uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
 
 268         // find the cached array binding for this leaf component type (if any)
 
 270         length = arrayBindings.length;
 
 271         while (++index < length) {
 
 272                 ArrayBinding currentBinding = arrayBindings[index];
 
 273                 if (currentBinding == null) // no matching array, but space left
 
 274                         return arrayBindings[index] = new ArrayBinding(type, dimensionCount);
 
 275                 if (currentBinding.leafComponentType == type)
 
 276                         return currentBinding;
 
 279         // no matching array, no space left
 
 282                 (arrayBindings = new ArrayBinding[length * 2]), 0,
 
 284         uniqueArrayBindings[dimIndex] = arrayBindings;
 
 285         return arrayBindings[length] = new ArrayBinding(type, dimensionCount);
 
 287 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding) {
 
 288         return createBinaryTypeFrom(binaryType, packageBinding, true);
 
 290 public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods) {
 
 291         BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this);
 
 293         // resolve any array bindings which reference the unresolvedType
 
 294         ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
 
 295         if (cachedType != null) {
 
 296                 if (cachedType.isBinaryBinding()) // sanity check before the cast... at this point the cache should ONLY contain unresolved types
 
 297                         return (BinaryTypeBinding) cachedType;
 
 299                 UnresolvedReferenceBinding unresolvedType = (UnresolvedReferenceBinding) cachedType;
 
 300                 unresolvedType.resolvedType = binaryBinding;
 
 301                 updateArrayCache(unresolvedType, binaryBinding);
 
 304         packageBinding.addType(binaryBinding);
 
 305         binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
 
 306         return binaryBinding;
 
 308 /* Used to create packages from the package statement.
 
 311 PackageBinding createPackage(char[][] compoundName) {
 
 313 //      PackageBinding packageBinding = getPackage0(compoundName[0]);
 
 314 //      if (packageBinding == null || packageBinding == TheNotFoundPackage) {
 
 315 //              packageBinding = new PackageBinding(compoundName[0], this);
 
 316 //              knownPackages.put(compoundName[0], packageBinding);
 
 319 //      for (int i = 1, length = compoundName.length; i < length; i++) {
 
 320 //              // check to see if it collides with a known type...
 
 321 //              // this case can only happen if the package does not exist as a directory in the file system
 
 322 //              // otherwise when the source type was defined, the correct error would have been reported
 
 323 //              // unless its an unresolved type which is referenced from an inconsistent class file
 
 324 //              ReferenceBinding type = packageBinding.getType0(compoundName[i]);
 
 325 //              if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding))
 
 328 //              PackageBinding parent = packageBinding;
 
 329 //              if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) {
 
 330 //                      // if the package is unknown, check to see if a type exists which would collide with the new package
 
 331 //                      // catches the case of a package statement of: package java.lang.Object;
 
 332 //                      // since the package can be added after a set of source files have already been compiled, we need
 
 333 //                      // whenever a package statement is encountered
 
 334 //                      if (nameEnvironment.findType(compoundName[i], parent.compoundName) != null)
 
 337 //                      packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this);
 
 338 //                      parent.addPackage(packageBinding);
 
 341 //      return packageBinding;
 
 343 /* Answer the type for the compoundName if it exists in the cache.
 
 344 * Answer theNotFoundType if it could not be resolved the first time
 
 345 * it was looked up, otherwise answer null.
 
 347 * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
 
 348 * assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
 
 351 public ReferenceBinding getCachedType(char[][] compoundName) {
 
 352         if (compoundName.length == 1) {
 
 353                 if (defaultPackage == null)
 
 355                 return defaultPackage.getType0(compoundName[0]);
 
 358         PackageBinding packageBinding = getPackage0(compoundName[0]);
 
 359         if (packageBinding == null || packageBinding == TheNotFoundPackage)
 
 362         for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
 
 363                 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage)
 
 365         return packageBinding.getType0(compoundName[compoundName.length - 1]);
 
 367 /* Answer the top level package named name if it exists in the cache.
 
 368 * Answer theNotFoundPackage if it could not be resolved the first time
 
 369 * it was looked up, otherwise answer null.
 
 371 * NOTE: Senders must convert theNotFoundPackage into a real problem
 
 372 * package if its to returned.
 
 375 PackageBinding getPackage0(char[] name) {
 
 376         return knownPackages.get(name);
 
 378 /* Answer the top level package named name.
 
 379 * Ask the oracle for the package if its not in the cache.
 
 380 * Answer null if the package cannot be found.
 
 383 PackageBinding getTopLevelPackage(char[] name) {
 
 384         PackageBinding packageBinding = getPackage0(name);
 
 385         if (packageBinding != null) {
 
 386                 if (packageBinding == TheNotFoundPackage)
 
 389                         return packageBinding;
 
 392         if (nameEnvironment.isPackage(null, name)) {
 
 393                 knownPackages.put(name, packageBinding = new PackageBinding(name, this));
 
 394                 return packageBinding;
 
 397         knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
 
 400 /* Answer the type corresponding to the compoundName.
 
 401 * Ask the oracle for the type if its not in the cache.
 
 402 * Answer null if the type cannot be found... likely a fatal error.
 
 405 public ReferenceBinding getType(char[][] compoundName) {
 
 406         ReferenceBinding referenceBinding;
 
 408         if (compoundName.length == 1) {
 
 409                 if (defaultPackage == null)
 
 412                 if ((referenceBinding = defaultPackage.getType0(compoundName[0])) == null) {
 
 413                         PackageBinding packageBinding = getPackage0(compoundName[0]);
 
 414                         if (packageBinding != null && packageBinding != TheNotFoundPackage)
 
 415                                 return null; // collides with a known package... should not call this method in such a case
 
 416                         referenceBinding = askForType(defaultPackage, compoundName[0]);
 
 419                 PackageBinding packageBinding = getPackage0(compoundName[0]);
 
 420                 if (packageBinding == TheNotFoundPackage)
 
 423                 if (packageBinding != null) {
 
 424                         for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
 
 425                                 if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null)
 
 427                                 if (packageBinding == TheNotFoundPackage)
 
 432                 if (packageBinding == null)
 
 433                         referenceBinding = askForType(compoundName);
 
 434                 else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null)
 
 435                         referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]);
 
 438         if (referenceBinding == null || referenceBinding == TheNotFoundType)
 
 440         if (referenceBinding instanceof UnresolvedReferenceBinding)
 
 441                 referenceBinding = ((UnresolvedReferenceBinding) referenceBinding).resolve(this);
 
 443         // compoundName refers to a nested type incorrectly (for example, package1.A$B)
 
 444         if (referenceBinding.isNestedType())
 
 445                 return new ProblemReferenceBinding(compoundName, InternalNameProvided);
 
 447                 return referenceBinding;
 
 449 /* Answer the type corresponding to the name from the binary file.
 
 450 * Does not ask the oracle for the type if its not found in the cache... instead an
 
 451 * unresolved type is returned which must be resolved before used.
 
 453 * NOTE: Does NOT answer base types nor array types!
 
 455 * NOTE: Aborts compilation if the class file cannot be found.
 
 458 ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end) {
 
 460                 end = signature.length;
 
 462         char[][] compoundName = CharOperation.splitOn('/', signature, start, end);
 
 463         ReferenceBinding binding = getCachedType(compoundName);
 
 464         if (binding == null) {
 
 465                 PackageBinding packageBinding = computePackageFrom(compoundName);
 
 466                 binding = new UnresolvedReferenceBinding(compoundName, packageBinding);
 
 467                 packageBinding.addType(binding);
 
 468         } else if (binding == TheNotFoundType) {
 
 469                 problemReporter.isClassPathCorrect(compoundName, null);
 
 470                 return null; // will not get here since the above error aborts the compilation
 
 474 /* Answer the type corresponding to the signature from the binary file.
 
 475 * Does not ask the oracle for the type if its not found in the cache... instead an
 
 476 * unresolved type is returned which must be resolved before used.
 
 478 * NOTE: Does answer base types & array types.
 
 480 * NOTE: Aborts compilation if the class file cannot be found.
 
 483 TypeBinding getTypeFromSignature(char[] signature, int start, int end) {
 
 485         while (signature[start] == '[') {
 
 490                 end = signature.length - 1;
 
 492         // Just switch on signature[start] - the L case is the else
 
 493         TypeBinding binding = null;
 
 495                 switch (signature[start]) {
 
 497                                 binding = IntBinding;
 
 500                                 binding = BooleanBinding;
 
 503                                 binding = VoidBinding;
 
 506                                 binding = CharBinding;
 
 509                                 binding = DoubleBinding;
 
 512                                 binding = ByteBinding;
 
 515                                 binding = FloatBinding;
 
 518                                 binding = LongBinding;
 
 521                                 binding = ShortBinding;
 
 524                                 throw new Error(Util.bind("error.undefinedBaseType",String.valueOf(signature[start]))); //$NON-NLS-1$
 
 527                 binding = getTypeFromConstantPoolName(signature, start + 1, end);
 
 533                 return createArrayType(binding, dimension);
 
 535 /* Ask the oracle if a package exists named name in the package named compoundName.
 
 538 boolean isPackage(char[][] compoundName, char[] name) {
 
 539         if (compoundName == null || compoundName.length == 0)
 
 540                 return nameEnvironment.isPackage(null, name);
 
 542                 return nameEnvironment.isPackage(compoundName, name);
 
 544 // The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
 
 546 public MethodVerifier methodVerifier() {
 
 547         if (verifier == null)
 
 548                 verifier = new MethodVerifier(this);
 
 551 public void reset() {
 
 552         this.defaultPackage = new PackageBinding(this); // assume the default package always exists
 
 553         this.defaultImports = null;
 
 554         this.knownPackages = new HashtableOfPackage();
 
 556         this.verifier = null;
 
 557         for (int i = this.uniqueArrayBindings.length; --i >= 0;)
 
 558                 this.uniqueArrayBindings[i] = null;
 
 559         this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
 
 561         for (int i = this.units.length; --i >= 0;)
 
 562                 this.units[i] = null;
 
 563         this.lastUnitIndex = -1;
 
 564         this.lastCompletedUnitIndex = -1;
 
 566         // name environment has a longer life cycle, and must be reset in
 
 567         // the code which created it.
 
 569 void updateArrayCache(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
 
 570         nextDimension : for (int i = 0, length = uniqueArrayBindings.length; i < length; i++) {
 
 571                 ArrayBinding[] arrayBindings = uniqueArrayBindings[i];
 
 572                 if (arrayBindings != null) {
 
 573                         for (int j = 0, max = arrayBindings.length; j < max; j++) {
 
 574                                 ArrayBinding currentBinding = arrayBindings[j];
 
 575                                 if (currentBinding == null)
 
 576                                         continue nextDimension;
 
 577                                 if (currentBinding.leafComponentType == unresolvedType) {
 
 578                                         currentBinding.leafComponentType = resolvedType;
 
 579                                         continue nextDimension;