multiplatform: remove MultiplatformGradleProjectTaskRunner

JPS is now able to build multiplatform projects, so build/run actions should be delegated to gradle only with "Delegate IDE build/run action actions" setting enabled.
This commit is contained in:
Sergey Rostov
2018-04-13 14:14:30 +03:00
parent f7695dd039
commit 4a6554a36d
5 changed files with 0 additions and 365 deletions
@@ -1,189 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.configurations.JavaRunConfigurationModule
import com.intellij.execution.configurations.ModuleBasedConfiguration
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleOrderEntry
import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.openapi.roots.OrderEnumerationHandler
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.task.*
import com.intellij.task.impl.ModuleBuildTaskImpl
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.idea.project.targetPlatform
import org.jetbrains.kotlin.idea.util.rootManager
import org.jetbrains.plugins.gradle.execution.build.GradleProjectTaskRunner
import org.jetbrains.plugins.gradle.model.ExternalSourceDirectorySet
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataCache
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import java.io.File
import kotlin.concurrent.getOrSet
/**
* Ensures that build/run actions are always delegated to Gradle for multiplatform projects.
*/
class MultiplatformGradleProjectTaskRunner : GradleProjectTaskRunner() {
override fun canRun(projectTask: ProjectTask) =
when (projectTask) {
is ModuleBuildTask ->
projectTask.module.isMultiplatformModule()
is ExecuteRunConfigurationTask -> {
val runProfile = projectTask.runProfile
if (runProfile is ModuleBasedConfiguration<*>) {
runProfile.configurationModule.module?.isMultiplatformModule() == true
} else {
false
}
}
else -> false
}
override fun run(
project: Project,
context: ProjectTaskContext,
callback: ProjectTaskNotification?,
tasks: Collection<ProjectTask>
) {
val configuration = context.runConfiguration
if (configuration is ModuleBasedConfiguration<*> &&
(configuration.configurationModule is JavaRunConfigurationModule || configuration is KotlinRunConfiguration)
) {
val module = configuration.configurationModule.module
if (module?.targetPlatform == TargetPlatformKind.Common) {
val implModule = module.findJvmImplementationModule()
if (implModule != null) {
val replacedTasks = tasks.map { it.replaceModule(module, implModule) }
super.run(project, context, callback, replacedTasks)
return
}
}
}
super.run(project, context, callback, tasks)
}
private fun ProjectTask.replaceModule(origin: Module, replacement: Module): ProjectTask =
when (this) {
is ModuleFilesBuildTask -> this
is ModuleBuildTask ->
if (module == origin)
ModuleBuildTaskImpl(replacement, isIncrementalBuild, isIncludeDependentModules, isIncludeRuntimeDependencies)
else
this
else -> this
}
}
class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradleOrderEnumeratorHandler.FactoryImpl) :
OrderEnumerationHandler() {
override fun addCustomModuleRoots(
type: OrderRootType,
rootModel: ModuleRootModel,
result: MutableCollection<String>,
includeProduction: Boolean,
includeTests: Boolean
): Boolean {
if (factory.isEnumerating(rootModel.module)) return false
factory.startEnumerating(rootModel.module)
try {
if (type != OrderRootType.CLASSES) return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) {
val gradleProjectPath =
ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!!
val externalRootProject = externalProjectDataCache.getRootExternalProject(
GradleConstants.SYSTEM_ID,
File(gradleProjectPath)
) ?: return false
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
for (sourceSet in externalSourceSets.values) {
if (includeTests) {
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.TEST], result)
}
if (includeProduction) {
addOutputModuleRoots(sourceSet.sources[ExternalSystemSourceType.SOURCE], result)
}
}
}
val implModule = rootModel.module.findJvmImplementationModule()
implModule
?.rootManager
?.orderEntries()
?.satisfying { orderEntry -> (orderEntry as? ModuleOrderEntry)?.module != rootModel.module }
?.compileOnly()
?.classesRoots
?.mapTo(result) { it.url }
} finally {
factory.doneEnumerating(rootModel.module)
}
return false
}
private fun addOutputModuleRoots(directorySet: ExternalSourceDirectorySet?, result: MutableCollection<String>) {
directorySet?.gradleOutputDirs?.mapTo(result) { VfsUtilCore.pathToUrl(it.absolutePath) }
}
class FactoryImpl : Factory() {
private val activeSet = ThreadLocal<MutableSet<Module>>()
fun startEnumerating(module: Module) {
activeSet.getOrSet { hashSetOf() } += module
}
fun doneEnumerating(module: Module) {
activeSet.get()?.remove(module)
}
fun isEnumerating(module: Module) = activeSet.get()?.contains(module) ?: false
override fun isApplicable(module: Module): Boolean {
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module) &&
module.isMultiplatformModule() &&
!isEnumerating(module)
}
override fun createHandler(module: Module): OrderEnumerationHandler =
MultiplatformGradleOrderEnumeratorHandler(this)
}
}
private fun Module.isMultiplatformModule(): Boolean {
val settings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this)
return settings.targetPlatformKind is TargetPlatformKind.Common || settings.implementedModuleNames.isNotEmpty()
}
@@ -1,167 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.codeInsight.gradle
import com.intellij.compiler.options.CompileStepBeforeRun
import com.intellij.execution.Location
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.configurations.JavaCommandLineState
import com.intellij.execution.executors.DefaultRunExecutor
import com.intellij.execution.runners.ExecutionEnvironmentBuilder
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.application.invokeAndWaitIfNeed
import com.intellij.psi.PsiManager
import com.intellij.testFramework.MapDataContext
import org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.psi.KtFile
import org.junit.Test
class GradleMultiplatformRunTest : GradleImportingTestCase() {
@Test
fun testMultiplatformClasspath() {
createProjectSubFile(
"build.gradle",
"""
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4")
}
}
apply plugin: 'kotlin-platform-common'
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-common:1.1.4"
}
""".trimIndent()
)
createProjectSubFile(
"settings.gradle",
"""
rootProject.name = 'MultiTest'
include 'MultiTest-jvm', 'MultiTest-js'
""".trimIndent()
)
createProjectSubFile(
"MultiTest-js/build.gradle",
"""
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4")
}
}
apply plugin: 'kotlin-platform-js'
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:1.1.4"
implement project(":")
}
""".trimIndent()
)
createProjectSubFile(
"MultiTest-jvm/build.gradle",
"""
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.4")
}
}
apply plugin: 'kotlin-platform-jvm'
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.4"
implement project(":")
}
""".trimIndent()
)
val virtualFile = createProjectSubFile("src/main/kotlin/foo.kt", "fun main(args: Array<String>) { println(\"Foo!\") }")
importProject()
val javaParameters = invokeAndWaitIfNeed {
val psiFile = PsiManager.getInstance(myProject).findFile(virtualFile) as KtFile
val function = psiFile.declarations.single()
val dataContext = MapDataContext().apply {
put(CommonDataKeys.PROJECT, myProject)
put(LangDataKeys.MODULE, function.module)
put(Location.DATA_KEY, PsiLocation.fromPsiElement(function))
}
val configurationContext = ConfigurationContext.getFromContext(dataContext)
val producer = RunConfigurationProducer.getInstance(KotlinRunConfigurationProducer::class.java)
val configuration = producer.createConfigurationFromContext(configurationContext)!!
val executionEnvironment = ExecutionEnvironmentBuilder.create(
myProject,
DefaultRunExecutor.getRunExecutorInstance(),
configuration.configuration
)
.build()
val compileStepBeforeRun = CompileStepBeforeRun(myProject)
compileStepBeforeRun.executeTask(
dataContext, configuration.configuration, executionEnvironment,
CompileStepBeforeRun.MakeBeforeRunTask()
)
val state = configuration.configuration.getState(
DefaultRunExecutor.getRunExecutorInstance(),
executionEnvironment
) as JavaCommandLineState
state.javaParameters
}
val p = javaParameters.classPath
assertTrue(p.virtualFiles.any { it.findChild("FooKt.class") != null })
}
}
-3
View File
@@ -50,9 +50,6 @@
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleProjectTaskRunner" order="first,before gradle"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleOrderEnumeratorHandler$FactoryImpl" order="first"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
-3
View File
@@ -58,9 +58,6 @@
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleProjectTaskRunner" order="first,before gradle"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleOrderEnumeratorHandler$FactoryImpl" order="first"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
-3
View File
@@ -60,9 +60,6 @@
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleProjectTaskRunner" order="first,before gradle"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleOrderEnumeratorHandler$FactoryImpl" order="first"/>
<moduleBuilder builderClass="org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder" />
</extensions>