diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java index 84b4f3d03ce..ace34b45e2e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -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 directives, JetScope rootScope) { - processImportsInFile(classes, scope, directives, rootScope, configuration, trace, qualifiedExpressionResolver, psiBuilder); + private void processImportsInFile(@NotNull LookupMode lookupMode, WritableScope scope, List 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 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 resolvedDirectives = Maps.newHashMap(); @@ -127,19 +128,19 @@ public class ImportsResolver { for (JetImportDirective importDirective : importDirectives) { Collection 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); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java index a36ba7b4d4e..a3ac86261b6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java @@ -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 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 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 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 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 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 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 lookupSelectorDescriptors(@NotNull JetSimpleNameExpression selector, @NotNull Collection declarationDescriptors, @NotNull BindingTrace trace, - @NotNull JetScope scopeToCheckVisibility, boolean onlyClasses, boolean storeResult) { + @NotNull JetScope scopeToCheckVisibility, @NotNull LookupMode lookupMode, boolean storeResult) { Set 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 results, @NotNull LookupResult result) { @@ -216,17 +235,18 @@ public class QualifiedExpressionResolver { @NotNull public Collection 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 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 filterAndStoreResolutionResult(@NotNull Collection 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 filteredDescriptors; - if (onlyClasses) { + if (lookupMode == LookupMode.ONLY_CLASSES) { filteredDescriptors = Collections2.filter(descriptors, new Predicate() { @Override public boolean apply(@Nullable DeclarationDescriptor descriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java index dae859ea127..0d65c30842d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java @@ -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) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index 8e5160902e5..0b0a36ef6aa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -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(),