From 06dbbe2452d5d7078acc7f97c2c3081792469402 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Fri, 22 May 2020 18:19:11 +0300 Subject: [PATCH] KotlinDslModels: project can be null in ExternalSystemTaskNotificationListener.onStart --- ...or.kt => KotlinDslScriptModelProcessor.kt} | 31 +++++++------ .../gradle/importing/KotlinDslSyncListener.kt | 46 +++++++++++-------- 2 files changed, 45 insertions(+), 32 deletions(-) rename idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/{KotlinDslScrtiptModelProcessor.kt => KotlinDslScriptModelProcessor.kt} (85%) diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScrtiptModelProcessor.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelProcessor.kt similarity index 85% rename from idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScrtiptModelProcessor.kt rename to idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelProcessor.kt index 6960d9747df..f34a0f6697e 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScrtiptModelProcessor.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelProcessor.kt @@ -21,11 +21,6 @@ import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext import java.io.File import java.util.concurrent.ConcurrentHashMap -var Project.kotlinGradleDslSync: MutableMap - by NotNullableUserDataProperty>( - Key("Kotlin DSL Scripts Models"), ConcurrentHashMap() - ) - fun processScriptModel( resolverCtx: ProjectResolverContext, model: KotlinDslScriptsModel, @@ -40,7 +35,13 @@ fun processScriptModel( val project = task.findProject() ?: return val models = model.toListOfScriptModels(project) - project.kotlinGradleDslSync[task]?.models?.addAll(models) + val tasks = KotlinDslSyncListener.instance.tasks + val sync = synchronized(tasks) { tasks[task] } + if (sync != null) { + synchronized(sync) { + sync.models.addAll(models) + } + } if (models.containsErrors()) { throw IllegalStateException(KotlinIdeaGradleBundle.message("title.kotlin.build.script")) @@ -106,14 +107,16 @@ class KotlinDslGradleBuildSync(val workingDir: String, val taskId: ExternalSyste } fun saveScriptModels(project: Project, build: KotlinDslGradleBuildSync) { - val errorReporter = KotlinGradleDslErrorReporter(project, build.taskId) + synchronized(build) { + val errorReporter = KotlinGradleDslErrorReporter(project, build.taskId) - build.models.forEach { model -> - errorReporter.reportError(File(model.file), model) + build.models.forEach { model -> + errorReporter.reportError(File(model.file), model) + } + + // todo: use real info about projects + build.projectRoots.addAll(build.models.map { toSystemIndependentName(File(it.file).parent) }) + + GradleBuildRootsManager.getInstance(project).update(build) } - - // todo: use real info about projects - build.projectRoots.addAll(build.models.map { toSystemIndependentName(File(it.file).parent) }) - - GradleBuildRootsManager.getInstance(project).update(build) } \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslSyncListener.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslSyncListener.kt index 1f13b26c437..8e006b607e6 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslSyncListener.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslSyncListener.kt @@ -6,53 +6,63 @@ package org.jetbrains.kotlin.idea.scripting.gradle.importing import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager -import java.lang.Exception +import java.util.* class KotlinDslSyncListener : ExternalSystemTaskNotificationListenerAdapter() { + companion object { + val instance: KotlinDslSyncListener + get() = ExternalSystemTaskNotificationListener.EP_NAME + .extensionList.filterIsInstance().single() + } + + val tasks = WeakHashMap() + override fun onStart(id: ExternalSystemTaskId, workingDir: String?) { - if (id.type != ExternalSystemTaskType.RESOLVE_PROJECT) return - if (id.projectSystemId != GRADLE_SYSTEM_ID) return + if (!isGradleProjectResolve(id)) return if (workingDir == null) return - val project = id.findProject() ?: return + synchronized(tasks) { tasks[id] = KotlinDslGradleBuildSync(workingDir, id) } + // project may be null in case of new project + val project = id.findProject() ?: return GradleBuildRootsManager.getInstance(project).markImportingInProgress(workingDir) - 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 (!isGradleProjectResolve(id)) return + val sync = synchronized(tasks) { tasks.remove(id) } ?: return + + // project may be null in case of new project val project = id.findProject() ?: return - val sync = project.kotlinGradleDslSync.remove(id) ?: return - saveScriptModels(project, sync) } override fun onFailure(id: ExternalSystemTaskId, e: Exception) { - if (id.type != ExternalSystemTaskType.RESOLVE_PROJECT) return - if (id.projectSystemId != GRADLE_SYSTEM_ID) return - - val project = id.findProject() ?: return - val sync = project.kotlinGradleDslSync[id] ?: return + if (!isGradleProjectResolve(id)) return + val sync = synchronized(tasks) { tasks[id] } ?: return sync.failed = true } override fun onCancel(id: ExternalSystemTaskId) { - if (id.type != ExternalSystemTaskType.RESOLVE_PROJECT) return - if (id.projectSystemId != GRADLE_SYSTEM_ID) return + if (!isGradleProjectResolve(id)) return + val cancelled = synchronized(tasks) { tasks.remove(id) } + + // project may be null in case of new project val project = id.findProject() ?: return - - val cancelled = project.kotlinGradleDslSync.remove(id) if (cancelled != null) { GradleBuildRootsManager.getInstance(project).markImportingInProgress(cancelled.workingDir, false) } } + + private fun isGradleProjectResolve(id: ExternalSystemTaskId) = + id.type == ExternalSystemTaskType.RESOLVE_PROJECT && + id.projectSystemId == GRADLE_SYSTEM_ID }