From 42deb7db48f5da0e850c878a45e4ecbdb19f704a Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Tue, 24 Dec 2019 17:08:00 +0300 Subject: [PATCH] KT-34582 Exclude `kotlin.coroutines.experimental` package from completion and auto-import - Exclusion happens only when `ReleaseCoroutines` feature is supported - Add `LANGUAGE_VERSION` to few tests to make sure that previous exclusions still work when `experimental` package is not excluded entirely - ^KT-34582 Fixed --- .../testData/basic/common/CoroutineContext.kt | 2 ++ .../common/CoroutineContextReleaseCoroutines.kt | 7 +++++++ .../test/JSBasicCompletionTestGenerated.java | 5 +++++ .../test/JvmBasicCompletionTestGenerated.java | 5 +++++ .../idea/core/excludedFromImportsAndCompletion.kt | 13 +++++++++++++ .../quickfix/autoImports/excludedCoroutineImpl.kt | 1 + .../autoImports/excludedCoroutineIntrinsics.kt | 1 + 7 files changed, 34 insertions(+) create mode 100644 idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt diff --git a/idea/idea-completion/testData/basic/common/CoroutineContext.kt b/idea/idea-completion/testData/basic/common/CoroutineContext.kt index bcf052941ba..5305156df15 100644 --- a/idea/idea-completion/testData/basic/common/CoroutineContext.kt +++ b/idea/idea-completion/testData/basic/common/CoroutineContext.kt @@ -2,5 +2,7 @@ suspend fun foo() { corou } +// LANGUAGE_VERSION: 1.2 // EXIST: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines.experimental)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} +// ABSENT: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} // ABSENT: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines.experimental.intrinsics)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} diff --git a/idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt b/idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt new file mode 100644 index 00000000000..87036696335 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt @@ -0,0 +1,7 @@ +suspend fun foo() { + corou +} + +// ABSENT: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines.experimental)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} +// EXIST: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} +// ABSENT: {"lookupString":"coroutineContext","tailText":" (kotlin.coroutines.experimental.intrinsics)","typeText":"CoroutineContext","attributes":"","allLookupStrings":"coroutineContext, getCoroutineContext","itemText":"coroutineContext"} 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 c79f48a782b..e9e1aa34a9b 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 @@ -90,6 +90,11 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes runTest("idea/idea-completion/testData/basic/common/CoroutineContext.kt"); } + @TestMetadata("CoroutineContextReleaseCoroutines.kt") + public void testCoroutineContextReleaseCoroutines() throws Exception { + runTest("idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt"); + } + @TestMetadata("DataClassMembers.kt") public void testDataClassMembers() throws Exception { runTest("idea/idea-completion/testData/basic/common/DataClassMembers.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 75cb8e5d18d..15cf0e65c14 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 @@ -90,6 +90,11 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT runTest("idea/idea-completion/testData/basic/common/CoroutineContext.kt"); } + @TestMetadata("CoroutineContextReleaseCoroutines.kt") + public void testCoroutineContextReleaseCoroutines() throws Exception { + runTest("idea/idea-completion/testData/basic/common/CoroutineContextReleaseCoroutines.kt"); + } + @TestMetadata("DataClassMembers.kt") public void testDataClassMembers() throws Exception { runTest("idea/idea-completion/testData/basic/common/DataClassMembers.kt"); diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/excludedFromImportsAndCompletion.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/excludedFromImportsAndCompletion.kt index 2853ca7210a..1ab4f4c7bfa 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/excludedFromImportsAndCompletion.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/excludedFromImportsAndCompletion.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.idea.core import com.intellij.codeInsight.JavaProjectCodeInsightSettings import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.psi.KtFile @@ -25,8 +27,19 @@ private val exclusions = private fun shouldBeHiddenAsInternalImplementationDetail(fqName: String, locationFqName: String) = exclusions.any { fqName.startsWith(it) } && (locationFqName.isBlank() || !fqName.startsWith(locationFqName)) +/** + * We do not want to show nothing from "kotlin.coroutines.experimental" when release coroutines are available, + * since in 1.3 this package is obsolete. + * + * However, we still want to show this package when release coroutines are not available. + */ +private fun usesOutdatedCoroutinesPackage(fqName: String, inFile: KtFile): Boolean = + fqName.startsWith("kotlin.coroutines.experimental.") && + inFile.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) + fun DeclarationDescriptor.isExcludedFromAutoImport(project: Project, inFile: KtFile?): Boolean { val fqName = importableFqName?.asString() ?: return false return JavaProjectCodeInsightSettings.getSettings(project).isExcluded(fqName) || + (inFile != null && usesOutdatedCoroutinesPackage(fqName, inFile)) || shouldBeHiddenAsInternalImplementationDetail(fqName, inFile?.packageFqName?.asString() ?: "") } diff --git a/idea/testData/quickfix/autoImports/excludedCoroutineImpl.kt b/idea/testData/quickfix/autoImports/excludedCoroutineImpl.kt index 43ac3ed327d..e98d76753a3 100644 --- a/idea/testData/quickfix/autoImports/excludedCoroutineImpl.kt +++ b/idea/testData/quickfix/autoImports/excludedCoroutineImpl.kt @@ -1,5 +1,6 @@ // "Import" "false" // WITH_RUNTIME +// LANGUAGE_VERSION: 1.2 // ACTION: Create local variable 'CoroutineImpl' // ACTION: Create object 'CoroutineImpl' // ACTION: Create parameter 'CoroutineImpl' diff --git a/idea/testData/quickfix/autoImports/excludedCoroutineIntrinsics.kt b/idea/testData/quickfix/autoImports/excludedCoroutineIntrinsics.kt index 4076cb01cc6..f233bec1436 100644 --- a/idea/testData/quickfix/autoImports/excludedCoroutineIntrinsics.kt +++ b/idea/testData/quickfix/autoImports/excludedCoroutineIntrinsics.kt @@ -1,5 +1,6 @@ // "Import" "false" // WITH_RUNTIME +// LANGUAGE_VERSION: 1.2 // ACTION: Create function 'suspendCoroutineOrReturn' // ACTION: Rename reference // ERROR: Unresolved reference: suspendCoroutineOrReturn