Create enumeration LookupMode instead of using boolean onlyClasses

This commit is contained in:
Nikolay Krasko
2012-12-29 16:46:19 +04:00
parent 73785e74bc
commit 69f699e6a1
4 changed files with 73 additions and 49 deletions
@@ -36,6 +36,7 @@ import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver.LookupMode;
public class ImportsResolver {
@NotNull
@@ -75,30 +76,30 @@ public class ImportsResolver {
}
public void processTypeImports(@NotNull JetScope rootScope) {
processImports(true, rootScope);
processImports(LookupMode.ONLY_CLASSES, rootScope);
}
public void processMembersImports(@NotNull JetScope rootScope) {
processImports(false, rootScope);
processImports(LookupMode.EVERYTHING, rootScope);
}
private void processImports(boolean onlyClasses, @NotNull JetScope rootScope) {
private void processImports(@NotNull LookupMode lookupMode, @NotNull JetScope rootScope) {
for (JetFile file : context.getNamespaceDescriptors().keySet()) {
WritableScope namespaceScope = context.getNamespaceScopes().get(file);
processImportsInFile(onlyClasses, namespaceScope, Lists.newArrayList(file.getImportDirectives()), rootScope);
processImportsInFile(lookupMode, namespaceScope, Lists.newArrayList(file.getImportDirectives()), rootScope);
}
for (JetScript script : context.getScripts().keySet()) {
WritableScope scriptScope = context.getScriptScopes().get(script);
processImportsInFile(onlyClasses, scriptScope, script.getImportDirectives(), rootScope);
processImportsInFile(lookupMode, scriptScope, script.getImportDirectives(), rootScope);
}
}
private void processImportsInFile(boolean classes, WritableScope scope, List<JetImportDirective> directives, JetScope rootScope) {
processImportsInFile(classes, scope, directives, rootScope, configuration, trace, qualifiedExpressionResolver, psiBuilder);
private void processImportsInFile(@NotNull LookupMode lookupMode, WritableScope scope, List<JetImportDirective> directives, JetScope rootScope) {
processImportsInFile(lookupMode, scope, directives, rootScope, configuration, trace, qualifiedExpressionResolver, psiBuilder);
}
public static void processImportsInFile(
boolean onlyClasses,
@NotNull LookupMode lookupMode,
@NotNull WritableScope namespaceScope,
@NotNull List<JetImportDirective> importDirectives,
@NotNull JetScope rootScope,
@@ -109,7 +110,7 @@ public class ImportsResolver {
) {
Importer.DelayedImporter delayedImporter = new Importer.DelayedImporter(namespaceScope);
if (!onlyClasses) {
if (lookupMode == LookupMode.EVERYTHING) {
namespaceScope.clearImports();
}
@@ -119,7 +120,7 @@ public class ImportsResolver {
JetImportDirective defaultImportDirective = psiBuilder.createImportDirective(defaultImportPath);
qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, namespaceScope, delayedImporter,
temporaryTrace, configuration, onlyClasses);
temporaryTrace, configuration, lookupMode);
}
Map<JetImportDirective, DeclarationDescriptor> resolvedDirectives = Maps.newHashMap();
@@ -127,19 +128,19 @@ public class ImportsResolver {
for (JetImportDirective importDirective : importDirectives) {
Collection<? extends DeclarationDescriptor> descriptors =
qualifiedExpressionResolver.processImportReference(importDirective, rootScope, namespaceScope, delayedImporter,
trace, configuration, onlyClasses);
trace, configuration, lookupMode);
if (descriptors.size() == 1) {
resolvedDirectives.put(importDirective, descriptors.iterator().next());
}
for (DeclarationDescriptor descriptor : descriptors) {
JetExpression importedReference = importDirective.getImportedReference();
if (onlyClasses || importedReference == null) continue;
if (lookupMode == LookupMode.ONLY_CLASSES || importedReference == null) continue;
reportPlatformClassMappedToKotlin(configuration, trace, importedReference, descriptor);
}
}
delayedImporter.processImports();
if (!onlyClasses) {
if (lookupMode == LookupMode.EVERYTHING) {
for (JetImportDirective importDirective : importDirectives) {
reportUselessImport(importDirective, namespaceScope, resolvedDirectives, trace);
}
@@ -36,6 +36,13 @@ import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
public class QualifiedExpressionResolver {
public enum LookupMode {
// Only classifier and packages are resolved
ONLY_CLASSES,
// Resolve all descriptors
EVERYTHING
}
@NotNull
public Collection<? extends DeclarationDescriptor> analyseImportReference(
@@ -44,7 +51,7 @@ public class QualifiedExpressionResolver {
@NotNull BindingTrace trace,
@NotNull ModuleConfiguration moduleConfiguration
) {
return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, moduleConfiguration, false);
return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, moduleConfiguration, LookupMode.EVERYTHING);
}
@NotNull
@@ -55,7 +62,7 @@ public class QualifiedExpressionResolver {
@NotNull Importer importer,
@NotNull BindingTrace trace,
@NotNull ModuleConfiguration moduleConfiguration,
boolean onlyClasses
@NotNull LookupMode lookupMode
) {
if (importDirective.isAbsoluteInRootNamespace()) {
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
@@ -69,16 +76,20 @@ public class QualifiedExpressionResolver {
Collection<? extends DeclarationDescriptor> descriptors;
if (importedReference instanceof JetQualifiedExpression) {
//store result only when we find all descriptors, not only classes on the second phase
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)importedReference, scope, scopeToCheckVisibility, trace, onlyClasses, !onlyClasses);
descriptors = lookupDescriptorsForQualifiedExpression(
(JetQualifiedExpression)importedReference, scope, scopeToCheckVisibility, trace,
lookupMode, lookupMode == LookupMode.EVERYTHING);
}
else {
assert importedReference instanceof JetSimpleNameExpression;
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)importedReference, scope, scopeToCheckVisibility, trace, onlyClasses, true, !onlyClasses);
descriptors = lookupDescriptorsForSimpleNameReference(
(JetSimpleNameExpression)importedReference, scope, scopeToCheckVisibility, trace,
lookupMode, true, lookupMode == LookupMode.EVERYTHING);
}
JetSimpleNameExpression referenceExpression = JetPsiUtil.getLastReference(importedReference);
if (importDirective.isAllUnder()) {
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression, trace, onlyClasses)) {
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression, trace, lookupMode)) {
return Collections.emptyList();
}
@@ -101,18 +112,20 @@ public class QualifiedExpressionResolver {
}
private boolean canImportMembersFrom(@NotNull Collection<? extends DeclarationDescriptor> descriptors,
@NotNull JetSimpleNameExpression reference, @NotNull BindingTrace trace, boolean onlyClasses) {
@NotNull JetSimpleNameExpression reference, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode
) {
if (onlyClasses) {
if (lookupMode == LookupMode.ONLY_CLASSES) {
return true;
}
if (descriptors.size() == 1) {
return canImportMembersFrom(descriptors.iterator().next(), reference, trace, onlyClasses);
return canImportMembersFrom(descriptors.iterator().next(), reference, trace, lookupMode);
}
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace, "trace to find out if members can be imported from", reference);
boolean canImport = false;
for (DeclarationDescriptor descriptor : descriptors) {
canImport |= canImportMembersFrom(descriptor, reference, temporaryTrace, onlyClasses);
canImport |= canImportMembersFrom(descriptor, reference, temporaryTrace, lookupMode);
}
if (!canImport) {
temporaryTrace.commit();
@@ -121,9 +134,10 @@ public class QualifiedExpressionResolver {
}
private boolean canImportMembersFrom(@NotNull DeclarationDescriptor descriptor,
@NotNull JetSimpleNameExpression reference, @NotNull BindingTrace trace, boolean onlyClasses) {
@NotNull JetSimpleNameExpression reference, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode
) {
assert !onlyClasses;
assert lookupMode == LookupMode.EVERYTHING;
if (descriptor instanceof NamespaceDescriptor) {
return true;
}
@@ -148,24 +162,26 @@ public class QualifiedExpressionResolver {
}
JetUserType qualifier = userType.getQualifier();
if (qualifier == null) {
return lookupDescriptorsForSimpleNameReference(referenceExpression, outerScope, outerScope, trace, true, false, true);
return lookupDescriptorsForSimpleNameReference(referenceExpression, outerScope, outerScope, trace, LookupMode.ONLY_CLASSES, false, true);
}
Collection<? extends DeclarationDescriptor> declarationDescriptors = lookupDescriptorsForUserType(qualifier, outerScope, trace);
return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, outerScope, true, true);
return lookupSelectorDescriptors(referenceExpression, declarationDescriptors, trace, outerScope, LookupMode.ONLY_CLASSES, true);
}
@NotNull
public Collection<? extends DeclarationDescriptor> lookupDescriptorsForQualifiedExpression(@NotNull JetQualifiedExpression importedReference,
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, boolean onlyClasses, boolean storeResult) {
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode, boolean storeResult) {
JetExpression receiverExpression = importedReference.getReceiverExpression();
Collection<? extends DeclarationDescriptor> declarationDescriptors;
if (receiverExpression instanceof JetQualifiedExpression) {
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace, onlyClasses, storeResult);
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace,
lookupMode, storeResult);
}
else {
assert receiverExpression instanceof JetSimpleNameExpression;
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace, onlyClasses, true, storeResult);
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression)receiverExpression, outerScope, scopeToCheckVisibility, trace,
lookupMode, true, storeResult);
}
JetExpression selectorExpression = importedReference.getSelectorExpression();
@@ -175,37 +191,40 @@ public class QualifiedExpressionResolver {
JetSimpleNameExpression selector = (JetSimpleNameExpression)selectorExpression;
JetSimpleNameExpression lastReference = JetPsiUtil.getLastReference(receiverExpression);
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference, trace, onlyClasses)) {
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference, trace, lookupMode)) {
return Collections.emptyList();
}
return lookupSelectorDescriptors(selector, declarationDescriptors, trace, scopeToCheckVisibility, onlyClasses, storeResult);
return lookupSelectorDescriptors(selector, declarationDescriptors, trace, scopeToCheckVisibility, lookupMode, storeResult);
}
@NotNull
private Collection<? extends DeclarationDescriptor> lookupSelectorDescriptors(@NotNull JetSimpleNameExpression selector,
@NotNull Collection<? extends DeclarationDescriptor> declarationDescriptors, @NotNull BindingTrace trace,
@NotNull JetScope scopeToCheckVisibility, boolean onlyClasses, boolean storeResult) {
@NotNull JetScope scopeToCheckVisibility, @NotNull LookupMode lookupMode, boolean storeResult) {
Set<SuccessfulLookupResult> results = Sets.newHashSet();
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof NamespaceDescriptor) {
addResult(results, lookupSimpleNameReference(selector, ((NamespaceDescriptor)declarationDescriptor).getMemberScope(), onlyClasses, true));
addResult(results, lookupSimpleNameReference(selector, ((NamespaceDescriptor)declarationDescriptor).getMemberScope(),
lookupMode, true));
}
if (declarationDescriptor instanceof ClassDescriptor) {
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope((ClassDescriptor)declarationDescriptor, onlyClasses), onlyClasses, false));
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope((ClassDescriptor)declarationDescriptor,
lookupMode), lookupMode, false));
ClassDescriptor classObjectDescriptor = ((ClassDescriptor)declarationDescriptor).getClassObjectDescriptor();
if (classObjectDescriptor != null) {
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope(classObjectDescriptor, onlyClasses), onlyClasses, false));
addResult(results, lookupSimpleNameReference(selector, getAppropriateScope(classObjectDescriptor, lookupMode),
lookupMode, false));
}
}
}
return filterAndStoreResolutionResult(results, selector, trace, scopeToCheckVisibility, onlyClasses, storeResult);
return filterAndStoreResolutionResult(results, selector, trace, scopeToCheckVisibility, lookupMode, storeResult);
}
@NotNull
private JetScope getAppropriateScope(@NotNull ClassDescriptor classDescriptor, boolean onlyClasses) {
return onlyClasses ? classDescriptor.getUnsubstitutedInnerClassesScope() : classDescriptor.getDefaultType().getMemberScope();
private JetScope getAppropriateScope(@NotNull ClassDescriptor classDescriptor, @NotNull LookupMode lookupMode) {
return lookupMode == LookupMode.ONLY_CLASSES ? classDescriptor.getUnsubstitutedInnerClassesScope() : classDescriptor.getDefaultType().getMemberScope();
}
private void addResult(@NotNull Set<SuccessfulLookupResult> results, @NotNull LookupResult result) {
@@ -216,17 +235,18 @@ public class QualifiedExpressionResolver {
@NotNull
public Collection<? extends DeclarationDescriptor> lookupDescriptorsForSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, boolean onlyClasses, boolean namespaceLevel, boolean storeResult) {
@NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode, boolean namespaceLevel, boolean storeResult) {
LookupResult lookupResult = lookupSimpleNameReference(referenceExpression, outerScope, onlyClasses, namespaceLevel);
LookupResult lookupResult = lookupSimpleNameReference(referenceExpression, outerScope, lookupMode, namespaceLevel);
if (lookupResult == LookupResult.EMPTY) return Collections.emptyList();
return filterAndStoreResolutionResult(Collections.singletonList((SuccessfulLookupResult)lookupResult), referenceExpression, trace, scopeToCheckVisibility,
onlyClasses, storeResult);
lookupMode, storeResult);
}
@NotNull
private LookupResult lookupSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression,
@NotNull JetScope outerScope, boolean onlyClasses, boolean namespaceLevel) {
@NotNull JetScope outerScope, @NotNull LookupMode lookupMode, boolean namespaceLevel) {
Name referencedName = referenceExpression.getReferencedNameAsName();
Set<DeclarationDescriptor> descriptors = Sets.newHashSet();
@@ -240,7 +260,7 @@ public class QualifiedExpressionResolver {
descriptors.add(classifierDescriptor);
}
if (onlyClasses) {
if (lookupMode == LookupMode.ONLY_CLASSES) {
ClassDescriptor objectDescriptor = outerScope.getObjectDescriptor(referencedName);
if (objectDescriptor != null) {
descriptors.add(objectDescriptor);
@@ -261,7 +281,7 @@ public class QualifiedExpressionResolver {
@NotNull
private Collection<? extends DeclarationDescriptor> filterAndStoreResolutionResult(@NotNull Collection<SuccessfulLookupResult> lookupResults,
@NotNull JetSimpleNameExpression referenceExpression, @NotNull final BindingTrace trace, @NotNull JetScope scopeToCheckVisibility,
boolean onlyClasses, boolean storeResult) {
@NotNull LookupMode lookupMode, boolean storeResult) {
if (lookupResults.isEmpty()) {
return Collections.emptyList();
@@ -284,7 +304,7 @@ public class QualifiedExpressionResolver {
}
Collection<DeclarationDescriptor> filteredDescriptors;
if (onlyClasses) {
if (lookupMode == LookupMode.ONLY_CLASSES) {
filteredDescriptors = Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
@@ -38,6 +38,8 @@ import org.jetbrains.jet.util.QualifiedNamesUtil;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver.LookupMode;
public class ResolveSessionUtils {
// This name is used as a key for the case when something has no name _due to a syntactic error_
@@ -285,11 +287,11 @@ public class ResolveSessionUtils {
if (element instanceof JetDotQualifiedExpression) {
descriptors = qualifiedExpressionResolver.lookupDescriptorsForQualifiedExpression(
(JetDotQualifiedExpression) element, rootPackage.getMemberScope(), scope, trace, false, false);
(JetDotQualifiedExpression) element, rootPackage.getMemberScope(), scope, trace, LookupMode.EVERYTHING, false);
}
else {
descriptors = qualifiedExpressionResolver.lookupDescriptorsForSimpleNameReference(
(JetSimpleNameExpression) element, rootPackage.getMemberScope(), scope, trace, false, false, false);
(JetSimpleNameExpression) element, rootPackage.getMemberScope(), scope, trace, LookupMode.EVERYTHING, false, false);
}
for (DeclarationDescriptor descriptor : descriptors) {
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.*;
@@ -78,7 +79,7 @@ public class ScopeProvider {
fileScope.importScope(rootPackageDescriptor.getMemberScope());
}
ImportsResolver.processImportsInFile(true, fileScope, Lists.newArrayList(file.getImportDirectives()),
ImportsResolver.processImportsInFile(QualifiedExpressionResolver.LookupMode.ONLY_CLASSES, fileScope, Lists.newArrayList(file.getImportDirectives()),
rootPackageDescriptor.getMemberScope(),
resolveSession.getModuleConfiguration(), resolveSession.getTrace(),
resolveSession.getInjector().getQualifiedExpressionResolver(),
@@ -119,7 +120,7 @@ public class ScopeProvider {
fileMemberScope.changeLockLevel(WritableScope.LockLevel.BOTH);
ImportsResolver.processImportsInFile(false, fileMemberScope, Lists.newArrayList(file.getImportDirectives()),
ImportsResolver.processImportsInFile(QualifiedExpressionResolver.LookupMode.EVERYTHING, fileMemberScope, Lists.newArrayList(file.getImportDirectives()),
rootPackageDescriptor.getMemberScope(),
resolveSession.getModuleConfiguration(), resolveSession.getTrace(),
resolveSession.getInjector().getQualifiedExpressionResolver(),