diff --git a/idea/build.gradle.kts b/idea/build.gradle.kts
index 113a1a354ee..0c88433e109 100644
--- a/idea/build.gradle.kts
+++ b/idea/build.gradle.kts
@@ -87,6 +87,7 @@ dependencies {
Platform[193].orHigher {
implementation(commonDep("org.jetbrains.intellij.deps.completion", "completion-ranking-kotlin"))
+ implementation(intellijPluginDep("stats-collector"))
}
compileOnly(commonDep("org.jetbrains", "markdown"))
diff --git a/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties b/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties
index 04197a1f6b6..1acdc7363ff 100644
--- a/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties
+++ b/idea/idea-analysis/resources/org/jetbrains/kotlin/idea/KotlinBundle.properties
@@ -285,3 +285,7 @@ scratch.inlay.output.mode.description=Inlay output mode
# Code insight
dialog.import.on.paste.title3=Select Import to Remove
copy.paste.reference.notification={0} {0, choice, 1#import was|2#imports were} added
Review Added Imports...
+
+# Experimental features
+
+experimental.ml.completion=ML Completion for Kotlin
\ No newline at end of file
diff --git a/idea/resources/META-INF/plugin.xml b/idea/resources/META-INF/plugin.xml
index 4e97757eb9f..cec3145bbab 100644
--- a/idea/resources/META-INF/plugin.xml
+++ b/idea/resources/META-INF/plugin.xml
@@ -30,6 +30,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
Git4Idea
org.jetbrains.debugger.streams
+ com.intellij.stats.completion
+
diff --git a/idea/resources/META-INF/plugin.xml.201 b/idea/resources/META-INF/plugin.xml.201
index 63cd761d3e2..9f7cf1dc2ac 100644
--- a/idea/resources/META-INF/plugin.xml.201
+++ b/idea/resources/META-INF/plugin.xml.201
@@ -30,6 +30,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
Git4Idea
org.jetbrains.debugger.streams
+ com.intellij.stats.completion
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ExperimentalFeatures.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ExperimentalFeatures.kt
index bf8b0a0420a..24efdd73eb7 100644
--- a/idea/src/org/jetbrains/kotlin/idea/configuration/ExperimentalFeatures.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ExperimentalFeatures.kt
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.registry.Registry
import com.intellij.ui.components.JBCheckBox
import org.jdesktop.swingx.VerticalLayout
import org.jetbrains.kotlin.config.KotlinCompilerVersion
+import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.PlatformVersion
import org.jetbrains.kotlin.idea.projectWizard.WizardStatsService
import org.jetbrains.kotlin.idea.util.isDev
@@ -18,39 +19,60 @@ import javax.swing.JCheckBox
import javax.swing.JPanel
object ExperimentalFeatures {
- val NewJ2k = ExperimentalFeature(
+ val NewJ2k = RegistryExperimentalFeature(
title = "New Java to Kotlin converter",
registryKey = "kotlin.experimental.new.j2k",
enabledByDefault = true
)
- val NewWizard = ExperimentalFeature(
+ val NewWizard = object : RegistryExperimentalFeature(
title = "New Kotlin project wizard",
registryKey = "kotlin.experimental.project.wizard",
- enabledByDefault = false,
- shouldBeShown = {
- val platformVersion = PlatformVersion.getCurrent() ?: return@ExperimentalFeature true
- platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO
- },
- onFeatureStatusChanged = { enabled ->
+ enabledByDefault = false
+ ) {
+ override fun shouldBeShown(): Boolean {
+ val platformVersion = PlatformVersion.getCurrent() ?: return true
+ return platformVersion.platform != PlatformVersion.Platform.ANDROID_STUDIO
+ }
+
+ override fun onFeatureStatusChanged(enabled: Boolean) {
WizardStatsService.logWizardStatusChanged(isEnabled = enabled)
}
- )
+ }
+
+ object MLCompletionForKotlinFeature : ExperimentalFeature {
+ override val title: String
+ get() = KotlinBundle.message("experimental.ml.completion")
+
+ override fun shouldBeShown(): Boolean = MLCompletionForKotlin.isAvailable
+
+ override var isEnabled: Boolean
+ get() = MLCompletionForKotlin.isEnabled
+ set(value) {
+ MLCompletionForKotlin.isEnabled = value
+ }
+ }
val allFeatures: List = listOf(
NewJ2k,
- NewWizard
+ NewWizard,
+ MLCompletionForKotlinFeature
)
}
-class ExperimentalFeature(
- val title: String,
+interface ExperimentalFeature {
+ val title: String
+ var isEnabled: Boolean
+ fun shouldBeShown(): Boolean = true
+ fun onFeatureStatusChanged(enabled: Boolean) {}
+}
+
+open class RegistryExperimentalFeature(
+ override val title: String,
private val registryKey: String,
- private val enabledByDefault: Boolean,
- val shouldBeShown: () -> Boolean = { true },
- val onFeatureStatusChanged: (enabled: Boolean) -> Unit = {}
-) {
- var isEnabled
+ private val enabledByDefault: Boolean
+) : ExperimentalFeature {
+ final override var isEnabled
get() = Registry.`is`(registryKey, enabledByDefault)
set(value) {
Registry.get(registryKey).setValue(value)
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt
new file mode 100644
index 00000000000..98f56f2a0c6
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.configuration
+
+import com.intellij.completion.settings.CompletionMLRankingSettings
+import kotlin.reflect.jvm.isAccessible
+
+internal object MLCompletionForKotlin {
+ const val isAvailable: Boolean = true
+
+ var isEnabled: Boolean
+ get() {
+ val settings = CompletionMLRankingSettings.getInstance()
+ return settings.isRankingEnabledHacked && settings.isLanguageEnabled("Kotlin")
+ }
+ set(value) {
+ val settings = CompletionMLRankingSettings.getInstance()
+ if (value && !settings.isRankingEnabledHacked) {
+ settings.isRankingEnabledHacked = true
+ }
+
+ settings.setLanguageEnabled("Kotlin", value)
+ }
+}
+
+/**
+ * Setter for this property is package-private, so we have to use reflection to change its value.
+ */
+private var CompletionMLRankingSettings.isRankingEnabledHacked: Boolean
+ get() = isRankingEnabled
+ set(value) {
+ val rankingEnabledSetter = this::class.members.find { it.name == "setRankingEnabled" }
+ ?: error("Cannot find 'setRankingEnabled' in class members: ${this::class.members}")
+
+ rankingEnabledSetter.isAccessible = true
+ rankingEnabledSetter.call(this, value)
+ rankingEnabledSetter.isAccessible = false
+ }
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.192 b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.192
new file mode 100644
index 00000000000..360edbe7218
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.192
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.configuration
+
+internal object MLCompletionForKotlin {
+ const val isAvailable: Boolean = false
+
+ override var isEnabled: Boolean
+ get() = false
+ set(value) {
+ throw UnsupportedOperationException()
+ }
+}
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as34 b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as34
new file mode 100644
index 00000000000..360edbe7218
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as34
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.configuration
+
+internal object MLCompletionForKotlin {
+ const val isAvailable: Boolean = false
+
+ override var isEnabled: Boolean
+ get() = false
+ set(value) {
+ throw UnsupportedOperationException()
+ }
+}
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as35 b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as35
new file mode 100644
index 00000000000..360edbe7218
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as35
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.configuration
+
+internal object MLCompletionForKotlin {
+ const val isAvailable: Boolean = false
+
+ override var isEnabled: Boolean
+ get() = false
+ set(value) {
+ throw UnsupportedOperationException()
+ }
+}
diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as40 b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as40
new file mode 100644
index 00000000000..360edbe7218
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/configuration/MLCompletionForKotlin.kt.as40
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.configuration
+
+internal object MLCompletionForKotlin {
+ const val isAvailable: Boolean = false
+
+ override var isEnabled: Boolean
+ get() = false
+ set(value) {
+ throw UnsupportedOperationException()
+ }
+}