new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / 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.phpeclipse.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.internal.core.Util;
20 import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
21
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;
29
30 public class State {
31 // NOTE: this state cannot contain types that are not defined in this project
32
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;
40
41 int buildNumber;
42 long lastStructuralBuildTime;
43 SimpleLookupTable structuralBuildTimes;
44
45 private String[] knownPackageNames; // of the form "p1/p2"
46
47 static final byte VERSION = 0x0007;
48
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;
53
54 State() {
55 }
56
57 protected State(PHPBuilder javaBuilder) {
58         this.knownPackageNames = null;
59         this.javaProjectName = javaBuilder.currentProject.getName();
60         
61 //      this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
62 //      this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
63         this.references = new SimpleLookupTable(7);
64         this.typeLocators = new SimpleLookupTable(7);
65
66         this.buildNumber = 0; // indicates a full build
67         this.lastStructuralBuildTime = System.currentTimeMillis();
68         this.structuralBuildTimes = new SimpleLookupTable(3);
69 }
70
71 void copyFrom(State lastState) {
72         try {
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]);
85
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]);
92         }
93 }
94
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
100 }
101
102 boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
103         String existing = (String) typeLocators.get(qualifiedTypeName);
104         return existing != null && !existing.equals(typeLocator);
105 }
106
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);
120                                 }
121                         }
122                 }
123                 knownPackageNames = new String[names.size()];
124                 names.toArray(knownPackageNames);
125         }
126         for (int i = 0, l = knownPackageNames.length; i < l; i++)
127                 if (knownPackageNames[i].equals(qualifiedPackageName))
128                         return true;
129         return false;
130 }
131
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));
135 //      } else {
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));
139 //      }
140 }
141
142 void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
143         this.knownPackageNames = null;
144         typeLocators.put(qualifiedTypeName, typeLocator);
145 }
146
147 void recordStructuralDependency(IProject prereqProject, State prereqState) {
148         if (prereqState != null)
149                 structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
150 }
151
152 void removeLocator(String typeLocatorToRemove) {
153         this.knownPackageNames = null;
154         references.removeKey(typeLocatorToRemove);
155         typeLocators.removeValue(typeLocatorToRemove);
156 }
157
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]);
165                         return;
166                 case IResource.FILE :
167                         IPath typeLocatorPath = resource.getProjectRelativePath();
168                         if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
169                                 removeLocator(typeLocatorPath.toString());
170         }
171 }
172
173 void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
174         this.knownPackageNames = null;
175         typeLocators.removeKey(qualifiedTypeNameToRemove);
176 }
177
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$
184                 return null;
185         }
186
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$
192                 return null;
193         }
194         newState.buildNumber = in.readInt();
195         newState.lastStructuralBuildTime = in.readLong();
196
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;
201                 String folderName;
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;
209         }
210
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()) {
216                         case SOURCE_FOLDER :
217                                 newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
218                                 break;
219                         case BINARY_FOLDER :
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());
225                                 break;
226 //                      case EXTERNAL_JAR :
227 //                              newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
228 //                              break;
229 //                      case INTERNAL_JAR :
230 //                              newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
231                 }
232         }
233
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()));
237
238         String[] internedTypeLocators = new String[length = in.readInt()];
239         for (int i = 0; i < length; i++)
240                 internedTypeLocators[i] = in.readUTF();
241
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()]);
245
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;
254 //      }
255 //      internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
256
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()) {
262 //                      case 1 :
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);
271 //                              break;
272 //                      case 2 :
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);
280 //              }
281 //              newState.references.put(typeLocator, collection);
282 //      }
283 //      if (JavaBuilder.DEBUG)
284 //              System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
285         return newState;
286 }
287
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();
296                 names[i] = name;
297         }
298         return names;
299 }
300
301 void tagAsNoopBuild() {
302         this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
303 }
304
305 boolean wasNoopBuild() {
306         return buildNumber == -1;
307 }
308
309 void tagAsStructurallyChanged() {
310         this.lastStructuralBuildTime = System.currentTimeMillis();
311 }
312
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;
318         }
319         return true;
320 }
321
322 void write(DataOutputStream out) throws IOException {
323         int length;
324         Object[] keyTable;
325         Object[] valueTable;
326
327 /*
328  * byte                 VERSION
329  * String               project name
330  * int                          build number
331  * int                          last structural build number
332 */
333         out.writeByte(VERSION);
334         out.writeUTF(javaProjectName);
335         out.writeInt(buildNumber);
336         out.writeLong(lastStructuralBuildTime);
337
338 /*
339  * ClasspathMultiDirectory[]
340  * int                          id
341  * String               path(s)
342 */
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);
350         }
351
352 /*
353  * ClasspathLocation[]
354  * int                          id
355  * String               path(s)
356 */
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) {
364                                         out.writeInt(j);
365                                         continue next;
366                                 }
367                         }
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);
373                 } else {
374 //                      ClasspathJar jar = (ClasspathJar) c;
375 //                      if (jar.resource == null) {
376 //                              out.writeByte(EXTERNAL_JAR);
377 //                              out.writeUTF(jar.zipFilename);
378 //                      } else {
379 //                              out.writeByte(INTERNAL_JAR);
380 //                              out.writeUTF(jar.resource.getFullPath().toString());
381 //                      }
382                 }
383         }
384
385 /*
386  * Structural build numbers table
387  * String               prereq project name
388  * int                          last structural build number
389 */
390         out.writeInt(length = structuralBuildTimes.elementSize);
391         if (length > 0) {
392                 keyTable = structuralBuildTimes.keyTable;
393                 valueTable = structuralBuildTimes.valueTable;
394                 for (int i = 0, l = keyTable.length; i < l; i++) {
395                         if (keyTable[i] != null) {
396                                 length--;
397                                 out.writeUTF((String) keyTable[i]);
398                                 out.writeLong(((Long) valueTable[i]).longValue());
399                         }
400                 }
401 //              if (JavaBuilder.DEBUG && length != 0)
402 //                      System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
403         }
404
405 /*
406  * String[]             Interned type locators
407  */
408         out.writeInt(length = references.elementSize);
409         ArrayList internedTypeLocators = new ArrayList(length);
410         if (length > 0) {
411                 keyTable = references.keyTable;
412                 for (int i = 0, l = keyTable.length; i < l; i++) {
413                         if (keyTable[i] != null) {
414                                 length--;
415                                 String key = (String) keyTable[i];
416                                 out.writeUTF(key);
417                                 internedTypeLocators.add(key);
418                         }
419                 }
420 //              if (JavaBuilder.DEBUG && length != 0)
421 //                      System.out.println("references table is inconsistent"); //$NON-NLS-1$
422         }
423
424 /*
425  * Type locators table
426  * String               type name
427  * int                          interned locator id
428  */
429         out.writeInt(length = typeLocators.elementSize);
430         if (length > 0) {
431                 keyTable = typeLocators.keyTable;
432                 valueTable = typeLocators.valueTable;
433                 for (int i = 0, l = keyTable.length; i < l; i++) {
434                         if (keyTable[i] != null) {
435                                 length--;
436                                 out.writeUTF((String) keyTable[i]);
437                                 out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
438                         }
439                 }
440 //              if (JavaBuilder.DEBUG && length != 0)
441 //                      System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
442         }
443
444 /*
445  * char[][][]   Interned qualified names
446  * char[][]             Interned simple names
447  */
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);
463 //                                      }
464 //                              }
465 //                      }
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);
471 //                      }
472 //              }
473         }
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]));
485         }
486
487 /*
488  * References table
489  * int                  interned locator id
490  * ReferenceCollection
491 */
492         out.writeInt(length = references.elementSize);
493         if (length > 0) {
494                 keyTable = references.keyTable;
495                 for (int i = 0, l = keyTable.length; i < l; i++) {
496 //                      if (keyTable[i] != null) {
497 //                              length--;
498 //                              out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
499 //                              ReferenceCollection collection = (ReferenceCollection) valueTable[i];
500 //                              if (collection instanceof AdditionalTypeCollection) {
501 //                                      out.writeByte(1);
502 //                                      AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
503 //                                      writeNames(atc.definedTypeNames, out);
504 //                              } else {
505 //                                      out.writeByte(2);
506 //                              }
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]));
517 //                      }
518                 }
519 //              if (JavaBuilder.DEBUG && length != 0)
520 //                      System.out.println("references table is inconsistent"); //$NON-NLS-1$
521         }
522 }
523
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]);
533         }
534 }
535
536 /**
537  * Returns a string representation of the receiver.
538  */
539 public String toString() {
540         return "State for " + javaProjectName //$NON-NLS-1$
541                 + " (#" + buildNumber //$NON-NLS-1$
542                         + " @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
543                                 + ")"; //$NON-NLS-1$
544 }
545
546 /* Debug helper
547 void dump() {
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]);
555
556         System.out.print("\tStructural build numbers table:");
557         if (structuralBuildTimes.elementSize == 0) {
558                 System.out.print(" <empty>");
559         } else {
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());
565         }
566
567         System.out.print("\tType locators table:");
568         if (typeLocators.elementSize == 0) {
569                 System.out.print(" <empty>");
570         } else {
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());
576         }
577
578         System.out.print("\n\tReferences table:");
579         if (references.elementSize == 0) {
580                 System.out.print(" <empty>");
581         } else {
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]));
605                                 }
606                         }
607                 }
608         }
609         System.out.print("\n\n");
610 }
611 */
612 }