diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SubpackagesScope.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SubpackagesScope.kt index 047dbbf275b..74faea608d2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SubpackagesScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SubpackagesScope.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl import org.jetbrains.kotlin.utils.Printer @@ -47,6 +48,7 @@ public class SubpackagesScope(private val moduleDescriptor: ModuleDescriptor, pr override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { if (!kindFilter.acceptsKinds(DescriptorKindFilter.PACKAGES_MASK)) return listOf() + if (fqName.isRoot() && kindFilter.excludes.contains(DescriptorKindExclude.TopLevelPackages)) return listOf() val subFqNames = moduleDescriptor.getSubPackagesOf(fqName, nameFilter) val result = ArrayList(subFqNames.size()) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt index 85b66567d91..92bfceafb2c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScope.kt @@ -229,4 +229,17 @@ public trait DescriptorKindExclude { override val fullyExcludedDescriptorKinds: Int get() = 0 } + + public object TopLevelPackages : DescriptorKindExclude { + override fun excludes(descriptor: DeclarationDescriptor): Boolean { + val fqName = when (descriptor) { + is PackageFragmentDescriptor -> descriptor.fqName + is PackageViewDescriptor -> descriptor.fqName + else -> return false + } + return fqName.parent().isRoot() + } + + override val fullyExcludedDescriptorKinds: Int get() = 0 + } } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index 77faf1bfc0d..c5262d5ff28 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -75,10 +75,13 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, private val completionKind = calcCompletionKind() - override val descriptorKindFilter = if (isNoQualifierContext()) - completionKind.descriptorKindFilter?.withoutKinds(DescriptorKindFilter.PACKAGES_MASK) - else + override val descriptorKindFilter = if (isNoQualifierContext()) { + // it's an optimization because obtaining top-level packages from scope is very slow, we obtains them in other way + completionKind.descriptorKindFilter?.exclude(DescriptorKindExclude.TopLevelPackages) + } + else { completionKind.descriptorKindFilter + } private val parameterNameAndTypeCompletion = if (shouldCompleteParameterNameAndType()) ParameterNameAndTypeCompletion(collector, lookupElementFactory, prefixMatcher, resolutionFacade) @@ -202,8 +205,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration, } // getting root packages from scope is very slow so we do this in alternative way - if (isNoQualifierContext() && (completionKind.descriptorKindFilter?.kindMask ?: 0).and(DescriptorKindFilter.PACKAGES_MASK) != 0) { - //TODO: move this code somewhere else + if (isNoQualifierContext() && (descriptorKindFilter?.kindMask ?: 0).and(DescriptorKindFilter.PACKAGES_MASK) != 0) { + //TODO: move this code somewhere else? val packageNames = PackageIndexUtil.getSubPackageFqNames(FqName.ROOT, originalSearchScope, project, prefixMatcher.asNameFilter()) .toMutableSet() diff --git a/idea/idea-completion/testData/basic/common/PackageCompletionInClassBody.kt b/idea/idea-completion/testData/basic/common/PackageCompletionInClassBody.kt new file mode 100644 index 00000000000..b93bb6dcdd5 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/PackageCompletionInClassBody.kt @@ -0,0 +1,8 @@ +import java.util + +class A { + +} + +// EXIST: { lookupString: "kotlin", itemText: "kotlin", tailText: null, typeText: null } +// EXIST_JAVA_ONLY: { lookupString: "util", itemText: "util", tailText: " (java.util)", typeText: null } diff --git a/idea/idea-completion/testData/basic/common/TopLevelPackageInClassBody.kt b/idea/idea-completion/testData/basic/common/TopLevelPackageInClassBody.kt deleted file mode 100644 index adf75a918cf..00000000000 --- a/idea/idea-completion/testData/basic/common/TopLevelPackageInClassBody.kt +++ /dev/null @@ -1,5 +0,0 @@ -class A { - kot -} - -// EXIST: "kotlin" diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index 7774d5abeec..17d0f23125e 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -733,6 +733,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("PackageCompletionInClassBody.kt") + public void testPackageCompletionInClassBody() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/PackageCompletionInClassBody.kt"); + doTest(fileName); + } + @TestMetadata("PrivatesInSecondPressCompletion.kt") public void testPrivatesInSecondPressCompletion() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/PrivatesInSecondPressCompletion.kt"); @@ -865,12 +871,6 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } - @TestMetadata("TopLevelPackageInClassBody.kt") - public void testTopLevelPackageInClassBody() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelPackageInClassBody.kt"); - doTest(fileName); - } - @TestMetadata("TypeParameterFromOuterClass.kt") public void testTypeParameterFromOuterClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeParameterFromOuterClass.kt"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java index 6f4be44d652..09d6cf25142 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java @@ -733,6 +733,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("PackageCompletionInClassBody.kt") + public void testPackageCompletionInClassBody() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/PackageCompletionInClassBody.kt"); + doTest(fileName); + } + @TestMetadata("PrivatesInSecondPressCompletion.kt") public void testPrivatesInSecondPressCompletion() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/PrivatesInSecondPressCompletion.kt"); @@ -865,12 +871,6 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } - @TestMetadata("TopLevelPackageInClassBody.kt") - public void testTopLevelPackageInClassBody() throws Exception { - String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TopLevelPackageInClassBody.kt"); - doTest(fileName); - } - @TestMetadata("TypeParameterFromOuterClass.kt") public void testTypeParameterFromOuterClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/TypeParameterFromOuterClass.kt");