package org.eclipse.jdt.internal.compiler.lookup;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IUpdatableModule;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.*;
public class CompilationUnitScope extends Scope {
public LookupEnvironment environment;
public CompilationUnitDeclaration referenceContext;
public char[][] currentPackageName;
public PlainPackageBinding fPackage;
public ImportBinding[] imports;
public int importPtr;
public HashtableOfObject typeOrPackageCache;
public SourceTypeBinding[] topLevelTypes;
private SortedCompoundNameVector qualifiedReferences;
private SortedSimpleNameVector simpleNameReferences;
private SortedSimpleNameVector rootReferences;
private LinkedHashSet<ReferenceBindingSetWrapper> referencedTypes;
private Set<ReferenceBindingSetWrapper> referencedSuperTypesSet;
private ObjectVector referencedSuperTypes;
HashtableOfType constantPoolNameUsage;
private int captureID = 1;
private ImportBinding[] tempImports;
private boolean skipCachingImports;
boolean connectingHierarchy;
private ArrayList<Invocation> inferredInvocations;
Map<InferenceVariable.InferenceVarKey, InferenceVariable> uniqueInferenceVariables = new HashMap<>();
public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) {
this(unit, environment.globalOptions);
this.environment = environment;
}
public CompilationUnitScope(CompilationUnitDeclaration unit, CompilerOptions compilerOptions) {
super(COMPILATION_UNIT_SCOPE, null);
this.referenceContext = unit;
unit.scope = this;
this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
if (compilerOptions.produceReferenceInfo) {
this.qualifiedReferences = new SortedCompoundNameVector();
this.simpleNameReferences = new SortedSimpleNameVector();
this.rootReferences = new SortedSimpleNameVector();
this.referencedTypes = new LinkedHashSet<>();
this.referencedSuperTypesSet = new HashSet<>();
this.referencedSuperTypes = new ObjectVector();
} else {
this.qualifiedReferences = null;
this.simpleNameReferences = null;
this.rootReferences = null;
this.referencedTypes = null;
this.referencedSuperTypesSet = null;
this.referencedSuperTypes = null;
}
}
void buildFieldsAndMethods() {
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
this.topLevelTypes[i].scope.buildFieldsAndMethods();
}
void buildTypeBindings(AccessRestriction accessRestriction) {
this.topLevelTypes = new SourceTypeBinding[0];
boolean firstIsSynthetic = false;
if (this.referenceContext.compilationResult.compilationUnit != null) {
char[][] expectedPackageName = this.referenceContext.compilationResult.compilationUnit.getPackageName();
if (expectedPackageName != null && !this.referenceContext.isModuleInfo()
&& !CharOperation.equals(this.currentPackageName, expectedPackageName)) {
if (this.referenceContext.currentPackage != null
|| this.referenceContext.types != null
|| this.referenceContext.imports != null) {
problemReporter().packageIsNotExpectedPackage(this.referenceContext);
}
this.currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR : expectedPackageName;
}
}
if (this.currentPackageName == CharOperation.NO_CHAR_CHAR) {
this.fPackage = this.environment.defaultPackage;
if (this.referenceContext.isModuleInfo()) {
ModuleDeclaration moduleDecl = this.referenceContext.moduleDeclaration;
if (moduleDecl != null) {
moduleDecl.createScope(this);
moduleDecl.checkAndSetModifiers();
}
} else if (module() != this.environment.UnNamedModule) {
problemReporter().unnamedPackageInNamedModule(module());
}
} else {
if ((this.fPackage = this.environment.createPlainPackage(this.currentPackageName)) == null) {
if (this.referenceContext.currentPackage != null) {
problemReporter().packageCollidesWithType(this.referenceContext);
}
this.fPackage = this.environment.defaultPackage;
return;
} else if (this.referenceContext.isPackageInfo()) {
if (this.referenceContext.types == null || this.referenceContext.types.length == 0) {
this.referenceContext.types = new TypeDeclaration[1];
this.referenceContext.createPackageInfoType();
firstIsSynthetic = true;
}
if (this.referenceContext.currentPackage != null && this.referenceContext.currentPackage.annotations != null) {
this.referenceContext.types[0].annotations = this.referenceContext.currentPackage.annotations;
}
}
recordQualifiedReference(this.currentPackageName);
}
TypeDeclaration[] types = this.referenceContext.types;
int typeLength = (types == null) ? 0 : types.length;
this.topLevelTypes = new SourceTypeBinding[typeLength];
int count = 0;
nextType: for (int i = 0; i < typeLength; i++) {
TypeDeclaration typeDecl = types[i];
if (this.environment.root.isProcessingAnnotations && this.environment.isMissingType(typeDecl.name))
throw new SourceTypeCollisionException();
recordSimpleReference(typeDecl.name);
if (this.fPackage.hasType0Any(typeDecl.name)) {
if (this.environment.root.isProcessingAnnotations)
throw new SourceTypeCollisionException();
problemReporter().duplicateTypes(this.referenceContext, typeDecl);
continue nextType;
}
if ((typeDecl.modifiers & ClassFileConstants.AccPublic) != 0) {
char[] mainTypeName;
if ((mainTypeName = this.referenceContext.getMainTypeName()) != null
&& !CharOperation.equals(mainTypeName, typeDecl.name)) {
problemReporter().publicClassMustMatchFileName(this.referenceContext, typeDecl);
}
}
ClassScope child = new ClassScope(this, typeDecl);
SourceTypeBinding type = child.buildType(null, this.fPackage, accessRestriction);
if (firstIsSynthetic && i == 0)
type.modifiers |= ClassFileConstants.AccSynthetic;
if (type != null)
this.topLevelTypes[count++] = type;
}
if (count != this.topLevelTypes.length)
System.arraycopy(this.topLevelTypes, 0, this.topLevelTypes = new SourceTypeBinding[count], 0, count);
if (this.referenceContext.moduleDeclaration != null) {
this.module().completeIfNeeded(IUpdatableModule.UpdateKind.MODULE);
this.referenceContext.moduleDeclaration.resolvePackageDirectives(this);
this.module().completeIfNeeded(IUpdatableModule.UpdateKind.PACKAGE);
}
}
void checkAndSetImports() {
TypeDeclaration[] types = this.referenceContext.types;
if (types != null) {
for (int i = 0; i < types.length; i++) {
TypeDeclaration typeDecl = types[i];
if (this.fPackage != this.environment.defaultPackage && this.fPackage.getPackage(typeDecl.name, module()) != null) {
problemReporter().typeCollidesWithPackage(this.referenceContext, typeDecl);
}
}
}
if (this.referenceContext.moduleDeclaration != null) {
this.referenceContext.moduleDeclaration.resolveModuleDirectives(this);
}
if (this.referenceContext.imports == null) {
this.imports = getDefaultImports();
return;
}
int numberOfStatements = this.referenceContext.imports.length;
int numberOfImports = numberOfStatements + 1;
for (int i = 0; i < numberOfStatements; i++) {
ImportReference importReference = this.referenceContext.imports[i];
if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
numberOfImports--;
break;
}
}
ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
resolvedImports[0] = getDefaultImports()[0];
int index = 1;
nextImport : for (int i = 0; i < numberOfStatements; i++) {
ImportReference importReference = this.referenceContext.imports[i];
char[][] compoundName = importReference.tokens;
for (int j = 0; j < index; j++) {
ImportBinding resolved = resolvedImports[j];
if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic())
if (CharOperation.equals(compoundName, resolvedImports[j].compoundName))
continue nextImport;
}
if ((importReference.bits & ASTNode.OnDemand) != 0) {
if (CharOperation.equals(compoundName, this.currentPackageName))
continue nextImport;
Binding importBinding = findImport(compoundName, compoundName.length);
if (!importBinding.isValidBinding() || (importReference.isStatic() && importBinding instanceof PackageBinding))
continue nextImport;
resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
} else {
resolvedImports[index++] = new ImportBinding(compoundName, false, null, importReference);
}
}
if (resolvedImports.length > index)
System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
this.imports = resolvedImports;
}
void checkParameterizedTypes() {
if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return;
for (int i = 0, length = this.topLevelTypes.length; i < length; i++) {
ClassScope scope = this.topLevelTypes[i].scope;
scope.checkParameterizedTypeBounds();
scope.checkParameterizedSuperTypeCollisions();
}
}
public char[] computeConstantPoolName(LocalTypeBinding localType) {
if (localType.constantPoolName != null) {
return localType.constantPoolName;
}
if (this.constantPoolNameUsage == null)
this.constantPoolNameUsage = new HashtableOfType();
ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType();
int index = 0;
char[] candidateName;
boolean isCompliant15 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5;
while(true) {
if (localType.isMemberType()){
if (index == 0){
candidateName = CharOperation.concat(
localType.enclosingType().constantPoolName(),
localType.sourceName,
'$');
} else {
candidateName = CharOperation.concat(
localType.enclosingType().constantPoolName(),
'$',
String.valueOf(index).toCharArray(),
'$',
localType.sourceName);
}
} else if (localType.isAnonymousType()){
if (isCompliant15) {
candidateName = CharOperation.concat(
localType.enclosingType.constantPoolName(),
String.valueOf(index+1).toCharArray(),
'$');
} else {
candidateName = CharOperation.concat(
outerMostEnclosingType.constantPoolName(),
String.valueOf(index+1).toCharArray(),
'$');
}
} else {
if (isCompliant15) {
candidateName = CharOperation.concat(
CharOperation.concat(
localType.enclosingType().constantPoolName(),
String.valueOf(index+1).toCharArray(),
'$'),
localType.sourceName);
} else {
candidateName = CharOperation.concat(
outerMostEnclosingType.constantPoolName(),
'$',
String.valueOf(index+1).toCharArray(),
'$',
localType.sourceName);
}
}
if (this.constantPoolNameUsage.get(candidateName) != null) {
index ++;
} else {
this.constantPoolNameUsage.put(candidateName, localType);
break;
}
}
return candidateName;
}
void connectTypeHierarchy() {
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
this.topLevelTypes[i].scope.connectTypeHierarchy();
}
void faultInImports() {
if (this.tempImports != null)
return;
boolean unresolvedFound = false;
boolean reportUnresolved = !this.environment.suppressImportErrors;
if (this.typeOrPackageCache != null && !this.skipCachingImports)
return;
if (this.referenceContext.imports == null) {
this.typeOrPackageCache = new HashtableOfObject(1);
return;
}
int numberOfStatements = this.referenceContext.imports.length;
HashtableOfType typesBySimpleNames = null;
for (int i = 0; i < numberOfStatements; i++) {
if ((this.referenceContext.imports[i].bits & ASTNode.OnDemand) == 0) {
typesBySimpleNames = new HashtableOfType(this.topLevelTypes.length + numberOfStatements);
for (int j = 0, length = this.topLevelTypes.length; j < length; j++)
typesBySimpleNames.put(this.topLevelTypes[j].sourceName, this.topLevelTypes[j]);
break;
}
}
int numberOfImports = numberOfStatements + 1;
for (int i = 0; i < numberOfStatements; i++) {
ImportReference importReference = this.referenceContext.imports[i];
if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
numberOfImports--;
break;
}
}
this.tempImports = new ImportBinding[numberOfImports];
this.tempImports[0] = getDefaultImports()[0];
this.importPtr = 1;
CompilerOptions compilerOptions = compilerOptions();
boolean inJdtDebugCompileMode = compilerOptions.enableJdtDebugCompileMode;
nextImport : for (int i = 0; i < numberOfStatements; i++) {
ImportReference importReference = this.referenceContext.imports[i];
char[][] compoundName = importReference.tokens;
for (int j = 0; j < this.importPtr; j++) {
ImportBinding resolved = this.tempImports[j];
if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) {
if (CharOperation.equals(compoundName, resolved.compoundName)) {
problemReporter().unusedImport(importReference);
continue nextImport;
}
}
}
if ((importReference.bits & ASTNode.OnDemand) != 0) {
Binding importBinding = findImport(compoundName, compoundName.length);
if (!importBinding.isValidBinding()) {
problemReporter().importProblem(importReference, importBinding);
continue nextImport;
}
if (importBinding instanceof PackageBinding) {
PackageBinding uniquePackage = ((PackageBinding)importBinding).getVisibleFor(module(), false);
if (uniquePackage instanceof SplitPackageBinding && !inJdtDebugCompileMode) {
SplitPackageBinding splitPackage = (SplitPackageBinding) uniquePackage;
problemReporter().conflictingPackagesFromModules(splitPackage, module(), importReference.sourceStart, importReference.sourceEnd);
continue nextImport;
}
}
if (importReference.isStatic() && importBinding instanceof PackageBinding) {
problemReporter().cannotImportPackage(importReference);
continue nextImport;
}
recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference));
} else {
Binding importBinding = findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic());
if (importBinding instanceof SplitPackageBinding && !inJdtDebugCompileMode) {
SplitPackageBinding splitPackage = (SplitPackageBinding) importBinding;
int sourceEnd = (int)(importReference.sourcePositions[splitPackage.compoundName.length-1] & 0xFFFF);
problemReporter().conflictingPackagesFromModules((SplitPackageBinding) importBinding, module(), importReference.sourceStart, sourceEnd);
continue nextImport;
}
if (!importBinding.isValidBinding()) {
if (importBinding.problemId() == ProblemReasons.Ambiguous) {
} else {
unresolvedFound = true;
if (reportUnresolved) {
problemReporter().importProblem(importReference, importBinding);
}
continue nextImport;
}
}
if (importBinding instanceof PackageBinding) {
problemReporter().cannotImportPackage(importReference);
continue nextImport;
} else if (this.environment.useModuleSystem && importBinding instanceof ReferenceBinding) {
PackageBinding importedPackage = ((ReferenceBinding) importBinding).fPackage;
if (importedPackage != null) {
if (!importedPackage.isValidBinding()) {
problemReporter().importProblem(importReference, importedPackage);
continue nextImport;
}
importedPackage = (PackageBinding) findImport(importedPackage.compoundName, false, true);
if (importedPackage != null)
importedPackage = importedPackage.getVisibleFor(module(), true);
if (importedPackage instanceof SplitPackageBinding && !inJdtDebugCompileMode) {
SplitPackageBinding splitPackage = (SplitPackageBinding) importedPackage;
int sourceEnd = (int) importReference.sourcePositions[splitPackage.compoundName.length-1];
problemReporter().conflictingPackagesFromModules(splitPackage, module(), importReference.sourceStart, sourceEnd);
continue nextImport;
}
}
}
if(checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName) == -1)
continue nextImport;
if (importReference.isStatic()) {
if (importBinding.kind() == Binding.FIELD) {
checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference);
} else if (importBinding.kind() == Binding.METHOD) {
checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE, importReference);
}
}
}
}
if (this.tempImports.length > this.importPtr)
System.arraycopy(this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr);
this.imports = this.tempImports;
this.tempImports = null;
int length = this.imports.length;
this.typeOrPackageCache = new HashtableOfObject(length);
for (int i = 0; i < length; i++) {
ImportBinding binding = this.imports[i];
if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding || binding instanceof ImportConflictBinding)
this.typeOrPackageCache.put(binding.compoundName[binding.compoundName.length - 1], binding);
}
this.skipCachingImports = this.environment.suppressImportErrors && unresolvedFound;
}
public void faultInTypes() {
faultInImports();
if (this.referenceContext.moduleDeclaration != null) {
this.referenceContext.moduleDeclaration.resolveTypeDirectives(this);
} else if (this.referenceContext.currentPackage != null) {
this.referenceContext.currentPackage.checkPackageConflict(this);
}
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
this.topLevelTypes[i].faultInTypesForFieldsAndMethods();
}
public Binding findImport(char[][] compoundName, boolean findStaticImports, boolean onDemand) {
if(onDemand) {
return findImport(compoundName, compoundName.length);
} else {
return findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, findStaticImports);
}
}
private Binding findImport(char[][] compoundName, int length) {
recordQualifiedReference(compoundName);
ModuleBinding module = module();
Binding binding = this.environment.getTopLevelPackage(compoundName[0]);
int i = 1;
foundNothingOrType: if (binding != null) {
PackageBinding packageBinding = (PackageBinding) binding;
while (i < length) {
binding = packageBinding.getTypeOrPackage(compoundName[i++], module, i<length);
if (binding instanceof ReferenceBinding && binding.problemId() == ProblemReasons.NotAccessible) {
return this.environment.convertToRawType((TypeBinding) binding, false );
}
if (binding == null) {
break foundNothingOrType;
} else if (!binding.isValidBinding()) {
if (binding.problemId() == ProblemReasons.Ambiguous && packageBinding instanceof SplitPackageBinding)
return packageBinding;
binding = null;
break foundNothingOrType;
}
if (!(binding instanceof PackageBinding)) {
PackageBinding visibleFor = packageBinding.getVisibleFor(module, false);
if (visibleFor instanceof SplitPackageBinding)
return visibleFor;
break foundNothingOrType;
}
packageBinding = (PackageBinding) binding;
}
if (packageBinding.isValidBinding() && !module.canAccess(packageBinding))
return new ProblemPackageBinding(compoundName, ProblemReasons.NotAccessible, this.environment);
return packageBinding;
}
ReferenceBinding type;
if (binding == null) {
if (!module.isUnnamed()) {
Binding inaccessible = this.environment.getInaccessibleBinding(compoundName, module);
if (inaccessible != null)
return inaccessible;
}
if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
return problemType(compoundName, i, null);
type = findType(compoundName[0], this.environment.defaultPackage, this.environment.defaultPackage);
if (type == null || !type.isValidBinding())
return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, ProblemReasons.NotFound);
i = 1;
} else {
type = (ReferenceBinding) binding;
}
while (i < length) {
type = (ReferenceBinding)this.environment.convertToRawType(type, false );
if (!type.canBeSeenBy(this.fPackage))
return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), type, ProblemReasons.NotVisible);
char[] name = compoundName[i++];
type = type.getMemberType(name);
if (type == null)
return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, ProblemReasons.NotFound);
}
if (!type.canBeSeenBy(this.fPackage))
return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotVisible);
return type;
}
private Binding findSingleImport(char[][] compoundName, int mask, boolean findStaticImports) {
if (compoundName.length == 1) {
if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4 && !this.referenceContext.isModuleInfo())
return new ProblemReferenceBinding(compoundName, null, ProblemReasons.NotFound);
ReferenceBinding typeBinding = findType(compoundName[0], this.environment.defaultPackage, this.fPackage);
if (typeBinding == null)
return new ProblemReferenceBinding(compoundName, null, ProblemReasons.NotFound);
return typeBinding;
}
if (findStaticImports)
return findSingleStaticImport(compoundName, mask);
return findImport(compoundName, compoundName.length);
}
private Binding findSingleStaticImport(char[][] compoundName, int mask) {
Binding binding = findImport(compoundName, compoundName.length - 1);
if (!binding.isValidBinding()) return binding;
char[] name = compoundName[compoundName.length - 1];
if (binding instanceof PackageBinding) {
Binding temp = ((PackageBinding) binding).getTypeOrPackage(name, module(), false);
if (temp != null && temp instanceof ReferenceBinding)
return new ProblemReferenceBinding(compoundName, (ReferenceBinding) temp, ProblemReasons.InvalidTypeForStaticImport);
return binding;
}
ReferenceBinding type = (ReferenceBinding) binding;
FieldBinding field = (mask & Binding.FIELD) != 0 ? findField(type, name, null, true) : null;
if (field != null) {
if (field.problemId() == ProblemReasons.Ambiguous && ((ProblemFieldBinding) field).closestMatch.isStatic())
return field;
if (field.isValidBinding() && field.isStatic() && field.canBeSeenBy(type, null, this))
return field;
}
MethodBinding method = (mask & Binding.METHOD) != 0 ? findStaticMethod(type, name) : null;
if (method != null) return method;
type = findMemberType(name, type);
if (type == null || !type.isStatic()) {
if (field != null && !field.isValidBinding() && field.problemId() != ProblemReasons.NotFound)
return field;
return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotFound);
}
if (type.isValidBinding() && !type.canBeSeenBy(this.fPackage))
return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotVisible);
if (type.problemId() == ProblemReasons.NotVisible)
return new ProblemReferenceBinding(compoundName, ((ProblemReferenceBinding) type).closestMatch, ProblemReasons.NotVisible);
return type;
}
private MethodBinding findStaticMethod(ReferenceBinding currentType, char[] selector) {
if (!currentType.canBeSeenBy(this))
return null;
do {
currentType.initializeForStaticImports();
MethodBinding[] methods = currentType.getMethods(selector);
if (methods != Binding.NO_METHODS) {
for (int i = methods.length; --i >= 0;) {
MethodBinding method = methods[i];
if (method.isStatic() && method.canBeSeenBy(this.fPackage))
return method;
}
}
} while ((currentType = currentType.superclass()) != null);
return null;
}
ImportBinding[] getDefaultImports() {
if (this.environment.root.defaultImports != null) return this.environment.root.defaultImports;
Binding importBinding = this.environment.getTopLevelPackage(TypeConstants.JAVA);
if (importBinding != null)
importBinding = ((PackageBinding) importBinding).getTypeOrPackage(TypeConstants.JAVA_LANG[1], module(), false);
if (importBinding == null || !importBinding.isValidBinding()) {
problemReporter().isClassPathCorrect(
TypeConstants.JAVA_LANG_OBJECT,
this.referenceContext,
this.environment.missingClassFileLocation);
BinaryTypeBinding missingObject = this.environment.createMissingType(null, TypeConstants.JAVA_LANG_OBJECT);
importBinding = missingObject.fPackage;
}
return this.environment.root.defaultImports = new ImportBinding[] {new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null)};
}
public final Binding getImport(char[][] compoundName, boolean onDemand, boolean isStaticImport) {
if (onDemand)
return findImport(compoundName, compoundName.length);
return findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, isStaticImport);
}
public int nextCaptureID() {
return this.captureID++;
}
@Override
public ModuleBinding module() {
if (!this.referenceContext.isModuleInfo() &&
this.referenceContext.types == null &&
this.referenceContext.currentPackage == null &&
this.referenceContext.imports == null) {
this.environment = this.environment.UnNamedModule.environment;
return this.environment.UnNamedModule;
}
return super.module();
}
@Override
public ProblemReporter problemReporter() {
ProblemReporter problemReporter = this.referenceContext.problemReporter;
problemReporter.referenceContext = this.referenceContext;
return problemReporter;
}
void recordQualifiedReference(char[][] qualifiedName) {
if (this.qualifiedReferences == null) return;
int length = qualifiedName.length;
if (length > 1) {
recordRootReference(qualifiedName[0]);
while (this.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) {
recordRootReference(qualifiedName[0]);
recordSimpleReference(qualifiedName[0]);
}
}
void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
recordQualifiedReference(qualifiedEnclosingName);
if (qualifiedEnclosingName.length == 0)
recordRootReference(simpleName);
recordSimpleReference(simpleName);
}
void recordReference(ReferenceBinding type, char[] simpleName) {
ReferenceBinding actualType = typeToRecord(type);
if (actualType != null)
recordReference(actualType.compoundName, simpleName);
}
void recordRootReference(char[] simpleName) {
if (this.rootReferences == null) return;
this.rootReferences.add(simpleName);
}
void recordSimpleReference(char[] simpleName) {
if (this.simpleNameReferences == null) return;
this.simpleNameReferences.add(simpleName);
}
void recordSuperTypeReference(TypeBinding type) {
if (this.referencedSuperTypes == null) return;
ReferenceBinding actualType = typeToRecord(type);
if (actualType != null && this.referencedSuperTypesSet.add(new ReferenceBindingSetWrapper(actualType)))
this.referencedSuperTypes.add(actualType);
}
public void recordTypeConversion(TypeBinding superType, TypeBinding subType) {
recordSuperTypeReference(subType);
}
void recordTypeReference(TypeBinding type) {
if (this.referencedTypes == null) return;
ReferenceBinding actualType = typeToRecord(type);
if (actualType != null)
this.referencedTypes.add(new ReferenceBindingSetWrapper(actualType));
}
void recordTypeReferences(TypeBinding[] types) {
if (this.referencedTypes == null) return;
if (types == null || types.length == 0) return;
for (int i = 0, max = types.length; i < max; i++) {
ReferenceBinding actualType = typeToRecord(types[i]);
if (actualType != null)
this.referencedTypes.add(new ReferenceBindingSetWrapper(actualType));
}
}
Binding resolveSingleImport(ImportBinding importBinding, int mask) {
if (importBinding.resolvedImport == null) {
importBinding.resolvedImport = findSingleImport(importBinding.compoundName, mask, importBinding.isStatic());
if (!importBinding.resolvedImport.isValidBinding() || importBinding.resolvedImport instanceof PackageBinding) {
if (importBinding.resolvedImport.problemId() == ProblemReasons.Ambiguous)
return importBinding.resolvedImport;
if (this.imports != null) {
ImportBinding[] newImports = new ImportBinding[this.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() {
for (int i = 0; i < this.referencedSuperTypes.size; i++) {
ReferenceBinding type = (ReferenceBinding) this.referencedSuperTypes.elementAt(i);
this.referencedTypes.add(new ReferenceBindingSetWrapper(type));
if (!type.isLocalType()) {
ReferenceBinding enclosing = type.enclosingType();
if (enclosing != null)
recordSuperTypeReference(enclosing);
}
ReferenceBinding superclass = type.superclass();
if (superclass != null)
recordSuperTypeReference(superclass);
ReferenceBinding[] interfaces = type.superInterfaces();
if (interfaces != null)
for (int j = 0, length = interfaces.length; j < length; j++)
recordSuperTypeReference(interfaces[j]);
}
for (ReferenceBindingSetWrapper wrapper : this.referencedTypes) {
ReferenceBinding type = wrapper.referenceBinding;
if (!type.isLocalType())
recordQualifiedReference(type.isMemberType()
? CharOperation.splitOn('.', type.readableName())
: type.compoundName);
}
int size = this.qualifiedReferences.size;
char[][][] qualifiedRefs = new char[size][][];
for (int i = 0; i < size; i++)
qualifiedRefs[i] = this.qualifiedReferences.elementAt(i);
this.referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
size = this.simpleNameReferences.size;
char[][] simpleRefs = new char[size][];
for (int i = 0; i < size; i++)
simpleRefs[i] = this.simpleNameReferences.elementAt(i);
this.referenceContext.compilationResult.simpleNameReferences = simpleRefs;
size = this.rootReferences.size;
char[][] rootRefs = new char[size][];
for (int i = 0; i < size; i++)
rootRefs[i] = this.rootReferences.elementAt(i);
this.referenceContext.compilationResult.rootReferences = rootRefs;
}
@Override
public String toString() {
return "--- CompilationUnit Scope : " + new String(this.referenceContext.getFileName());
}
private ReferenceBinding typeToRecord(TypeBinding type) {
if (type == null)
return null;
while (type.isArrayType())
type = ((ArrayBinding) type).leafComponentType();
switch (type.kind()) {
case Binding.BASE_TYPE :
case Binding.TYPE_PARAMETER :
case Binding.WILDCARD_TYPE :
case Binding.INTERSECTION_TYPE :
case Binding.INTERSECTION_TYPE18:
case Binding.POLY_TYPE:
return null;
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
type = type.erasure();
}
ReferenceBinding refType = (ReferenceBinding) type;
if (refType.isLocalType()) return null;
return refType;
}
public void verifyMethods(MethodVerifier verifier) {
for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
this.topLevelTypes[i].verifyMethods(verifier);
}
private void recordImportBinding(ImportBinding bindingToAdd) {
if (this.tempImports.length == this.importPtr) {
System.arraycopy(this.tempImports, 0, (this.tempImports = new ImportBinding[this.importPtr + 1]), 0, this.importPtr);
}
this.tempImports[this.importPtr++] = bindingToAdd;
}
private void checkMoreStaticBindings(
char[][] compoundName,
HashtableOfType typesBySimpleNames,
int mask,
ImportReference importReference) {
Binding importBinding = findSingleStaticImport(compoundName, mask);
if (!importBinding.isValidBinding()) {
if (importBinding.problemId() == ProblemReasons.Ambiguous) {
checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName);
}
} else {
checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName);
}
if (((mask & Binding.METHOD) != 0) && (importBinding.kind() == Binding.METHOD)) {
mask &= ~Binding.METHOD;
checkMoreStaticBindings(compoundName, typesBySimpleNames, mask, importReference);
}
}
private int checkAndRecordImportBinding(
Binding importBinding,
HashtableOfType typesBySimpleNames,
ImportReference importReference,
char[][] compoundName) {
ReferenceBinding conflictingType = null;
if (importBinding instanceof MethodBinding) {
conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length);
if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic()))
conflictingType = null;
}
final char[] name = compoundName[compoundName.length - 1];
if (importBinding instanceof ReferenceBinding || conflictingType != null) {
ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType;
ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous
? ((ProblemReferenceBinding) referenceBinding).closestMatch
: referenceBinding;
if (importReference.isTypeUseDeprecated(typeToCheck, this))
problemReporter().deprecatedType(typeToCheck, importReference);
ReferenceBinding existingType = typesBySimpleNames.get(name);
if (existingType != null) {
if (TypeBinding.equalsEquals(existingType, referenceBinding)) {
for (int j = 0; j < this.importPtr; j++) {
ImportBinding resolved = this.tempImports[j];
if (resolved instanceof ImportConflictBinding) {
ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved;
if (TypeBinding.equalsEquals(importConflictBinding.conflictingTypeBinding, referenceBinding)) {
if (!importReference.isStatic()) {
problemReporter().duplicateImport(importReference);
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
}
}
} else if (resolved.resolvedImport == referenceBinding) {
if (importReference.isStatic() != resolved.isStatic()) {
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
}
}
}
return -1;
}
for (int j = 0, length = this.topLevelTypes.length; j < length; j++) {
if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) {
problemReporter().conflictingImport(importReference);
return -1;
}
}
if (importReference.isStatic() && importBinding instanceof ReferenceBinding && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
for (int j = 0; j < this.importPtr; j++) {
ImportBinding resolved = this.tempImports[j];
if (resolved.isStatic() && resolved.resolvedImport instanceof ReferenceBinding && importBinding != resolved.resolvedImport) {
if (CharOperation.equals(name, resolved.compoundName[resolved.compoundName.length - 1])) {
ReferenceBinding type = (ReferenceBinding) resolved.resolvedImport;
resolved.resolvedImport = new ProblemReferenceBinding(new char[][] { name }, type, ProblemReasons.Ambiguous);
return -1;
}
}
}
}
problemReporter().duplicateImport(importReference);
return -1;
}
typesBySimpleNames.put(name, referenceBinding);
} else if (importBinding instanceof FieldBinding) {
for (int j = 0; j < this.importPtr; j++) {
ImportBinding resolved = this.tempImports[j];
if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) {
if (CharOperation.equals(name, resolved.compoundName[resolved.compoundName.length - 1])) {
if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
FieldBinding field = (FieldBinding) resolved.resolvedImport;
resolved.resolvedImport = new ProblemFieldBinding(field, field.declaringClass, name, ProblemReasons.Ambiguous);
return -1;
} else {
problemReporter().duplicateImport(importReference);
return -1;
}
}
}
}
}
if (conflictingType == null) {
recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
} else {
recordImportBinding(new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference));
}
return this.importPtr;
}
@Override
public boolean hasDefaultNullnessFor(int location, int sourceStart) {
int nonNullByDefaultValue = localNonNullByDefaultValue(sourceStart);
if (nonNullByDefaultValue != 0) {
return (nonNullByDefaultValue & location) != 0;
}
if (this.fPackage != null)
return (this.fPackage.getDefaultNullness() & location) != 0;
return false;
}
@Override
public Binding checkRedundantDefaultNullness(int nullBits, int sourceStart) {
Binding target = localCheckRedundantDefaultNullness(nullBits, sourceStart);
if (target != null) {
return target;
}
if (this.fPackage != null) {
return this.fPackage.findDefaultNullnessTarget(n -> n == nullBits);
}
return null;
}
public void registerInferredInvocation(Invocation invocation) {
if (this.inferredInvocations == null)
this.inferredInvocations = new ArrayList<>();
this.inferredInvocations.add(invocation);
}
public void cleanUpInferenceContexts() {
if (this.inferredInvocations == null)
return;
for (Invocation invocation : this.inferredInvocations)
invocation.cleanUpInferenceContexts();
this.inferredInvocations = null;
}
}