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.phpeclipse.builder;
 
  13 import java.io.DataInputStream;
 
  14 import java.io.DataOutputStream;
 
  15 import java.io.IOException;
 
  16 import java.util.ArrayList;
 
  17 import java.util.Date;
 
  19 import net.sourceforge.phpdt.internal.core.Util;
 
  20 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
 
  22 import org.eclipse.core.resources.IContainer;
 
  23 import org.eclipse.core.resources.IProject;
 
  24 import org.eclipse.core.resources.IResource;
 
  25 import org.eclipse.core.resources.IResourceDelta;
 
  26 import org.eclipse.core.resources.IWorkspaceRoot;
 
  27 import org.eclipse.core.runtime.IPath;
 
  28 import org.eclipse.core.runtime.Path;
 
  31 // NOTE: this state cannot contain types that are not defined in this project
 
  33 String javaProjectName;
 
  34 ClasspathMultiDirectory[] sourceLocations;
 
  35 ClasspathLocation[] binaryLocations;
 
  36 // keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection
 
  37 SimpleLookupTable references;
 
  38 // keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
 
  39 SimpleLookupTable typeLocators;
 
  42 long lastStructuralBuildTime;
 
  43 SimpleLookupTable structuralBuildTimes;
 
  45 private String[] knownPackageNames; // of the form "p1/p2"
 
  47 static final byte VERSION = 0x0007;
 
  49 static final byte SOURCE_FOLDER = 1;
 
  50 static final byte BINARY_FOLDER = 2;
 
  51 static final byte EXTERNAL_JAR = 3;
 
  52 static final byte INTERNAL_JAR = 4;
 
  57 protected State(PHPBuilder javaBuilder) {
 
  58         this.knownPackageNames = null;
 
  59         this.javaProjectName = javaBuilder.currentProject.getName();
 
  61 //      this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
 
  62 //      this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
 
  63         this.references = new SimpleLookupTable(7);
 
  64         this.typeLocators = new SimpleLookupTable(7);
 
  66         this.buildNumber = 0; // indicates a full build
 
  67         this.lastStructuralBuildTime = System.currentTimeMillis();
 
  68         this.structuralBuildTimes = new SimpleLookupTable(3);
 
  71 void copyFrom(State lastState) {
 
  73                 this.knownPackageNames = null;
 
  74                 this.buildNumber = lastState.buildNumber + 1;
 
  75                 this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
 
  76                 this.references = (SimpleLookupTable) lastState.references.clone();
 
  77                 this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone();
 
  78         } catch (CloneNotSupportedException e) {
 
  79                 this.references = new SimpleLookupTable(lastState.references.elementSize);
 
  80                 Object[] keyTable = lastState.references.keyTable;
 
  81                 Object[] valueTable = lastState.references.valueTable;
 
  82                 for (int i = 0, l = keyTable.length; i < l; i++)
 
  83                         if (keyTable[i] != null)
 
  84                                 this.references.put(keyTable[i], valueTable[i]);
 
  86                 this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize);
 
  87                 keyTable = lastState.typeLocators.keyTable;
 
  88                 valueTable = lastState.typeLocators.valueTable;
 
  89                 for (int i = 0, l = keyTable.length; i < l; i++)
 
  90                         if (keyTable[i] != null)
 
  91                                 this.typeLocators.put(keyTable[i], valueTable[i]);
 
  95 char[][] getDefinedTypeNamesFor(String typeLocator) {
 
  96         Object c = references.get(typeLocator);
 
  97 //      if (c instanceof AdditionalTypeCollection)
 
  98 //              return ((AdditionalTypeCollection) c).definedTypeNames;
 
  99         return null; // means only one type is defined with the same name as the file... saves space
 
 102 boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
 
 103         String existing = (String) typeLocators.get(qualifiedTypeName);
 
 104         return existing != null && !existing.equals(typeLocator);
 
 107 boolean isKnownPackage(String qualifiedPackageName) {
 
 108         if (knownPackageNames == null) {
 
 109                 ArrayList names = new ArrayList(typeLocators.elementSize);
 
 110                 Object[] keyTable = typeLocators.keyTable;
 
 111                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 112                         if (keyTable[i] != null) {
 
 113                                 String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A
 
 114                                 int last = packageName.lastIndexOf('/');
 
 115                                 packageName = last == -1 ? null : packageName.substring(0, last);
 
 116                                 while (packageName != null && !names.contains(packageName)) {
 
 117                                         names.add(packageName);
 
 118                                         last = packageName.lastIndexOf('/');
 
 119                                         packageName = last == -1 ? null : packageName.substring(0, last);
 
 123                 knownPackageNames = new String[names.size()];
 
 124                 names.toArray(knownPackageNames);
 
 126         for (int i = 0, l = knownPackageNames.length; i < l; i++)
 
 127                 if (knownPackageNames[i].equals(qualifiedPackageName))
 
 132 void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) {
 
 133 //      if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) {
 
 134 //                      references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs));
 
 136 //              char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined
 
 137 //              typeNames.toArray(definedTypeNames);
 
 138 //              references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs));
 
 142 void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
 
 143         this.knownPackageNames = null;
 
 144         typeLocators.put(qualifiedTypeName, typeLocator);
 
 147 void recordStructuralDependency(IProject prereqProject, State prereqState) {
 
 148         if (prereqState != null)
 
 149                 structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
 
 152 void removeLocator(String typeLocatorToRemove) {
 
 153         this.knownPackageNames = null;
 
 154         references.removeKey(typeLocatorToRemove);
 
 155         typeLocators.removeValue(typeLocatorToRemove);
 
 158 void removePackage(IResourceDelta sourceDelta) {
 
 159         IResource resource = sourceDelta.getResource();
 
 160         switch(resource.getType()) {
 
 161                 case IResource.FOLDER :
 
 162                         IResourceDelta[] children = sourceDelta.getAffectedChildren();
 
 163                         for (int i = 0, l = children.length; i < l; i++)
 
 164                                 removePackage(children[i]);
 
 166                 case IResource.FILE :
 
 167                         IPath typeLocatorPath = resource.getProjectRelativePath();
 
 168                         if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
 
 169                                 removeLocator(typeLocatorPath.toString());
 
 173 void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
 
 174         this.knownPackageNames = null;
 
 175         typeLocators.removeKey(qualifiedTypeNameToRemove);
 
 178 static State read(IProject project, DataInputStream in) throws IOException {
 
 179 //      if (JavaBuilder.DEBUG)
 
 180 //              System.out.println("About to read state..."); //$NON-NLS-1$
 
 181         if (VERSION != in.readByte()) {
 
 182 //              if (JavaBuilder.DEBUG)
 
 183 //                      System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$
 
 187         State newState = new State();
 
 188         newState.javaProjectName = in.readUTF();
 
 189         if (!project.getName().equals(newState.javaProjectName)) {
 
 190 //              if (JavaBuilder.DEBUG)
 
 191 //                      System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$
 
 194         newState.buildNumber = in.readInt();
 
 195         newState.lastStructuralBuildTime = in.readLong();
 
 197         int length = in.readInt();
 
 198         newState.sourceLocations = new ClasspathMultiDirectory[length];
 
 199         for (int i = 0; i < length; i++) {
 
 200                 IContainer sourceFolder = project, outputFolder = project;
 
 202                 if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
 
 203                 if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
 
 204                 ClasspathMultiDirectory md =
 
 205                         (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in));
 
 206                 if (in.readBoolean())
 
 207                         md.hasIndependentOutputFolder = true;
 
 208                 newState.sourceLocations[i] = md;
 
 211         length = in.readInt();
 
 212         newState.binaryLocations = new ClasspathLocation[length];
 
 213         IWorkspaceRoot root = project.getWorkspace().getRoot();
 
 214         for (int i = 0; i < length; i++) {
 
 215                 switch (in.readByte()) {
 
 217                                 newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
 
 220                                 IPath path = new Path(in.readUTF());
 
 221                                 IContainer outputFolder = path.segmentCount() == 1
 
 222                                         ? (IContainer) root.getProject(path.toString())
 
 223                                         : (IContainer) root.getFolder(path);
 
 224                                 newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean());
 
 226 //                      case EXTERNAL_JAR :
 
 227 //                              newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
 
 229 //                      case INTERNAL_JAR :
 
 230 //                              newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
 
 234         newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
 
 235         for (int i = 0; i < length; i++)
 
 236                 newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong()));
 
 238         String[] internedTypeLocators = new String[length = in.readInt()];
 
 239         for (int i = 0; i < length; i++)
 
 240                 internedTypeLocators[i] = in.readUTF();
 
 242         newState.typeLocators = new SimpleLookupTable(length = in.readInt());
 
 243         for (int i = 0; i < length; i++)
 
 244                 newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]);
 
 246 //      char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false);
 
 247 //      char[][][] internedQualifiedNames = new char[length = in.readInt()][][];
 
 248 //      for (int i = 0; i < length; i++) {
 
 249 //              int qLength = in.readInt();
 
 250 //              char[][] qName = new char[qLength][];
 
 251 //              for (int j = 0; j < qLength; j++)
 
 252 //                      qName[j] = internedSimpleNames[in.readInt()];
 
 253 //              internedQualifiedNames[i] = qName;
 
 255 //      internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
 
 257 //      newState.references = new SimpleLookupTable(length = in.readInt());
 
 258 //      for (int i = 0; i < length; i++) {
 
 259 //              String typeLocator = internedTypeLocators[in.readInt()];
 
 260 //              ReferenceCollection collection = null;
 
 261 //              switch (in.readByte()) {
 
 263 //                              char[][] additionalTypeNames = readNames(in);
 
 264 //                              char[][][] qualifiedNames = new char[in.readInt()][][];
 
 265 //                              for (int j = 0, m = qualifiedNames.length; j < m; j++)
 
 266 //                                      qualifiedNames[j] = internedQualifiedNames[in.readInt()];
 
 267 //                              char[][] simpleNames = new char[in.readInt()][];
 
 268 //                              for (int j = 0, m = simpleNames.length; j < m; j++)
 
 269 //                                      simpleNames[j] = internedSimpleNames[in.readInt()];
 
 270 //                              collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames);
 
 273 //                              char[][][] qNames = new char[in.readInt()][][];
 
 274 //                              for (int j = 0, m = qNames.length; j < m; j++)
 
 275 //                                      qNames[j] = internedQualifiedNames[in.readInt()];
 
 276 //                              char[][] sNames = new char[in.readInt()][];
 
 277 //                              for (int j = 0, m = sNames.length; j < m; j++)
 
 278 //                                      sNames[j] = internedSimpleNames[in.readInt()];
 
 279 //                              collection = new ReferenceCollection(qNames, sNames);
 
 281 //              newState.references.put(typeLocator, collection);
 
 283 //      if (JavaBuilder.DEBUG)
 
 284 //              System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
 
 288 private static char[][] readNames(DataInputStream in) throws IOException {
 
 289         int length = in.readInt();
 
 290         char[][] names = new char[length][];
 
 291         for (int i = 0; i < length; i++) {
 
 292                 int nLength = in.readInt();
 
 293                 char[] name = new char[nLength];
 
 294                 for (int j = 0; j < nLength; j++)
 
 295                         name[j] = in.readChar();
 
 301 void tagAsNoopBuild() {
 
 302         this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
 
 305 boolean wasNoopBuild() {
 
 306         return buildNumber == -1;
 
 309 void tagAsStructurallyChanged() {
 
 310         this.lastStructuralBuildTime = System.currentTimeMillis();
 
 313 boolean wasStructurallyChanged(IProject prereqProject, State prereqState) {
 
 314         if (prereqState != null) {
 
 315                 Object o = structuralBuildTimes.get(prereqProject.getName());
 
 316                 long previous = o == null ? 0 : ((Long) o).longValue();
 
 317                 if (previous == prereqState.lastStructuralBuildTime) return false;
 
 322 void write(DataOutputStream out) throws IOException {
 
 329  * String               project name
 
 331  * int                          last structural build number
 
 333         out.writeByte(VERSION);
 
 334         out.writeUTF(javaProjectName);
 
 335         out.writeInt(buildNumber);
 
 336         out.writeLong(lastStructuralBuildTime);
 
 339  * ClasspathMultiDirectory[]
 
 343         out.writeInt(length = sourceLocations.length);
 
 344         for (int i = 0; i < length; i++) {
 
 345                 ClasspathMultiDirectory md = sourceLocations[i];
 
 346                 out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
 
 347                 out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
 
 348                 writeNames(md.exclusionPatterns, out);
 
 349                 out.writeBoolean(md.hasIndependentOutputFolder);
 
 353  * ClasspathLocation[]
 
 357         out.writeInt(length = binaryLocations.length);
 
 358         next : for (int i = 0; i < length; i++) {
 
 359                 ClasspathLocation c = binaryLocations[i];
 
 360                 if (c instanceof ClasspathMultiDirectory) {
 
 361                         out.writeByte(SOURCE_FOLDER);
 
 362                         for (int j = 0, m = sourceLocations.length; j < m; j++) {
 
 363                                 if (sourceLocations[j] == c) {
 
 368                 } else if (c instanceof ClasspathDirectory) {
 
 369                         out.writeByte(BINARY_FOLDER);
 
 370                         ClasspathDirectory cd = (ClasspathDirectory) c;
 
 371                         out.writeUTF(cd.binaryFolder.getFullPath().toString());
 
 372                         out.writeBoolean(cd.isOutputFolder);
 
 374 //                      ClasspathJar jar = (ClasspathJar) c;
 
 375 //                      if (jar.resource == null) {
 
 376 //                              out.writeByte(EXTERNAL_JAR);
 
 377 //                              out.writeUTF(jar.zipFilename);
 
 379 //                              out.writeByte(INTERNAL_JAR);
 
 380 //                              out.writeUTF(jar.resource.getFullPath().toString());
 
 386  * Structural build numbers table
 
 387  * String               prereq project name
 
 388  * int                          last structural build number
 
 390         out.writeInt(length = structuralBuildTimes.elementSize);
 
 392                 keyTable = structuralBuildTimes.keyTable;
 
 393                 valueTable = structuralBuildTimes.valueTable;
 
 394                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 395                         if (keyTable[i] != null) {
 
 397                                 out.writeUTF((String) keyTable[i]);
 
 398                                 out.writeLong(((Long) valueTable[i]).longValue());
 
 401 //              if (JavaBuilder.DEBUG && length != 0)
 
 402 //                      System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
 
 406  * String[]             Interned type locators
 
 408         out.writeInt(length = references.elementSize);
 
 409         ArrayList internedTypeLocators = new ArrayList(length);
 
 411                 keyTable = references.keyTable;
 
 412                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 413                         if (keyTable[i] != null) {
 
 415                                 String key = (String) keyTable[i];
 
 417                                 internedTypeLocators.add(key);
 
 420 //              if (JavaBuilder.DEBUG && length != 0)
 
 421 //                      System.out.println("references table is inconsistent"); //$NON-NLS-1$
 
 425  * Type locators table
 
 427  * int                          interned locator id
 
 429         out.writeInt(length = typeLocators.elementSize);
 
 431                 keyTable = typeLocators.keyTable;
 
 432                 valueTable = typeLocators.valueTable;
 
 433                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 434                         if (keyTable[i] != null) {
 
 436                                 out.writeUTF((String) keyTable[i]);
 
 437                                 out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
 
 440 //              if (JavaBuilder.DEBUG && length != 0)
 
 441 //                      System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
 
 445  * char[][][]   Interned qualified names
 
 446  * char[][]             Interned simple names
 
 448         ArrayList internedQualifiedNames = new ArrayList(31);
 
 449         ArrayList internedSimpleNames = new ArrayList(31);
 
 450         valueTable = references.valueTable;
 
 451         for (int i = 0, l = valueTable.length; i < l; i++) {
 
 452 //              if (valueTable[i] != null) {
 
 453 //                      ReferenceCollection collection = (ReferenceCollection) valueTable[i];
 
 454 //                      char[][][] qNames = collection.qualifiedNameReferences;
 
 455 //                      for (int j = 0, m = qNames.length; j < m; j++) {
 
 456 //                              char[][] qName = qNames[j];
 
 457 //                              if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned
 
 458 //                                      internedQualifiedNames.add(qName);
 
 459 //                                      for (int k = 0, n = qName.length; k < n; k++) {
 
 460 //                                              char[] sName = qName[k];
 
 461 //                                              if (!internedSimpleNames.contains(sName)) // remember the names have been interned
 
 462 //                                                      internedSimpleNames.add(sName);
 
 466 //                      char[][] sNames = collection.simpleNameReferences;
 
 467 //                      for (int j = 0, m = sNames.length; j < m; j++) {
 
 468 //                              char[] sName = sNames[j];
 
 469 //                              if (!internedSimpleNames.contains(sName)) // remember the names have been interned
 
 470 //                                      internedSimpleNames.add(sName);
 
 474         char[][] internedArray = new char[internedSimpleNames.size()][];
 
 475         internedSimpleNames.toArray(internedArray);
 
 476         writeNames(internedArray, out);
 
 477         // now write the interned qualified names as arrays of interned simple names
 
 478         out.writeInt(length = internedQualifiedNames.size());
 
 479         for (int i = 0; i < length; i++) {
 
 480                 char[][] qName = (char[][]) internedQualifiedNames.get(i);
 
 481                 int qLength = qName.length;
 
 482                 out.writeInt(qLength);
 
 483                 for (int j = 0; j < qLength; j++)
 
 484                         out.writeInt(internedSimpleNames.indexOf(qName[j]));
 
 489  * int                  interned locator id
 
 490  * ReferenceCollection
 
 492         out.writeInt(length = references.elementSize);
 
 494                 keyTable = references.keyTable;
 
 495                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 496 //                      if (keyTable[i] != null) {
 
 498 //                              out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
 
 499 //                              ReferenceCollection collection = (ReferenceCollection) valueTable[i];
 
 500 //                              if (collection instanceof AdditionalTypeCollection) {
 
 502 //                                      AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
 
 503 //                                      writeNames(atc.definedTypeNames, out);
 
 507 //                              char[][][] qNames = collection.qualifiedNameReferences;
 
 508 //                              int qLength = qNames.length;
 
 509 //                              out.writeInt(qLength);
 
 510 //                              for (int j = 0; j < qLength; j++)
 
 511 //                                      out.writeInt(internedQualifiedNames.indexOf(qNames[j]));
 
 512 //                              char[][] sNames = collection.simpleNameReferences;
 
 513 //                              int sLength = sNames.length;
 
 514 //                              out.writeInt(sLength);
 
 515 //                              for (int j = 0; j < sLength; j++)
 
 516 //                                      out.writeInt(internedSimpleNames.indexOf(sNames[j]));
 
 519 //              if (JavaBuilder.DEBUG && length != 0)
 
 520 //                      System.out.println("references table is inconsistent"); //$NON-NLS-1$
 
 524 private void writeNames(char[][] names, DataOutputStream out) throws IOException {
 
 525         int length = names == null ? 0 : names.length;
 
 526         out.writeInt(length);
 
 527         for (int i = 0; i < length; i++) {
 
 528                 char[] name = names[i];
 
 529                 int nLength = name.length;
 
 530                 out.writeInt(nLength);
 
 531                 for (int j = 0; j < nLength; j++)
 
 532                         out.writeChar(name[j]);
 
 537  * Returns a string representation of the receiver.
 
 539 public String toString() {
 
 540         return "State for " + javaProjectName //$NON-NLS-1$
 
 541                 + " (#" + buildNumber //$NON-NLS-1$
 
 542                         + " @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
 
 548         System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")");
 
 549         System.out.println("\tClass path source locations:");
 
 550         for (int i = 0, l = sourceLocations.length; i < l; i++)
 
 551                 System.out.println("\t\t" + sourceLocations[i]);
 
 552         System.out.println("\tClass path binary locations:");
 
 553         for (int i = 0, l = binaryLocations.length; i < l; i++)
 
 554                 System.out.println("\t\t" + binaryLocations[i]);
 
 556         System.out.print("\tStructural build numbers table:");
 
 557         if (structuralBuildTimes.elementSize == 0) {
 
 558                 System.out.print(" <empty>");
 
 560                 Object[] keyTable = structuralBuildTimes.keyTable;
 
 561                 Object[] valueTable = structuralBuildTimes.valueTable;
 
 562                 for (int i = 0, l = keyTable.length; i < l; i++)
 
 563                         if (keyTable[i] != null)
 
 564                                 System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
 
 567         System.out.print("\tType locators table:");
 
 568         if (typeLocators.elementSize == 0) {
 
 569                 System.out.print(" <empty>");
 
 571                 Object[] keyTable = typeLocators.keyTable;
 
 572                 Object[] valueTable = typeLocators.valueTable;
 
 573                 for (int i = 0, l = keyTable.length; i < l; i++)
 
 574                         if (keyTable[i] != null)
 
 575                                 System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
 
 578         System.out.print("\n\tReferences table:");
 
 579         if (references.elementSize == 0) {
 
 580                 System.out.print(" <empty>");
 
 582                 Object[] keyTable = references.keyTable;
 
 583                 Object[] valueTable = references.valueTable;
 
 584                 for (int i = 0, l = keyTable.length; i < l; i++) {
 
 585                         if (keyTable[i] != null) {
 
 586                                 System.out.print("\n\t\t" + keyTable[i].toString());
 
 587                                 ReferenceCollection c = (ReferenceCollection) valueTable[i];
 
 588                                 char[][][] qRefs = c.qualifiedNameReferences;
 
 589                                 System.out.print("\n\t\t\tqualified:");
 
 590                                 if (qRefs.length == 0)
 
 591                                         System.out.print(" <empty>");
 
 592                                 else for (int j = 0, m = qRefs.length; j < m; j++)
 
 593                                                 System.out.print("  '" + CharOperation.toString(qRefs[j]) + "'");
 
 594                                 char[][] sRefs = c.simpleNameReferences;
 
 595                                 System.out.print("\n\t\t\tsimple:");
 
 596                                 if (sRefs.length == 0)
 
 597                                         System.out.print(" <empty>");
 
 598                                 else for (int j = 0, m = sRefs.length; j < m; j++)
 
 599                                                 System.out.print("  " + new String(sRefs[j]));
 
 600                                 if (c instanceof AdditionalTypeCollection) {
 
 601                                         char[][] names = ((AdditionalTypeCollection) c).definedTypeNames;
 
 602                                         System.out.print("\n\t\t\tadditional type names:");
 
 603                                         for (int j = 0, m = names.length; j < m; j++)
 
 604                                                 System.out.print("  " + new String(names[j]));
 
 609         System.out.print("\n\n");