Scripting setting: auto reloading of script dependencies is now per definition
This commit is contained in:
+7
-3
@@ -17,6 +17,7 @@ import com.intellij.ui.HyperlinkLabel
|
|||||||
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
||||||
import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle
|
import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle
|
||||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||||
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
|
|
||||||
object LoadScriptConfigurationNotificationFactory {
|
object LoadScriptConfigurationNotificationFactory {
|
||||||
fun showNotification(file: VirtualFile, project: Project, onClick: () -> Unit): Boolean {
|
fun showNotification(file: VirtualFile, project: Project, onClick: () -> Unit): Boolean {
|
||||||
@@ -50,7 +51,7 @@ object LoadScriptConfigurationNotificationFactory {
|
|||||||
return@withSelectedEditor
|
return@withSelectedEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
val panel = NewLoadConfigurationNotificationPanel(onClick, project)
|
val panel = NewLoadConfigurationNotificationPanel(onClick, project, this@addLoadConfigurationNotificationPanel)
|
||||||
notificationPanel = panel
|
notificationPanel = panel
|
||||||
manager.addTopComponent(this, panel)
|
manager.addTopComponent(this, panel)
|
||||||
}
|
}
|
||||||
@@ -72,7 +73,8 @@ object LoadScriptConfigurationNotificationFactory {
|
|||||||
|
|
||||||
private class NewLoadConfigurationNotificationPanel(
|
private class NewLoadConfigurationNotificationPanel(
|
||||||
var onClick: () -> Unit,
|
var onClick: () -> Unit,
|
||||||
project: Project
|
project: Project,
|
||||||
|
file: VirtualFile
|
||||||
) : EditorNotificationPanel() {
|
) : EditorNotificationPanel() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -83,7 +85,9 @@ object LoadScriptConfigurationNotificationFactory {
|
|||||||
|
|
||||||
createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) {
|
createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) {
|
||||||
onClick()
|
onClick()
|
||||||
KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled = true
|
|
||||||
|
val scriptDefinition = file.findScriptDefinition(project) ?: return@createComponentActionLabel
|
||||||
|
KotlinScriptingSettings.getInstance(project).setAutoReloadConfigurations(scriptDefinition, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -171,6 +171,11 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun reorderScriptDefinitions() = lock.write {
|
fun reorderScriptDefinitions() = lock.write {
|
||||||
|
definitions?.forEach {
|
||||||
|
it.order = KotlinScriptingSettings.getInstance(project).getScriptDefinitionOrder(it)
|
||||||
|
}
|
||||||
|
definitions = definitions?.sortedBy { it.order }
|
||||||
|
|
||||||
updateDefinitions()
|
updateDefinitions()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +202,6 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit
|
|||||||
private fun updateDefinitions() {
|
private fun updateDefinitions() {
|
||||||
assert(lock.isWriteLocked) { "updateDefinitions should only be called under the write lock" }
|
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 fileTypeManager = FileTypeManager.getInstance()
|
||||||
|
|
||||||
val newExtensions = getKnownFilenameExtensions().filter {
|
val newExtensions = getKnownFilenameExtensions().filter {
|
||||||
|
|||||||
+7
-3
@@ -18,6 +18,7 @@ import org.jetbrains.annotations.TestOnly
|
|||||||
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
||||||
import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle
|
import org.jetbrains.kotlin.idea.core.util.KotlinIdeaCoreBundle
|
||||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||||
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
||||||
|
|
||||||
fun VirtualFile.removeScriptDependenciesNotificationPanel(project: Project) {
|
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
|
notificationPanel = panel
|
||||||
manager.addTopComponent(this, panel)
|
manager.addTopComponent(this, panel)
|
||||||
}
|
}
|
||||||
@@ -81,7 +82,8 @@ private var FileEditor.notificationPanel: NewScriptDependenciesNotificationPanel
|
|||||||
private class NewScriptDependenciesNotificationPanel(
|
private class NewScriptDependenciesNotificationPanel(
|
||||||
val onClick: () -> Unit,
|
val onClick: () -> Unit,
|
||||||
val compilationConfigurationResult: ScriptCompilationConfigurationWrapper,
|
val compilationConfigurationResult: ScriptCompilationConfigurationWrapper,
|
||||||
project: Project
|
project: Project,
|
||||||
|
file: VirtualFile
|
||||||
) : EditorNotificationPanel() {
|
) : EditorNotificationPanel() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -92,7 +94,9 @@ private class NewScriptDependenciesNotificationPanel(
|
|||||||
|
|
||||||
createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) {
|
createComponentActionLabel(KotlinIdeaCoreBundle.message("notification.action.text.enable.auto.reload")) {
|
||||||
onClick()
|
onClick()
|
||||||
KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled = true
|
|
||||||
|
val scriptDefinition = file.findScriptDefinition(project) ?: return@createComponentActionLabel
|
||||||
|
KotlinScriptingSettings.getInstance(project).setAutoReloadConfigurations(scriptDefinition, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -174,7 +174,7 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De
|
|||||||
if (forceSync) {
|
if (forceSync) {
|
||||||
loaders.firstOrNull { it.loadDependencies(isFirstLoad, file, scriptDefinition, loadingContext) }
|
loaders.firstOrNull { it.loadDependencies(isFirstLoad, file, scriptDefinition, loadingContext) }
|
||||||
} else {
|
} else {
|
||||||
val autoReloadEnabled = KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled
|
val autoReloadEnabled = KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(scriptDefinition)
|
||||||
val postponeLoading = isPostponedLoad && !autoReloadEnabled
|
val postponeLoading = isPostponedLoad && !autoReloadEnabled
|
||||||
|
|
||||||
if (postponeLoading) {
|
if (postponeLoading) {
|
||||||
@@ -206,7 +206,8 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De
|
|||||||
val applied = cached?.applied
|
val applied = cached?.applied
|
||||||
if (applied != null && applied.inputs.isUpToDate(project, virtualFile)) {
|
if (applied != null && applied.inputs.isUpToDate(project, virtualFile)) {
|
||||||
// in case user reverted to applied configuration
|
// 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)) {
|
} else if (cached == null || !cached.isUpToDate(project, virtualFile)) {
|
||||||
// don't start loading if nothing was changed
|
// don't start loading if nothing was changed
|
||||||
// (in case we checking for up-to-date and loading concurrently)
|
// (in case we checking for up-to-date and loading concurrently)
|
||||||
@@ -280,7 +281,6 @@ class DefaultScriptingSupport(manager: CompositeScriptConfigurationManager) : De
|
|||||||
} else {
|
} else {
|
||||||
val autoReload = skipNotification
|
val autoReload = skipNotification
|
||||||
|| oldConfiguration == null
|
|| oldConfiguration == null
|
||||||
|| KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled
|
|
||||||
|| ApplicationManager.getApplication().isUnitTestModeWithoutScriptLoadingNotification
|
|| ApplicationManager.getApplication().isUnitTestModeWithoutScriptLoadingNotification
|
||||||
|
|
||||||
if (autoReload) {
|
if (autoReload) {
|
||||||
|
|||||||
+6
-1
@@ -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.CachedConfigurationInputs
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.ScriptConfigurationSnapshot
|
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.debug
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||||
@@ -43,7 +44,11 @@ open class DefaultScriptConfigurationLoader(val project: Project) : ScriptConfig
|
|||||||
|
|
||||||
val result = getConfigurationThroughScriptingApi(ktFile, virtualFile, scriptDefinition)
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ interface ScriptConfigurationLoadingContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show notification about new configuration with suggestion to apply it.
|
* 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
|
* If configuration is null, then the result will be treated as failed, and
|
||||||
* reports will be displayed immediately.
|
* reports will be displayed immediately.
|
||||||
|
|||||||
+60
-26
@@ -10,9 +10,11 @@ import com.intellij.openapi.components.State
|
|||||||
import com.intellij.openapi.components.Storage
|
import com.intellij.openapi.components.Storage
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.util.addOptionTag
|
import com.intellij.util.addOptionTag
|
||||||
import com.intellij.util.attribute
|
|
||||||
import com.intellij.util.getAttributeBooleanValue
|
import com.intellij.util.getAttributeBooleanValue
|
||||||
import org.jdom.Element
|
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.idea.util.application.getServiceSafe
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||||
|
|
||||||
@@ -20,8 +22,7 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
|||||||
name = "KotlinScriptingSettings",
|
name = "KotlinScriptingSettings",
|
||||||
storages = [Storage("kotlinScripting.xml")]
|
storages = [Storage("kotlinScripting.xml")]
|
||||||
)
|
)
|
||||||
class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
class KotlinScriptingSettings(private val project: Project) : PersistentStateComponent<Element> {
|
||||||
var isAutoReloadEnabled = false
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if notification about multiple script definition applicable for one script file is suppressed
|
* true if notification about multiple script definition applicable for one script file is suppressed
|
||||||
@@ -33,13 +34,6 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
override fun getState(): Element {
|
override fun getState(): Element {
|
||||||
val definitionsRootElement = Element("KotlinScriptingSettings")
|
val definitionsRootElement = Element("KotlinScriptingSettings")
|
||||||
|
|
||||||
if (isAutoReloadEnabled) {
|
|
||||||
definitionsRootElement.addOptionTag(
|
|
||||||
KotlinScriptingSettings::isAutoReloadEnabled.name,
|
|
||||||
isAutoReloadEnabled.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suppressDefinitionsCheck) {
|
if (suppressDefinitionsCheck) {
|
||||||
definitionsRootElement.addOptionTag(
|
definitionsRootElement.addOptionTag(
|
||||||
KotlinScriptingSettings::suppressDefinitionsCheck.name,
|
KotlinScriptingSettings::suppressDefinitionsCheck.name,
|
||||||
@@ -59,9 +53,6 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun loadState(state: Element) {
|
override fun loadState(state: Element) {
|
||||||
state.getOptionTag(KotlinScriptingSettings::isAutoReloadEnabled.name)?.let {
|
|
||||||
isAutoReloadEnabled = it
|
|
||||||
}
|
|
||||||
state.getOptionTag(KotlinScriptingSettings::suppressDefinitionsCheck.name)?.let {
|
state.getOptionTag(KotlinScriptingSettings::suppressDefinitionsCheck.name)?.let {
|
||||||
suppressDefinitionsCheck = it
|
suppressDefinitionsCheck = it
|
||||||
}
|
}
|
||||||
@@ -70,29 +61,63 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
for (scriptDefinitionElement in scriptDefinitionsList) {
|
for (scriptDefinitionElement in scriptDefinitionsList) {
|
||||||
scriptDefinitions[scriptDefinitionElement.toKey()] = scriptDefinitionElement.toValue()
|
scriptDefinitions[scriptDefinitionElement.toKey()] = scriptDefinitionElement.toValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scriptDefinitionsList.isNotEmpty()) {
|
||||||
|
executeOnPooledThread {
|
||||||
|
ScriptDefinitionsManager.getInstance(project).reorderScriptDefinitions()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOrder(scriptDefinition: ScriptDefinition, order: Int) {
|
fun setOrder(scriptDefinition: ScriptDefinition, order: Int) {
|
||||||
scriptDefinitions[scriptDefinition.toKey()] = scriptDefinitions[scriptDefinition.toKey()]?.copy(order = order) ?:
|
scriptDefinitions[scriptDefinition.toKey()] =
|
||||||
KotlinScriptDefinitionValue(order)
|
scriptDefinitions[scriptDefinition.toKey()]?.copy(order = order) ?: KotlinScriptDefinitionValue(order)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun setEnabled(scriptDefinition: ScriptDefinition, isEnabled: Boolean) {
|
fun setEnabled(scriptDefinition: ScriptDefinition, isEnabled: Boolean) {
|
||||||
scriptDefinitions[scriptDefinition.toKey()] = scriptDefinitions[scriptDefinition.toKey()]?.copy(isEnabled = isEnabled) ?:
|
scriptDefinitions[scriptDefinition.toKey()] =
|
||||||
KotlinScriptDefinitionValue(scriptDefinitions.size, isEnabled)
|
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 {
|
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 {
|
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)
|
fun autoReloadConfigurations(scriptDefinition: ScriptDefinition): Boolean {
|
||||||
private data class KotlinScriptDefinitionValue(val order: Int, val isEnabled: Boolean = true)
|
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(
|
private fun Element.toKey() = KotlinScriptDefinitionKey(
|
||||||
getAttributeValue(KotlinScriptDefinitionKey::definitionName.name),
|
getAttributeValue(KotlinScriptDefinitionKey::definitionName.name),
|
||||||
@@ -104,8 +129,8 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
private fun Element.addScriptDefinitionContentElement(definition: KotlinScriptDefinitionKey, settings: KotlinScriptDefinitionValue) {
|
private fun Element.addScriptDefinitionContentElement(definition: KotlinScriptDefinitionKey, settings: KotlinScriptDefinitionValue) {
|
||||||
addElement(SCRIPT_DEFINITION_TAG).apply {
|
addElement(SCRIPT_DEFINITION_TAG).apply {
|
||||||
attribute(KotlinScriptDefinitionKey::className.name, definition.className)
|
setAttribute(KotlinScriptDefinitionKey::className.name, definition.className)
|
||||||
attribute(KotlinScriptDefinitionKey::definitionName.name, definition.definitionName)
|
setAttribute(KotlinScriptDefinitionKey::definitionName.name, definition.definitionName)
|
||||||
|
|
||||||
addElement(KotlinScriptDefinitionValue::order.name).apply {
|
addElement(KotlinScriptDefinitionValue::order.name).apply {
|
||||||
text = settings.order.toString()
|
text = settings.order.toString()
|
||||||
@@ -116,6 +141,11 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
text = settings.isEnabled.toString()
|
text = settings.isEnabled.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (settings.autoReloadConfigurations) {
|
||||||
|
addElement(KotlinScriptDefinitionValue::autoReloadConfigurations.name).apply {
|
||||||
|
text = settings.autoReloadConfigurations.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,10 +156,14 @@ class KotlinScriptingSettings : PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Element.toValue(): KotlinScriptDefinitionValue {
|
private fun Element.toValue(): KotlinScriptDefinitionValue {
|
||||||
val order = getChildText(KotlinScriptDefinitionValue::order.name)?.toInt() ?: Integer.MAX_VALUE
|
val order = getChildText(KotlinScriptDefinitionValue::order.name)?.toInt()
|
||||||
val isEnabled = getChildText(KotlinScriptDefinitionValue::isEnabled.name)?.toBoolean() ?: true
|
?: 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) =
|
private fun Element.getOptionTag(name: String) =
|
||||||
|
|||||||
+19
-2
@@ -34,11 +34,28 @@ fun runPartialGradleImport(project: Project) {
|
|||||||
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.import")
|
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.import")
|
||||||
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.label.import.project")
|
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<GradleProjectSettings>()
|
||||||
|
.firstOrNull()
|
||||||
|
if (projectSettings != null) {
|
||||||
|
return projectSettings.isUseAutoImport
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private const val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts"
|
private const val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts"
|
||||||
private var Project.notificationPanel: ScriptConfigurationChangedNotification?
|
private var Project.notificationPanel: ScriptConfigurationChangedNotification?
|
||||||
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(Key.create("load.script.configuration.panel"))
|
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(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
|
val existingPanel = project.notificationPanel
|
||||||
if (existingPanel != null) {
|
if (existingPanel != null) {
|
||||||
return
|
return
|
||||||
@@ -56,7 +73,7 @@ fun showNotificationForProjectImport(project: Project) {
|
|||||||
notification.notify(project)
|
notification.notify(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideNotificationForProjectImport(project: Project): Boolean {
|
fun scriptConfigurationsAreUpToDate(project: Project): Boolean {
|
||||||
if (project.notificationPanel == null) return false
|
if (project.notificationPanel == null) return false
|
||||||
project.notificationPanel?.expire()
|
project.notificationPanel?.expire()
|
||||||
return true
|
return true
|
||||||
|
|||||||
+40
-18
@@ -16,10 +16,12 @@ import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
|||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.testFramework.LightVirtualFileBase
|
import com.intellij.testFramework.LightVirtualFileBase
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||||
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
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.importing.KotlinDslScriptModelResolver
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||||
import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy
|
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 getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.load.changes")
|
||||||
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.text.load.script.configurations")
|
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(
|
class LoadConfigurationAction : AnAction(
|
||||||
KotlinIdeaGradleBundle.message("action.text.load.script.configurations"),
|
KotlinIdeaGradleBundle.message("action.text.load.script.configurations"),
|
||||||
@@ -56,29 +70,37 @@ class LoadConfigurationAction : AnAction(
|
|||||||
|
|
||||||
override fun update(e: AnActionEvent) {
|
override fun update(e: AnActionEvent) {
|
||||||
ensureValidActionVisibility(e)
|
ensureValidActionVisibility(e)
|
||||||
|
|
||||||
e.presentation.description = KotlinIdeaGradleBundle.message("action.description.load.script.configurations")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureValidActionVisibility(e: AnActionEvent) {
|
private fun ensureValidActionVisibility(e: AnActionEvent) {
|
||||||
val editor = e.getData(CommonDataKeys.EDITOR) ?: return
|
val editor = e.getData(CommonDataKeys.EDITOR) ?: return
|
||||||
|
|
||||||
|
e.presentation.isVisible = getNotificationVisibility(editor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getNotificationVisibility(editor: Editor): Boolean {
|
||||||
if (DiffUtil.isDiffEditor(editor)) {
|
if (DiffUtil.isDiffEditor(editor)) {
|
||||||
e.presentation.isVisible = false
|
return false
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
private fun getKotlinScriptFile(editor: Editor): VirtualFile? {
|
||||||
val project = project ?: return false
|
return FileDocumentManager.getInstance()
|
||||||
|
.getFile(editor.document)
|
||||||
val documentManager = FileDocumentManager.getInstance()
|
?.takeIf {
|
||||||
val virtualFile = documentManager.getFile(document)
|
it !is LightVirtualFileBase
|
||||||
if (virtualFile is LightVirtualFileBase) return false
|
&& it.isValid
|
||||||
if (virtualFile == null || !virtualFile.isValid) return false
|
&& it.fileType != KotlinFileType.INSTANCE
|
||||||
|
&& isGradleKotlinScript(it)
|
||||||
return GradleBuildRootsManager.getInstance(project).isConfigurationOutOfDate(virtualFile)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+30
@@ -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
|
||||||
|
}
|
||||||
+30
@@ -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
|
||||||
|
}
|
||||||
+7
-20
@@ -32,13 +32,12 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.dependencies.Environment
|
import kotlin.script.dependencies.Environment
|
||||||
import kotlin.script.dependencies.ScriptContents
|
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
|
||||||
import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult
|
import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult
|
||||||
import kotlin.script.experimental.dependencies.ScriptReport
|
import kotlin.script.experimental.dependencies.ScriptReport
|
||||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||||
import kotlin.script.experimental.location.ScriptExpectedLocation
|
|
||||||
import kotlin.script.templates.standard.ScriptTemplateWithArgs
|
import kotlin.script.templates.standard.ScriptTemplateWithArgs
|
||||||
|
|
||||||
class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionSourceAsContributor {
|
class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionSourceAsContributor {
|
||||||
@@ -232,17 +231,12 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
|||||||
additionalResolverClasspath(gradleLibDir)
|
additionalResolverClasspath(gradleLibDir)
|
||||||
).map {
|
).map {
|
||||||
it.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>()?.let { legacyDef ->
|
it.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>()?.let { legacyDef ->
|
||||||
@Suppress("DEPRECATION")
|
// Expand scope for old gradle script definition
|
||||||
if (legacyDef.scriptExpectedLocations.contains(ScriptExpectedLocation.Project)) null
|
GradleKotlinScriptDefinitionWrapper(
|
||||||
else {
|
it.hostConfiguration,
|
||||||
// Expand scope for old gradle script definition
|
legacyDef,
|
||||||
ScriptDefinition.FromLegacy(
|
projectSettings.resolveGradleVersion().version
|
||||||
it.hostConfiguration,
|
)
|
||||||
GradleKotlinScriptDefinitionFromAnnotatedTemplate(
|
|
||||||
legacyDef
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} ?: it
|
} ?: 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<ScriptExpectedLocation>
|
|
||||||
get() = listOf(ScriptExpectedLocation.Project)
|
|
||||||
}
|
|
||||||
+2
-2
@@ -54,9 +54,9 @@ class GradleScriptListener(project: Project) : ScriptChangeListener(project) {
|
|||||||
.getScriptInfo(vFile)?.model?.inputs?.isUpToDate(project, vFile) ?: return
|
.getScriptInfo(vFile)?.model?.inputs?.isUpToDate(project, vFile) ?: return
|
||||||
|
|
||||||
if (upToDate) {
|
if (upToDate) {
|
||||||
hideNotificationForProjectImport(project)
|
scriptConfigurationsAreUpToDate(project)
|
||||||
} else {
|
} else {
|
||||||
showNotificationForProjectImport(project)
|
scriptConfigurationsNeedToBeUpdated(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -182,7 +182,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() {
|
|||||||
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
||||||
actualizeBuildRoot(workingDir)?.importing = inProgress
|
actualizeBuildRoot(workingDir)?.importing = inProgress
|
||||||
updateNotifications(workingDir)
|
updateNotifications(workingDir)
|
||||||
hideNotificationForProjectImport(project)
|
scriptConfigurationsAreUpToDate(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(build: KotlinDslGradleBuildSync) {
|
fun update(build: KotlinDslGradleBuildSync) {
|
||||||
@@ -206,7 +206,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() {
|
|||||||
|
|
||||||
add(newSupport)
|
add(newSupport)
|
||||||
|
|
||||||
hideNotificationForProjectImport(project)
|
scriptConfigurationsAreUpToDate(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun merge(old: GradleBuildRootData, new: GradleBuildRootData): GradleBuildRootData {
|
private fun merge(old: GradleBuildRootData, new: GradleBuildRootData): GradleBuildRootData {
|
||||||
|
|||||||
@@ -2203,6 +2203,8 @@ action.usage.update.text=Usage update
|
|||||||
progress.title.analyze.extraction.data=Analyze extraction data...
|
progress.title.analyze.extraction.data=Analyze extraction data...
|
||||||
fix.move.file.to.package.dir.name.text=source root
|
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
|
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.is.enabled=Is Enabled
|
||||||
kotlin.script.definitions.model.name.pattern.extension=Pattern/Extension
|
kotlin.script.definitions.model.name.pattern.extension=Pattern/Extension
|
||||||
kotlin.script.definitions.model.name.name=Name
|
kotlin.script.definitions.model.name.name=Name
|
||||||
|
|||||||
@@ -11,14 +11,24 @@ import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesColle
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightSettings
|
import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightSettings
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightWorkspaceSettings
|
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.idea.core.script.settings.KotlinScriptingSettings
|
||||||
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
|
|
||||||
class IDESettingsFUSCollector : ProjectUsagesCollector() {
|
class IDESettingsFUSCollector : ProjectUsagesCollector() {
|
||||||
override fun getMetrics(project: Project): Set<MetricEvent> {
|
override fun getMetrics(project: Project): Set<MetricEvent> {
|
||||||
val metrics = mutableSetOf<MetricEvent>()
|
val metrics = mutableSetOf<MetricEvent>()
|
||||||
|
|
||||||
val scriptingAutoReloadEnabled = KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled
|
for (definition in ScriptDefinitionsManager.getInstance(project).getAllDefinitions()) {
|
||||||
metrics.add(MetricEvent("scriptingAutoReloadEnabled", flagUsage(scriptingAutoReloadEnabled)))
|
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 settings: KotlinCodeInsightSettings = KotlinCodeInsightSettings.getInstance()
|
||||||
val projectSettings: KotlinCodeInsightWorkspaceSettings = KotlinCodeInsightWorkspaceSettings.getInstance(project)
|
val projectSettings: KotlinCodeInsightWorkspaceSettings = KotlinCodeInsightWorkspaceSettings.getInstance(project)
|
||||||
|
|||||||
+52
-18
@@ -10,19 +10,27 @@ import com.intellij.ui.BooleanTableCellRenderer
|
|||||||
import com.intellij.util.ui.ColumnInfo
|
import com.intellij.util.ui.ColumnInfo
|
||||||
import com.intellij.util.ui.ListTableModel
|
import com.intellij.util.ui.ListTableModel
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
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.StandardIdeScriptDefinition
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager
|
||||||
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||||
import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate
|
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<KotlinScriptDefinitionsModelDescriptor>) :
|
class KotlinScriptDefinitionsModel private constructor(definitions: MutableList<ModelDescriptor>) :
|
||||||
ListTableModel<KotlinScriptDefinitionsModelDescriptor>(
|
ListTableModel<ModelDescriptor>(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
ScriptDefinitionName(),
|
ScriptDefinitionName(),
|
||||||
ScriptDefinitionPattern(),
|
ScriptDefinitionPattern(),
|
||||||
ScriptDefinitionIsEnabled()
|
ScriptDefinitionIsEnabled(),
|
||||||
|
ScriptDefinitionAutoReloadConfigurations()
|
||||||
),
|
),
|
||||||
definitions,
|
definitions,
|
||||||
0
|
0
|
||||||
@@ -30,19 +38,25 @@ class KotlinScriptDefinitionsModel private constructor(definitions: MutableList<
|
|||||||
|
|
||||||
fun getDefinitions() = items.map { it.definition }
|
fun getDefinitions() = items.map { it.definition }
|
||||||
fun setDefinitions(definitions: List<ScriptDefinition>, settings: KotlinScriptingSettings) {
|
fun setDefinitions(definitions: List<ScriptDefinition>, 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<KotlinScriptDefinitionsModelDescriptor, String>(
|
private class ScriptDefinitionName : ColumnInfo<ModelDescriptor, String>(
|
||||||
KotlinBundle.message("kotlin.script.definitions.model.name.name")
|
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<KotlinScriptDefinitionsModelDescriptor, String>(
|
private class ScriptDefinitionPattern : ColumnInfo<ModelDescriptor, String>(
|
||||||
KotlinBundle.message("kotlin.script.definitions.model.name.pattern.extension")
|
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
|
val definition = item.definition
|
||||||
return definition.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>()?.scriptFilePattern?.pattern
|
return definition.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>()?.scriptFilePattern?.pattern
|
||||||
?: (definition as? ScriptDefinition.FromConfigurations)?.filePathPattern
|
?: (definition as? ScriptDefinition.FromConfigurations)?.filePathPattern
|
||||||
@@ -50,27 +64,47 @@ class KotlinScriptDefinitionsModel private constructor(definitions: MutableList<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ScriptDefinitionIsEnabled : ColumnInfo<KotlinScriptDefinitionsModelDescriptor, Boolean>(
|
private class ScriptDefinitionIsEnabled : BooleanColumn(
|
||||||
KotlinBundle.message("kotlin.script.definitions.model.name.is.enabled")
|
KotlinBundle.message("kotlin.script.definitions.model.name.is.enabled")
|
||||||
) {
|
) {
|
||||||
override fun valueOf(item: KotlinScriptDefinitionsModelDescriptor): Boolean = item.isEnabled
|
override fun valueOf(item: ModelDescriptor): Boolean = item.isEnabled
|
||||||
override fun setValue(item: KotlinScriptDefinitionsModelDescriptor, value: Boolean) {
|
override fun setValue(item: ModelDescriptor, value: Boolean) {
|
||||||
item.isEnabled = value
|
item.isEnabled = value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEditor(item: KotlinScriptDefinitionsModelDescriptor?) = BooleanTableCellEditor()
|
override fun isCellEditable(item: ModelDescriptor): Boolean {
|
||||||
override fun getRenderer(item: KotlinScriptDefinitionsModelDescriptor?) = BooleanTableCellRenderer()
|
return item.definition.asLegacyOrNull<StandardIdeScriptDefinition>() == null
|
||||||
override fun isCellEditable(item: KotlinScriptDefinitionsModelDescriptor) =
|
&& item.definition.canDefinitionBeSwitchedOff
|
||||||
item.definition.asLegacyOrNull<StandardIdeScriptDefinition>() == null
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
companion object {
|
||||||
fun createModel(definitions: List<ScriptDefinition>, settings: KotlinScriptingSettings): KotlinScriptDefinitionsModel =
|
fun createModel(definitions: List<ScriptDefinition>, settings: KotlinScriptingSettings): KotlinScriptDefinitionsModel =
|
||||||
KotlinScriptDefinitionsModel(definitions.mapTo(arrayListOf()) {
|
KotlinScriptDefinitionsModel(definitions.mapTo(arrayListOf()) {
|
||||||
KotlinScriptDefinitionsModelDescriptor(
|
ModelDescriptor(
|
||||||
it,
|
it,
|
||||||
settings.isScriptDefinitionEnabled(it)
|
settings.isScriptDefinitionEnabled(it),
|
||||||
|
settings.autoReloadConfigurations(it)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class BooleanColumn(message: String) : ColumnInfo<ModelDescriptor, Boolean>(message) {
|
||||||
|
override fun getEditor(item: ModelDescriptor?) = BooleanTableCellEditor()
|
||||||
|
override fun getRenderer(item: ModelDescriptor?) = BooleanTableCellRenderer()
|
||||||
|
override fun getWidth(table: JTable?): Int = 90
|
||||||
}
|
}
|
||||||
+12
-12
@@ -8,7 +8,7 @@
|
|||||||
<properties/>
|
<properties/>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<grid id="6126a" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="6126a" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
@@ -18,13 +18,13 @@
|
|||||||
<children>
|
<children>
|
||||||
<vspacer id="7a19">
|
<vspacer id="7a19">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</vspacer>
|
</vspacer>
|
||||||
<grid id="b9ce9" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="b9ce9" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties/>
|
||||||
<clientProperties>
|
<clientProperties>
|
||||||
@@ -47,16 +47,16 @@
|
|||||||
</vspacer>
|
</vspacer>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
|
<component id="54c9d" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text resource-bundle="messages/KotlinBundle" key="kotlin.script.definitions.model.name.autoReloadScriptDependencies.description"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<component id="cc285" class="javax.swing.JCheckBox" binding="scriptDependenciesAutoReload">
|
|
||||||
<constraints>
|
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<text resource-bundle="messages/KotlinBundle" key="reload.script.dependencies.on.file.change"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
+9
-10
@@ -25,7 +25,6 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab
|
|||||||
|
|
||||||
private JPanel root;
|
private JPanel root;
|
||||||
private JPanel panelScriptDefinitionsChooser;
|
private JPanel panelScriptDefinitionsChooser;
|
||||||
private JCheckBox scriptDependenciesAutoReload;
|
|
||||||
|
|
||||||
private KotlinScriptDefinitionsModel model;
|
private KotlinScriptDefinitionsModel model;
|
||||||
|
|
||||||
@@ -55,19 +54,18 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isModified() {
|
public boolean isModified() {
|
||||||
return isModified(scriptDependenciesAutoReload, settings.isAutoReloadEnabled())
|
return isScriptDefinitionsChanged();
|
||||||
|| isScriptDefinitionsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply() {
|
public void apply() {
|
||||||
settings.setAutoReloadEnabled(scriptDependenciesAutoReload.isSelected());
|
|
||||||
|
|
||||||
if (isScriptDefinitionsChanged()) {
|
if (isScriptDefinitionsChanged()) {
|
||||||
for (KotlinScriptDefinitionsModelDescriptor item : model.getItems()) {
|
for (ModelDescriptor item : model.getItems()) {
|
||||||
ScriptDefinition definition = item.getDefinition();
|
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.setEnabled(definition, item.isEnabled());
|
||||||
|
settings.setAutoReloadConfigurations(definition, item.getAutoReloadConfigurations());
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.reorderScriptDefinitions();
|
manager.reorderScriptDefinitions();
|
||||||
@@ -76,16 +74,17 @@ public class KotlinScriptingSettingsConfigurable implements SearchableConfigurab
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
scriptDependenciesAutoReload.setSelected(settings.isAutoReloadEnabled());
|
|
||||||
|
|
||||||
model.setDefinitions(manager.getAllDefinitions(), settings);
|
model.setDefinitions(manager.getAllDefinitions(), settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isScriptDefinitionsChanged() {
|
private boolean isScriptDefinitionsChanged() {
|
||||||
for (KotlinScriptDefinitionsModelDescriptor item : model.getItems()) {
|
for (ModelDescriptor item : model.getItems()) {
|
||||||
if (settings.isScriptDefinitionEnabled(item.getDefinition()) != item.isEnabled()) {
|
if (settings.isScriptDefinitionEnabled(item.getDefinition()) != item.isEnabled()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (settings.autoReloadConfigurations(item.getDefinition()) != item.getAutoReloadConfigurations()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return !model.getDefinitions().equals(manager.getAllDefinitions());
|
return !model.getDefinitions().equals(manager.getAllDefinitions());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,17 +20,20 @@ class ScriptOptionsSaveTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
fun testSaveAutoReload() {
|
fun testSaveAutoReload() {
|
||||||
val project = myFixture.project
|
val project = myFixture.project
|
||||||
val settings = KotlinScriptingSettings.getInstance(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(
|
assertEquals(
|
||||||
"isAutoReloadEnabled should be set to true",
|
"isAutoReloadEnabled should be set to true",
|
||||||
"<KotlinScriptingSettings><option name=\"isAutoReloadEnabled\" value=\"true\" /></KotlinScriptingSettings>",
|
"true",
|
||||||
XMLOutputter().outputString(settings.state)
|
XMLOutputter().outputString(settings.state)
|
||||||
|
.substringAfter("<autoReloadConfigurations>")
|
||||||
|
.substringBefore("</autoReloadConfigurations>")
|
||||||
)
|
)
|
||||||
|
|
||||||
settings.isAutoReloadEnabled = initialAutoReload
|
settings.setAutoReloadConfigurations(definition, initialAutoReload)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testSaveScriptDefinitionOff() {
|
fun testSaveScriptDefinitionOff() {
|
||||||
@@ -45,8 +48,10 @@ class ScriptOptionsSaveTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"scriptDefinition should be off",
|
"scriptDefinition should be off",
|
||||||
"<KotlinScriptingSettings><scriptDefinition><order>0</order><isEnabled>false</isEnabled></scriptDefinition></KotlinScriptingSettings>",
|
"false",
|
||||||
XMLOutputter().outputString(settings.state).replace("scriptDefinition .*\">".toRegex(), "scriptDefinition>")
|
XMLOutputter().outputString(settings.state)
|
||||||
|
.substringAfter("<isEnabled>")
|
||||||
|
.substringBefore("</isEnabled>")
|
||||||
)
|
)
|
||||||
|
|
||||||
settings.setEnabled(scriptDefinition, initialIsEnabled)
|
settings.setEnabled(scriptDefinition, initialIsEnabled)
|
||||||
|
|||||||
+6
-1
@@ -41,6 +41,11 @@ abstract class ScriptDefinition : UserDataHolderBase() {
|
|||||||
|
|
||||||
open val isDefault = false
|
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 baseClassType: KotlinType
|
||||||
abstract val compilerOptions: Iterable<String>
|
abstract val compilerOptions: Iterable<String>
|
||||||
abstract val annotationsForSamWithReceivers: List<String>
|
abstract val annotationsForSamWithReceivers: List<String>
|
||||||
@@ -59,7 +64,7 @@ abstract class ScriptDefinition : UserDataHolderBase() {
|
|||||||
override val legacyDefinition: KotlinScriptDefinition
|
override val legacyDefinition: KotlinScriptDefinition
|
||||||
) : ScriptDefinition() {
|
) : ScriptDefinition() {
|
||||||
|
|
||||||
override val compilationConfiguration by lazy {
|
override val compilationConfiguration: ScriptCompilationConfiguration by lazy {
|
||||||
ScriptCompilationConfigurationFromDefinition(
|
ScriptCompilationConfigurationFromDefinition(
|
||||||
hostConfiguration,
|
hostConfiguration,
|
||||||
legacyDefinition
|
legacyDefinition
|
||||||
|
|||||||
Reference in New Issue
Block a user