9b0a223506cdff767b79f874e7c4767adb8a6b7f
[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.ArrayList;
17 import java.util.Date;
18
19 import net.sourceforge.phpdt.core.compiler.CharOperation;
20 import net.sourceforge.phpdt.internal.compiler.util.Util;
21 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
22
23 import org.eclipse.core.resources.IContainer;
24 import org.eclipse.core.resources.IProject;
25 import org.eclipse.core.resources.IResource;
26 import org.eclipse.core.resources.IResourceDelta;
27 import org.eclipse.core.resources.IWorkspaceRoot;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.Path;
30
31 public class State {
32   // NOTE: this state cannot contain types that are not defined in this project
33
34   String javaProjectName;
35   ClasspathMultiDirectory[] sourceLocations;
36   //ClasspathLocation[] binaryLocations;
37   // keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an
38   // AdditionalTypeCollection
39 //  SimpleLookupTable references;
40   // keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
41 //  SimpleLookupTable typeLocators;
42
43   int buildNumber;
44   long lastStructuralBuildTime;
45   SimpleLookupTable structuralBuildTimes;
46
47   private String[] knownPackageNames; // of the form "p1/p2"
48
49   static final byte VERSION = 0x0007;
50
51   static final byte SOURCE_FOLDER = 1;
52 //  static final byte BINARY_FOLDER = 2;
53 //  static final byte EXTERNAL_JAR = 3;
54 //  static final byte INTERNAL_JAR = 4;
55
56   State() {
57   }
58
59   protected State(PHPBuilder javaBuilder) {
60     this.knownPackageNames = null;
61     this.javaProjectName = javaBuilder.currentProject.getName();
62     this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
63     //  this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
64 //    this.references = new SimpleLookupTable(7);
65 //    this.typeLocators = new SimpleLookupTable(7);
66
67     this.buildNumber = 0; // indicates a full build
68     this.lastStructuralBuildTime = System.currentTimeMillis();
69     this.structuralBuildTimes = new SimpleLookupTable(3);
70   }
71
72   void copyFrom(State lastState) {
73 //    try {
74       this.knownPackageNames = null;
75       this.buildNumber = lastState.buildNumber + 1;
76       this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
77 //      this.references = (SimpleLookupTable) lastState.references.clone();
78 //      this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone();
79 //    } catch (CloneNotSupportedException e) {
80 //      this.references = new SimpleLookupTable(lastState.references.elementSize);
81 //      Object[] keyTable = lastState.references.keyTable;
82 //      Object[] valueTable = lastState.references.valueTable;
83 //      for (int i = 0, l = keyTable.length; i < l; i++)
84 //        if (keyTable[i] != null)
85 //          this.references.put(keyTable[i], valueTable[i]);
86 //
87 //      this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize);
88 //      keyTable = lastState.typeLocators.keyTable;
89 //      valueTable = lastState.typeLocators.valueTable;
90 //      for (int i = 0, l = keyTable.length; i < l; i++)
91 //        if (keyTable[i] != null)
92 //          this.typeLocators.put(keyTable[i], valueTable[i]);
93 //    }
94   }
95
96 //  char[][] getDefinedTypeNamesFor(String typeLocator) {
97 //    Object c = references.get(typeLocator);
98 //    if (c instanceof AdditionalTypeCollection)
99 //      return ((AdditionalTypeCollection) c).definedTypeNames;
100 //    return null; // means only one type is defined with the same name as the file... saves space
101 //  }
102
103 //  boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
104 //    String existing = (String) typeLocators.get(qualifiedTypeName);
105 //    return existing != null && !existing.equals(typeLocator);
106 //  }
107
108 //  boolean isKnownPackage(String qualifiedPackageName) {
109 //    if (knownPackageNames == null) {
110 //      ArrayList names = new ArrayList(typeLocators.elementSize);
111 //      Object[] keyTable = typeLocators.keyTable;
112 //      for (int i = 0, l = keyTable.length; i < l; i++) {
113 //        if (keyTable[i] != null) {
114 //          String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A
115 //          int last = packageName.lastIndexOf('/');
116 //          packageName = last == -1 ? null : packageName.substring(0, last);
117 //          while (packageName != null && !names.contains(packageName)) {
118 //            names.add(packageName);
119 //            last = packageName.lastIndexOf('/');
120 //            packageName = last == -1 ? null : packageName.substring(0, last);
121 //          }
122 //        }
123 //      }
124 //      knownPackageNames = new String[names.size()];
125 //      names.toArray(knownPackageNames);
126 //    }
127 //    for (int i = 0, l = knownPackageNames.length; i < l; i++)
128 //      if (knownPackageNames[i].equals(qualifiedPackageName))
129 //        return true;
130 //    return false;
131 //  }
132
133 //  void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) {
134 //    if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) {
135 //      references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs));
136 //    } else {
137 //      char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined
138 //      typeNames.toArray(definedTypeNames);
139 //      references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs));
140 //    }
141 //  }
142 //
143 //  void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
144 //    this.knownPackageNames = null;
145 //    typeLocators.put(qualifiedTypeName, typeLocator);
146 //  }
147
148   void recordStructuralDependency(IProject prereqProject, State prereqState) {
149     if (prereqState != null)
150       structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
151   }
152
153 //  void removeLocator(String typeLocatorToRemove) {
154 //    this.knownPackageNames = null;
155 //    references.removeKey(typeLocatorToRemove);
156 //    typeLocators.removeValue(typeLocatorToRemove);
157 //  }
158
159   void removePackage(IResourceDelta sourceDelta) {
160     IResource resource = sourceDelta.getResource();
161     switch (resource.getType()) {
162       case IResource.FOLDER :
163         IResourceDelta[] children = sourceDelta.getAffectedChildren();
164         for (int i = 0, l = children.length; i < l; i++)
165           removePackage(children[i]);
166         return;
167       case IResource.FILE :
168         IPath typeLocatorPath = resource.getProjectRelativePath();
169 //        if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
170 //          removeLocator(typeLocatorPath.toString());
171     }
172   }
173
174 //  void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
175 //    this.knownPackageNames = null;
176 //    typeLocators.removeKey(qualifiedTypeNameToRemove);
177 //  }
178
179   static State read(IProject project, DataInputStream in) throws IOException {
180     if (PHPBuilder.DEBUG)
181       System.out.println("About to read state..."); //$NON-NLS-1$
182     if (VERSION != in.readByte()) {
183       if (PHPBuilder.DEBUG)
184         System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$
185       return null;
186     }
187
188     State newState = new State();
189     newState.javaProjectName = in.readUTF();
190     if (!project.getName().equals(newState.javaProjectName)) {
191       if (PHPBuilder.DEBUG)
192         System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$
193       return null;
194     }
195     newState.buildNumber = in.readInt();
196     newState.lastStructuralBuildTime = in.readLong();
197     
198     int length;
199 //    int length = in.readInt();
200 //    newState.sourceLocations = new ClasspathMultiDirectory[0];
201     //  newState.sourceLocations = new ClasspathMultiDirectory[length];
202     //  for (int i = 0; i < length; i++) {
203     //          IContainer sourceFolder = project, outputFolder = project;
204     //          String folderName;
205     //          if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
206     //          if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
207     //          ClasspathMultiDirectory md =
208     //                  (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in));
209     //          if (in.readBoolean())
210     //                  md.hasIndependentOutputFolder = true;
211     //          newState.sourceLocations[i] = md;
212     //  }
213
214 //    length = in.readInt();
215     //  newState.binaryLocations = new ClasspathLocation[length];
216     //  IWorkspaceRoot root = project.getWorkspace().getRoot();
217     //  for (int i = 0; i < length; i++) {
218     //          switch (in.readByte()) {
219     //                  case SOURCE_FOLDER :
220     //                          newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
221     //                          break;
222     //                  case BINARY_FOLDER :
223     //                          IPath path = new Path(in.readUTF());
224     //                          IContainer outputFolder = path.segmentCount() == 1
225     //                                  ? (IContainer) root.getProject(path.toString())
226     //                                  : (IContainer) root.getFolder(path);
227     //                          newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean());
228     //                          break;
229     //                  case EXTERNAL_JAR :
230     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
231     //                          break;
232     //                  case INTERNAL_JAR :
233     //                          newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
234     //          }
235     //  }
236
237     newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
238     for (int i = 0; i < length; i++)
239       newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong()));
240
241 //    String[] internedTypeLocators = new String[length = in.readInt()];
242 //    for (int i = 0; i < length; i++)
243 //      internedTypeLocators[i] = in.readUTF();
244
245 //    newState.typeLocators = new SimpleLookupTable(length = in.readInt());
246 //    for (int i = 0; i < length; i++)
247 //      newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]);
248
249 //    char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false);
250 //    char[][][] internedQualifiedNames = new char[length = in.readInt()][][];
251 //    for (int i = 0; i < length; i++) {
252 //      int qLength = in.readInt();
253 //      char[][] qName = new char[qLength][];
254 //      for (int j = 0; j < qLength; j++)
255 //        qName[j] = internedSimpleNames[in.readInt()];
256 //      internedQualifiedNames[i] = qName;
257 //    }
258 //    internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
259 //
260 //    newState.references = new SimpleLookupTable(length = in.readInt());
261 //    for (int i = 0; i < length; i++) {
262 //      String typeLocator = internedTypeLocators[in.readInt()];
263 //      ReferenceCollection collection = null;
264 //      switch (in.readByte()) {
265 //        case 1 :
266 //          char[][] additionalTypeNames = readNames(in);
267 //          char[][][] qualifiedNames = new char[in.readInt()][][];
268 //          for (int j = 0, m = qualifiedNames.length; j < m; j++)
269 //            qualifiedNames[j] = internedQualifiedNames[in.readInt()];
270 //          char[][] simpleNames = new char[in.readInt()][];
271 //          for (int j = 0, m = simpleNames.length; j < m; j++)
272 //            simpleNames[j] = internedSimpleNames[in.readInt()];
273 //          collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames);
274 //          break;
275 //        case 2 :
276 //          char[][][] qNames = new char[in.readInt()][][];
277 //          for (int j = 0, m = qNames.length; j < m; j++)
278 //            qNames[j] = internedQualifiedNames[in.readInt()];
279 //          char[][] sNames = new char[in.readInt()][];
280 //          for (int j = 0, m = sNames.length; j < m; j++)
281 //            sNames[j] = internedSimpleNames[in.readInt()];
282 //          collection = new ReferenceCollection(qNames, sNames);
283 //      }
284 //      newState.references.put(typeLocator, collection);
285 //    }
286     if (PHPBuilder.DEBUG)
287       System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
288     return newState;
289   }
290
291   private static char[][] readNames(DataInputStream in) throws IOException {
292     int length = in.readInt();
293     char[][] names = new char[length][];
294     for (int i = 0; i < length; i++) {
295       int nLength = in.readInt();
296       char[] name = new char[nLength];
297       for (int j = 0; j < nLength; j++)
298         name[j] = in.readChar();
299       names[i] = name;
300     }
301     return names;
302   }
303
304   void tagAsNoopBuild() {
305     this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
306   }
307
308   boolean wasNoopBuild() {
309     return buildNumber == -1;
310   }
311
312   void tagAsStructurallyChanged() {
313     this.lastStructuralBuildTime = System.currentTimeMillis();
314   }
315
316   boolean wasStructurallyChanged(IProject prereqProject, State prereqState) {
317     if (prereqState != null) {
318       Object o = structuralBuildTimes.get(prereqProject.getName());
319       long previous = o == null ? 0 : ((Long) o).longValue();
320       if (previous == prereqState.lastStructuralBuildTime)
321         return false;
322     }
323     return true;
324   }
325
326   void write(DataOutputStream out) throws IOException {
327     int length;
328     Object[] keyTable;
329     Object[] valueTable;
330
331     /*
332          * byte VERSION String project name int build number int last structural build number
333          */
334     out.writeByte(VERSION);
335     out.writeUTF(javaProjectName);
336     out.writeInt(buildNumber);
337     out.writeLong(lastStructuralBuildTime);
338
339     /*
340          * ClasspathMultiDirectory[] int id String path(s)
341          */
342 //    out.writeInt(length = sourceLocations.length);
343 //    for (int i = 0; i < length; i++) {
344 //      ClasspathMultiDirectory md = sourceLocations[i];
345 //      out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
346 //      out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
347 //      writeNames(md.exclusionPatterns, out);
348 //      out.writeBoolean(md.hasIndependentOutputFolder);
349 //    }
350
351     /*
352          * ClasspathLocation[] int id String path(s)
353          */
354     //  out.writeInt(length = binaryLocations.length);
355     //  next : for (int i = 0; i < length; i++) {
356     //          ClasspathLocation c = binaryLocations[i];
357     //          if (c instanceof ClasspathMultiDirectory) {
358     //                  out.writeByte(SOURCE_FOLDER);
359     //                  for (int j = 0, m = sourceLocations.length; j < m; j++) {
360     //                          if (sourceLocations[j] == c) {
361     //                                  out.writeInt(j);
362     //                                  continue next;
363     //                          }
364     //                  }
365     //          } else if (c instanceof ClasspathDirectory) {
366     //                  out.writeByte(BINARY_FOLDER);
367     //                  ClasspathDirectory cd = (ClasspathDirectory) c;
368     //                  out.writeUTF(cd.binaryFolder.getFullPath().toString());
369     //                  out.writeBoolean(cd.isOutputFolder);
370     //          } else {
371     //                  ClasspathJar jar = (ClasspathJar) c;
372     //                  if (jar.resource == null) {
373     //                          out.writeByte(EXTERNAL_JAR);
374     //                          out.writeUTF(jar.zipFilename);
375     //                  } else {
376     //                          out.writeByte(INTERNAL_JAR);
377     //                          out.writeUTF(jar.resource.getFullPath().toString());
378     //                  }
379     //          }
380     //  }
381
382     /*
383          * Structural build numbers table String prereq project name int last structural build number
384          */
385     out.writeInt(length = structuralBuildTimes.elementSize);
386     if (length > 0) {
387       keyTable = structuralBuildTimes.keyTable;
388       valueTable = structuralBuildTimes.valueTable;
389       for (int i = 0, l = keyTable.length; i < l; i++) {
390         if (keyTable[i] != null) {
391           length--;
392           out.writeUTF((String) keyTable[i]);
393           out.writeLong(((Long) valueTable[i]).longValue());
394         }
395       }
396       if (PHPBuilder.DEBUG && length != 0)
397         System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
398     }
399
400     /*
401          * String[] Interned type locators
402          */
403 //    out.writeInt(length = references.elementSize);
404 //    ArrayList internedTypeLocators = new ArrayList(length);
405 //    if (length > 0) {
406 //      keyTable = references.keyTable;
407 //      for (int i = 0, l = keyTable.length; i < l; i++) {
408 //        if (keyTable[i] != null) {
409 //          length--;
410 //          String key = (String) keyTable[i];
411 //          out.writeUTF(key);
412 //          internedTypeLocators.add(key);
413 //        }
414 //      }
415 //      if (PHPBuilder.DEBUG && length != 0)
416 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
417 //    }
418
419     /*
420          * Type locators table String type name int interned locator id
421          */
422 //    out.writeInt(length = typeLocators.elementSize);
423 //    if (length > 0) {
424 //      keyTable = typeLocators.keyTable;
425 //      valueTable = typeLocators.valueTable;
426 //      for (int i = 0, l = keyTable.length; i < l; i++) {
427 //        if (keyTable[i] != null) {
428 //          length--;
429 //          out.writeUTF((String) keyTable[i]);
430 //          out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
431 //        }
432 //      }
433 //      if (PHPBuilder.DEBUG && length != 0)
434 //        System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
435 //    }
436
437     /*
438          * char[][][] Interned qualified names char[][] Interned simple names
439          */
440 //    ArrayList internedQualifiedNames = new ArrayList(31);
441 //    ArrayList internedSimpleNames = new ArrayList(31);
442 //    valueTable = references.valueTable;
443 //    for (int i = 0, l = valueTable.length; i < l; i++) {
444 //      if (valueTable[i] != null) {
445 //        ReferenceCollection collection = (ReferenceCollection) valueTable[i];
446 //        char[][][] qNames = collection.qualifiedNameReferences;
447 //        for (int j = 0, m = qNames.length; j < m; j++) {
448 //          char[][] qName = qNames[j];
449 //          if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned
450 //            internedQualifiedNames.add(qName);
451 //            for (int k = 0, n = qName.length; k < n; k++) {
452 //              char[] sName = qName[k];
453 //              if (!internedSimpleNames.contains(sName)) // remember the names have been interned
454 //                internedSimpleNames.add(sName);
455 //            }
456 //          }
457 //        }
458 //        char[][] sNames = collection.simpleNameReferences;
459 //        for (int j = 0, m = sNames.length; j < m; j++) {
460 //          char[] sName = sNames[j];
461 //          if (!internedSimpleNames.contains(sName)) // remember the names have been interned
462 //            internedSimpleNames.add(sName);
463 //        }
464 //      }
465 //    }
466 //    char[][] internedArray = new char[internedSimpleNames.size()][];
467 //    internedSimpleNames.toArray(internedArray);
468 //    writeNames(internedArray, out);
469 //    // now write the interned qualified names as arrays of interned simple names
470 //    out.writeInt(length = internedQualifiedNames.size());
471 //    for (int i = 0; i < length; i++) {
472 //      char[][] qName = (char[][]) internedQualifiedNames.get(i);
473 //      int qLength = qName.length;
474 //      out.writeInt(qLength);
475 //      for (int j = 0; j < qLength; j++)
476 //        out.writeInt(internedSimpleNames.indexOf(qName[j]));
477 //    }
478 //
479 //    /*
480 //       * References table int interned locator id ReferenceCollection
481 //       */
482 //    out.writeInt(length = references.elementSize);
483 //    if (length > 0) {
484 //      keyTable = references.keyTable;
485 //      for (int i = 0, l = keyTable.length; i < l; i++) {
486 //        if (keyTable[i] != null) {
487 //          length--;
488 //          out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
489 //          ReferenceCollection collection = (ReferenceCollection) valueTable[i];
490 //          if (collection instanceof AdditionalTypeCollection) {
491 //            out.writeByte(1);
492 //            AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
493 //            writeNames(atc.definedTypeNames, out);
494 //          } else {
495 //            out.writeByte(2);
496 //          }
497 //          char[][][] qNames = collection.qualifiedNameReferences;
498 //          int qLength = qNames.length;
499 //          out.writeInt(qLength);
500 //          for (int j = 0; j < qLength; j++)
501 //            out.writeInt(internedQualifiedNames.indexOf(qNames[j]));
502 //          char[][] sNames = collection.simpleNameReferences;
503 //          int sLength = sNames.length;
504 //          out.writeInt(sLength);
505 //          for (int j = 0; j < sLength; j++)
506 //            out.writeInt(internedSimpleNames.indexOf(sNames[j]));
507 //        }
508 //      }
509 //      if (PHPBuilder.DEBUG && length != 0)
510 //        System.out.println("references table is inconsistent"); //$NON-NLS-1$
511 //    }
512   }
513
514   private void writeNames(char[][] names, DataOutputStream out) throws IOException {
515     int length = names == null ? 0 : names.length;
516     out.writeInt(length);
517     for (int i = 0; i < length; i++) {
518       char[] name = names[i];
519       int nLength = name.length;
520       out.writeInt(nLength);
521       for (int j = 0; j < nLength; j++)
522         out.writeChar(name[j]);
523     }
524   }
525
526   /**
527    * Returns a string representation of the receiver.
528    */
529   public String toString() {
530     return "State for " + javaProjectName //$NON-NLS-1$
531     +" (#" + buildNumber //$NON-NLS-1$
532     +" @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
533     +")"; //$NON-NLS-1$
534   }
535
536   /*
537    * Debug helper void dump() { System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new
538    * Date(lastStructuralBuildTime) + ")"); System.out.println("\tClass path source locations:"); for (int i = 0, l =
539    * sourceLocations.length; i < l; i++) System.out.println("\t\t" + sourceLocations[i]); System.out.println("\tClass path binary
540    * locations:"); for (int i = 0, l = binaryLocations.length; i < l; i++) System.out.println("\t\t" + binaryLocations[i]);
541    * 
542    * System.out.print("\tStructural build numbers table:"); if (structuralBuildTimes.elementSize == 0) { System.out.print(" <empty>
543    * "); } else { Object[] keyTable = structuralBuildTimes.keyTable; Object[] valueTable = structuralBuildTimes.valueTable; for
544    * (int i = 0, l = keyTable.length; i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " +
545    * valueTable[i].toString()); }
546    * 
547    * System.out.print("\tType locators table:"); if (typeLocators.elementSize == 0) { System.out.print(" <empty> "); } else {
548    * Object[] keyTable = typeLocators.keyTable; Object[] valueTable = typeLocators.valueTable; for (int i = 0, l = keyTable.length;
549    * i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); }
550    * 
551    * System.out.print("\n\tReferences table:"); if (references.elementSize == 0) { System.out.print(" <empty> "); } else { Object[]
552    * keyTable = references.keyTable; Object[] valueTable = references.valueTable; for (int i = 0, l = keyTable.length; i
553    * < l; i++) { if (keyTable[i] != null) { System.out.print("\n\t\t" + keyTable[i].toString()); ReferenceCollection c =
554    * (ReferenceCollection) valueTable[i]; char[][][] qRefs = c.qualifiedNameReferences; System.out.print("\n\t\t\tqualified:"); if
555    * (qRefs.length == 0) System.out.print(" <empty> "); else for (int j = 0, m = qRefs.length; j < m; j++) System.out.print(" '" +
556    * CharOperation.toString(qRefs[j]) + "'"); char[][] sRefs = c.simpleNameReferences; System.out.print("\n\t\t\tsimple:"); if
557    * (sRefs.length == 0) System.out.print(" <empty> "); else for (int j = 0, m = sRefs.length; j < m; j++) System.out.print(" " +
558    * new String(sRefs[j])); if (c instanceof AdditionalTypeCollection) { char[][] names = ((AdditionalTypeCollection)
559    * c).definedTypeNames; System.out.print("\n\t\t\tadditional type names:"); for (int j = 0, m = names.length; j < m; j++)
560    * System.out.print(" " + new String(names[j])); } } } } System.out.print("\n\n"); }
561    */
562 }