Fix order of ExternalSystemListeners

in 201 the order of ExternalSystemListener.EP isn't guaranteed.
But we need to update script definitions and only then we can store script models,
because they need to know script definitions additional classpath
This commit is contained in:
Natalia Selezneva
2020-05-15 18:36:34 +03:00
parent 1a1bcefb2a
commit 879fe9b493
7 changed files with 100 additions and 61 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionSourceAsContributor
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager
import org.jetbrains.kotlin.idea.core.script.loadDefinitionsFromTemplates
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslSyncListener
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinitionAdapterFromNewAPIBase
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
import org.jetbrains.kotlin.scripting.definitions.getEnvironment
@@ -139,6 +140,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
): List<ScriptDefinition> = try {
doLoadGradleTemplates(templateClass, dependencySelector, additionalResolverClasspath)
} catch (t: Throwable) {
scriptingDebugLog { "error loading gradle script templates ${t.message}" }
// TODO: review exception handling
failedToLoad.set(true)
if (t is IllegalStateException) {
@@ -209,6 +211,8 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
dependencySelector.matches(it.name)
}.takeIf { it.isNotEmpty() }?.asList() ?: error(KotlinIdeaGradleBundle.message("error.text.missing.jars.in.gradle.directory"))
scriptingDebugLog { "loading gradle script templates from $templateClasspath" }
return loadDefinitionsFromTemplates(
listOf(templateClass),
templateClasspath,
@@ -276,7 +280,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
private class ErrorScriptDependenciesResolver(private val message: String? = null) : DependenciesResolver {
override fun resolve(scriptContents: ScriptContents, environment: Environment): ResolveResult {
val failureMessage = if (GradleScriptDefinitionsUpdater.gradleState.isSyncInProgress) {
val failureMessage = if (KotlinDslSyncListener.gradleState.isSyncInProgress) {
KotlinIdeaGradleBundle.message("error.text.highlighting.is.impossible.during.gradle.import")
} else {
message ?: KotlinIdeaGradleBundle.message(
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2019 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 com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
class GradleScriptDefinitionsUpdater : ExternalSystemTaskNotificationListenerAdapter() {
companion object {
internal val gradleState = GradleSyncState()
}
override fun onStart(id: ExternalSystemTaskId, workingDir: String?) {
if (id.type == ExternalSystemTaskType.RESOLVE_PROJECT && id.projectSystemId == GRADLE_SYSTEM_ID) {
gradleState.isSyncInProgress = true
}
}
override fun onEnd(id: ExternalSystemTaskId) {
if (id.type == ExternalSystemTaskType.RESOLVE_PROJECT && id.projectSystemId == GRADLE_SYSTEM_ID) {
gradleState.isSyncInProgress = false
val project = id.findProject() ?: return
val gradleDefinitionsContributor =
ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(
project
)
gradleDefinitionsContributor?.reloadIfNecessary()
}
}
}
internal class GradleSyncState {
var isSyncInProgress: Boolean = false
}
@@ -8,26 +8,60 @@ package org.jetbrains.kotlin.idea.scripting.gradle.importing
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
import org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsContributor
class KotlinDslSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
override fun onStart(id: ExternalSystemTaskId, workingDir: String?) {
if (id.type != ExternalSystemTaskType.RESOLVE_PROJECT) return
if (id.projectSystemId != GRADLE_SYSTEM_ID) return
if (!isGradleProjectImport(id)) return
if (workingDir == null) return
gradleState.isSyncInProgress = true
val project = id.findProject() ?: return
project.kotlinGradleDslSync[id] = KotlinDslGradleBuildSync(workingDir, id)
}
override fun onEnd(id: ExternalSystemTaskId) {
if (id.type != ExternalSystemTaskType.RESOLVE_PROJECT) return
if (id.projectSystemId != GRADLE_SYSTEM_ID) return
if (!isGradleProjectImport(id)) return
gradleState.isSyncInProgress = false
val project = id.findProject() ?: return
val sync = project.kotlinGradleDslSync.remove(id) ?: return
saveScriptModels(project, sync)
@Suppress("DEPRECATION")
ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(project)?.reloadIfNecessary()
val sync = project.kotlinGradleDslSync.remove(id)
if (sync != null) {
// For Gradle 6.0 or higher
saveScriptModels(project, sync)
}
}
override fun onCancel(id: ExternalSystemTaskId) {
if (!isGradleProjectImport(id)) return
gradleState.isSyncInProgress = false
val project = id.findProject() ?: return
project.kotlinGradleDslSync.remove(id)
}
private fun isGradleProjectImport(id: ExternalSystemTaskId): Boolean {
return id.type == ExternalSystemTaskType.RESOLVE_PROJECT || id.projectSystemId == GRADLE_SYSTEM_ID
}
companion object {
internal val gradleState = GradleSyncState()
}
}
// TODO: state should be stored by gradle build,
// now it is marked as complete after first gradle project was imported
internal class GradleSyncState {
var isSyncInProgress: Boolean = false
}
@@ -0,0 +1,53 @@
/*
* 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.importing
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
import org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsContributor
class KotlinDslSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
override fun onStart(id: ExternalSystemTaskId, workingDir: String?) {
if (!isGradleProjectImport(id)) return
if (workingDir == null) return
gradleState.isSyncInProgress = true
}
override fun onEnd(id: ExternalSystemTaskId) {
if (!isGradleProjectImport(id)) return
gradleState.isSyncInProgress = false
val project = id.findProject() ?: return
@Suppress("DEPRECATION")
ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(project)?.reloadIfNecessary()
}
override fun onCancel(id: ExternalSystemTaskId) {
if (!isGradleProjectImport(id)) return
gradleState.isSyncInProgress = false
}
private fun isGradleProjectImport(id: ExternalSystemTaskId): Boolean {
return id.type == ExternalSystemTaskType.RESOLVE_PROJECT || id.projectSystemId == GRADLE_SYSTEM_ID
}
companion object {
internal val gradleState = GradleSyncState()
}
}
// TODO: state should be stored by gradle build,
// now it is marked as complete after first gradle project was imported
internal class GradleSyncState {
var isSyncInProgress: Boolean = false
}
-5
View File
@@ -29,13 +29,8 @@
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinTargetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryDataService"/>
<externalSystemTaskNotificationListener
id="GradleScriptDefinitionsUpdater"
implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsUpdater"
/>
<externalSystemTaskNotificationListener
implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslSyncListener"
order="after GradleScriptDefinitionsUpdater"
/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.MissingGradleScriptConfigurationNotificationProvider"/>
+1 -2
View File
@@ -24,8 +24,7 @@
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryDataService"/>
<externalSystemTaskNotificationListener
id="GradleScriptDefinitionsUpdater"
implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsUpdater"
implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslSyncListener"
/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.MissingGradleScriptConfigurationNotificationProvider"/>
@@ -25,13 +25,8 @@
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinTargetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryDataService"/>
<externalSystemTaskNotificationListener
id="GradleScriptDefinitionsUpdater"
implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsUpdater"
/>
<externalSystemTaskNotificationListener
implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslSyncListener"
order="after GradleScriptDefinitionsUpdater"
/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.MissingGradleScriptConfigurationNotificationProvider"/>