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.core.builder;
 
  13 import java.io.DataInputStream;
 
  14 import java.io.DataOutputStream;
 
  15 import java.io.IOException;
 
  16 import java.util.Date;
 
  18 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
 
  20 import org.eclipse.core.resources.IProject;
 
  21 import org.eclipse.core.resources.IResource;
 
  22 import org.eclipse.core.resources.IResourceDelta;
 
  23 import org.eclipse.core.runtime.IPath;
 
  26   // NOTE: this state cannot contain types that are not defined in this project
 
  28   String javaProjectName;
 
  29   ClasspathMultiDirectory[] sourceLocations;
 
  30   //ClasspathLocation[] binaryLocations;
 
  31   // keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an
 
  32   // AdditionalTypeCollection
 
  33 //  SimpleLookupTable references;
 
  34   // keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
 
  35 //  SimpleLookupTable typeLocators;
 
  38   long lastStructuralBuildTime;
 
  39   SimpleLookupTable structuralBuildTimes;
 
  41   private String[] knownPackageNames; // of the form "p1/p2"
 
  43   static final byte VERSION = 0x0007;
 
  45   static final byte SOURCE_FOLDER = 1;
 
  46 //  static final byte BINARY_FOLDER = 2;
 
  47 //  static final byte EXTERNAL_JAR = 3;
 
  48 //  static final byte INTERNAL_JAR = 4;
 
  53   protected State(PHPBuilder javaBuilder) {
 
  54     this.knownPackageNames = null;
 
  55     this.javaProjectName = javaBuilder.currentProject.getName();
 
  56     this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
 
  57     //  this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
 
  58 //    this.references = new SimpleLookupTable(7);
 
  59 //    this.typeLocators = new SimpleLookupTable(7);
 
  61     this.buildNumber = 0; // indicates a full build
 
  62     this.lastStructuralBuildTime = System.currentTimeMillis();
 
  63     this.structuralBuildTimes = new SimpleLookupTable(3);
 
  66   void copyFrom(State lastState) {
 
  68       this.knownPackageNames = null;
 
  69       this.buildNumber = lastState.buildNumber + 1;
 
  70       this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
 
  71 //      this.references = (SimpleLookupTable) lastState.references.clone();
 
  72 //      this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone();
 
  73 //    } catch (CloneNotSupportedException e) {
 
  74 //      this.references = new SimpleLookupTable(lastState.references.elementSize);
 
  75 //      Object[] keyTable = lastState.references.keyTable;
 
  76 //      Object[] valueTable = lastState.references.valueTable;
 
  77 //      for (int i = 0, l = keyTable.length; i < l; i++)
 
  78 //        if (keyTable[i] != null)
 
  79 //          this.references.put(keyTable[i], valueTable[i]);
 
  81 //      this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize);
 
  82 //      keyTable = lastState.typeLocators.keyTable;
 
  83 //      valueTable = lastState.typeLocators.valueTable;
 
  84 //      for (int i = 0, l = keyTable.length; i < l; i++)
 
  85 //        if (keyTable[i] != null)
 
  86 //          this.typeLocators.put(keyTable[i], valueTable[i]);
 
  90 //  char[][] getDefinedTypeNamesFor(String typeLocator) {
 
  91 //    Object c = references.get(typeLocator);
 
  92 //    if (c instanceof AdditionalTypeCollection)
 
  93 //      return ((AdditionalTypeCollection) c).definedTypeNames;
 
  94 //    return null; // means only one type is defined with the same name as the file... saves space
 
  97 //  boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
 
  98 //    String existing = (String) typeLocators.get(qualifiedTypeName);
 
  99 //    return existing != null && !existing.equals(typeLocator);
 
 102 //  boolean isKnownPackage(String qualifiedPackageName) {
 
 103 //    if (knownPackageNames == null) {
 
 104 //      ArrayList names = new ArrayList(typeLocators.elementSize);
 
 105 //      Object[] keyTable = typeLocators.keyTable;
 
 106 //      for (int i = 0, l = keyTable.length; i < l; i++) {
 
 107 //        if (keyTable[i] != null) {
 
 108 //          String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A
 
 109 //          int last = packageName.lastIndexOf('/');
 
 110 //          packageName = last == -1 ? null : packageName.substring(0, last);
 
 111 //          while (packageName != null && !names.contains(packageName)) {
 
 112 //            names.add(packageName);
 
 113 //            last = packageName.lastIndexOf('/');
 
 114 //            packageName = last == -1 ? null : packageName.substring(0, last);
 
 118 //      knownPackageNames = new String[names.size()];
 
 119 //      names.toArray(knownPackageNames);
 
 121 //    for (int i = 0, l = knownPackageNames.length; i < l; i++)
 
 122 //      if (knownPackageNames[i].equals(qualifiedPackageName))
 
 127 //  void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) {
 
 128 //    if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) {
 
 129 //      references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs));
 
 131 //      char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined
 
 132 //      typeNames.toArray(definedTypeNames);
 
 133 //      references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs));
 
 137 //  void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
 
 138 //    this.knownPackageNames = null;
 
 139 //    typeLocators.put(qualifiedTypeName, typeLocator);
 
 142   void recordStructuralDependency(IProject prereqProject, State prereqState) {
 
 143     if (prereqState != null)
 
 144       structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
 
 147 //  void removeLocator(String typeLocatorToRemove) {
 
 148 //    this.knownPackageNames = null;
 
 149 //    references.removeKey(typeLocatorToRemove);
 
 150 //    typeLocators.removeValue(typeLocatorToRemove);
 
 153   void removePackage(IResourceDelta sourceDelta) {
 
 154     IResource resource = sourceDelta.getResource();
 
 155     switch (resource.getType()) {
 
 156       case IResource.FOLDER :
 
 157         IResourceDelta[] children = sourceDelta.getAffectedChildren();
 
 158         for (int i = 0, l = children.length; i < l; i++)
 
 159           removePackage(children[i]);
 
 161       case IResource.FILE :
 
 162         IPath typeLocatorPath = resource.getProjectRelativePath();
 
 163 //        if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
 
 164 //          removeLocator(typeLocatorPath.toString());
 
 168 //  void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
 
 169 //    this.knownPackageNames = null;
 
 170 //    typeLocators.removeKey(qualifiedTypeNameToRemove);
 
 173   static State read(IProject project, DataInputStream in) throws IOException {
 
 174     if (PHPBuilder.DEBUG)
 
 175       System.out.println("About to read state..."); //$NON-NLS-1$
 
 176     if (VERSION != in.readByte()) {
 
 177       if (PHPBuilder.DEBUG)
 
 178         System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$
 
 182     State newState = new State();
 
 183     newState.javaProjectName = in.readUTF();
 
 184     if (!project.getName().equals(newState.javaProjectName)) {
 
 185       if (PHPBuilder.DEBUG)
 
 186         System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$
 
 189     newState.buildNumber = in.readInt();
 
 190     newState.lastStructuralBuildTime = in.readLong();
 
 193 //    int length = in.readInt();
 
 194 //    newState.sourceLocations = new ClasspathMultiDirectory[0];
 
 195     //  newState.sourceLocations = new ClasspathMultiDirectory[length];
 
 196     //  for (int i = 0; i < length; i++) {
 
 197     //          IContainer sourceFolder = project, outputFolder = project;
 
 198     //          String folderName;
 
 199     //          if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
 
 200     //          if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
 
 201     //          ClasspathMultiDirectory md =
 
 202     //                  (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in));
 
 203     //          if (in.readBoolean())
 
 204     //                  md.hasIndependentOutputFolder = true;
 
 205     //          newState.sourceLocations[i] = md;
 
 208 //    length = in.readInt();
 
 209     //  newState.binaryLocations = new ClasspathLocation[length];
 
 210     //  IWorkspaceRoot root = project.getWorkspace().getRoot();
 
 211     //  for (int i = 0; i < length; i++) {
 
 212     //          switch (in.readByte()) {
 
 213     //                  case SOURCE_FOLDER :
 
 214     //                          newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
 
 216     //                  case BINARY_FOLDER :
 
 217     //                          IPath path = new Path(in.readUTF());
 
 218     //                          IContainer outputFolder = path.segmentCount() == 1
 
 219     //                                  ? (IContainer) root.getProject(path.toString())
 
 220     //                                  : (IContainer) root.getFolder(path);
 
 221     //                          newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean());
 
 223     //                  case EXTERNAL_JAR :
 
 224     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
 
 226     //                  case INTERNAL_JAR :
 
 227     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
 
 231     newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
 
 232     for (int i = 0; i < length; i++)
 
 233       newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong()));
 
 235 //    String[] internedTypeLocators = new String[length = in.readInt()];
 
 236 //    for (int i = 0; i < length; i++)
 
 237 //      internedTypeLocators[i] = in.readUTF();
 
 239 //    newState.typeLocators = new SimpleLookupTable(length = in.readInt());
 
 240 //    for (int i = 0; i < length; i++)
 
 241 //      newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]);
 
 243 //    char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false);
 
 244 //    char[][][] internedQualifiedNames = new char[length = in.readInt()][][];
 
 245 //    for (int i = 0; i < length; i++) {
 
 246 //      int qLength = in.readInt();
 
 247 //      char[][] qName = new char[qLength][];
 
 248 //      for (int j = 0; j < qLength; j++)
 
 249 //        qName[j] = internedSimpleNames[in.readInt()];
 
 250 //      internedQualifiedNames[i] = qName;
 
 252 //    internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
 
 254 //    newState.references = new SimpleLookupTable(length = in.readInt());
 
 255 //    for (int i = 0; i < length; i++) {
 
 256 //      String typeLocator = internedTypeLocators[in.readInt()];
 
 257 //      ReferenceCollection collection = null;
 
 258 //      switch (in.readByte()) {
 
 260 //          char[][] additionalTypeNames = readNames(in);
 
 261 //          char[][][] qualifiedNames = new char[in.readInt()][][];
 
 262 //          for (int j = 0, m = qualifiedNames.length; j < m; j++)
 
 263 //            qualifiedNames[j] = internedQualifiedNames[in.readInt()];
 
 264 //          char[][] simpleNames = new char[in.readInt()][];
 
 265 //          for (int j = 0, m = simpleNames.length; j < m; j++)
 
 266 //            simpleNames[j] = internedSimpleNames[in.readInt()];
 
 267 //          collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames);
 
 270 //          char[][][] qNames = new char[in.readInt()][][];
 
 271 //          for (int j = 0, m = qNames.length; j < m; j++)
 
 272 //            qNames[j] = internedQualifiedNames[in.readInt()];
 
 273 //          char[][] sNames = new char[in.readInt()][];
 
 274 //          for (int j = 0, m = sNames.length; j < m; j++)
 
 275 //            sNames[j] = internedSimpleNames[in.readInt()];
 
 276 //          collection = new ReferenceCollection(qNames, sNames);
 
 278 //      newState.references.put(typeLocator, collection);
 
 280     if (PHPBuilder.DEBUG)
 
 281       System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
 
 285   private static char[][] readNames(DataInputStream in) throws IOException {
 
 286     int length = in.readInt();
 
 287     char[][] names = new char[length][];
 
 288     for (int i = 0; i < length; i++) {
 
 289       int nLength = in.readInt();
 
 290       char[] name = new char[nLength];
 
 291       for (int j = 0; j < nLength; j++)
 
 292         name[j] = in.readChar();
 
 298   void tagAsNoopBuild() {
 
 299     this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
 
 302   boolean wasNoopBuild() {
 
 303     return buildNumber == -1;
 
 306   void tagAsStructurallyChanged() {
 
 307     this.lastStructuralBuildTime = System.currentTimeMillis();
 
 310   boolean wasStructurallyChanged(IProject prereqProject, State prereqState) {
 
 311     if (prereqState != null) {
 
 312       Object o = structuralBuildTimes.get(prereqProject.getName());
 
 313       long previous = o == null ? 0 : ((Long) o).longValue();
 
 314       if (previous == prereqState.lastStructuralBuildTime)
 
 320   void write(DataOutputStream out) throws IOException {
 
 326          * byte VERSION String project name int build number int last structural build number
 
 328     out.writeByte(VERSION);
 
 329     out.writeUTF(javaProjectName);
 
 330     out.writeInt(buildNumber);
 
 331     out.writeLong(lastStructuralBuildTime);
 
 334          * ClasspathMultiDirectory[] int id String path(s)
 
 336 //    out.writeInt(length = sourceLocations.length);
 
 337 //    for (int i = 0; i < length; i++) {
 
 338 //      ClasspathMultiDirectory md = sourceLocations[i];
 
 339 //      out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
 
 340 //      out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
 
 341 //      writeNames(md.exclusionPatterns, out);
 
 342 //      out.writeBoolean(md.hasIndependentOutputFolder);
 
 346          * ClasspathLocation[] int id String path(s)
 
 348     //  out.writeInt(length = binaryLocations.length);
 
 349     //  next : for (int i = 0; i < length; i++) {
 
 350     //          ClasspathLocation c = binaryLocations[i];
 
 351     //          if (c instanceof ClasspathMultiDirectory) {
 
 352     //                  out.writeByte(SOURCE_FOLDER);
 
 353     //                  for (int j = 0, m = sourceLocations.length; j < m; j++) {
 
 354     //                          if (sourceLocations[j] == c) {
 
 359     //          } else if (c instanceof ClasspathDirectory) {
 
 360     //                  out.writeByte(BINARY_FOLDER);
 
 361     //                  ClasspathDirectory cd = (ClasspathDirectory) c;
 
 362     //                  out.writeUTF(cd.binaryFolder.getFullPath().toString());
 
 363     //                  out.writeBoolean(cd.isOutputFolder);
 
 365     //                  ClasspathJar jar = (ClasspathJar) c;
 
 366     //                  if (jar.resource == null) {
 
 367     //                          out.writeByte(EXTERNAL_JAR);
 
 368     //                          out.writeUTF(jar.zipFilename);
 
 370     //                          out.writeByte(INTERNAL_JAR);
 
 371     //                          out.writeUTF(jar.resource.getFullPath().toString());
 
 377          * Structural build numbers table String prereq project name int last structural build number
 
 379     out.writeInt(length = structuralBuildTimes.elementSize);
 
 381       keyTable = structuralBuildTimes.keyTable;
 
 382       valueTable = structuralBuildTimes.valueTable;
 
 383       for (int i = 0, l = keyTable.length; i < l; i++) {
 
 384         if (keyTable[i] != null) {
 
 386           out.writeUTF((String) keyTable[i]);
 
 387           out.writeLong(((Long) valueTable[i]).longValue());
 
 390       if (PHPBuilder.DEBUG && length != 0)
 
 391         System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
 
 395          * String[] Interned type locators
 
 397 //    out.writeInt(length = references.elementSize);
 
 398 //    ArrayList internedTypeLocators = new ArrayList(length);
 
 400 //      keyTable = references.keyTable;
 
 401 //      for (int i = 0, l = keyTable.length; i < l; i++) {
 
 402 //        if (keyTable[i] != null) {
 
 404 //          String key = (String) keyTable[i];
 
 405 //          out.writeUTF(key);
 
 406 //          internedTypeLocators.add(key);
 
 409 //      if (PHPBuilder.DEBUG && length != 0)
 
 410 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
 
 414          * Type locators table String type name int interned locator id
 
 416 //    out.writeInt(length = typeLocators.elementSize);
 
 418 //      keyTable = typeLocators.keyTable;
 
 419 //      valueTable = typeLocators.valueTable;
 
 420 //      for (int i = 0, l = keyTable.length; i < l; i++) {
 
 421 //        if (keyTable[i] != null) {
 
 423 //          out.writeUTF((String) keyTable[i]);
 
 424 //          out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
 
 427 //      if (PHPBuilder.DEBUG && length != 0)
 
 428 //        System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
 
 432          * char[][][] Interned qualified names char[][] Interned simple names
 
 434 //    ArrayList internedQualifiedNames = new ArrayList(31);
 
 435 //    ArrayList internedSimpleNames = new ArrayList(31);
 
 436 //    valueTable = references.valueTable;
 
 437 //    for (int i = 0, l = valueTable.length; i < l; i++) {
 
 438 //      if (valueTable[i] != null) {
 
 439 //        ReferenceCollection collection = (ReferenceCollection) valueTable[i];
 
 440 //        char[][][] qNames = collection.qualifiedNameReferences;
 
 441 //        for (int j = 0, m = qNames.length; j < m; j++) {
 
 442 //          char[][] qName = qNames[j];
 
 443 //          if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned
 
 444 //            internedQualifiedNames.add(qName);
 
 445 //            for (int k = 0, n = qName.length; k < n; k++) {
 
 446 //              char[] sName = qName[k];
 
 447 //              if (!internedSimpleNames.contains(sName)) // remember the names have been interned
 
 448 //                internedSimpleNames.add(sName);
 
 452 //        char[][] sNames = collection.simpleNameReferences;
 
 453 //        for (int j = 0, m = sNames.length; j < m; j++) {
 
 454 //          char[] sName = sNames[j];
 
 455 //          if (!internedSimpleNames.contains(sName)) // remember the names have been interned
 
 456 //            internedSimpleNames.add(sName);
 
 460 //    char[][] internedArray = new char[internedSimpleNames.size()][];
 
 461 //    internedSimpleNames.toArray(internedArray);
 
 462 //    writeNames(internedArray, out);
 
 463 //    // now write the interned qualified names as arrays of interned simple names
 
 464 //    out.writeInt(length = internedQualifiedNames.size());
 
 465 //    for (int i = 0; i < length; i++) {
 
 466 //      char[][] qName = (char[][]) internedQualifiedNames.get(i);
 
 467 //      int qLength = qName.length;
 
 468 //      out.writeInt(qLength);
 
 469 //      for (int j = 0; j < qLength; j++)
 
 470 //        out.writeInt(internedSimpleNames.indexOf(qName[j]));
 
 474 //       * References table int interned locator id ReferenceCollection
 
 476 //    out.writeInt(length = references.elementSize);
 
 478 //      keyTable = references.keyTable;
 
 479 //      for (int i = 0, l = keyTable.length; i < l; i++) {
 
 480 //        if (keyTable[i] != null) {
 
 482 //          out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
 
 483 //          ReferenceCollection collection = (ReferenceCollection) valueTable[i];
 
 484 //          if (collection instanceof AdditionalTypeCollection) {
 
 486 //            AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
 
 487 //            writeNames(atc.definedTypeNames, out);
 
 491 //          char[][][] qNames = collection.qualifiedNameReferences;
 
 492 //          int qLength = qNames.length;
 
 493 //          out.writeInt(qLength);
 
 494 //          for (int j = 0; j < qLength; j++)
 
 495 //            out.writeInt(internedQualifiedNames.indexOf(qNames[j]));
 
 496 //          char[][] sNames = collection.simpleNameReferences;
 
 497 //          int sLength = sNames.length;
 
 498 //          out.writeInt(sLength);
 
 499 //          for (int j = 0; j < sLength; j++)
 
 500 //            out.writeInt(internedSimpleNames.indexOf(sNames[j]));
 
 503 //      if (PHPBuilder.DEBUG && length != 0)
 
 504 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
 
 508   private void writeNames(char[][] names, DataOutputStream out) throws IOException {
 
 509     int length = names == null ? 0 : names.length;
 
 510     out.writeInt(length);
 
 511     for (int i = 0; i < length; i++) {
 
 512       char[] name = names[i];
 
 513       int nLength = name.length;
 
 514       out.writeInt(nLength);
 
 515       for (int j = 0; j < nLength; j++)
 
 516         out.writeChar(name[j]);
 
 521    * Returns a string representation of the receiver.
 
 523   public String toString() {
 
 524     return "State for " + javaProjectName //$NON-NLS-1$
 
 525     +" (#" + buildNumber //$NON-NLS-1$
 
 526     +" @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
 
 531    * Debug helper void dump() { System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new
 
 532    * Date(lastStructuralBuildTime) + ")"); System.out.println("\tClass path source locations:"); for (int i = 0, l =
 
 533    * sourceLocations.length; i < l; i++) System.out.println("\t\t" + sourceLocations[i]); System.out.println("\tClass path binary
 
 534    * locations:"); for (int i = 0, l = binaryLocations.length; i < l; i++) System.out.println("\t\t" + binaryLocations[i]);
 
 536    * System.out.print("\tStructural build numbers table:"); if (structuralBuildTimes.elementSize == 0) { System.out.print(" <empty>
 
 537    * "); } else { Object[] keyTable = structuralBuildTimes.keyTable; Object[] valueTable = structuralBuildTimes.valueTable; for
 
 538    * (int i = 0, l = keyTable.length; i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " +
 
 539    * valueTable[i].toString()); }
 
 541    * System.out.print("\tType locators table:"); if (typeLocators.elementSize == 0) { System.out.print(" <empty> "); } else {
 
 542    * Object[] keyTable = typeLocators.keyTable; Object[] valueTable = typeLocators.valueTable; for (int i = 0, l = keyTable.length;
 
 543    * i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); }
 
 545    * System.out.print("\n\tReferences table:"); if (references.elementSize == 0) { System.out.print(" <empty> "); } else { Object[]
 
 546    * keyTable = references.keyTable; Object[] valueTable = references.valueTable; for (int i = 0, l = keyTable.length; i
 
 547    * < l; i++) { if (keyTable[i] != null) { System.out.print("\n\t\t" + keyTable[i].toString()); ReferenceCollection c =
 
 548    * (ReferenceCollection) valueTable[i]; char[][][] qRefs = c.qualifiedNameReferences; System.out.print("\n\t\t\tqualified:"); if
 
 549    * (qRefs.length == 0) System.out.print(" <empty> "); else for (int j = 0, m = qRefs.length; j < m; j++) System.out.print(" '" +
 
 550    * CharOperation.toString(qRefs[j]) + "'"); char[][] sRefs = c.simpleNameReferences; System.out.print("\n\t\t\tsimple:"); if
 
 551    * (sRefs.length == 0) System.out.print(" <empty> "); else for (int j = 0, m = sRefs.length; j < m; j++) System.out.print(" " +
 
 552    * new String(sRefs[j])); if (c instanceof AdditionalTypeCollection) { char[][] names = ((AdditionalTypeCollection)
 
 553    * c).definedTypeNames; System.out.print("\n\t\t\tadditional type names:"); for (int j = 0, m = names.length; j < m; j++)
 
 554    * System.out.print(" " + new String(names[j])); } } } } System.out.print("\n\n"); }