From 681c2e9492d6a7977be79ab0c2385a2c1a6ee28d Mon Sep 17 00:00:00 2001 From: Andrei Klunnyi Date: Tue, 30 Jun 2020 13:43:09 +0200 Subject: [PATCH] KT-39788 MPP, Gradle runner: Run does not add resource directory to classpath // classpath fix The reason of resource directory absence was that it couldn't be loaded from the project configuration file. Just after the import it remained in the memory and runner couldn' get it. KotlinOutputPathsDataService as a pair to KotlinOutputPaths is what was missing. Details are provided below. ------------------------------------------------------------------------ On a disk configuration represents a binary file containing serialized graph of external project structure. It contains nodes belonging to both IDEA and its plugins. To deserialize a node IDEA tries to load its class using a chain of class-loaders: its own and those provided by actual set of plugins. The nuance is how to get plugins' ones. The approach is the following. There is an association between a node's payload and a service which is supposed to consume it see KotlinOutputPathsDataService#getTargetDataKey and DataNode#getKey). Plugin services are guaranteed to be loaded by plugin class loader. No association - service - no plugin, node was just skipped. ------------------------------------------------------------------------ --- .../idea/configuration/KotlinMPPDataNodes.kt | 3 +- .../KotlinOutputPathsDataService.kt | 34 +++++++++++++++++++ idea/resources/META-INF/gradle-java.xml | 1 + idea/resources/META-INF/gradle-java.xml.193 | 1 + 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinOutputPathsDataService.kt diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPDataNodes.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPDataNodes.kt index 5299edca6ab..e0ec8e3dedd 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPDataNodes.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinMPPDataNodes.kt @@ -70,7 +70,8 @@ class KotlinTargetData @PropertyMapping("externalName") constructor(externalName } } -class KotlinOutputPathsData(val paths: MultiMap) : AbstractExternalEntityData(GradleConstants.SYSTEM_ID) { +class KotlinOutputPathsData @PropertyMapping("paths") constructor(val paths: MultiMap) : + AbstractExternalEntityData(GradleConstants.SYSTEM_ID) { companion object { val KEY = ExternalKey.create(KotlinOutputPathsData::class.java, ProjectKeys.CONTENT_ROOT.processingWeight + 1) } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinOutputPathsDataService.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinOutputPathsDataService.kt new file mode 100644 index 00000000000..66e495afd34 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinOutputPathsDataService.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.configuration + +import com.intellij.openapi.externalSystem.model.DataNode +import com.intellij.openapi.externalSystem.model.project.ProjectData +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider +import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService +import com.intellij.openapi.project.Project + +/** + * This service appeared as a solution of the problem when [KotlinOutputPathsData] couldn't be deserialized after having been stored on disk + * as a part of [DataNode] graph. Though we don't need the service itself, for now its the only way to make things work. + * + * Deserialization takes place at [serialization.kt#createDataClassResolver] (located in [platform-api.jar]). + * + * Graph contains nodes belonging to both IDEA and its plugins. To deserialize a node IDEA tries to load its class using a chain of + * class-loaders: its own and those provided by actual set of plugins. The nuance is how to get plugins' ones. The approach is the + * following. There is an association between a node's payload and a service which is supposed to consume it, see [getTargetDataKey] and + * [DataNode.key]. Plugin services are guaranteed to be loaded by plugin class loader. No service - no plugin, node is just skipped. + * + */ +class KotlinOutputPathsDataService : AbstractProjectDataService() { + override fun getTargetDataKey() = KotlinOutputPathsData.KEY + + override fun importData( + toImport: MutableCollection>, projectData: ProjectData?, project: Project, + modelsProvider: IdeModifiableModelsProvider + ) { + } +} \ No newline at end of file diff --git a/idea/resources/META-INF/gradle-java.xml b/idea/resources/META-INF/gradle-java.xml index 5ecfbfc77dd..8b646878ad3 100644 --- a/idea/resources/META-INF/gradle-java.xml +++ b/idea/resources/META-INF/gradle-java.xml @@ -25,6 +25,7 @@ + +