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