misc changes
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / CompilationUnitScope.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.compiler.lookup;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.core.compiler.CharOperation;
16 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
17 import net.sourceforge.phpdt.internal.compiler.util.CompoundNameVector;
18 import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType;
19 import net.sourceforge.phpdt.internal.compiler.util.ObjectVector;
20 import net.sourceforge.phpdt.internal.compiler.util.SimpleNameVector;
21 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
22 import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
23 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
24
25 public class CompilationUnitScope extends Scope {
26
27   public LookupEnvironment environment;
28   public CompilationUnitDeclaration referenceContext;
29   public char[][] currentPackageName;
30   public PackageBinding fPackage;
31   public ImportBinding[] imports;
32
33   public SourceTypeBinding[] topLevelTypes;
34
35   private CompoundNameVector qualifiedReferences;
36   private SimpleNameVector simpleNameReferences;
37   private ObjectVector referencedTypes;
38
39   HashtableOfType constantPoolNameUsage;
40
41   public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) {
42     super(COMPILATION_UNIT_SCOPE, null);
43     this.environment = environment;
44     this.referenceContext = unit;
45     unit.scope = this;
46     this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
47
48     //  if (environment.options.produceReferenceInfo) {
49     //          this.qualifiedReferences = new CompoundNameVector();
50     //          this.simpleNameReferences = new SimpleNameVector();
51     //          this.referencedTypes = new ObjectVector();
52     //  } else {
53     this.qualifiedReferences = null; // used to test if dependencies should be recorded
54     this.simpleNameReferences = null;
55     this.referencedTypes = null;
56     //  }
57   }
58   void buildFieldsAndMethods() {
59     for (int i = 0, length = topLevelTypes.length; i < length; i++)
60       topLevelTypes[i].scope.buildFieldsAndMethods();
61   }
62   void buildTypeBindings() {
63     if (referenceContext.compilationResult.compilationUnit != null) {
64       char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit.getPackageName();
65       if (expectedPackageName != null && !CharOperation.equals(currentPackageName, expectedPackageName)) {
66
67         // only report if the unit isn't structurally empty
68         //                      if (referenceContext.currentPackage != null 
69         //                                      || referenceContext.types != null 
70         //                                      || referenceContext.imports != null) {
71         //                              problemReporter().packageIsNotExpectedPackage(referenceContext);
72         //                      }
73         currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR : expectedPackageName;
74       }
75     }
76     if (currentPackageName == CharOperation.NO_CHAR_CHAR) {
77       if ((fPackage = environment.defaultPackage) == null) {
78         problemReporter().mustSpecifyPackage(referenceContext);
79         return;
80       }
81     } else {
82                 if ((fPackage = environment.createPackage(currentPackageName)) == null) {
83 //                              problemReporter().packageCollidesWithType(referenceContext);
84                         return;
85                 }
86       recordQualifiedReference(currentPackageName); // always dependent on your own package
87     }
88
89     // Skip typeDeclarations which know of previously reported errors
90     ArrayList types = referenceContext.types;
91     int typeLength = (types == null) ? 0 : types.size();
92     topLevelTypes = new SourceTypeBinding[typeLength];
93     int count = 0;
94     nextType : for (int i = 0; i < typeLength; i++) {
95       if (types.get(i) instanceof TypeDeclaration) {
96         TypeDeclaration typeDecl = (TypeDeclaration) types.get(i);
97         ReferenceBinding typeBinding = fPackage.getType0(typeDecl.name);
98         recordSimpleReference(typeDecl.name); // needed to detect collision cases
99         if (typeBinding != null && !(typeBinding instanceof UnresolvedReferenceBinding)) {
100           // if a type exists, it must be a valid type - cannot be a NotFound problem type
101           // unless its an unresolved type which is now being defined
102           problemReporter().duplicateTypes(referenceContext, typeDecl);
103           continue nextType;
104         }
105         if (fPackage != environment.defaultPackage && fPackage.getPackage(typeDecl.name) != null) {
106           // if a package exists, it must be a valid package - cannot be a NotFound problem package
107           problemReporter().typeCollidesWithPackage(referenceContext, typeDecl);
108           continue nextType;
109         }
110
111         if ((typeDecl.modifiers & AccPublic) != 0) {
112           char[] mainTypeName;
113             if ((mainTypeName = referenceContext.getMainTypeName()) != null
114             // mainTypeName == null means that implementor of ICompilationUnit decided to return null
115               && !CharOperation.equals(mainTypeName, typeDecl.name)) {
116             problemReporter().publicClassMustMatchFileName(referenceContext, typeDecl);
117             continue nextType;
118           }
119         }
120
121         ClassScope child = new ClassScope(this, typeDecl);
122         SourceTypeBinding type = child.buildType(null, fPackage);
123         if (type != null) {
124           topLevelTypes[count++] = type;
125         }
126       }
127     }
128
129     // shrink topLevelTypes... only happens if an error was reported
130     if (count != topLevelTypes.length)
131       System.arraycopy(topLevelTypes, 0, topLevelTypes = new SourceTypeBinding[count], 0, count);
132   }
133   void checkAndSetImports() {
134     // initialize the default imports if necessary... share the default java.lang.* import
135     if (environment.defaultImports == null) {
136       Binding importBinding = environment.getTopLevelPackage(JAVA);
137       if (importBinding != null)
138         importBinding = ((PackageBinding) importBinding).getTypeOrPackage(JAVA_LANG[1]);
139
140       // abort if java.lang cannot be found...
141       if (importBinding == null || !importBinding.isValidBinding())
142         problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit());
143
144       environment.defaultImports = new ImportBinding[] { new ImportBinding(JAVA_LANG, true, importBinding, null)};
145     }
146     if (referenceContext.imports == null) {
147       imports = environment.defaultImports;
148       return;
149     }
150
151     // allocate the import array, add java.lang.* by default
152     int numberOfStatements = referenceContext.imports.length;
153     int numberOfImports = numberOfStatements + 1;
154     for (int i = 0; i < numberOfStatements; i++) {
155       ImportReference importReference = referenceContext.imports[i];
156       if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) {
157         numberOfImports--;
158         break;
159       }
160     }
161     ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
162     resolvedImports[0] = environment.defaultImports[0];
163     int index = 1;
164
165     nextImport : for (int i = 0; i < numberOfStatements; i++) {
166       ImportReference importReference = referenceContext.imports[i];
167       char[][] compoundName = importReference.tokens;
168
169       // skip duplicates or imports of the current package
170       for (int j = 0; j < index; j++)
171         if (resolvedImports[j].onDemand == importReference.onDemand)
172           if (CharOperation.equals(compoundName, resolvedImports[j].compoundName))
173             continue nextImport;
174       if (importReference.onDemand == true)
175         if (CharOperation.equals(compoundName, currentPackageName))
176           continue nextImport;
177
178       if (importReference.onDemand) {
179         Binding importBinding = findOnDemandImport(compoundName);
180         if (!importBinding.isValidBinding())
181           continue nextImport; // we report all problems in faultInImports()
182         resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
183       } else {
184         resolvedImports[index++] = new ImportBinding(compoundName, false, null, importReference);
185       }
186     }
187
188     // shrink resolvedImports... only happens if an error was reported
189     if (resolvedImports.length > index)
190       System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
191     imports = resolvedImports;
192   }
193   /*
194    * INTERNAL USE-ONLY
195    * Innerclasses get their name computed as they are generated, since some may not
196    * be actually outputed if sitting inside unreachable code.
197    */
198   public char[] computeConstantPoolName(LocalTypeBinding localType) {
199     if (localType.constantPoolName() != null) {
200       return localType.constantPoolName();
201     }
202     // delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes.
203
204     if (constantPoolNameUsage == null)
205       constantPoolNameUsage = new HashtableOfType();
206
207     ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType();
208
209     // ensure there is not already such a local type name defined by the user
210     int index = 0;
211     char[] candidateName;
212     while (true) {
213       if (localType.isMemberType()) {
214         if (index == 0) {
215           candidateName = CharOperation.concat(localType.enclosingType().constantPoolName(), localType.sourceName, '$');
216         } else {
217           // in case of collision, then member name gets extra $1 inserted
218           // e.g. class X { { class L{} new X(){ class L{} } } }
219           candidateName =
220             CharOperation.concat(localType.enclosingType().constantPoolName(), '$', String.valueOf(index).toCharArray(), '$', localType.sourceName);
221         }
222       } else if (localType.isAnonymousType()) {
223         candidateName = CharOperation.concat(outerMostEnclosingType.constantPoolName(), String.valueOf(index + 1).toCharArray(), '$');
224       } else {
225         candidateName =
226           CharOperation.concat(outerMostEnclosingType.constantPoolName(), '$', String.valueOf(index + 1).toCharArray(), '$', localType.sourceName);
227       }
228       if (constantPoolNameUsage.get(candidateName) != null) {
229         index++;
230       } else {
231         constantPoolNameUsage.put(candidateName, localType);
232         break;
233       }
234     }
235     return candidateName;
236   }
237
238   void connectTypeHierarchy() {
239     for (int i = 0, length = topLevelTypes.length; i < length; i++)
240       topLevelTypes[i].scope.connectTypeHierarchy();
241   }
242   void faultInImports() {
243     if (referenceContext.imports == null)
244       return;
245
246     // collect the top level type names if a single type import exists
247     int numberOfStatements = referenceContext.imports.length;
248     HashtableOfType typesBySimpleNames = null;
249     for (int i = 0; i < numberOfStatements; i++) {
250       if (!referenceContext.imports[i].onDemand) {
251         typesBySimpleNames = new HashtableOfType(topLevelTypes.length + numberOfStatements);
252         for (int j = 0, length = topLevelTypes.length; j < length; j++)
253           typesBySimpleNames.put(topLevelTypes[j].sourceName, topLevelTypes[j]);
254         break;
255       }
256     }
257
258     // allocate the import array, add java.lang.* by default
259     int numberOfImports = numberOfStatements + 1;
260     for (int i = 0; i < numberOfStatements; i++) {
261       ImportReference importReference = referenceContext.imports[i];
262       if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) {
263         numberOfImports--;
264         break;
265       }
266     }
267     ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
268     resolvedImports[0] = environment.defaultImports[0];
269     int index = 1;
270
271     nextImport : for (int i = 0; i < numberOfStatements; i++) {
272       ImportReference importReference = referenceContext.imports[i];
273       char[][] compoundName = importReference.tokens;
274
275       // skip duplicates or imports of the current package
276       for (int j = 0; j < index; j++)
277         if (resolvedImports[j].onDemand == importReference.onDemand)
278           if (CharOperation.equals(compoundName, resolvedImports[j].compoundName)) {
279             problemReporter().unusedImport(importReference); // since skipped, must be reported now
280             continue nextImport;
281           }
282       if (importReference.onDemand == true)
283         if (CharOperation.equals(compoundName, currentPackageName)) {
284           problemReporter().unusedImport(importReference); // since skipped, must be reported now
285           continue nextImport;
286         }
287       if (importReference.onDemand) {
288         Binding importBinding = findOnDemandImport(compoundName);
289         if (!importBinding.isValidBinding()) {
290           problemReporter().importProblem(importReference, importBinding);
291           continue nextImport;
292         }
293         resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
294       } else {
295         Binding typeBinding = findSingleTypeImport(compoundName);
296         if (!typeBinding.isValidBinding()) {
297           problemReporter().importProblem(importReference, typeBinding);
298           continue nextImport;
299         }
300         if (typeBinding instanceof PackageBinding) {
301           problemReporter().cannotImportPackage(importReference);
302           continue nextImport;
303         }
304         if (typeBinding instanceof ReferenceBinding) {
305           ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
306           if (importReference.isTypeUseDeprecated(referenceBinding, this)) {
307             problemReporter().deprecatedType((TypeBinding) typeBinding, importReference);
308           }
309         }
310         ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]);
311         if (existingType != null) {
312           // duplicate test above should have caught this case, but make sure
313           if (existingType == typeBinding) {
314             continue nextImport;
315           }
316           // either the type collides with a top level type or another imported type
317           for (int j = 0, length = topLevelTypes.length; j < length; j++) {
318             if (CharOperation.equals(topLevelTypes[j].sourceName, existingType.sourceName)) {
319               problemReporter().conflictingImport(importReference);
320               continue nextImport;
321             }
322           }
323           problemReporter().duplicateImport(importReference);
324           continue nextImport;
325         }
326         resolvedImports[index++] = new ImportBinding(compoundName, false, typeBinding, importReference);
327         typesBySimpleNames.put(compoundName[compoundName.length - 1], (ReferenceBinding) typeBinding);
328       }
329     }
330
331     // shrink resolvedImports... only happens if an error was reported
332     if (resolvedImports.length > index)
333       System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
334     imports = resolvedImports;
335   }
336   public void faultInTypes() {
337     faultInImports();
338     if (topLevelTypes==null) {
339                         topLevelTypes = new SourceTypeBinding[0];
340     }
341     for (int i = 0, length = topLevelTypes.length; i < length; i++)
342       topLevelTypes[i].faultInTypesForFieldsAndMethods();
343   }
344   private Binding findOnDemandImport(char[][] compoundName) {
345     recordQualifiedReference(compoundName);
346
347     Binding binding = environment.getTopLevelPackage(compoundName[0]);
348     int i = 1;
349     int length = compoundName.length;
350     foundNothingOrType : if (binding != null) {
351       PackageBinding packageBinding = (PackageBinding) binding;
352       while (i < length) {
353         binding = packageBinding.getTypeOrPackage(compoundName[i++]);
354         if (binding == null || !binding.isValidBinding()) {
355           binding = null;
356           break foundNothingOrType;
357         }
358         if (!(binding instanceof PackageBinding))
359           break foundNothingOrType;
360
361         packageBinding = (PackageBinding) binding;
362       }
363       return packageBinding;
364     }
365
366     ReferenceBinding type;
367     if (binding == null) {
368       //                if (environment.defaultPackage == null
369       //                                || environment.options.complianceLevel >= CompilerOptions.JDK1_4){
370       //                        return new ProblemReferenceBinding(
371       //                                CharOperation.subarray(compoundName, 0, i),
372       //                                NotFound);
373       //                }
374       type = findType(compoundName[0], environment.defaultPackage, environment.defaultPackage);
375       if (type == null || !type.isValidBinding())
376         return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound);
377       i = 1; // reset to look for member types inside the default package type
378     } else {
379       type = (ReferenceBinding) binding;
380     }
381
382     for (; i < length; i++) {
383       if (!type.canBeSeenBy(fPackage)) {
384         return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), type, NotVisible);
385       }
386       // does not look for inherited member types on purpose
387       if ((type = type.getMemberType(compoundName[i])) == null) {
388         return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i + 1), NotFound);
389       }
390     }
391     if (!type.canBeSeenBy(fPackage))
392       return new ProblemReferenceBinding(compoundName, type, NotVisible);
393     return type;
394   }
395   private Binding findSingleTypeImport(char[][] compoundName) {
396     if (compoundName.length == 1) {
397       // findType records the reference
398       // the name cannot be a package
399       //                if (environment.defaultPackage == null 
400       //                        || environment.options.complianceLevel >= CompilerOptions.JDK1_4)
401       //                        return new ProblemReferenceBinding(compoundName, NotFound);
402       ReferenceBinding typeBinding = findType(compoundName[0], environment.defaultPackage, fPackage);
403       if (typeBinding == null)
404         return new ProblemReferenceBinding(compoundName, NotFound);
405       else
406         return typeBinding;
407     }
408     return findOnDemandImport(compoundName);
409   }
410   /* Answer the problem reporter to use for raising new problems.
411   *
412   * Note that as a side-effect, this updates the current reference context
413   * (unit, type or method) in case the problem handler decides it is necessary
414   * to abort.
415   */
416
417   public ProblemReporter problemReporter() {
418     ProblemReporter problemReporter = referenceContext.problemReporter;
419     problemReporter.referenceContext = referenceContext;
420     return problemReporter;
421   }
422
423   /*
424   What do we hold onto:
425   
426   1. when we resolve 'a.b.c', say we keep only 'a.b.c'
427    & when we fail to resolve 'c' in 'a.b', lets keep 'a.b.c'
428   THEN when we come across a new/changed/removed item named 'a.b.c',
429    we would find all references to 'a.b.c'
430   -> This approach fails because every type is resolved in every onDemand import to
431    detect collision cases... so the references could be 10 times bigger than necessary.
432   
433   2. when we resolve 'a.b.c', lets keep 'a.b' & 'c'
434    & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'c'
435   THEN when we come across a new/changed/removed item named 'a.b.c',
436    we would find all references to 'a.b' & 'c'
437   -> This approach does not have a space problem but fails to handle collision cases.
438    What happens if a type is added named 'a.b'? We would search for 'a' & 'b' but
439    would not find a match.
440   
441   3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c'
442    & when we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
443   THEN when we come across a new/changed/removed item named 'a.b.c',
444    we would find all references to 'a.b' & 'c'
445   OR 'a.b' -> 'a' & 'b'
446   OR 'a' -> '' & 'a'
447   -> As long as each single char[] is interned, we should not have a space problem
448    and can handle collision cases.
449   
450   4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c'
451    & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c'
452   THEN when we come across a new/changed/removed item named 'a.b.c',
453    we would find all references to 'a.b' & 'c'
454   OR 'a.b' -> 'a' & 'b' in the simple name collection
455   OR 'a' -> 'a' in the simple name collection
456   -> As long as each single char[] is interned, we should not have a space problem
457    and can handle collision cases.
458   */
459   void recordQualifiedReference(char[][] qualifiedName) {
460     if (qualifiedReferences == null)
461       return; // not recording dependencies
462
463     int length = qualifiedName.length;
464     if (length > 1) {
465       while (!qualifiedReferences.contains(qualifiedName)) {
466         qualifiedReferences.add(qualifiedName);
467         if (length == 2) {
468           recordSimpleReference(qualifiedName[0]);
469           recordSimpleReference(qualifiedName[1]);
470           return;
471         }
472         length--;
473         recordSimpleReference(qualifiedName[length]);
474         System.arraycopy(qualifiedName, 0, qualifiedName = new char[length][], 0, length);
475       }
476     } else if (length == 1) {
477       recordSimpleReference(qualifiedName[0]);
478     }
479   }
480   void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
481     recordQualifiedReference(qualifiedEnclosingName);
482     recordSimpleReference(simpleName);
483   }
484   void recordSimpleReference(char[] simpleName) {
485     if (simpleNameReferences == null)
486       return; // not recording dependencies
487
488     if (!simpleNameReferences.contains(simpleName))
489       simpleNameReferences.add(simpleName);
490   }
491   void recordTypeReference(TypeBinding type) {
492     if (referencedTypes == null)
493       return; // not recording dependencies
494
495     if (type.isArrayType())
496       type = ((ArrayBinding) type).leafComponentType;
497     if (!type.isBaseType() && !referencedTypes.containsIdentical(type))
498       referencedTypes.add(type);
499   }
500   void recordTypeReferences(TypeBinding[] types) {
501     if (qualifiedReferences == null)
502       return; // not recording dependencies
503     if (types == null || types.length == 0)
504       return;
505
506     for (int i = 0, max = types.length; i < max; i++) {
507       // No need to record supertypes of method arguments & thrown exceptions, just the compoundName
508       // If a field/method is retrieved from such a type then a separate call does the job
509       TypeBinding type = types[i];
510       if (type.isArrayType())
511         type = ((ArrayBinding) type).leafComponentType;
512       if (!type.isBaseType()) {
513         ReferenceBinding actualType = (ReferenceBinding) type;
514         if (!actualType.isLocalType())
515           recordQualifiedReference(actualType.isMemberType() ? CharOperation.splitOn('.', actualType.readableName()) : actualType.compoundName);
516       }
517     }
518   }
519   Binding resolveSingleTypeImport(ImportBinding importBinding) {
520     if (importBinding.resolvedImport == null) {
521       importBinding.resolvedImport = findSingleTypeImport(importBinding.compoundName);
522       if (!importBinding.resolvedImport.isValidBinding() || importBinding.resolvedImport instanceof PackageBinding) {
523         if (this.imports != null) {
524           ImportBinding[] newImports = new ImportBinding[imports.length - 1];
525           for (int i = 0, n = 0, max = this.imports.length; i < max; i++)
526             if (this.imports[i] != importBinding) {
527               newImports[n++] = this.imports[i];
528             }
529           this.imports = newImports;
530         }
531         return null;
532       }
533     }
534     return importBinding.resolvedImport;
535   }
536   public void storeDependencyInfo() {
537     // add the type hierarchy of each referenced type
538     // cannot do early since the hierarchy may not be fully resolved
539     for (int i = 0; i < referencedTypes.size; i++) { // grows as more types are added
540       ReferenceBinding type = (ReferenceBinding) referencedTypes.elementAt(i);
541       if (!type.isLocalType()) {
542         recordQualifiedReference(type.isMemberType() ? CharOperation.splitOn('.', type.readableName()) : type.compoundName);
543         ReferenceBinding enclosing = type.enclosingType();
544         if (enclosing != null && !referencedTypes.containsIdentical(enclosing))
545           referencedTypes.add(enclosing); // to record its supertypes
546       }
547       ReferenceBinding superclass = type.superclass();
548       if (superclass != null && !referencedTypes.containsIdentical(superclass))
549         referencedTypes.add(superclass); // to record its supertypes
550       ReferenceBinding[] interfaces = type.superInterfaces();
551       if (interfaces != null && interfaces.length > 0)
552         for (int j = 0, length = interfaces.length; j < length; j++)
553           if (!referencedTypes.containsIdentical(interfaces[j]))
554             referencedTypes.add(interfaces[j]); // to record its supertypes
555     }
556
557     int size = qualifiedReferences.size;
558     char[][][] qualifiedRefs = new char[size][][];
559     for (int i = 0; i < size; i++)
560       qualifiedRefs[i] = qualifiedReferences.elementAt(i);
561     referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
562
563     size = simpleNameReferences.size;
564     char[][] simpleRefs = new char[size][];
565     for (int i = 0; i < size; i++)
566       simpleRefs[i] = simpleNameReferences.elementAt(i);
567     referenceContext.compilationResult.simpleNameReferences = simpleRefs;
568   }
569   public String toString() {
570     return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$
571   }
572   public void verifyMethods(MethodVerifier verifier) {
573     for (int i = 0, length = topLevelTypes.length; i < length; i++)
574       topLevelTypes[i].verifyMethods(verifier);
575   }
576 }