import java.util.ArrayList;
import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
+import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
import net.sourceforge.phpdt.internal.compiler.util.CompoundNameVector;
import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject;
import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType;
import net.sourceforge.phpdt.internal.compiler.util.ObjectVector;
import net.sourceforge.phpdt.internal.compiler.util.SimpleNameVector;
-import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
-import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
-import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
public class CompilationUnitScope extends Scope {
- public LookupEnvironment environment;
- public CompilationUnitDeclaration referenceContext;
- public char[][] currentPackageName;
- public PackageBinding fPackage;
- public ImportBinding[] imports;
-
- public SourceTypeBinding[] topLevelTypes;
-
- private CompoundNameVector qualifiedReferences;
- private SimpleNameVector simpleNameReferences;
- private ObjectVector referencedTypes;
-
- HashtableOfType constantPoolNameUsage;
- public HashtableOfObject resolvedSingeTypeImports;
-
- public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) {
- super(COMPILATION_UNIT_SCOPE, null);
- this.environment = environment;
- this.referenceContext = unit;
- unit.scope = this;
-// this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
- this.currentPackageName = null;
- // if (environment.options.produceReferenceInfo) {
- // this.qualifiedReferences = new CompoundNameVector();
- // this.simpleNameReferences = new SimpleNameVector();
- // this.referencedTypes = new ObjectVector();
- // } else {
- this.qualifiedReferences = null; // used to test if dependencies should be recorded
- this.simpleNameReferences = null;
- this.referencedTypes = null;
- // }
- }
- void buildFieldsAndMethods() {
- for (int i = 0, length = topLevelTypes.length; i < length; i++)
- topLevelTypes[i].scope.buildFieldsAndMethods();
- }
- void buildTypeBindings() {
- if (referenceContext.compilationResult.compilationUnit != null) {
- char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit.getPackageName();
- if (expectedPackageName != null && !CharOperation.equals(currentPackageName, expectedPackageName)) {
-
- // only report if the unit isn't structurally empty
- // if (referenceContext.currentPackage != null
- // || referenceContext.types != null
- // || referenceContext.imports != null) {
- // problemReporter().packageIsNotExpectedPackage(referenceContext);
- // }
- currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR : expectedPackageName;
- }
- }
- if (currentPackageName == CharOperation.NO_CHAR_CHAR) {
- if ((fPackage = environment.defaultPackage) == null) {
- problemReporter().mustSpecifyPackage(referenceContext);
- return;
- }
- } else {
- if ((fPackage = environment.createPackage(currentPackageName)) == null) {
-// problemReporter().packageCollidesWithType(referenceContext);
- return;
- }
- recordQualifiedReference(currentPackageName); // always dependent on your own package
- }
-
- // Skip typeDeclarations which know of previously reported errors
- ArrayList types = referenceContext.types;
- int typeLength = (types == null) ? 0 : types.size();
- topLevelTypes = new SourceTypeBinding[typeLength];
- int count = 0;
- nextType : for (int i = 0; i < typeLength; i++) {
- if (types.get(i) instanceof TypeDeclaration) {
- TypeDeclaration typeDecl = (TypeDeclaration) types.get(i);
- ReferenceBinding typeBinding = fPackage.getType0(typeDecl.name);
- recordSimpleReference(typeDecl.name); // needed to detect collision cases
- if (typeBinding != null && !(typeBinding instanceof UnresolvedReferenceBinding)) {
- // if a type exists, it must be a valid type - cannot be a NotFound problem type
- // unless its an unresolved type which is now being defined
- problemReporter().duplicateTypes(referenceContext, typeDecl);
- continue nextType;
- }
- if (fPackage != environment.defaultPackage && fPackage.getPackage(typeDecl.name) != null) {
- // if a package exists, it must be a valid package - cannot be a NotFound problem package
- problemReporter().typeCollidesWithPackage(referenceContext, typeDecl);
- continue nextType;
- }
-
- if ((typeDecl.modifiers & AccPublic) != 0) {
- char[] mainTypeName;
- if ((mainTypeName = referenceContext.getMainTypeName()) != null
- // mainTypeName == null means that implementor of ICompilationUnit decided to return null
- && !CharOperation.equals(mainTypeName, typeDecl.name)) {
- problemReporter().publicClassMustMatchFileName(referenceContext, typeDecl);
- continue nextType;
- }
- }
-
- ClassScope child = new ClassScope(this, typeDecl);
- SourceTypeBinding type = child.buildType(null, fPackage);
- if (type != null) {
- topLevelTypes[count++] = type;
- }
- }
- }
-
- // shrink topLevelTypes... only happens if an error was reported
- if (count != topLevelTypes.length)
- System.arraycopy(topLevelTypes, 0, topLevelTypes = new SourceTypeBinding[count], 0, count);
- }
-
- void checkAndSetImports() {
- // initialize the default imports if necessary... share the default java.lang.* import
- if (environment.defaultImports == null) {
- Binding importBinding = environment.getTopLevelPackage(JAVA);
- if (importBinding != null)
- importBinding = ((PackageBinding) importBinding).getTypeOrPackage(JAVA_LANG[1]);
-
- // abort if java.lang cannot be found...
- if (importBinding == null || !importBinding.isValidBinding())
- problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT, referenceCompilationUnit());
-
- environment.defaultImports = new ImportBinding[] { new ImportBinding(JAVA_LANG, true, importBinding, null)};
- }
- if (referenceContext.imports == null) {
- imports = environment.defaultImports;
- return;
- }
-
- // allocate the import array, add java.lang.* by default
- int numberOfStatements = referenceContext.imports.length;
-// int numberOfImports = numberOfStatements + 1;
- int numberOfImports = numberOfStatements;
-// for (int i = 0; i < numberOfStatements; i++) {
-// ImportReference importReference = referenceContext.imports[i];
-// if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) {
-// numberOfImports--;
-// break;
-// }
-// }
- ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
- resolvedImports[0] = environment.defaultImports[0];
- int index = 1;
-
- nextImport : for (int i = 0; i < numberOfStatements; i++) {
- ImportReference importReference = referenceContext.imports[i];
- IFile file = importReference.getFile();
- SourceTypeBinding typeBinding;
-// char[][] compoundName = importReference.tokens;
- char[][] compoundName=null;
- if (file != null){
- IPath path = file.getProjectRelativePath();
- String[] segs = path.segments();
- compoundName = new char[segs.length][];
- for (int j = 0; j < segs.length; j++) {
- compoundName[j] = segs[j].toCharArray();
- }
- }
- if (compoundName==null) {
- continue nextImport;
- }
-
- // skip duplicates or imports of the current package
- for (int j = 0; j < index; j++)
- if (resolvedImports[j].onDemand == importReference.onDemand)
- if (CharOperation.equals(compoundName, resolvedImports[j].compoundName))
- continue nextImport;
- if (importReference.onDemand == true)
- if (CharOperation.equals(compoundName, currentPackageName))
- continue nextImport;
-
- if (importReference.onDemand) {
- Binding importBinding = findOnDemandImport(compoundName);
- if (!importBinding.isValidBinding())
- continue nextImport; // we report all problems in faultInImports()
- resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
- } else {
- resolvedImports[index++] = new ImportBinding(compoundName, false, null, importReference);
- }
- }
-
- // shrink resolvedImports... only happens if an error was reported
- if (resolvedImports.length > index)
- System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
- imports = resolvedImports;
- }
- /*
- * INTERNAL USE-ONLY
- * Innerclasses get their name computed as they are generated, since some may not
- * be actually outputed if sitting inside unreachable code.
- */
- public char[] computeConstantPoolName(LocalTypeBinding localType) {
- if (localType.constantPoolName() != null) {
- return localType.constantPoolName();
- }
- // delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes.
-
- if (constantPoolNameUsage == null)
- constantPoolNameUsage = new HashtableOfType();
-
- ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType();
-
- // ensure there is not already such a local type name defined by the user
- int index = 0;
- char[] candidateName;
- while (true) {
- if (localType.isMemberType()) {
- if (index == 0) {
- candidateName = CharOperation.concat(localType.enclosingType().constantPoolName(), localType.sourceName, '$');
- } else {
- // in case of collision, then member name gets extra $1 inserted
- // e.g. class X { { class L{} new X(){ class L{} } } }
- candidateName =
- CharOperation.concat(localType.enclosingType().constantPoolName(), '$', String.valueOf(index).toCharArray(), '$', localType.sourceName);
- }
- } else if (localType.isAnonymousType()) {
- candidateName = CharOperation.concat(outerMostEnclosingType.constantPoolName(), String.valueOf(index + 1).toCharArray(), '$');
- } else {
- candidateName =
- CharOperation.concat(outerMostEnclosingType.constantPoolName(), '$', String.valueOf(index + 1).toCharArray(), '$', localType.sourceName);
- }
- if (constantPoolNameUsage.get(candidateName) != null) {
- index++;
- } else {
- constantPoolNameUsage.put(candidateName, localType);
- break;
- }
- }
- return candidateName;
- }
-
- void connectTypeHierarchy() {
- for (int i = 0, length = topLevelTypes.length; i < length; i++)
- topLevelTypes[i].scope.connectTypeHierarchy();
- }
- void faultInImports() {
- if (referenceContext.imports == null)
- return;
-//
-// // collect the top level type names if a single type import exists
- int numberOfStatements = referenceContext.imports.length;
-// HashtableOfType typesBySimpleNames = null;
-// for (int i = 0; i < numberOfStatements; i++) {
-// if (!referenceContext.imports[i].onDemand) {
-// typesBySimpleNames = new HashtableOfType(topLevelTypes.length + numberOfStatements);
-// for (int j = 0, length = topLevelTypes.length; j < length; j++)
-// typesBySimpleNames.put(topLevelTypes[j].sourceName, topLevelTypes[j]);
-// break;
-// }
-// }
-//
-// // allocate the import array, add java.lang.* by default
-// int numberOfImports = numberOfStatements + 1;
-// for (int i = 0; i < numberOfStatements; i++) {
-// ImportReference importReference = referenceContext.imports[i];
-// if (importReference.onDemand && CharOperation.equals(JAVA_LANG, importReference.tokens)) {
-// numberOfImports--;
-// break;
-// }
-// }
- ImportBinding[] resolvedImports = new ImportBinding[numberOfStatements];
-// resolvedImports[0] = environment.defaultImports[0];
-// int index = 1;
- int index = 0;
- nextImport : for (int i = 0; i < numberOfStatements; i++) {
- ImportReference importReference = referenceContext.imports[i];
- // create the file name segments here:
-// char[][] compoundName = importReference.tokens;
-//
-// // skip duplicates or imports of the current package
-// for (int j = 0; j < index; j++)
-// if (resolvedImports[j].onDemand == importReference.onDemand)
-// if (CharOperation.equals(compoundName, resolvedImports[j].compoundName)) {
-// problemReporter().unusedImport(importReference); // since skipped, must be reported now
-// continue nextImport;
-// }
-// if (importReference.onDemand == true)
-// if (CharOperation.equals(compoundName, currentPackageName)) {
-// problemReporter().unusedImport(importReference); // since skipped, must be reported now
-// continue nextImport;
-// }
-// if (importReference.onDemand) {
-// Binding importBinding = findOnDemandImport(compoundName);
-// if (!importBinding.isValidBinding()) {
-// problemReporter().importProblem(importReference, importBinding);
-// continue nextImport;
-// }
-// resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
-// } else {
- IFile file = importReference.getFile();
- SourceTypeBinding typeBinding;
- char[][] compoundName;
- if (file != null){
- typeBinding = new SourceTypeBinding();
-// findSingleTypeImport(compoundName);
- IPath path = file.getProjectRelativePath();
- String[] segs = path.segments();
- compoundName = new char[segs.length][];
- for (int j = 0; j < segs.length; j++) {
- compoundName[j] = segs[j].toCharArray();
- }
- typeBinding.compoundName = compoundName; // compoundName;
-// this.fPackage = fPackage;
- typeBinding.fileName = file.getLocation().toString().toCharArray();
-// typeBinding.modifiers = scope.referenceContext.modifiers;
-// typeBinding.sourceName = scope.referenceContext.name;
- typeBinding.sourceName = path.lastSegment().toCharArray();
-// this.scope = scope;
- } else {
-// if (!typeBinding.isValidBinding()) {
-// problemReporter().importProblem(importReference, typeBinding);
- continue nextImport;
-// }
- }
-// if (typeBinding instanceof PackageBinding) {
-// problemReporter().cannotImportPackage(importReference);
-// continue nextImport;
-// }
-// if (typeBinding instanceof ReferenceBinding) {
-// ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
-// if (importReference.isTypeUseDeprecated(referenceBinding, this)) {
-// problemReporter().deprecatedType((TypeBinding) typeBinding, importReference);
-// }
-// }
-// ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]);
-// if (existingType != null) {
-// // duplicate test above should have caught this case, but make sure
-// if (existingType == typeBinding) {
-// continue nextImport;
-// }
-// // either the type collides with a top level type or another imported type
-// for (int j = 0, length = topLevelTypes.length; j < length; j++) {
-// if (CharOperation.equals(topLevelTypes[j].sourceName, existingType.sourceName)) {
-// problemReporter().conflictingImport(importReference);
-// continue nextImport;
-// }
-// }
-// problemReporter().duplicateImport(importReference);
-// continue nextImport;
-// }
- resolvedImports[index++] = new ImportBinding(compoundName, false, typeBinding, importReference);
- imports = resolvedImports;
-// typesBySimpleNames.put(compoundName[compoundName.length - 1], (ReferenceBinding) typeBinding);
-// }
- }
-//
-// // shrink resolvedImports... only happens if an error was reported
- if (resolvedImports.length > index)
- System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
- imports = resolvedImports;
-
- int length = imports.length;
- resolvedSingeTypeImports = new HashtableOfObject(length);
- for (int i = 0; i < length; i++) {
- ImportBinding binding = imports[i];
- if (!binding.onDemand)
- resolvedSingeTypeImports.put(binding.compoundName[binding.compoundName.length - 1], binding);
+ public LookupEnvironment environment;
+
+ public CompilationUnitDeclaration referenceContext;
+
+ public char[][] currentPackageName;
+
+ public PackageBinding fPackage;
+
+ public ImportBinding[] imports;
+
+ public SourceTypeBinding[] topLevelTypes;
+
+ private CompoundNameVector qualifiedReferences;
+
+ private SimpleNameVector simpleNameReferences;
+
+ private ObjectVector referencedTypes;
+
+ HashtableOfType constantPoolNameUsage;
+
+ public HashtableOfObject resolvedSingeTypeImports;
+
+ public CompilationUnitScope(CompilationUnitDeclaration unit,
+ LookupEnvironment environment) {
+ super(COMPILATION_UNIT_SCOPE, null);
+ this.environment = environment;
+ this.referenceContext = unit;
+ unit.scope = this;
+ // this.currentPackageName = unit.currentPackage == null ?
+ // CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
+ this.currentPackageName = null;
+ // if (environment.options.produceReferenceInfo) {
+ // this.qualifiedReferences = new CompoundNameVector();
+ // this.simpleNameReferences = new SimpleNameVector();
+ // this.referencedTypes = new ObjectVector();
+ // } else {
+ this.qualifiedReferences = null; // used to test if dependencies
+ // should be recorded
+ this.simpleNameReferences = null;
+ this.referencedTypes = null;
+ // }
+ }
+
+ void buildFieldsAndMethods() {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].scope.buildFieldsAndMethods();
}
- }
- public void faultInTypes() {
- faultInImports();
- if (topLevelTypes==null) {
+
+ void buildTypeBindings() {
+ if (referenceContext.compilationResult.compilationUnit != null) {
+ char[][] expectedPackageName = referenceContext.compilationResult.compilationUnit
+ .getPackageName();
+ if (expectedPackageName != null
+ && !CharOperation.equals(currentPackageName,
+ expectedPackageName)) {
+
+ // only report if the unit isn't structurally empty
+ // if (referenceContext.currentPackage != null
+ // || referenceContext.types != null
+ // || referenceContext.imports != null) {
+ // problemReporter().packageIsNotExpectedPackage(referenceContext);
+ // }
+ currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR
+ : expectedPackageName;
+ }
+ }
+ if (currentPackageName == CharOperation.NO_CHAR_CHAR) {
+ if ((fPackage = environment.defaultPackage) == null) {
+ problemReporter().mustSpecifyPackage(referenceContext);
+ return;
+ }
+ } else {
+ if ((fPackage = environment.createPackage(currentPackageName)) == null) {
+ // problemReporter().packageCollidesWithType(referenceContext);
+ return;
+ }
+ recordQualifiedReference(currentPackageName); // always dependent
+ // on your own
+ // package
+ }
+
+ // Skip typeDeclarations which know of previously reported errors
+ ArrayList types = referenceContext.types;
+ int typeLength = (types == null) ? 0 : types.size();
+ topLevelTypes = new SourceTypeBinding[typeLength];
+ int count = 0;
+ nextType: for (int i = 0; i < typeLength; i++) {
+ if (types.get(i) instanceof TypeDeclaration) {
+ TypeDeclaration typeDecl = (TypeDeclaration) types.get(i);
+ ReferenceBinding typeBinding = fPackage.getType0(typeDecl.name);
+ recordSimpleReference(typeDecl.name); // needed to detect
+ // collision cases
+ if (typeBinding != null
+ && !(typeBinding instanceof UnresolvedReferenceBinding)) {
+ // if a type exists, it must be a valid type - cannot be a
+ // NotFound problem type
+ // unless its an unresolved type which is now being defined
+ problemReporter()
+ .duplicateTypes(referenceContext, typeDecl);
+ continue nextType;
+ }
+ if (fPackage != environment.defaultPackage
+ && fPackage.getPackage(typeDecl.name) != null) {
+ // if a package exists, it must be a valid package - cannot
+ // be a NotFound problem package
+ problemReporter().typeCollidesWithPackage(referenceContext,
+ typeDecl);
+ continue nextType;
+ }
+
+ if ((typeDecl.modifiers & AccPublic) != 0) {
+ char[] mainTypeName;
+ if ((mainTypeName = referenceContext.getMainTypeName()) != null
+ // mainTypeName == null means that implementor of
+ // ICompilationUnit decided to return null
+ && !CharOperation.equals(mainTypeName,
+ typeDecl.name)) {
+ problemReporter().publicClassMustMatchFileName(
+ referenceContext, typeDecl);
+ continue nextType;
+ }
+ }
+
+ ClassScope child = new ClassScope(this, typeDecl);
+ SourceTypeBinding type = child.buildType(null, fPackage);
+ if (type != null) {
+ topLevelTypes[count++] = type;
+ }
+ }
+ }
+
+ // shrink topLevelTypes... only happens if an error was reported
+ if (count != topLevelTypes.length)
+ System.arraycopy(topLevelTypes, 0,
+ topLevelTypes = new SourceTypeBinding[count], 0, count);
+ }
+
+ void checkAndSetImports() {
+ // initialize the default imports if necessary... share the default
+ // java.lang.* import
+ if (environment.defaultImports == null) {
+ Binding importBinding = environment.getTopLevelPackage(JAVA);
+ if (importBinding != null)
+ importBinding = ((PackageBinding) importBinding)
+ .getTypeOrPackage(JAVA_LANG[1]);
+
+ // abort if java.lang cannot be found...
+ if (importBinding == null || !importBinding.isValidBinding())
+ problemReporter().isClassPathCorrect(JAVA_LANG_OBJECT,
+ referenceCompilationUnit());
+
+ environment.defaultImports = new ImportBinding[] { new ImportBinding(
+ JAVA_LANG, true, importBinding, null) };
+ }
+ if (referenceContext.imports == null) {
+ imports = environment.defaultImports;
+ return;
+ }
+
+ // allocate the import array, add java.lang.* by default
+ int numberOfStatements = referenceContext.imports.length;
+ // int numberOfImports = numberOfStatements + 1;
+ int numberOfImports = numberOfStatements;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // ImportReference importReference = referenceContext.imports[i];
+ // if (importReference.onDemand && CharOperation.equals(JAVA_LANG,
+ // importReference.tokens)) {
+ // numberOfImports--;
+ // break;
+ // }
+ // }
+ ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
+ resolvedImports[0] = environment.defaultImports[0];
+ int index = 1;
+
+ nextImport: for (int i = 0; i < numberOfStatements; i++) {
+ ImportReference importReference = referenceContext.imports[i];
+ IFile file = importReference.getFile();
+ //SourceTypeBinding typeBinding;
+ // char[][] compoundName = importReference.tokens;
+ char[][] compoundName = null;
+ if (file != null) {
+ IPath path = file.getProjectRelativePath();
+ String[] segs = path.segments();
+ compoundName = new char[segs.length][];
+ for (int j = 0; j < segs.length; j++) {
+ compoundName[j] = segs[j].toCharArray();
+ }
+ }
+ if (compoundName == null) {
+ continue nextImport;
+ }
+
+ // skip duplicates or imports of the current package
+ for (int j = 0; j < index; j++)
+ if (resolvedImports[j].onDemand == importReference.onDemand)
+ if (CharOperation.equals(compoundName,
+ resolvedImports[j].compoundName))
+ continue nextImport;
+ if (importReference.onDemand == true)
+ if (CharOperation.equals(compoundName, currentPackageName))
+ continue nextImport;
+
+ if (importReference.onDemand) {
+ Binding importBinding = findOnDemandImport(compoundName);
+ if (!importBinding.isValidBinding())
+ continue nextImport; // we report all problems in
+ // faultInImports()
+ resolvedImports[index++] = new ImportBinding(compoundName,
+ true, importBinding, importReference);
+ } else {
+ resolvedImports[index++] = new ImportBinding(compoundName,
+ false, null, importReference);
+ }
+ }
+
+ // shrink resolvedImports... only happens if an error was reported
+ if (resolvedImports.length > index)
+ System.arraycopy(resolvedImports, 0,
+ resolvedImports = new ImportBinding[index], 0, index);
+ imports = resolvedImports;
+ }
+
+ /*
+ * INTERNAL USE-ONLY Innerclasses get their name computed as they are
+ * generated, since some may not be actually outputed if sitting inside
+ * unreachable code.
+ */
+ public char[] computeConstantPoolName(LocalTypeBinding localType) {
+ if (localType.constantPoolName() != null) {
+ return localType.constantPoolName();
+ }
+ // delegates to the outermost enclosing classfile, since it is the only
+ // one with a global vision of its innertypes.
+
+ if (constantPoolNameUsage == null)
+ constantPoolNameUsage = new HashtableOfType();
+
+ ReferenceBinding outerMostEnclosingType = localType.scope
+ .outerMostClassScope().enclosingSourceType();
+
+ // ensure there is not already such a local type name defined by the
+ // user
+ int index = 0;
+ char[] candidateName;
+ while (true) {
+ if (localType.isMemberType()) {
+ if (index == 0) {
+ candidateName = CharOperation.concat(localType
+ .enclosingType().constantPoolName(),
+ localType.sourceName, '$');
+ } else {
+ // in case of collision, then member name gets extra $1
+ // inserted
+ // e.g. class X { { class L{} new X(){ class L{} } } }
+ candidateName = CharOperation.concat(localType
+ .enclosingType().constantPoolName(), '$', String
+ .valueOf(index).toCharArray(), '$',
+ localType.sourceName);
+ }
+ } else if (localType.isAnonymousType()) {
+ candidateName = CharOperation.concat(outerMostEnclosingType
+ .constantPoolName(), String.valueOf(index + 1)
+ .toCharArray(), '$');
+ } else {
+ candidateName = CharOperation.concat(outerMostEnclosingType
+ .constantPoolName(), '$', String.valueOf(index + 1)
+ .toCharArray(), '$', localType.sourceName);
+ }
+ if (constantPoolNameUsage.get(candidateName) != null) {
+ index++;
+ } else {
+ constantPoolNameUsage.put(candidateName, localType);
+ break;
+ }
+ }
+ return candidateName;
+ }
+
+ void connectTypeHierarchy() {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].scope.connectTypeHierarchy();
+ }
+
+ void faultInImports() {
+ if (referenceContext.imports == null)
+ return;
+ //
+ // // collect the top level type names if a single type import exists
+ int numberOfStatements = referenceContext.imports.length;
+ // HashtableOfType typesBySimpleNames = null;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // if (!referenceContext.imports[i].onDemand) {
+ // typesBySimpleNames = new HashtableOfType(topLevelTypes.length +
+ // numberOfStatements);
+ // for (int j = 0, length = topLevelTypes.length; j < length; j++)
+ // typesBySimpleNames.put(topLevelTypes[j].sourceName,
+ // topLevelTypes[j]);
+ // break;
+ // }
+ // }
+ //
+ // // allocate the import array, add java.lang.* by default
+ // int numberOfImports = numberOfStatements + 1;
+ // for (int i = 0; i < numberOfStatements; i++) {
+ // ImportReference importReference = referenceContext.imports[i];
+ // if (importReference.onDemand && CharOperation.equals(JAVA_LANG,
+ // importReference.tokens)) {
+ // numberOfImports--;
+ // break;
+ // }
+ // }
+ ImportBinding[] resolvedImports = new ImportBinding[numberOfStatements];
+ // resolvedImports[0] = environment.defaultImports[0];
+ // int index = 1;
+ int index = 0;
+ nextImport: for (int i = 0; i < numberOfStatements; i++) {
+ ImportReference importReference = referenceContext.imports[i];
+ // create the file name segments here:
+ // char[][] compoundName = importReference.tokens;
+ //
+ // // skip duplicates or imports of the current package
+ // for (int j = 0; j < index; j++)
+ // if (resolvedImports[j].onDemand == importReference.onDemand)
+ // if (CharOperation.equals(compoundName,
+ // resolvedImports[j].compoundName)) {
+ // problemReporter().unusedImport(importReference); // since
+ // skipped, must be reported now
+ // continue nextImport;
+ // }
+ // if (importReference.onDemand == true)
+ // if (CharOperation.equals(compoundName, currentPackageName)) {
+ // problemReporter().unusedImport(importReference); // since
+ // skipped, must be reported now
+ // continue nextImport;
+ // }
+ // if (importReference.onDemand) {
+ // Binding importBinding = findOnDemandImport(compoundName);
+ // if (!importBinding.isValidBinding()) {
+ // problemReporter().importProblem(importReference, importBinding);
+ // continue nextImport;
+ // }
+ // resolvedImports[index++] = new ImportBinding(compoundName, true,
+ // importBinding, importReference);
+ // } else {
+ IFile file = importReference.getFile();
+ SourceTypeBinding typeBinding;
+ char[][] compoundName;
+ if (file != null) {
+ typeBinding = new SourceTypeBinding();
+ // findSingleTypeImport(compoundName);
+ IPath path = file.getProjectRelativePath();
+ String[] segs = path.segments();
+ compoundName = new char[segs.length][];
+ for (int j = 0; j < segs.length; j++) {
+ compoundName[j] = segs[j].toCharArray();
+ }
+ typeBinding.compoundName = compoundName; // compoundName;
+ // this.fPackage = fPackage;
+ typeBinding.fileName = file.getFullPath().toString()
+ .toCharArray();
+ // typeBinding.modifiers = scope.referenceContext.modifiers;
+ // typeBinding.sourceName = scope.referenceContext.name;
+ typeBinding.sourceName = path.lastSegment().toCharArray();
+ // this.scope = scope;
+ } else {
+ // if (!typeBinding.isValidBinding()) {
+ // problemReporter().importProblem(importReference,
+ // typeBinding);
+ continue nextImport;
+ // }
+ }
+ // if (typeBinding instanceof PackageBinding) {
+ // problemReporter().cannotImportPackage(importReference);
+ // continue nextImport;
+ // }
+ // if (typeBinding instanceof ReferenceBinding) {
+ // ReferenceBinding referenceBinding = (ReferenceBinding)
+ // typeBinding;
+ // if (importReference.isTypeUseDeprecated(referenceBinding, this))
+ // {
+ // problemReporter().deprecatedType((TypeBinding) typeBinding,
+ // importReference);
+ // }
+ // }
+ // ReferenceBinding existingType =
+ // typesBySimpleNames.get(compoundName[compoundName.length - 1]);
+ // if (existingType != null) {
+ // // duplicate test above should have caught this case, but make
+ // sure
+ // if (existingType == typeBinding) {
+ // continue nextImport;
+ // }
+ // // either the type collides with a top level type or another
+ // imported type
+ // for (int j = 0, length = topLevelTypes.length; j < length; j++) {
+ // if (CharOperation.equals(topLevelTypes[j].sourceName,
+ // existingType.sourceName)) {
+ // problemReporter().conflictingImport(importReference);
+ // continue nextImport;
+ // }
+ // }
+ // problemReporter().duplicateImport(importReference);
+ // continue nextImport;
+ // }
+ resolvedImports[index++] = new ImportBinding(compoundName, false,
+ typeBinding, importReference);
+ imports = resolvedImports;
+ // typesBySimpleNames.put(compoundName[compoundName.length - 1],
+ // (ReferenceBinding) typeBinding);
+ // }
+ }
+ //
+ // // shrink resolvedImports... only happens if an error was reported
+ if (resolvedImports.length > index)
+ System.arraycopy(resolvedImports, 0,
+ resolvedImports = new ImportBinding[index], 0, index);
+ imports = resolvedImports;
+
+ int length = imports.length;
+ resolvedSingeTypeImports = new HashtableOfObject(length);
+ for (int i = 0; i < length; i++) {
+ ImportBinding binding = imports[i];
+ if (!binding.onDemand)
+ resolvedSingeTypeImports.put(
+ binding.compoundName[binding.compoundName.length - 1],
+ binding);
+ }
+ }
+
+ public void faultInTypes() {
+ faultInImports();
+ if (topLevelTypes == null) {
topLevelTypes = new SourceTypeBinding[0];
- }
- for (int i = 0, length = topLevelTypes.length; i < length; i++)
- topLevelTypes[i].faultInTypesForFieldsAndMethods();
- }
- private Binding findOnDemandImport(char[][] compoundName) {
- recordQualifiedReference(compoundName);
-
- Binding binding = environment.getTopLevelPackage(compoundName[0]);
- int i = 1;
- int length = compoundName.length;
- foundNothingOrType : if (binding != null) {
- PackageBinding packageBinding = (PackageBinding) binding;
- while (i < length) {
- binding = packageBinding.getTypeOrPackage(compoundName[i++]);
- if (binding == null || !binding.isValidBinding()) {
- binding = null;
- break foundNothingOrType;
- }
- if (!(binding instanceof PackageBinding))
- break foundNothingOrType;
-
- packageBinding = (PackageBinding) binding;
- }
- return packageBinding;
- }
-
- ReferenceBinding type;
- if (binding == null) {
- // if (environment.defaultPackage == null
- // || environment.options.complianceLevel >= CompilerOptions.JDK1_4){
- // return new ProblemReferenceBinding(
- // CharOperation.subarray(compoundName, 0, i),
- // NotFound);
- // }
- type = findType(compoundName[0], environment.defaultPackage, environment.defaultPackage);
- if (type == null || !type.isValidBinding())
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound);
- i = 1; // reset to look for member types inside the default package type
- } else {
- type = (ReferenceBinding) binding;
- }
-
- for (; i < length; i++) {
- if (!type.canBeSeenBy(fPackage)) {
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), type, NotVisible);
- }
- // does not look for inherited member types on purpose
- if ((type = type.getMemberType(compoundName[i])) == null) {
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i + 1), NotFound);
- }
- }
- if (!type.canBeSeenBy(fPackage))
- return new ProblemReferenceBinding(compoundName, type, NotVisible);
- return type;
- }
- private Binding findSingleTypeImport(char[][] compoundName) {
-// if (compoundName.length == 1) {
- // findType records the reference
- // the name cannot be a package
- // if (environment.defaultPackage == null
- // || environment.options.complianceLevel >= CompilerOptions.JDK1_4)
- // return new ProblemReferenceBinding(compoundName, NotFound);
- ReferenceBinding typeBinding = findType(compoundName[0], environment.defaultPackage, fPackage);
- if (typeBinding == null)
- return new ProblemReferenceBinding(compoundName, NotFound);
- else
- return typeBinding;
-// }
-// return findOnDemandImport(compoundName);
- }
- /* Answer the problem reporter to use for raising new problems.
- *
- * Note that as a side-effect, this updates the current reference context
- * (unit, type or method) in case the problem handler decides it is necessary
- * to abort.
- */
-
- public ProblemReporter problemReporter() {
- ProblemReporter problemReporter = referenceContext.problemReporter;
- problemReporter.referenceContext = referenceContext;
- return problemReporter;
- }
-
- /*
- What do we hold onto:
-
- 1. when we resolve 'a.b.c', say we keep only 'a.b.c'
- & when we fail to resolve 'c' in 'a.b', lets keep 'a.b.c'
- THEN when we come across a new/changed/removed item named 'a.b.c',
- we would find all references to 'a.b.c'
- -> This approach fails because every type is resolved in every onDemand import to
- detect collision cases... so the references could be 10 times bigger than necessary.
-
- 2. when we resolve 'a.b.c', lets keep 'a.b' & 'c'
- & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'c'
- THEN when we come across a new/changed/removed item named 'a.b.c',
- we would find all references to 'a.b' & 'c'
- -> This approach does not have a space problem but fails to handle collision cases.
- What happens if a type is added named 'a.b'? We would search for 'a' & 'b' but
- would not find a match.
-
- 3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c'
- & when we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
- THEN when we come across a new/changed/removed item named 'a.b.c',
- we would find all references to 'a.b' & 'c'
- OR 'a.b' -> 'a' & 'b'
- OR 'a' -> '' & 'a'
- -> As long as each single char[] is interned, we should not have a space problem
- and can handle collision cases.
-
- 4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c'
- & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c'
- THEN when we come across a new/changed/removed item named 'a.b.c',
- we would find all references to 'a.b' & 'c'
- OR 'a.b' -> 'a' & 'b' in the simple name collection
- OR 'a' -> 'a' in the simple name collection
- -> As long as each single char[] is interned, we should not have a space problem
- and can handle collision cases.
- */
- void recordQualifiedReference(char[][] qualifiedName) {
- if (qualifiedReferences == null)
- return; // not recording dependencies
-
- int length = qualifiedName.length;
- if (length > 1) {
- while (!qualifiedReferences.contains(qualifiedName)) {
- qualifiedReferences.add(qualifiedName);
- if (length == 2) {
- recordSimpleReference(qualifiedName[0]);
- recordSimpleReference(qualifiedName[1]);
- return;
- }
- length--;
- recordSimpleReference(qualifiedName[length]);
- System.arraycopy(qualifiedName, 0, qualifiedName = new char[length][], 0, length);
- }
- } else if (length == 1) {
- recordSimpleReference(qualifiedName[0]);
- }
- }
- void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
- recordQualifiedReference(qualifiedEnclosingName);
- recordSimpleReference(simpleName);
- }
- void recordSimpleReference(char[] simpleName) {
- if (simpleNameReferences == null)
- return; // not recording dependencies
-
- if (!simpleNameReferences.contains(simpleName))
- simpleNameReferences.add(simpleName);
- }
- void recordTypeReference(TypeBinding type) {
- if (referencedTypes == null)
- return; // not recording dependencies
-
- if (type.isArrayType())
- type = ((ArrayBinding) type).leafComponentType;
- if (!type.isBaseType() && !referencedTypes.containsIdentical(type))
- referencedTypes.add(type);
- }
- void recordTypeReferences(TypeBinding[] types) {
- if (qualifiedReferences == null)
- return; // not recording dependencies
- if (types == null || types.length == 0)
- return;
-
- for (int i = 0, max = types.length; i < max; i++) {
- // No need to record supertypes of method arguments & thrown exceptions, just the compoundName
- // If a field/method is retrieved from such a type then a separate call does the job
- TypeBinding type = types[i];
- if (type.isArrayType())
- type = ((ArrayBinding) type).leafComponentType;
- if (!type.isBaseType()) {
- ReferenceBinding actualType = (ReferenceBinding) type;
- if (!actualType.isLocalType())
- recordQualifiedReference(actualType.isMemberType() ? CharOperation.splitOn('.', actualType.readableName()) : actualType.compoundName);
- }
- }
- }
- Binding resolveSingleTypeImport(ImportBinding importBinding) {
- if (importBinding.resolvedImport == null) {
- importBinding.resolvedImport = findSingleTypeImport(importBinding.compoundName);
- if (!importBinding.resolvedImport.isValidBinding() || importBinding.resolvedImport instanceof PackageBinding) {
- if (this.imports != null) {
- ImportBinding[] newImports = new ImportBinding[imports.length - 1];
- for (int i = 0, n = 0, max = this.imports.length; i < max; i++)
- if (this.imports[i] != importBinding) {
- newImports[n++] = this.imports[i];
- }
- this.imports = newImports;
- }
- return null;
- }
- }
- return importBinding.resolvedImport;
- }
- public void storeDependencyInfo() {
- // add the type hierarchy of each referenced type
- // cannot do early since the hierarchy may not be fully resolved
- for (int i = 0; i < referencedTypes.size; i++) { // grows as more types are added
- ReferenceBinding type = (ReferenceBinding) referencedTypes.elementAt(i);
- if (!type.isLocalType()) {
- recordQualifiedReference(type.isMemberType() ? CharOperation.splitOn('.', type.readableName()) : type.compoundName);
- ReferenceBinding enclosing = type.enclosingType();
- if (enclosing != null && !referencedTypes.containsIdentical(enclosing))
- referencedTypes.add(enclosing); // to record its supertypes
- }
- ReferenceBinding superclass = type.superclass();
- if (superclass != null && !referencedTypes.containsIdentical(superclass))
- referencedTypes.add(superclass); // to record its supertypes
- ReferenceBinding[] interfaces = type.superInterfaces();
- if (interfaces != null && interfaces.length > 0)
- for (int j = 0, length = interfaces.length; j < length; j++)
- if (!referencedTypes.containsIdentical(interfaces[j]))
- referencedTypes.add(interfaces[j]); // to record its supertypes
- }
-
- int size = qualifiedReferences.size;
- char[][][] qualifiedRefs = new char[size][][];
- for (int i = 0; i < size; i++)
- qualifiedRefs[i] = qualifiedReferences.elementAt(i);
- referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
-
- size = simpleNameReferences.size;
- char[][] simpleRefs = new char[size][];
- for (int i = 0; i < size; i++)
- simpleRefs[i] = simpleNameReferences.elementAt(i);
- referenceContext.compilationResult.simpleNameReferences = simpleRefs;
- }
- public String toString() {
- return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$
- }
- public void verifyMethods(MethodVerifier verifier) {
- for (int i = 0, length = topLevelTypes.length; i < length; i++)
- topLevelTypes[i].verifyMethods(verifier);
- }
+ }
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].faultInTypesForFieldsAndMethods();
+ }
+
+ private Binding findOnDemandImport(char[][] compoundName) {
+ recordQualifiedReference(compoundName);
+
+ Binding binding = environment.getTopLevelPackage(compoundName[0]);
+ int i = 1;
+ int length = compoundName.length;
+ foundNothingOrType: if (binding != null) {
+ PackageBinding packageBinding = (PackageBinding) binding;
+ while (i < length) {
+ binding = packageBinding.getTypeOrPackage(compoundName[i++]);
+ if (binding == null || !binding.isValidBinding()) {
+ binding = null;
+ break foundNothingOrType;
+ }
+ if (!(binding instanceof PackageBinding))
+ break foundNothingOrType;
+
+ packageBinding = (PackageBinding) binding;
+ }
+ return packageBinding;
+ }
+
+ ReferenceBinding type;
+ if (binding == null) {
+ // if (environment.defaultPackage == null
+ // || environment.options.complianceLevel >=
+ // CompilerOptions.JDK1_4){
+ // return new ProblemReferenceBinding(
+ // CharOperation.subarray(compoundName, 0, i),
+ // NotFound);
+ // }
+ type = findType(compoundName[0], environment.defaultPackage,
+ environment.defaultPackage);
+ if (type == null || !type.isValidBinding())
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i), NotFound);
+ i = 1; // reset to look for member types inside the default package
+ // type
+ } else {
+ type = (ReferenceBinding) binding;
+ }
+
+ for (; i < length; i++) {
+ if (!type.canBeSeenBy(fPackage)) {
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i), type, NotVisible);
+ }
+ // does not look for inherited member types on purpose
+ if ((type = type.getMemberType(compoundName[i])) == null) {
+ return new ProblemReferenceBinding(CharOperation.subarray(
+ compoundName, 0, i + 1), NotFound);
+ }
+ }
+ if (!type.canBeSeenBy(fPackage))
+ return new ProblemReferenceBinding(compoundName, type, NotVisible);
+ return type;
+ }
+
+ private Binding findSingleTypeImport(char[][] compoundName) {
+ // if (compoundName.length == 1) {
+ // findType records the reference
+ // the name cannot be a package
+ // if (environment.defaultPackage == null
+ // || environment.options.complianceLevel >= CompilerOptions.JDK1_4)
+ // return new ProblemReferenceBinding(compoundName, NotFound);
+ ReferenceBinding typeBinding = findType(compoundName[0],
+ environment.defaultPackage, fPackage);
+ if (typeBinding == null)
+ return new ProblemReferenceBinding(compoundName, NotFound);
+ else
+ return typeBinding;
+ // }
+ // return findOnDemandImport(compoundName);
+ }
+
+ /*
+ * Answer the problem reporter to use for raising new problems.
+ *
+ * Note that as a side-effect, this updates the current reference context
+ * (unit, type or method) in case the problem handler decides it is
+ * necessary to abort.
+ */
+
+ public ProblemReporter problemReporter() {
+ ProblemReporter problemReporter = referenceContext.problemReporter;
+ problemReporter.referenceContext = referenceContext;
+ return problemReporter;
+ }
+
+ /*
+ * What do we hold onto:
+ *
+ * 1. when we resolve 'a.b.c', say we keep only 'a.b.c' & when we fail to
+ * resolve 'c' in 'a.b', lets keep 'a.b.c' THEN when we come across a
+ * new/changed/removed item named 'a.b.c', we would find all references to
+ * 'a.b.c' -> This approach fails because every type is resolved in every
+ * onDemand import to detect collision cases... so the references could be
+ * 10 times bigger than necessary.
+ *
+ * 2. when we resolve 'a.b.c', lets keep 'a.b' & 'c' & when we fail to
+ * resolve 'c' in 'a.b', lets keep 'a.b' & 'c' THEN when we come across a
+ * new/changed/removed item named 'a.b.c', we would find all references to
+ * 'a.b' & 'c' -> This approach does not have a space problem but fails to
+ * handle collision cases. What happens if a type is added named 'a.b'? We
+ * would search for 'a' & 'b' but would not find a match.
+ *
+ * 3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c' & when
+ * we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
+ * THEN when we come across a new/changed/removed item named 'a.b.c', we
+ * would find all references to 'a.b' & 'c' OR 'a.b' -> 'a' & 'b' OR 'a' -> '' &
+ * 'a' -> As long as each single char[] is interned, we should not have a
+ * space problem and can handle collision cases.
+ *
+ * 4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c' & when we
+ * fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c' THEN when
+ * we come across a new/changed/removed item named 'a.b.c', we would find
+ * all references to 'a.b' & 'c' OR 'a.b' -> 'a' & 'b' in the simple name
+ * collection OR 'a' -> 'a' in the simple name collection -> As long as each
+ * single char[] is interned, we should not have a space problem and can
+ * handle collision cases.
+ */
+ void recordQualifiedReference(char[][] qualifiedName) {
+ if (qualifiedReferences == null)
+ return; // not recording dependencies
+
+ int length = qualifiedName.length;
+ if (length > 1) {
+ while (!qualifiedReferences.contains(qualifiedName)) {
+ qualifiedReferences.add(qualifiedName);
+ if (length == 2) {
+ recordSimpleReference(qualifiedName[0]);
+ recordSimpleReference(qualifiedName[1]);
+ return;
+ }
+ length--;
+ recordSimpleReference(qualifiedName[length]);
+ System.arraycopy(qualifiedName, 0,
+ qualifiedName = new char[length][], 0, length);
+ }
+ } else if (length == 1) {
+ recordSimpleReference(qualifiedName[0]);
+ }
+ }
+
+ void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
+ recordQualifiedReference(qualifiedEnclosingName);
+ recordSimpleReference(simpleName);
+ }
+
+ void recordSimpleReference(char[] simpleName) {
+ if (simpleNameReferences == null)
+ return; // not recording dependencies
+
+ if (!simpleNameReferences.contains(simpleName))
+ simpleNameReferences.add(simpleName);
+ }
+
+ void recordTypeReference(TypeBinding type) {
+ if (referencedTypes == null)
+ return; // not recording dependencies
+
+ if (type.isArrayType())
+ type = ((ArrayBinding) type).leafComponentType;
+ if (!type.isBaseType() && !referencedTypes.containsIdentical(type))
+ referencedTypes.add(type);
+ }
+
+ void recordTypeReferences(TypeBinding[] types) {
+ if (qualifiedReferences == null)
+ return; // not recording dependencies
+ if (types == null || types.length == 0)
+ return;
+
+ for (int i = 0, max = types.length; i < max; i++) {
+ // No need to record supertypes of method arguments & thrown
+ // exceptions, just the compoundName
+ // If a field/method is retrieved from such a type then a separate
+ // call does the job
+ TypeBinding type = types[i];
+ if (type.isArrayType())
+ type = ((ArrayBinding) type).leafComponentType;
+ if (!type.isBaseType()) {
+ ReferenceBinding actualType = (ReferenceBinding) type;
+ if (!actualType.isLocalType())
+ recordQualifiedReference(actualType.isMemberType() ? CharOperation
+ .splitOn('.', actualType.readableName())
+ : actualType.compoundName);
+ }
+ }
+ }
+
+ Binding resolveSingleTypeImport(ImportBinding importBinding) {
+ if (importBinding.resolvedImport == null) {
+ importBinding.resolvedImport = findSingleTypeImport(importBinding.compoundName);
+ if (!importBinding.resolvedImport.isValidBinding()
+ || importBinding.resolvedImport instanceof PackageBinding) {
+ if (this.imports != null) {
+ ImportBinding[] newImports = new ImportBinding[imports.length - 1];
+ for (int i = 0, n = 0, max = this.imports.length; i < max; i++)
+ if (this.imports[i] != importBinding) {
+ newImports[n++] = this.imports[i];
+ }
+ this.imports = newImports;
+ }
+ return null;
+ }
+ }
+ return importBinding.resolvedImport;
+ }
+
+ public void storeDependencyInfo() {
+ // add the type hierarchy of each referenced type
+ // cannot do early since the hierarchy may not be fully resolved
+ for (int i = 0; i < referencedTypes.size; i++) { // grows as more
+ // types are added
+ ReferenceBinding type = (ReferenceBinding) referencedTypes
+ .elementAt(i);
+ if (!type.isLocalType()) {
+ recordQualifiedReference(type.isMemberType() ? CharOperation
+ .splitOn('.', type.readableName()) : type.compoundName);
+ ReferenceBinding enclosing = type.enclosingType();
+ if (enclosing != null
+ && !referencedTypes.containsIdentical(enclosing))
+ referencedTypes.add(enclosing); // to record its supertypes
+ }
+ ReferenceBinding superclass = type.superclass();
+ if (superclass != null
+ && !referencedTypes.containsIdentical(superclass))
+ referencedTypes.add(superclass); // to record its supertypes
+ ReferenceBinding[] interfaces = type.superInterfaces();
+ if (interfaces != null && interfaces.length > 0)
+ for (int j = 0, length = interfaces.length; j < length; j++)
+ if (!referencedTypes.containsIdentical(interfaces[j]))
+ referencedTypes.add(interfaces[j]); // to record its
+ // supertypes
+ }
+
+ int size = qualifiedReferences.size;
+ char[][][] qualifiedRefs = new char[size][][];
+ for (int i = 0; i < size; i++)
+ qualifiedRefs[i] = qualifiedReferences.elementAt(i);
+ referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
+
+ size = simpleNameReferences.size;
+ char[][] simpleRefs = new char[size][];
+ for (int i = 0; i < size; i++)
+ simpleRefs[i] = simpleNameReferences.elementAt(i);
+ referenceContext.compilationResult.simpleNameReferences = simpleRefs;
+ }
+
+ public String toString() {
+ return "--- CompilationUnit Scope : " + new String(referenceContext.getFileName()); //$NON-NLS-1$
+ }
+
+ public void verifyMethods(MethodVerifier verifier) {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].verifyMethods(verifier);
+ }
}