RC2 compatibility
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / builder / State.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.core.builder;
12
13 import java.io.DataInputStream;
14 import java.io.DataOutputStream;
15 import java.io.IOException;
16 import java.util.Date;
17
18 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
19
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;
24
25 public class State {
26   // NOTE: this state cannot contain types that are not defined in this project
27
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;
36
37   int buildNumber;
38   long lastStructuralBuildTime;
39   SimpleLookupTable structuralBuildTimes;
40
41   private String[] knownPackageNames; // of the form "p1/p2"
42
43   static final byte VERSION = 0x0007;
44
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;
49
50   State() {
51   }
52
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);
60
61     this.buildNumber = 0; // indicates a full build
62     this.lastStructuralBuildTime = System.currentTimeMillis();
63     this.structuralBuildTimes = new SimpleLookupTable(3);
64   }
65
66   void copyFrom(State lastState) {
67 //    try {
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]);
80 //
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]);
87 //    }
88   }
89
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
95 //  }
96
97 //  boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
98 //    String existing = (String) typeLocators.get(qualifiedTypeName);
99 //    return existing != null && !existing.equals(typeLocator);
100 //  }
101
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);
115 //          }
116 //        }
117 //      }
118 //      knownPackageNames = new String[names.size()];
119 //      names.toArray(knownPackageNames);
120 //    }
121 //    for (int i = 0, l = knownPackageNames.length; i < l; i++)
122 //      if (knownPackageNames[i].equals(qualifiedPackageName))
123 //        return true;
124 //    return false;
125 //  }
126
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));
130 //    } else {
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));
134 //    }
135 //  }
136 //
137 //  void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
138 //    this.knownPackageNames = null;
139 //    typeLocators.put(qualifiedTypeName, typeLocator);
140 //  }
141
142   void recordStructuralDependency(IProject prereqProject, State prereqState) {
143     if (prereqState != null)
144       structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
145   }
146
147 //  void removeLocator(String typeLocatorToRemove) {
148 //    this.knownPackageNames = null;
149 //    references.removeKey(typeLocatorToRemove);
150 //    typeLocators.removeValue(typeLocatorToRemove);
151 //  }
152
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]);
160         return;
161       case IResource.FILE :
162         IPath typeLocatorPath = resource.getProjectRelativePath();
163 //        if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
164 //          removeLocator(typeLocatorPath.toString());
165     }
166   }
167
168 //  void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
169 //    this.knownPackageNames = null;
170 //    typeLocators.removeKey(qualifiedTypeNameToRemove);
171 //  }
172
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$
179       return null;
180     }
181
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$
187       return null;
188     }
189     newState.buildNumber = in.readInt();
190     newState.lastStructuralBuildTime = in.readLong();
191     
192     int length;
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;
206     //  }
207
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()];
215     //                          break;
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());
222     //                          break;
223     //                  case EXTERNAL_JAR :
224     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
225     //                          break;
226     //                  case INTERNAL_JAR :
227     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
228     //          }
229     //  }
230
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()));
234
235 //    String[] internedTypeLocators = new String[length = in.readInt()];
236 //    for (int i = 0; i < length; i++)
237 //      internedTypeLocators[i] = in.readUTF();
238
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()]);
242
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;
251 //    }
252 //    internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
253 //
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()) {
259 //        case 1 :
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);
268 //          break;
269 //        case 2 :
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);
277 //      }
278 //      newState.references.put(typeLocator, collection);
279 //    }
280     if (PHPBuilder.DEBUG)
281       System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
282     return newState;
283   }
284
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();
293       names[i] = name;
294     }
295     return names;
296   }
297
298   void tagAsNoopBuild() {
299     this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
300   }
301
302   boolean wasNoopBuild() {
303     return buildNumber == -1;
304   }
305
306   void tagAsStructurallyChanged() {
307     this.lastStructuralBuildTime = System.currentTimeMillis();
308   }
309
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)
315         return false;
316     }
317     return true;
318   }
319
320   void write(DataOutputStream out) throws IOException {
321     int length;
322     Object[] keyTable;
323     Object[] valueTable;
324
325     /*
326          * byte VERSION String project name int build number int last structural build number
327          */
328     out.writeByte(VERSION);
329     out.writeUTF(javaProjectName);
330     out.writeInt(buildNumber);
331     out.writeLong(lastStructuralBuildTime);
332
333     /*
334          * ClasspathMultiDirectory[] int id String path(s)
335          */
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);
343 //    }
344
345     /*
346          * ClasspathLocation[] int id String path(s)
347          */
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) {
355     //                                  out.writeInt(j);
356     //                                  continue next;
357     //                          }
358     //                  }
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);
364     //          } else {
365     //                  ClasspathJar jar = (ClasspathJar) c;
366     //                  if (jar.resource == null) {
367     //                          out.writeByte(EXTERNAL_JAR);
368     //                          out.writeUTF(jar.zipFilename);
369     //                  } else {
370     //                          out.writeByte(INTERNAL_JAR);
371     //                          out.writeUTF(jar.resource.getFullPath().toString());
372     //                  }
373     //          }
374     //  }
375
376     /*
377          * Structural build numbers table String prereq project name int last structural build number
378          */
379     out.writeInt(length = structuralBuildTimes.elementSize);
380     if (length > 0) {
381       keyTable = structuralBuildTimes.keyTable;
382       valueTable = structuralBuildTimes.valueTable;
383       for (int i = 0, l = keyTable.length; i < l; i++) {
384         if (keyTable[i] != null) {
385           length--;
386           out.writeUTF((String) keyTable[i]);
387           out.writeLong(((Long) valueTable[i]).longValue());
388         }
389       }
390       if (PHPBuilder.DEBUG && length != 0)
391         System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
392     }
393
394     /*
395          * String[] Interned type locators
396          */
397 //    out.writeInt(length = references.elementSize);
398 //    ArrayList internedTypeLocators = new ArrayList(length);
399 //    if (length > 0) {
400 //      keyTable = references.keyTable;
401 //      for (int i = 0, l = keyTable.length; i < l; i++) {
402 //        if (keyTable[i] != null) {
403 //          length--;
404 //          String key = (String) keyTable[i];
405 //          out.writeUTF(key);
406 //          internedTypeLocators.add(key);
407 //        }
408 //      }
409 //      if (PHPBuilder.DEBUG && length != 0)
410 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
411 //    }
412
413     /*
414          * Type locators table String type name int interned locator id
415          */
416 //    out.writeInt(length = typeLocators.elementSize);
417 //    if (length > 0) {
418 //      keyTable = typeLocators.keyTable;
419 //      valueTable = typeLocators.valueTable;
420 //      for (int i = 0, l = keyTable.length; i < l; i++) {
421 //        if (keyTable[i] != null) {
422 //          length--;
423 //          out.writeUTF((String) keyTable[i]);
424 //          out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
425 //        }
426 //      }
427 //      if (PHPBuilder.DEBUG && length != 0)
428 //        System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
429 //    }
430
431     /*
432          * char[][][] Interned qualified names char[][] Interned simple names
433          */
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);
449 //            }
450 //          }
451 //        }
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);
457 //        }
458 //      }
459 //    }
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]));
471 //    }
472 //
473 //    /*
474 //       * References table int interned locator id ReferenceCollection
475 //       */
476 //    out.writeInt(length = references.elementSize);
477 //    if (length > 0) {
478 //      keyTable = references.keyTable;
479 //      for (int i = 0, l = keyTable.length; i < l; i++) {
480 //        if (keyTable[i] != null) {
481 //          length--;
482 //          out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
483 //          ReferenceCollection collection = (ReferenceCollection) valueTable[i];
484 //          if (collection instanceof AdditionalTypeCollection) {
485 //            out.writeByte(1);
486 //            AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
487 //            writeNames(atc.definedTypeNames, out);
488 //          } else {
489 //            out.writeByte(2);
490 //          }
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]));
501 //        }
502 //      }
503 //      if (PHPBuilder.DEBUG && length != 0)
504 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
505 //    }
506   }
507
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]);
517     }
518   }
519
520   /**
521    * Returns a string representation of the receiver.
522    */
523   public String toString() {
524     return "State for " + javaProjectName //$NON-NLS-1$
525     +" (#" + buildNumber //$NON-NLS-1$
526     +" @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
527     +")"; //$NON-NLS-1$
528   }
529
530   /*
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]);
535    * 
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()); }
540    * 
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()); }
544    * 
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"); }
555    */
556 }