From fd07d5f3017715902a248559ec3d506e1755fad7 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Thu, 28 May 2020 18:26:30 +0300 Subject: [PATCH] Scripting setting: auto reloading of script dependencies is now per definition --- ...dScriptConfigurationNotificationFactory.kt | 10 ++- .../core/script/ScriptDefinitionsManager.kt | 9 +- .../ScriptNewDependenciesNotification.kt | 10 ++- .../configuration/DefaultScriptingSupport.kt | 6 +- .../DefaultScriptConfigurationLoader.kt | 7 +- .../ScriptConfigurationLoadingContext.kt | 2 +- .../settings/KotlinScriptingSettings.kt | 86 +++++++++++++------ .../scripting/gradle/GradleImportHelper.kt | 21 ++++- .../gradle/GradleImportHelper.kt.201 | 58 +++++++++---- .../GradleKotlinScriptDefinitionWrapper.kt | 30 +++++++ ...GradleKotlinScriptDefinitionWrapper.kt.201 | 30 +++++++ .../gradle/GradleScriptDefinitionsProvider.kt | 27 ++---- .../scripting/gradle/GradleScriptListener.kt | 4 +- .../gradle/roots/GradleBuildRootsManager.kt | 4 +- .../messages/KotlinBundle.properties | 2 + .../kotlin/idea/IDESettingsFUSCollector.kt | 14 ++- .../KotlinScriptDefinitionsModel.kt | 70 +++++++++++---- .../KotlinScriptingSettingsConfigurable.form | 24 +++--- .../KotlinScriptingSettingsConfigurable.java | 19 ++-- .../idea/script/ScriptOptionsSaveTest.kt | 17 ++-- .../scripting/definitions/ScriptDefinition.kt | 7 +- 21 files changed, 323 insertions(+), 134 deletions(-) create mode 100644 idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt create mode 100644 idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt.201 diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/LoadScriptConfigurationNotificationFactory.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/LoadScriptConfigurationNotificationFactory.kt index aab2960e052..a396052edd3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/LoadScriptConfigurationNotificationFactory.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/LoadScriptConfigurationNotificationFactory.kt @@ -17,6 +17,7 @@ import com.intellij.ui.HyperlinkLabel import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle import org.jetbrains.kotlin.psi.UserDataProperty +import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition object LoadScriptConfigurationNotificationFactory { fun showNotification(file: VirtualFile, project: Project, onClick: () -> Unit): Boolean { @@ -50,7 +51,7 @@ object LoadScriptConfigurationNotificationFactory { return@withSelectedEditor } - val panel = NewLoadConfigurationNotificationPanel(onClick, project) + val panel = NewLoadConfigurationNotificationPanel(onClick, project, this@addLoadConfigurationNotificationPanel) notificationPanel = panel manager.addTopComponent(this, panel) } @@ -72,7 +73,8 @@ object LoadScriptConfigurationNotificationFactory { private class NewLoadConfigurationNotificationPanel( var onClick: () -> Unit, - project: Project + project: Project, + file: VirtualFile ) : EditorNotificationPanel() { init { @@ -83,7 +85,9 @@ object LoadScriptConfigurationNotificationFactory { createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) { onClick() - KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled = true + + val scriptDefinition = file.findScriptDefinition(project) ?: return@createComponentActionLabel + KotlinScriptingSettings.getInstance(project).setAutoReloadConfigurations(scriptDefinition, true) } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt index 8e7307ed927..333e0b6c386 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt @@ -171,6 +171,11 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit } fun reorderScriptDefinitions() = lock.write { + definitions?.forEach { + it.order = KotlinScriptingSettings.getInstance(project).getScriptDefinitionOrder(it) + } + definitions = definitions?.sortedBy { it.order } + updateDefinitions() } @@ -197,10 +202,6 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit private fun updateDefinitions() { assert(lock.isWriteLocked) { "updateDefinitions should only be called under the write lock" } - definitions = definitions?.sortedBy { - KotlinScriptingSettings.getInstance(project).getScriptDefinitionOrder(it) - } - val fileTypeManager = FileTypeManager.getInstance() val newExtensions = getKnownFilenameExtensions().filter { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptNewDependenciesNotification.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptNewDependenciesNotification.kt index 0829ad484e2..2dd675b146f 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptNewDependenciesNotification.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptNewDependenciesNotification.kt @@ -18,6 +18,7 @@ import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle import org.jetbrains.kotlin.psi.UserDataProperty +import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper fun VirtualFile.removeScriptDependenciesNotificationPanel(project: Project) { @@ -45,7 +46,7 @@ fun VirtualFile.addScriptDependenciesNotificationPanel( } } - val panel = NewScriptDependenciesNotificationPanel(onClick, compilationConfigurationResult, project) + val panel = NewScriptDependenciesNotificationPanel(onClick, compilationConfigurationResult, project, this@addScriptDependenciesNotificationPanel) notificationPanel = panel manager.addTopComponent(this, panel) } @@ -81,7 +82,8 @@ private var FileEditor.notificationPanel: NewScriptDependenciesNotificationPanel private class NewScriptDependenciesNotificationPanel( val onClick: () -> Unit, val compilationConfigurationResult: ScriptCompilationConfigurationWrapper, - project: Project + project: Project, + file: VirtualFile ) : EditorNotificationPanel() { init { @@ -92,7 +94,9 @@ private class NewScriptDependenciesNotificationPanel( createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) { onClick() - KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled = true + + val scriptDefinition = file.findScriptDefinition(project) ?: return@createComponentActionLabel + KotlinScriptingSettings.getInstance(project).setAutoReloadConfigurations(scriptDefinition, true) } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/DefaultScriptingSupport.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/DefaultScriptingSupport.kt index 6c4ce711c5d..79eda187b17 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/DefaultScriptingSupport.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/DefaultScriptingSupport.kt @@ -174,7 +174,7 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De if (forceSync) { loaders.firstOrNull { it.loadDependencies(isFirstLoad, file, scriptDefinition, loadingContext) } } else { - val autoReloadEnabled = KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled + val autoReloadEnabled = KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(scriptDefinition) val postponeLoading = isPostponedLoad && !autoReloadEnabled if (postponeLoading) { @@ -206,7 +206,8 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De val applied = cached?.applied if (applied != null && applied.inputs.isUpToDate(project, virtualFile)) { // in case user reverted to applied configuration - suggestOrSaveConfiguration(virtualFile, applied, skipNotification = isLoadingPostponed) + val skipNotification = isLoadingPostponed || KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(scriptDefinition) + suggestOrSaveConfiguration(virtualFile, applied, skipNotification) } else if (cached == null || !cached.isUpToDate(project, virtualFile)) { // don't start loading if nothing was changed // (in case we checking for up-to-date and loading concurrently) @@ -280,7 +281,6 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De } else { val autoReload = skipNotification || oldConfiguration == null - || KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled || ApplicationManager.getApplication().isUnitTestModeWithoutScriptLoadingNotification if (autoReload) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/DefaultScriptConfigurationLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/DefaultScriptConfigurationLoader.kt index 98feb9a2265..7ec2195574f 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/DefaultScriptConfigurationLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/DefaultScriptConfigurationLoader.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs import org.jetbrains.kotlin.idea.core.script.configuration.cache.ScriptConfigurationSnapshot import org.jetbrains.kotlin.idea.core.script.debug +import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition @@ -43,7 +44,11 @@ open class DefaultScriptConfigurationLoader(val project: Project) : ScriptConfig val result = getConfigurationThroughScriptingApi(ktFile, virtualFile, scriptDefinition) - context.suggestNewConfiguration(virtualFile, result) + if (KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(scriptDefinition)) { + context.saveNewConfiguration(virtualFile, result) + } else { + context.suggestNewConfiguration(virtualFile, result) + } return true } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/ScriptConfigurationLoadingContext.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/ScriptConfigurationLoadingContext.kt index c1ef7dc30f9..641edd94607 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/ScriptConfigurationLoadingContext.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/loader/ScriptConfigurationLoadingContext.kt @@ -14,7 +14,7 @@ interface ScriptConfigurationLoadingContext { /** * Show notification about new configuration with suggestion to apply it. - * User may disable this notifications, in this case configuration will be saved immediately. + * User may disable this notifications, in this case [saveNewConfiguration] should be called * * If configuration is null, then the result will be treated as failed, and * reports will be displayed immediately. diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt index 2b45a290c21..b4266a2562c 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt @@ -10,9 +10,11 @@ import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.project.Project import com.intellij.util.addOptionTag -import com.intellij.util.attribute import com.intellij.util.getAttributeBooleanValue import org.jdom.Element +import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager +import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings.KotlinScriptDefinitionValue.Companion.DEFAULT +import org.jetbrains.kotlin.idea.util.application.executeOnPooledThread import org.jetbrains.kotlin.idea.util.application.getServiceSafe import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition @@ -20,8 +22,7 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition name = "KotlinScriptingSettings", storages = [Storage("kotlinScripting.xml")] ) -class KotlinScriptingSettings : PersistentStateComponent { - var isAutoReloadEnabled = false +class KotlinScriptingSettings(private val project: Project) : PersistentStateComponent { /** * true if notification about multiple script definition applicable for one script file is suppressed @@ -33,13 +34,6 @@ class KotlinScriptingSettings : PersistentStateComponent { override fun getState(): Element { val definitionsRootElement = Element("KotlinScriptingSettings") - if (isAutoReloadEnabled) { - definitionsRootElement.addOptionTag( - KotlinScriptingSettings::isAutoReloadEnabled.name, - isAutoReloadEnabled.toString() - ) - } - if (suppressDefinitionsCheck) { definitionsRootElement.addOptionTag( KotlinScriptingSettings::suppressDefinitionsCheck.name, @@ -59,9 +53,6 @@ class KotlinScriptingSettings : PersistentStateComponent { } override fun loadState(state: Element) { - state.getOptionTag(KotlinScriptingSettings::isAutoReloadEnabled.name)?.let { - isAutoReloadEnabled = it - } state.getOptionTag(KotlinScriptingSettings::suppressDefinitionsCheck.name)?.let { suppressDefinitionsCheck = it } @@ -70,29 +61,63 @@ class KotlinScriptingSettings : PersistentStateComponent { for (scriptDefinitionElement in scriptDefinitionsList) { scriptDefinitions[scriptDefinitionElement.toKey()] = scriptDefinitionElement.toValue() } + + if (scriptDefinitionsList.isNotEmpty()) { + executeOnPooledThread { + ScriptDefinitionsManager.getInstance(project).reorderScriptDefinitions() + } + } } fun setOrder(scriptDefinition: ScriptDefinition, order: Int) { - scriptDefinitions[scriptDefinition.toKey()] = scriptDefinitions[scriptDefinition.toKey()]?.copy(order = order) ?: - KotlinScriptDefinitionValue(order) + scriptDefinitions[scriptDefinition.toKey()] = + scriptDefinitions[scriptDefinition.toKey()]?.copy(order = order) ?: KotlinScriptDefinitionValue(order) } fun setEnabled(scriptDefinition: ScriptDefinition, isEnabled: Boolean) { - scriptDefinitions[scriptDefinition.toKey()] = scriptDefinitions[scriptDefinition.toKey()]?.copy(isEnabled = isEnabled) ?: - KotlinScriptDefinitionValue(scriptDefinitions.size, isEnabled) + scriptDefinitions[scriptDefinition.toKey()] = + scriptDefinitions[scriptDefinition.toKey()]?.copy(isEnabled = isEnabled) ?: KotlinScriptDefinitionValue( + scriptDefinition.order, + isEnabled = isEnabled + ) + } + + fun setAutoReloadConfigurations(scriptDefinition: ScriptDefinition, autoReloadScriptDependencies: Boolean) { + scriptDefinitions[scriptDefinition.toKey()] = + scriptDefinitions[scriptDefinition.toKey()]?.copy(autoReloadConfigurations = autoReloadScriptDependencies) + ?: KotlinScriptDefinitionValue( + scriptDefinition.order, + autoReloadConfigurations = autoReloadScriptDependencies + ) } fun getScriptDefinitionOrder(scriptDefinition: ScriptDefinition): Int { - return scriptDefinitions[scriptDefinition.toKey()]?.order ?: Integer.MAX_VALUE + return scriptDefinitions[scriptDefinition.toKey()]?.order ?: DEFAULT.order } fun isScriptDefinitionEnabled(scriptDefinition: ScriptDefinition): Boolean { - return scriptDefinitions[scriptDefinition.toKey()]?.isEnabled ?: true + return scriptDefinitions[scriptDefinition.toKey()]?.isEnabled ?: DEFAULT.isEnabled } - private data class KotlinScriptDefinitionKey(val definitionName: String, val className: String) - private data class KotlinScriptDefinitionValue(val order: Int, val isEnabled: Boolean = true) + fun autoReloadConfigurations(scriptDefinition: ScriptDefinition): Boolean { + return scriptDefinitions[scriptDefinition.toKey()]?.autoReloadConfigurations ?: DEFAULT.autoReloadConfigurations + } + + private data class KotlinScriptDefinitionKey( + val definitionName: String, + val className: String + ) + + private data class KotlinScriptDefinitionValue( + val order: Int, + val isEnabled: Boolean = true, + val autoReloadConfigurations: Boolean = false + ) { + companion object { + val DEFAULT = KotlinScriptDefinitionValue(Integer.MAX_VALUE) + } + } private fun Element.toKey() = KotlinScriptDefinitionKey( getAttributeValue(KotlinScriptDefinitionKey::definitionName.name), @@ -104,8 +129,8 @@ class KotlinScriptingSettings : PersistentStateComponent { private fun Element.addScriptDefinitionContentElement(definition: KotlinScriptDefinitionKey, settings: KotlinScriptDefinitionValue) { addElement(SCRIPT_DEFINITION_TAG).apply { - attribute(KotlinScriptDefinitionKey::className.name, definition.className) - attribute(KotlinScriptDefinitionKey::definitionName.name, definition.definitionName) + setAttribute(KotlinScriptDefinitionKey::className.name, definition.className) + setAttribute(KotlinScriptDefinitionKey::definitionName.name, definition.definitionName) addElement(KotlinScriptDefinitionValue::order.name).apply { text = settings.order.toString() @@ -116,6 +141,11 @@ class KotlinScriptingSettings : PersistentStateComponent { text = settings.isEnabled.toString() } } + if (settings.autoReloadConfigurations) { + addElement(KotlinScriptDefinitionValue::autoReloadConfigurations.name).apply { + text = settings.autoReloadConfigurations.toString() + } + } } } @@ -126,10 +156,14 @@ class KotlinScriptingSettings : PersistentStateComponent { } private fun Element.toValue(): KotlinScriptDefinitionValue { - val order = getChildText(KotlinScriptDefinitionValue::order.name)?.toInt() ?: Integer.MAX_VALUE - val isEnabled = getChildText(KotlinScriptDefinitionValue::isEnabled.name)?.toBoolean() ?: true + val order = getChildText(KotlinScriptDefinitionValue::order.name)?.toInt() + ?: DEFAULT.order + val isEnabled = getChildText(KotlinScriptDefinitionValue::isEnabled.name)?.toBoolean() + ?: DEFAULT.isEnabled + val autoReloadScriptDependencies = getChildText(KotlinScriptDefinitionValue::autoReloadConfigurations.name)?.toBoolean() + ?: DEFAULT.autoReloadConfigurations - return KotlinScriptDefinitionValue(order, isEnabled) + return KotlinScriptDefinitionValue(order, isEnabled, autoReloadScriptDependencies) } private fun Element.getOptionTag(name: String) = diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt index 06e8967c07a..355934599b9 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt @@ -34,11 +34,28 @@ fun runPartialGradleImport(project: Project) { fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.import") fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.label.import.project") +fun autoReloadScriptConfigurations(project: Project): Boolean { + val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID) + val projectSettings = gradleSettings.getLinkedProjectsSettings() + .filterIsInstance() + .firstOrNull() + if (projectSettings != null) { + return projectSettings.isUseAutoImport + } + + return false +} + private const val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts" private var Project.notificationPanel: ScriptConfigurationChangedNotification? by UserDataProperty(Key.create("load.script.configuration.panel")) -fun showNotificationForProjectImport(project: Project) { +fun scriptConfigurationsNeedToBeUpdated(project: Project) { + if (autoReloadScriptConfigurations(project)) { + // import should be run automatically by Gradle plugin + return + } + val existingPanel = project.notificationPanel if (existingPanel != null) { return @@ -56,7 +73,7 @@ fun showNotificationForProjectImport(project: Project) { notification.notify(project) } -fun hideNotificationForProjectImport(project: Project): Boolean { +fun scriptConfigurationsAreUpToDate(project: Project): Boolean { if (project.notificationPanel == null) return false project.notificationPanel?.expire() return true diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt.201 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt.201 index 368c521591a..79cdd03a248 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt.201 +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleImportHelper.kt.201 @@ -16,10 +16,12 @@ import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder import com.intellij.openapi.externalSystem.util.ExternalSystemUtil import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Key +import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.LightVirtualFileBase +import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle +import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy @@ -40,9 +42,21 @@ fun runPartialGradleImport(project: Project) { fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.load.changes") fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.text.load.script.configurations") -fun showNotificationForProjectImport(project: Project) {} +fun autoReloadScriptConfigurations(project: Project): Boolean { + return GradleScriptDefinitionsContributor.getDefinitions(project).any { + KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(it) + } +} -fun hideNotificationForProjectImport(project: Project): Boolean = true +fun scriptConfigurationsNeedToBeUpdated(project: Project) { + if (autoReloadScriptConfigurations(project)) { + runPartialGradleImport(project) + } else { + // notification is shown in LoadConfigurationAction + } +} + +fun scriptConfigurationsAreUpToDate(project: Project): Boolean = true class LoadConfigurationAction : AnAction( KotlinIdeaGradleBundle.message("action.text.load.script.configurations"), @@ -56,29 +70,37 @@ class LoadConfigurationAction : AnAction( override fun update(e: AnActionEvent) { ensureValidActionVisibility(e) - - e.presentation.description = KotlinIdeaGradleBundle.message("action.description.load.script.configurations") } private fun ensureValidActionVisibility(e: AnActionEvent) { val editor = e.getData(CommonDataKeys.EDITOR) ?: return + e.presentation.isVisible = getNotificationVisibility(editor) + } + + private fun getNotificationVisibility(editor: Editor): Boolean { if (DiffUtil.isDiffEditor(editor)) { - e.presentation.isVisible = false - return + return false } - e.presentation.isVisible = editor.getNotificationVisibility() + val project = editor.project ?: return false + val file = getKotlinScriptFile(editor) ?: return false + + if (autoReloadScriptConfigurations(project)) { + return false + } + + return GradleBuildRootsManager.getInstance(project).isConfigurationOutOfDate(file) } - private fun Editor.getNotificationVisibility(): Boolean { - val project = project ?: return false - - val documentManager = FileDocumentManager.getInstance() - val virtualFile = documentManager.getFile(document) - if (virtualFile is LightVirtualFileBase) return false - if (virtualFile == null || !virtualFile.isValid) return false - - return GradleBuildRootsManager.getInstance(project).isConfigurationOutOfDate(virtualFile) - } + private fun getKotlinScriptFile(editor: Editor): VirtualFile? { + return FileDocumentManager.getInstance() + .getFile(editor.document) + ?.takeIf { + it !is LightVirtualFileBase + && it.isValid + && it.fileType != KotlinFileType.INSTANCE + && isGradleKotlinScript(it) + } + } } \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt new file mode 100644 index 00000000000..fe57d04f814 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt @@ -0,0 +1,30 @@ +/* + * 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.scripting.gradle + +import org.jetbrains.kotlin.scripting.definitions.ScriptCompilationConfigurationFromDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition +import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.ScriptingHostConfiguration + +class GradleKotlinScriptDefinitionWrapper( + hostConfiguration: ScriptingHostConfiguration, + legacyDefinition: KotlinScriptDefinitionFromAnnotatedTemplate, + gradleVersion: String, +) : ScriptDefinition.FromLegacy(hostConfiguration, legacyDefinition) { + override val compilationConfiguration by lazy { + ScriptCompilationConfigurationFromDefinition( + hostConfiguration, + legacyDefinition + ).with { + ScriptCompilationConfiguration.ide.acceptedLocations.put(listOf(ScriptAcceptedLocation.Project)) + } + } + + override val canAutoReloadScriptConfigurationsBeSwitchedOff = !kotlinDslScriptsModelImportSupported(gradleVersion) + override val canDefinitionBeSwitchedOff: Boolean = false +} \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt.201 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt.201 new file mode 100644 index 00000000000..04c0961b005 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleKotlinScriptDefinitionWrapper.kt.201 @@ -0,0 +1,30 @@ +/* + * 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.scripting.gradle + +import org.jetbrains.kotlin.scripting.definitions.ScriptCompilationConfigurationFromDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition +import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate +import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.ScriptingHostConfiguration +import kotlin.script.experimental.location.ScriptExpectedLocation + +class GradleKotlinScriptDefinitionWrapper( + hostConfiguration: ScriptingHostConfiguration, + legacyDefinition: KotlinScriptDefinitionFromAnnotatedTemplate, + gradleVersion: String, +) : ScriptDefinition.FromLegacy(hostConfiguration, legacyDefinition) { + override val compilationConfiguration by lazy { + ScriptCompilationConfigurationFromDefinition( + hostConfiguration, + legacyDefinition + ).with { + ScriptCompilationConfiguration.ide.acceptedLocations.put(listOf(ScriptAcceptedLocation.Project)) + } + } + + override val canDefinitionBeSwitchedOff: Boolean = false +} \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptDefinitionsProvider.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptDefinitionsProvider.kt index 6b52537b508..a2fe2e6a5c2 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptDefinitionsProvider.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptDefinitionsProvider.kt @@ -32,13 +32,12 @@ import java.util.concurrent.atomic.AtomicBoolean import kotlin.reflect.KClass import kotlin.script.dependencies.Environment import kotlin.script.dependencies.ScriptContents -import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.* import kotlin.script.experimental.dependencies.DependenciesResolver import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult import kotlin.script.experimental.dependencies.ScriptReport import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration -import kotlin.script.experimental.location.ScriptExpectedLocation import kotlin.script.templates.standard.ScriptTemplateWithArgs class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionSourceAsContributor { @@ -232,17 +231,12 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD additionalResolverClasspath(gradleLibDir) ).map { it.asLegacyOrNull()?.let { legacyDef -> - @Suppress("DEPRECATION") - if (legacyDef.scriptExpectedLocations.contains(ScriptExpectedLocation.Project)) null - else { - // Expand scope for old gradle script definition - ScriptDefinition.FromLegacy( - it.hostConfiguration, - GradleKotlinScriptDefinitionFromAnnotatedTemplate( - legacyDef - ) - ) - } + // Expand scope for old gradle script definition + GradleKotlinScriptDefinitionWrapper( + it.hostConfiguration, + legacyDef, + projectSettings.resolveGradleVersion().version + ) } ?: it } } @@ -306,10 +300,3 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD } } -class GradleKotlinScriptDefinitionFromAnnotatedTemplate( - base: KotlinScriptDefinitionFromAnnotatedTemplate -) : KotlinScriptDefinitionFromAnnotatedTemplate(base.template, base.environment, base.templateClasspath) { - @Suppress("DEPRECATION") - override val scriptExpectedLocations: List - get() = listOf(ScriptExpectedLocation.Project) -} \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt index d14921422eb..11b93513757 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/GradleScriptListener.kt @@ -54,9 +54,9 @@ class GradleScriptListener(project: Project) : ScriptChangeListener(project) { .getScriptInfo(vFile)?.model?.inputs?.isUpToDate(project, vFile) ?: return if (upToDate) { - hideNotificationForProjectImport(project) + scriptConfigurationsAreUpToDate(project) } else { - showNotificationForProjectImport(project) + scriptConfigurationsNeedToBeUpdated(project) } } } \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt index 2621dfd4e77..ea384c98be9 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/roots/GradleBuildRootsManager.kt @@ -182,7 +182,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() { fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) { actualizeBuildRoot(workingDir)?.importing = inProgress updateNotifications(workingDir) - hideNotificationForProjectImport(project) + scriptConfigurationsAreUpToDate(project) } fun update(build: KotlinDslGradleBuildSync) { @@ -206,7 +206,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() { add(newSupport) - hideNotificationForProjectImport(project) + scriptConfigurationsAreUpToDate(project) } private fun merge(old: GradleBuildRootData, new: GradleBuildRootData): GradleBuildRootData { diff --git a/idea/resources-en/messages/KotlinBundle.properties b/idea/resources-en/messages/KotlinBundle.properties index 8b14450acc6..c8dbcebd0cf 100644 --- a/idea/resources-en/messages/KotlinBundle.properties +++ b/idea/resources-en/messages/KotlinBundle.properties @@ -2203,6 +2203,8 @@ action.usage.update.text=Usage update progress.title.analyze.extraction.data=Analyze extraction data... fix.move.file.to.package.dir.name.text=source root move.refactoring.error.text.cannot.perform.refactoring.since.the.following.files.already.exist=Cannot perform refactoring since the following files already exist:\n\n +kotlin.script.definitions.model.name.autoReloadScriptDependencies.description=Enable auto reload if you want to load script configurations automatically on file change +kotlin.script.definitions.model.name.autoReloadScriptDependencies=Auto Reload kotlin.script.definitions.model.name.is.enabled=Is Enabled kotlin.script.definitions.model.name.pattern.extension=Pattern/Extension kotlin.script.definitions.model.name.name=Name diff --git a/idea/src/org/jetbrains/kotlin/idea/IDESettingsFUSCollector.kt b/idea/src/org/jetbrains/kotlin/idea/IDESettingsFUSCollector.kt index 815a2bd67cb..bd131ba4dab 100644 --- a/idea/src/org/jetbrains/kotlin/idea/IDESettingsFUSCollector.kt +++ b/idea/src/org/jetbrains/kotlin/idea/IDESettingsFUSCollector.kt @@ -11,14 +11,24 @@ import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesColle import com.intellij.openapi.project.Project import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightSettings import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightWorkspaceSettings +import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings +import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition class IDESettingsFUSCollector : ProjectUsagesCollector() { override fun getMetrics(project: Project): Set { val metrics = mutableSetOf() - val scriptingAutoReloadEnabled = KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled - metrics.add(MetricEvent("scriptingAutoReloadEnabled", flagUsage(scriptingAutoReloadEnabled))) + for (definition in ScriptDefinitionsManager.getInstance(project).getAllDefinitions()) { + if (definition.canAutoReloadScriptConfigurationsBeSwitchedOff) { + val scriptingAutoReloadEnabled = KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(definition) + val data = FeatureUsageData() + .addData("enabled", scriptingAutoReloadEnabled) + .addData("definition_name", definition.name) + .addData("pluginVersion", KotlinPluginUtil.getPluginVersion()) + metrics.add(MetricEvent("scriptingAutoReloadEnabled", data)) + } + } val settings: KotlinCodeInsightSettings = KotlinCodeInsightSettings.getInstance() val projectSettings: KotlinCodeInsightWorkspaceSettings = KotlinCodeInsightWorkspaceSettings.getInstance(project) diff --git a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptDefinitionsModel.kt b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptDefinitionsModel.kt index ce63738a253..b83c0911094 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptDefinitionsModel.kt +++ b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptDefinitionsModel.kt @@ -10,19 +10,27 @@ import com.intellij.ui.BooleanTableCellRenderer import com.intellij.util.ui.ColumnInfo import com.intellij.util.ui.ListTableModel import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.StandardIdeScriptDefinition +import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate +import javax.swing.JTable -class KotlinScriptDefinitionsModelDescriptor(val definition: ScriptDefinition, var isEnabled: Boolean) +class ModelDescriptor( + val definition: ScriptDefinition, + var isEnabled: Boolean, + var autoReloadConfigurations: Boolean +) -class KotlinScriptDefinitionsModel private constructor(definitions: MutableList) : - ListTableModel( +class KotlinScriptDefinitionsModel private constructor(definitions: MutableList) : + ListTableModel( arrayOf( ScriptDefinitionName(), ScriptDefinitionPattern(), - ScriptDefinitionIsEnabled() + ScriptDefinitionIsEnabled(), + ScriptDefinitionAutoReloadConfigurations() ), definitions, 0 @@ -30,19 +38,25 @@ class KotlinScriptDefinitionsModel private constructor(definitions: MutableList< fun getDefinitions() = items.map { it.definition } fun setDefinitions(definitions: List, settings: KotlinScriptingSettings) { - items = definitions.mapTo(arrayListOf()) { KotlinScriptDefinitionsModelDescriptor(it, settings.isScriptDefinitionEnabled(it)) } + items = definitions.mapTo(arrayListOf()) { + ModelDescriptor( + it, + settings.isScriptDefinitionEnabled(it), + settings.autoReloadConfigurations(it) + ) + } } - private class ScriptDefinitionName : ColumnInfo( + private class ScriptDefinitionName : ColumnInfo( KotlinBundle.message("kotlin.script.definitions.model.name.name") ) { - override fun valueOf(item: KotlinScriptDefinitionsModelDescriptor) = item.definition.name + override fun valueOf(item: ModelDescriptor) = item.definition.name } - private class ScriptDefinitionPattern : ColumnInfo( + private class ScriptDefinitionPattern : ColumnInfo( KotlinBundle.message("kotlin.script.definitions.model.name.pattern.extension") ) { - override fun valueOf(item: KotlinScriptDefinitionsModelDescriptor): String { + override fun valueOf(item: ModelDescriptor): String { val definition = item.definition return definition.asLegacyOrNull()?.scriptFilePattern?.pattern ?: (definition as? ScriptDefinition.FromConfigurations)?.filePathPattern @@ -50,27 +64,47 @@ class KotlinScriptDefinitionsModel private constructor(definitions: MutableList< } } - private class ScriptDefinitionIsEnabled : ColumnInfo( + private class ScriptDefinitionIsEnabled : BooleanColumn( KotlinBundle.message("kotlin.script.definitions.model.name.is.enabled") ) { - override fun valueOf(item: KotlinScriptDefinitionsModelDescriptor): Boolean = item.isEnabled - override fun setValue(item: KotlinScriptDefinitionsModelDescriptor, value: Boolean) { + override fun valueOf(item: ModelDescriptor): Boolean = item.isEnabled + override fun setValue(item: ModelDescriptor, value: Boolean) { item.isEnabled = value } - override fun getEditor(item: KotlinScriptDefinitionsModelDescriptor?) = BooleanTableCellEditor() - override fun getRenderer(item: KotlinScriptDefinitionsModelDescriptor?) = BooleanTableCellRenderer() - override fun isCellEditable(item: KotlinScriptDefinitionsModelDescriptor) = - item.definition.asLegacyOrNull() == null + override fun isCellEditable(item: ModelDescriptor): Boolean { + return item.definition.asLegacyOrNull() == null + && item.definition.canDefinitionBeSwitchedOff + } + } + + private class ScriptDefinitionAutoReloadConfigurations : BooleanColumn( + KotlinBundle.message("kotlin.script.definitions.model.name.autoReloadScriptDependencies") + ) { + override fun valueOf(item: ModelDescriptor): Boolean = item.autoReloadConfigurations + override fun setValue(item: ModelDescriptor, value: Boolean) { + item.autoReloadConfigurations = value + } + + override fun isCellEditable(item: ModelDescriptor): Boolean { + return item.definition.canAutoReloadScriptConfigurationsBeSwitchedOff + } } companion object { fun createModel(definitions: List, settings: KotlinScriptingSettings): KotlinScriptDefinitionsModel = KotlinScriptDefinitionsModel(definitions.mapTo(arrayListOf()) { - KotlinScriptDefinitionsModelDescriptor( + ModelDescriptor( it, - settings.isScriptDefinitionEnabled(it) + settings.isScriptDefinitionEnabled(it), + settings.autoReloadConfigurations(it) ) }) } +} + +private abstract class BooleanColumn(message: String) : ColumnInfo(message) { + override fun getEditor(item: ModelDescriptor?) = BooleanTableCellEditor() + override fun getRenderer(item: ModelDescriptor?) = BooleanTableCellRenderer() + override fun getWidth(table: JTable?): Int = 90 } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.form b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.form index 5a8dbbd84ff..1bf60e3749a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.form +++ b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.form @@ -8,7 +8,7 @@ - + @@ -18,13 +18,13 @@ - + - + - + @@ -47,16 +47,16 @@ + + + + + + + + - - - - - - - - diff --git a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.java b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.java index 926c1afb8b3..2c156a4f3fc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.java +++ b/idea/src/org/jetbrains/kotlin/idea/script/configuration/KotlinScriptingSettingsConfigurable.java @@ -25,7 +25,6 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab private JPanel root; private JPanel panelScriptDefinitionsChooser; - private JCheckBox scriptDependenciesAutoReload; private KotlinScriptDefinitionsModel model; @@ -55,19 +54,18 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab @Override public boolean isModified() { - return isModified(scriptDependenciesAutoReload, settings.isAutoReloadEnabled()) - || isScriptDefinitionsChanged(); + return isScriptDefinitionsChanged(); } @Override public void apply() { - settings.setAutoReloadEnabled(scriptDependenciesAutoReload.isSelected()); - if (isScriptDefinitionsChanged()) { - for (KotlinScriptDefinitionsModelDescriptor item : model.getItems()) { + for (ModelDescriptor item : model.getItems()) { ScriptDefinition definition = item.getDefinition(); - settings.setOrder(definition, model.getItems().indexOf(item)); + int order = model.getItems().indexOf(item); + settings.setOrder(definition, order); settings.setEnabled(definition, item.isEnabled()); + settings.setAutoReloadConfigurations(definition, item.getAutoReloadConfigurations()); } manager.reorderScriptDefinitions(); @@ -76,16 +74,17 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab @Override public void reset() { - scriptDependenciesAutoReload.setSelected(settings.isAutoReloadEnabled()); - model.setDefinitions(manager.getAllDefinitions(), settings); } private boolean isScriptDefinitionsChanged() { - for (KotlinScriptDefinitionsModelDescriptor item : model.getItems()) { + for (ModelDescriptor item : model.getItems()) { if (settings.isScriptDefinitionEnabled(item.getDefinition()) != item.isEnabled()) { return true; } + if (settings.autoReloadConfigurations(item.getDefinition()) != item.getAutoReloadConfigurations()) { + return true; + } } return !model.getDefinitions().equals(manager.getAllDefinitions()); } diff --git a/idea/tests/org/jetbrains/kotlin/idea/script/ScriptOptionsSaveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/script/ScriptOptionsSaveTest.kt index cfdbd316180..c6d1528a1a3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/script/ScriptOptionsSaveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/script/ScriptOptionsSaveTest.kt @@ -20,17 +20,20 @@ class ScriptOptionsSaveTest : KotlinLightCodeInsightFixtureTestCase() { fun testSaveAutoReload() { val project = myFixture.project val settings = KotlinScriptingSettings.getInstance(project) - val initialAutoReload = settings.isAutoReloadEnabled + val definition = ScriptDefinitionsManager.getInstance(project).getAllDefinitions().first() + val initialAutoReload = settings.autoReloadConfigurations(definition) - settings.isAutoReloadEnabled = !initialAutoReload + settings.setAutoReloadConfigurations(definition, !initialAutoReload) assertEquals( "isAutoReloadEnabled should be set to true", - "", + "true", XMLOutputter().outputString(settings.state) + .substringAfter("") + .substringBefore("") ) - settings.isAutoReloadEnabled = initialAutoReload + settings.setAutoReloadConfigurations(definition, initialAutoReload) } fun testSaveScriptDefinitionOff() { @@ -45,8 +48,10 @@ class ScriptOptionsSaveTest : KotlinLightCodeInsightFixtureTestCase() { assertEquals( "scriptDefinition should be off", - "0false", - XMLOutputter().outputString(settings.state).replace("scriptDefinition .*\">".toRegex(), "scriptDefinition>") + "false", + XMLOutputter().outputString(settings.state) + .substringAfter("") + .substringBefore("") ) settings.setEnabled(scriptDefinition, initialIsEnabled) diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt index 2dd7b4b43ef..45152808a71 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt @@ -41,6 +41,11 @@ abstract class ScriptDefinition : UserDataHolderBase() { open val isDefault = false + // Store IDE-related settings in script definition + var order: Int = Integer.MAX_VALUE + open val canAutoReloadScriptConfigurationsBeSwitchedOff: Boolean get() = true + open val canDefinitionBeSwitchedOff: Boolean get() = true + abstract val baseClassType: KotlinType abstract val compilerOptions: Iterable abstract val annotationsForSamWithReceivers: List @@ -59,7 +64,7 @@ abstract class ScriptDefinition : UserDataHolderBase() { override val legacyDefinition: KotlinScriptDefinition ) : ScriptDefinition() { - override val compilationConfiguration by lazy { + override val compilationConfiguration: ScriptCompilationConfiguration by lazy { ScriptCompilationConfigurationFromDefinition( hostConfiguration, legacyDefinition