From b888ea601cc4680a58aa55abec67fb9dcc63e2a2 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 14 Jan 2015 20:55:53 +0300 Subject: [PATCH] Changed imports semantics: imports order does not affect resolve, explicit imports have higher priority for classes --- .../org/jetbrains/kotlin/resolve/Importer.kt | 133 ++++++++---------- .../kotlin/resolve/ImportsResolver.java | 8 +- .../resolve/QualifiedExpressionResolver.java | 14 +- .../kotlin/resolve/lazy/ImportsProvider.java | 59 ++++---- .../kotlin/resolve/lazy/LazyImportScope.kt | 54 ++++--- .../tests/imports/AllUnderImportsAmbiguity.kt | 17 +++ .../imports/AllUnderImportsAmbiguity.txt | 31 ++++ .../imports/AllUnderImportsLessPriority.kt | 17 +++ .../imports/AllUnderImportsLessPriority.txt | 31 ++++ .../AllUnderImportsSamePriorityForFunction.kt | 19 +++ ...AllUnderImportsSamePriorityForFunction.txt | 13 ++ .../AllUnderImportsSamePriorityForProperty.kt | 19 +++ ...AllUnderImportsSamePriorityForProperty.txt | 13 ++ .../tests/imports/ExplicitImportsAmbiguity.kt | 17 +++ .../imports/ExplicitImportsAmbiguity.txt | 31 ++++ .../ExplicitImportsUnambiguityForFunction.kt | 19 +++ .../ExplicitImportsUnambiguityForFunction.txt | 13 ++ .../imports/ImportConflictAllPackage.resolve | 8 +- .../ImportConflictPackageAndClass.resolve | 2 +- .../ImportConflictSameNameClass.resolve | 8 +- .../imports/ImportResolveOrderStable.resolve | 4 +- .../checkers/JetDiagnosticsTestGenerated.java | 36 +++++ .../kotlin/idea/caches/KotlinIndicesHelper.kt | 3 +- 23 files changed, 427 insertions(+), 142 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.txt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.kt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.txt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.kt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.txt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.kt create mode 100644 compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.txt create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.txt create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.kt create mode 100644 compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt index 5241bdeb2cb..1321302cc16 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/Importer.kt @@ -23,95 +23,84 @@ import org.jetbrains.kotlin.resolve.scopes.FilteringScope import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.WritableScope import java.util.ArrayList +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.utils.Printer -public trait Importer { - public fun addAllUnderImport(descriptor: DeclarationDescriptor) - public fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) +public class Importer(private val platformToKotlinClassMap: PlatformToKotlinClassMap) { + private val allUnderImportScopes = ArrayList() + private val explicitImports = ArrayList>() - public open class StandardImporter( - private val fileScope: WritableScope, - private val platformToKotlinClassMap: PlatformToKotlinClassMap - ) : Importer { - - override fun addAllUnderImport(descriptor: DeclarationDescriptor) { - importAllUnderDeclaration(descriptor) + public fun addAllUnderImport(descriptor: DeclarationDescriptor) { + if (descriptor is PackageViewDescriptor) { + val scope = NoSubpackagesInPackageScope(descriptor) + allUnderImportScopes.add(createFilteringScope(scope, descriptor, platformToKotlinClassMap)) } - - override fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) { - importDeclarationAlias(descriptor, aliasName) + else if (descriptor is ClassDescriptor && descriptor.getKind() != ClassKind.OBJECT) { + allUnderImportScopes.add(descriptor.getStaticScope()) + allUnderImportScopes.add(descriptor.getUnsubstitutedInnerClassesScope()) + val classObjectDescriptor = descriptor.getClassObjectDescriptor() + if (classObjectDescriptor != null) { + allUnderImportScopes.add(classObjectDescriptor.getUnsubstitutedInnerClassesScope()) + } } + } - protected fun importDeclarationAlias(descriptor: DeclarationDescriptor, aliasName: Name) { + private fun createFilteringScope(scope: JetScope, descriptor: PackageViewDescriptor, platformToKotlinClassMap: PlatformToKotlinClassMap): JetScope { + val kotlinAnalogsForClassesInside = platformToKotlinClassMap.mapPlatformClassesInside(descriptor) + if (kotlinAnalogsForClassesInside.isEmpty()) return scope + return FilteringScope(scope) { descriptor -> kotlinAnalogsForClassesInside.all { it.getName() != descriptor.getName() } } + } + + public fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) { + explicitImports.add(descriptor to aliasName) + } + + public fun doImport(targetScope: WritableScope) { + // import all imports with '*' first because they have lower priority + targetScope.importScope(AllUnderImportsScope(allUnderImportScopes)) + + for ((descriptor, name) in explicitImports) { when (descriptor) { - is ClassifierDescriptor -> fileScope.importClassifierAlias(aliasName, descriptor) - is PackageViewDescriptor -> fileScope.importPackageAlias(aliasName, descriptor) - is FunctionDescriptor -> fileScope.importFunctionAlias(aliasName, descriptor) - is VariableDescriptor -> fileScope.importVariableAlias(aliasName, descriptor) + is ClassifierDescriptor -> targetScope.importClassifierAlias(name, descriptor) + is PackageViewDescriptor -> targetScope.importPackageAlias(name, descriptor) + is FunctionDescriptor -> targetScope.importFunctionAlias(name, descriptor) + is VariableDescriptor -> targetScope.importVariableAlias(name, descriptor) else -> error("Unknown descriptor") } } - - protected fun importAllUnderDeclaration(descriptor: DeclarationDescriptor) { - if (descriptor is PackageViewDescriptor) { - val scope = NoSubpackagesInPackageScope(descriptor) - fileScope.importScope(createFilteringScope(scope, descriptor, platformToKotlinClassMap)) - } - else if (descriptor is ClassDescriptor && descriptor.getKind() != ClassKind.OBJECT) { - fileScope.importScope(descriptor.getStaticScope()) - fileScope.importScope(descriptor.getUnsubstitutedInnerClassesScope()) - val classObjectDescriptor = descriptor.getClassObjectDescriptor() - if (classObjectDescriptor != null) { - fileScope.importScope(classObjectDescriptor.getUnsubstitutedInnerClassesScope()) - } - } - } - - private fun createFilteringScope(scope: JetScope, descriptor: PackageViewDescriptor, platformToKotlinClassMap: PlatformToKotlinClassMap): JetScope { - val kotlinAnalogsForClassesInside = platformToKotlinClassMap.mapPlatformClassesInside(descriptor) - if (kotlinAnalogsForClassesInside.isEmpty()) return scope - return FilteringScope(scope) { descriptor -> kotlinAnalogsForClassesInside.all { it.getName() != descriptor.getName() } } - } } - public class DelayedImporter( - fileScope: WritableScope, - platformToKotlinClassMap: PlatformToKotlinClassMap - ) : StandardImporter(fileScope, platformToKotlinClassMap) { - - private trait DelayedImportEntry - - private class AllUnderImportEntry(val descriptor: DeclarationDescriptor) : DelayedImportEntry - - private class AliasImportEntry(val descriptor: DeclarationDescriptor, val name: Name) : DelayedImportEntry - - private val imports = ArrayList() - - override fun addAllUnderImport(descriptor: DeclarationDescriptor) { - imports.add(AllUnderImportEntry(descriptor)) + private class AllUnderImportsScope(private val scopes: Collection) : JetScope { + override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + return scopes.flatMap { it.getDescriptors(kindFilter, nameFilter) } } - override fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) { - imports.add(AliasImportEntry(descriptor, aliasName)) + override fun getClassifier(name: Name): ClassifierDescriptor? { + return scopes.stream().map { it.getClassifier(name) }.filterNotNull().singleOrNull() } - public fun processImports() { - for (anImport in imports) { - if (anImport is AllUnderImportEntry) { - importAllUnderDeclaration(anImport.descriptor) - } - else { - anImport as AliasImportEntry - importDeclarationAlias(anImport.descriptor, anImport.name) - } - } - } - } - - object DoNothingImporter : Importer { - override fun addAllUnderImport(descriptor: DeclarationDescriptor) { + override fun getProperties(name: Name): Collection { + return scopes.flatMap { it.getProperties(name) } } - override fun addAliasImport(descriptor: DeclarationDescriptor, aliasName: Name) { + override fun getFunctions(name: Name): Collection { + return scopes.flatMap { it.getFunctions(name) } + } + + override fun getPackage(name: Name): PackageViewDescriptor? = null // packages are not imported by all under imports + + override fun getLocalVariable(name: Name): VariableDescriptor? = null + + override fun getContainingDeclaration(): DeclarationDescriptor = throw UnsupportedOperationException() + + override fun getDeclarationsByLabel(labelName: Name): Collection = listOf() + + override fun getImplicitReceiversHierarchy(): List = listOf() + + override fun getOwnDeclaredDescriptors(): Collection = listOf() + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.getSimpleName()) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java index 160a031d0e0..777cb6ba178 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ImportsResolver.java @@ -99,7 +99,7 @@ public class ImportsResolver { ) { @NotNull JetScope rootScope = JetModuleUtil.getSubpackagesOfRootScope(module); - Importer.DelayedImporter delayedImporter = new Importer.DelayedImporter(fileScope, module.getPlatformToKotlinClassMap()); + Importer importer = new Importer(module.getPlatformToKotlinClassMap()); if (lookupMode == LookupMode.EVERYTHING) { fileScope.clearImports(); } @@ -109,7 +109,7 @@ public class ImportsResolver { trace, "transient trace to resolve default imports"); //not to trace errors of default imports JetImportDirective defaultImportDirective = importsFactory.createImportDirective(defaultImportPath); - qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, fileScope, delayedImporter, + qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, fileScope, importer, temporaryTrace, lookupMode); } @@ -119,7 +119,7 @@ public class ImportsResolver { for (JetImportDirective importDirective : importDirectives) { Collection descriptors = - qualifiedExpressionResolver.processImportReference(importDirective, rootScopeForFile, fileScope, delayedImporter, + qualifiedExpressionResolver.processImportReference(importDirective, rootScopeForFile, fileScope, importer, trace, lookupMode); if (!descriptors.isEmpty()) { resolvedDirectives.put(importDirective, descriptors); @@ -129,7 +129,7 @@ public class ImportsResolver { checkPlatformTypesMappedToKotlin(module, trace, importDirective, descriptors); } } - delayedImporter.processImports(); + importer.doImport(fileScope); if (lookupMode == LookupMode.EVERYTHING) { for (JetImportDirective importDirective : importDirectives) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java index 0948d505413..d61523c3852 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.java @@ -58,7 +58,7 @@ public class QualifiedExpressionResolver { @NotNull JetImportDirective importDirective, @NotNull JetScope scope, @NotNull JetScope scopeToCheckVisibility, - @NotNull Importer importer, + @Nullable Importer importer, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode ) { @@ -91,8 +91,10 @@ public class QualifiedExpressionResolver { return Collections.emptyList(); } - for (DeclarationDescriptor descriptor : descriptors) { - importer.addAllUnderImport(descriptor); + if (importer != null) { + for (DeclarationDescriptor descriptor : descriptors) { + importer.addAllUnderImport(descriptor); + } } return Collections.emptyList(); } @@ -102,8 +104,10 @@ public class QualifiedExpressionResolver { return Collections.emptyList(); } - for (DeclarationDescriptor descriptor : descriptors) { - importer.addAliasImport(descriptor, aliasName); + if (importer != null) { + for (DeclarationDescriptor descriptor : descriptors) { + importer.addAliasImport(descriptor, aliasName); + } } return descriptors; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ImportsProvider.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ImportsProvider.java index bc3c71d5e45..2bb288ce225 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ImportsProvider.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ImportsProvider.java @@ -16,8 +16,12 @@ package org.jetbrains.kotlin.resolve.lazy; -import com.google.common.collect.*; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; import kotlin.Function0; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.JetImportDirective; @@ -25,8 +29,8 @@ import org.jetbrains.kotlin.resolve.ImportPath; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; +import java.util.Collections; import java.util.List; -import java.util.Set; class ImportsProvider { private final List importDirectives; @@ -43,8 +47,8 @@ class ImportsProvider { } @NotNull - public List getImports(@NotNull Name name) { - return importsCacheValue.invoke().getImports(name); + public List getImports(@NotNull Name name, @NotNull LookupMode mode) { + return importsCacheValue.invoke().getImports(name, mode); } @NotNull @@ -52,6 +56,12 @@ class ImportsProvider { return importDirectives; } + public enum LookupMode { + CLASS, + PACKAGE, + FUNCTION_OR_PROPERTY + } + private static class NameToImportsCache { private final ListMultimap nameToDirectives; private final List allUnderImports; @@ -61,47 +71,42 @@ class ImportsProvider { allUnderImports = imports; } - private List getImports(@NotNull Name name) { - return nameToDirectives.containsKey(name) ? nameToDirectives.get(name) : allUnderImports; + private List getImports(@NotNull Name name, @NotNull LookupMode mode) { + switch (mode) { + case CLASS: + return nameToDirectives.containsKey(name) ? nameToDirectives.get(name) : allUnderImports; // for class lookup explicit imports have priority + + case PACKAGE: + return nameToDirectives.containsKey(name) ? nameToDirectives.get(name) : Collections.emptyList(); // no packages import by all under imports + + case FUNCTION_OR_PROPERTY: + return nameToDirectives.containsKey(name) ? KotlinPackage.plus(nameToDirectives.get(name), allUnderImports) : allUnderImports; + + default: + throw new IllegalArgumentException(); + } } private static NameToImportsCache createIndex(List importDirectives) { ImmutableListMultimap.Builder namesToRelativeImportsBuilder = ImmutableListMultimap.builder(); - Set processedAliases = Sets.newHashSet(); - List processedAllUnderImports = Lists.newArrayList(); + List allUnderImports = Lists.newArrayList(); for (JetImportDirective anImport : importDirectives) { ImportPath path = anImport.getImportPath(); - if (path == null) { - // Could be some parse errors - continue; - } + if (path == null) continue; // Could be some parse errors if (path.isAllUnder()) { - processedAllUnderImports.add(anImport); - - // All-Under import is relevant to all names found so far - for (Name aliasName : processedAliases) { - namesToRelativeImportsBuilder.put(aliasName, anImport); - } + allUnderImports.add(anImport); } else { Name aliasName = path.getImportedName(); assert aliasName != null; - - if (!processedAliases.contains(aliasName)) { - processedAliases.add(aliasName); - - // Add to relevant imports all all-under imports found by this moment - namesToRelativeImportsBuilder.putAll(aliasName, processedAllUnderImports); - } - namesToRelativeImportsBuilder.put(aliasName, anImport); } } - return new NameToImportsCache(namesToRelativeImportsBuilder.build(), ImmutableList.copyOf(processedAllUnderImports)); + return new NameToImportsCache(namesToRelativeImportsBuilder.build(), ImmutableList.copyOf(allUnderImports)); } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index 24e73ab2577..72374a2fbca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.resolve.lazy -import com.google.common.collect.Sets import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.psi.JetCodeFragment import org.jetbrains.kotlin.psi.JetFile @@ -32,6 +31,7 @@ import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.LookupMode import java.util.LinkedHashSet +import java.util.HashSet public class LazyImportScope(private val resolveSession: ResolveSession, private val containingDeclaration: PackageViewDescriptor, @@ -69,7 +69,7 @@ public class LazyImportScope(private val resolveSession: ResolveSession, val directiveImportScope = WritableScopeImpl(JetScope.Empty, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString()) directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH) - val importer = Importer.StandardImporter(directiveImportScope, resolveSession.getModuleDescriptor().platformToKotlinClassMap) + val importer = Importer(resolveSession.getModuleDescriptor().platformToKotlinClassMap) directiveUnderResolve = directive val descriptors: Collection @@ -77,6 +77,7 @@ public class LazyImportScope(private val resolveSession: ResolveSession, val resolver = resolveSession.getQualifiedExpressionResolver() descriptors = resolver.processImportReference(directive, rootScope, containingDeclaration.getMemberScope(), importer, traceForImportResolve, mode) + importer.doImport(directiveImportScope) if (mode == LookupMode.EVERYTHING) { ImportsResolver.checkPlatformTypesMappedToKotlin(containingDeclaration.getModule(), traceForImportResolve, directive, descriptors) } @@ -109,29 +110,40 @@ public class LazyImportScope(private val resolveSession: ResolveSession, } } - private fun selectFirstFromImports(name: Name, lookupMode: LookupMode, descriptorSelector: JetScopeSelectorUtil.ScopeByNameSelector): D? { + private fun selectSingleFromImports( + name: Name, + lookupMode: LookupMode, + selectImportsMode: ImportsProvider.LookupMode, + descriptorSelector: JetScopeSelectorUtil.ScopeByNameSelector + ): D? { fun compute(): D? { - for (directive in importsProvider.getImports(name)) { - if (directive == directiveUnderResolve) { - // This is the recursion in imports analysis - return null - } - - val foundDescriptor = descriptorSelector.get(getImportScope(directive, lookupMode), name) - if (foundDescriptor != null) { - return foundDescriptor - } + // for classes and packages it never returns a mix of explicit and all-under imports so they all have the same priority + val imports = importsProvider.getImports(name, selectImportsMode) + if (imports.contains(directiveUnderResolve)) { + // This is the recursion in imports analysis + return null } - return null + var target: D? = null + for (directive in imports) { + val resolved = descriptorSelector.get(getImportScope(directive, lookupMode), name) ?: continue + if (target != null && target != resolved) return null // ambiguity + target = resolved + } + return target } return resolveSession.getStorageManager().compute(::compute) } - private fun collectFromImports(name: Name, lookupMode: LookupMode, descriptorsSelector: JetScopeSelectorUtil.ScopeByNameMultiSelector): Collection { + private fun collectFromImports( + name: Name, + lookupMode: LookupMode, + selectImportsMode: ImportsProvider.LookupMode, + descriptorsSelector: JetScopeSelectorUtil.ScopeByNameMultiSelector + ): Collection { return resolveSession.getStorageManager().compute { - val descriptors = Sets.newHashSet() - for (directive in importsProvider.getImports(name)) { + val descriptors = HashSet() + for (directive in importsProvider.getImports(name, selectImportsMode)) { if (directive == directiveUnderResolve) { // This is the recursion in imports analysis throw IllegalStateException("Recursion while resolving many imports: " + directive.getText()) @@ -146,15 +158,15 @@ public class LazyImportScope(private val resolveSession: ResolveSession, private fun getImportScope(directive: JetImportDirective, lookupMode: LookupMode) = importedScopesProvider(directive).scopeForMode(lookupMode) - override fun getClassifier(name: Name) = selectFirstFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR) + override fun getClassifier(name: Name) = selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, ImportsProvider.LookupMode.CLASS, JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR) - override fun getPackage(name: Name) = selectFirstFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR) + override fun getPackage(name: Name) = selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, ImportsProvider.LookupMode.PACKAGE, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR) - override fun getProperties(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR) + override fun getProperties(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, ImportsProvider.LookupMode.FUNCTION_OR_PROPERTY, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR) override fun getLocalVariable(name: Name) = null - override fun getFunctions(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR) + override fun getFunctions(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, ImportsProvider.LookupMode.FUNCTION_OR_PROPERTY, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR) override fun getDeclarationsByLabel(labelName: Name): Collection = listOf() diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt new file mode 100644 index 00000000000..2e7741bb479 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a + +class X + +// FILE: b.kt +package b + +class X + +// FILE: c.kt +package c + +import a.* +import b.* + +class Y : X \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.txt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.txt new file mode 100644 index 00000000000..07413aa03e4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.txt @@ -0,0 +1,31 @@ +package + +package a { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package b { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package c { + + internal final class Y { + public constructor Y() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.kt new file mode 100644 index 00000000000..8b2c0dd0003 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a + +open class X + +// FILE: b.kt +package b + +class X + +// FILE: c.kt +package c + +import a.X +import b.* + +class Y : X() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.txt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.txt new file mode 100644 index 00000000000..99170b046a1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.txt @@ -0,0 +1,31 @@ +package + +package a { + + internal open class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package b { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package c { + + internal final class Y : a.X { + public constructor Y() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.kt new file mode 100644 index 00000000000..bd1386f665b --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.kt @@ -0,0 +1,19 @@ +// FILE: a.kt +package a + +fun X(p: Int) {} + +// FILE: b.kt +package b + +fun X(): Int = 1 + +// FILE: c.kt +package c + +import b.* +import a.X + +fun foo() { + val v: Int = X() +} diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.txt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.txt new file mode 100644 index 00000000000..9c54988727b --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.txt @@ -0,0 +1,13 @@ +package + +package a { + internal fun X(/*0*/ p: kotlin.Int): kotlin.Unit +} + +package b { + internal fun X(): kotlin.Int +} + +package c { + internal fun foo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.kt new file mode 100644 index 00000000000..d1b4b80778b --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.kt @@ -0,0 +1,19 @@ +// FILE: a.kt +package a + +var X: Int = 1 + +// FILE: b.kt +package b + +var X: String = "" + +// FILE: c.kt +package c + +import a.X +import b.* + +fun foo() { + X = 1 +} diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.txt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.txt new file mode 100644 index 00000000000..fb00091d06c --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.txt @@ -0,0 +1,13 @@ +package + +package a { + internal var X: kotlin.Int +} + +package b { + internal var X: kotlin.String +} + +package c { + internal fun foo(): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt new file mode 100644 index 00000000000..531567ef13f --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a + +class X + +// FILE: b.kt +package b + +class X + +// FILE: c.kt +package c + +import a.X +import b.X + +class Y : X \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.txt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.txt new file mode 100644 index 00000000000..07413aa03e4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.txt @@ -0,0 +1,31 @@ +package + +package a { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package b { + + internal final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package c { + + internal final class Y { + public constructor Y() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.kt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.kt new file mode 100644 index 00000000000..e7a5ea76530 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.kt @@ -0,0 +1,19 @@ +// FILE: a.kt +package a + +fun X(p: Int) {} + +// FILE: b.kt +package b + +fun X(): Int = 1 + +// FILE: c.kt +package c + +import b.X +import a.X + +fun foo() { + val v: Int = X() +} diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.txt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.txt new file mode 100644 index 00000000000..9c54988727b --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.txt @@ -0,0 +1,13 @@ +package + +package a { + internal fun X(/*0*/ p: kotlin.Int): kotlin.Unit +} + +package b { + internal fun X(): kotlin.Int +} + +package c { + internal fun foo(): kotlin.Unit +} diff --git a/compiler/testData/resolve/imports/ImportConflictAllPackage.resolve b/compiler/testData/resolve/imports/ImportConflictAllPackage.resolve index b5485c62c34..077b485f6e0 100644 --- a/compiler/testData/resolve/imports/ImportConflictAllPackage.resolve +++ b/compiler/testData/resolve/imports/ImportConflictAllPackage.resolve @@ -5,7 +5,7 @@ package test import testing.first.* import testing.second.* -val a1: `second`TestClass? = null +val a1: `!`TestClass? = null //FILE:mainToFirst.kt //---------------------------------------------------------------------------------- @@ -14,16 +14,16 @@ package test import testing.second.* import testing.first.* -val a2: `first`TestClass? = null +val a2: `!`TestClass? = null //FILE:importFirst.kt //---------------------------------------------------------------------------------- package testing.first -class ~first~TestClass +class TestClass //FILE:importSecond.kt //---------------------------------------------------------------------------------- package testing.second -class ~second~TestClass \ No newline at end of file +class TestClass \ No newline at end of file diff --git a/compiler/testData/resolve/imports/ImportConflictPackageAndClass.resolve b/compiler/testData/resolve/imports/ImportConflictPackageAndClass.resolve index c5c5747658e..6e859f3d379 100644 --- a/compiler/testData/resolve/imports/ImportConflictPackageAndClass.resolve +++ b/compiler/testData/resolve/imports/ImportConflictPackageAndClass.resolve @@ -16,7 +16,7 @@ import testing.second.TestClass import testing.first.* // Single import has priority over package import -val a2: `first`TestClass? = null +val a2: `second`TestClass? = null //FILE:importFirst.kt diff --git a/compiler/testData/resolve/imports/ImportConflictSameNameClass.resolve b/compiler/testData/resolve/imports/ImportConflictSameNameClass.resolve index 901694793f3..29852ea1867 100644 --- a/compiler/testData/resolve/imports/ImportConflictSameNameClass.resolve +++ b/compiler/testData/resolve/imports/ImportConflictSameNameClass.resolve @@ -5,7 +5,7 @@ package test import testing.first.TestClass import testing.second.TestClass -val a1: `second`TestClass? = null +val a1: `!`TestClass? = null //FILE:mainToFirst.kt //---------------------------------------------------------------------------------- @@ -14,13 +14,13 @@ package test import testing.second.TestClass import testing.first.TestClass -val a2: `first`TestClass? = null +val a2: `!`TestClass? = null //FILE:importFirst.kt //---------------------------------------------------------------------------------- package testing.first -class ~first~TestClass +class TestClass //FILE:importSecond.kt @@ -28,4 +28,4 @@ class ~first~TestClass package testing.second class testing.second -class ~second~TestClass \ No newline at end of file +class TestClass \ No newline at end of file diff --git a/compiler/testData/resolve/imports/ImportResolveOrderStable.resolve b/compiler/testData/resolve/imports/ImportResolveOrderStable.resolve index d883216630d..680e85831cc 100644 --- a/compiler/testData/resolve/imports/ImportResolveOrderStable.resolve +++ b/compiler/testData/resolve/imports/ImportResolveOrderStable.resolve @@ -8,7 +8,7 @@ import testing.allUnder.* // The goal is to activate lazy resolve in order Second, Other class FirstOrder: `other`Other, FirstInternal -trait FirstInternal: `allUnder`Second +trait FirstInternal: `exact`Second @@ -22,7 +22,7 @@ import testing.allUnder.* // The goal is to activate lazy resolve in order Other, Second class FirstOrder: FirstInternal, `other`Other -trait FirstInternal: `allUnder`Second +trait FirstInternal: `exact`Second diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index c624e33b5db..493e6e4bec6 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -4703,6 +4703,42 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/imports"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AllUnderImportsAmbiguity.kt") + public void testAllUnderImportsAmbiguity() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt"); + doTest(fileName); + } + + @TestMetadata("AllUnderImportsLessPriority.kt") + public void testAllUnderImportsLessPriority() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/AllUnderImportsLessPriority.kt"); + doTest(fileName); + } + + @TestMetadata("AllUnderImportsSamePriorityForFunction.kt") + public void testAllUnderImportsSamePriorityForFunction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForFunction.kt"); + doTest(fileName); + } + + @TestMetadata("AllUnderImportsSamePriorityForProperty.kt") + public void testAllUnderImportsSamePriorityForProperty() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/AllUnderImportsSamePriorityForProperty.kt"); + doTest(fileName); + } + + @TestMetadata("ExplicitImportsAmbiguity.kt") + public void testExplicitImportsAmbiguity() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt"); + doTest(fileName); + } + + @TestMetadata("ExplicitImportsUnambiguityForFunction.kt") + public void testExplicitImportsUnambiguityForFunction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ExplicitImportsUnambiguityForFunction.kt"); + doTest(fileName); + } + @TestMetadata("importFunctionWithAllUnderImport.kt") public void testImportFunctionWithAllUnderImport() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/importFunctionWithAllUnderImport.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/caches/KotlinIndicesHelper.kt b/idea/src/org/jetbrains/kotlin/idea/caches/KotlinIndicesHelper.kt index ce840e48294..feef8ef11cc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/caches/KotlinIndicesHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/caches/KotlinIndicesHelper.kt @@ -186,7 +186,6 @@ public class KotlinIndicesHelper( private fun analyzeImportReference( importDirective: JetImportDirective, scope: JetScope, trace: BindingTrace ): Collection { - return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, Importer.DoNothingImporter, trace, - LookupMode.EVERYTHING) + return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, null, trace, LookupMode.EVERYTHING) } }