X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FCompilationUnitScope.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FCompilationUnitScope.java;h=0000000000000000000000000000000000000000;hb=6f0cd02d46e011bd5599e1b7fefc6159cb811135;hp=d4a8d4f4809a865e7f9f9cbd1e077656b6cff0f0;hpb=622d0e5a4b1b35b6918a516a79a0cc22272a919e;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/src/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java deleted file mode 100644 index d4a8d4f..0000000 --- a/src/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java +++ /dev/null @@ -1,604 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.compiler.lookup; - -import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; -import org.eclipse.jdt.internal.compiler.ast.ImportReference; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; -import org.eclipse.jdt.internal.compiler.util.CompoundNameVector; -import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; -import org.eclipse.jdt.internal.compiler.util.HashtableOfType; -import org.eclipse.jdt.internal.compiler.util.ObjectVector; -import org.eclipse.jdt.internal.compiler.util.SimpleNameVector; - -public class CompilationUnitScope extends Scope { - - public LookupEnvironment environment; - public CompilationUnitDeclaration referenceContext; - public char[][] currentPackageName; - public PackageBinding fPackage; - public ImportBinding[] imports; - public HashtableOfObject resolvedSingeTypeImports; - - public SourceTypeBinding[] topLevelTypes; - - private CompoundNameVector qualifiedReferences; - private SimpleNameVector simpleNameReferences; - private ObjectVector referencedTypes; - - HashtableOfType constantPoolNameUsage; - -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; - - 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() { - topLevelTypes = new SourceTypeBinding[0]; // want it initialized if the package cannot be resolved - 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 - TypeDeclaration[] types = referenceContext.types; - int typeLength = (types == null) ? 0 : types.length; - topLevelTypes = new SourceTypeBinding[typeLength]; - int count = 0; - nextType: for (int i = 0; i < typeLength; i++) { - TypeDeclaration typeDecl = types[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() { - if (referenceContext.imports == null) { - imports = getDefaultImports(); - return; - } - - // allocate the import array, add java.lang.* by default - int numberOfStatements = referenceContext.imports.length; - 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[numberOfImports]; - resolvedImports[0] = getDefaultImports()[0]; - int index = 1; - - nextImport : for (int i = 0; i < numberOfStatements; i++) { - ImportReference importReference = referenceContext.imports[i]; - 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)) - 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[numberOfImports]; - resolvedImports[0] = getDefaultImports()[0]; - int index = 1; - - nextImport : for (int i = 0; i < numberOfStatements; i++) { - ImportReference importReference = referenceContext.imports[i]; - 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 { - Binding typeBinding = findSingleTypeImport(compoundName); - 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); - 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(); - - 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 >= ClassFileConstants.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 >= ClassFileConstants.JDK1_4) - return new ProblemReferenceBinding(compoundName, NotFound); - ReferenceBinding typeBinding = findType(compoundName[0], environment.defaultPackage, fPackage); - if (typeBinding == null) - return new ProblemReferenceBinding(compoundName, NotFound); - return typeBinding; - } - return findOnDemandImport(compoundName); -} -ImportBinding[] getDefaultImports() { - // initialize the default imports if necessary... share the default java.lang.* import - if (environment.defaultImports != null) return environment.defaultImports; - - 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()); - - return environment.defaultImports = new ImportBinding[] {new ImportBinding(JAVA_LANG, true, importBinding, null)}; -} -/* 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()) return; - if (referencedTypes.containsIdentical(type)) return; - if (((ReferenceBinding) type).isLocalType()) return; - - 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); -} -}