Fix "Run" action for Kotlin sources in non-Android modules
This commit is contained in:
+96
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.android
|
||||||
|
|
||||||
|
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.module.ModuleManager
|
||||||
|
import com.intellij.openapi.roots.ModuleRootModel
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
|
import org.jetbrains.android.facet.AndroidFacet
|
||||||
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
|
import org.jetbrains.kotlin.idea.run.isMultiplatformModule
|
||||||
|
import org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler
|
||||||
|
import org.jetbrains.plugins.gradle.model.ExternalSourceDirectorySet
|
||||||
|
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataCache
|
||||||
|
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/*
|
||||||
|
Partially copied from org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler.
|
||||||
|
|
||||||
|
Unfortunately, GradleOrderEnumeratorHandler doesn't work for Android Studio as it returns 'false' for
|
||||||
|
GradleSystemRunningSettings::isUseGradleAwareMake(), so only resource directories are added.
|
||||||
|
We can't specify 'isUseGradleAwareMake()' cause it's a global IDEA preference.
|
||||||
|
|
||||||
|
Everything works for Java-only projects because there's only a single classes directory,
|
||||||
|
but Kotlin Gradle plugin adds a separate output directory, and it's not attached by default.
|
||||||
|
*/
|
||||||
|
class AndroidGradleOrderEnumerationHandler(module: Module) : GradleOrderEnumeratorHandler(module) {
|
||||||
|
override fun shouldProcessDependenciesRecursively() = false
|
||||||
|
|
||||||
|
override fun addCustomModuleRoots(
|
||||||
|
type: OrderRootType,
|
||||||
|
rootModel: ModuleRootModel,
|
||||||
|
result: MutableCollection<String>,
|
||||||
|
includeProduction: Boolean,
|
||||||
|
includeTests: Boolean
|
||||||
|
): Boolean {
|
||||||
|
if (type != OrderRootType.CLASSES) return false
|
||||||
|
|
||||||
|
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
|
||||||
|
KotlinFacet.get(rootModel.module) ?: return false
|
||||||
|
|
||||||
|
val module = rootModel.module
|
||||||
|
fun Module.isAndroidModule() = AndroidFacet.getInstance(this) != null
|
||||||
|
|
||||||
|
// The current module has to be an ordinary Java module, but the code below is for Android projects
|
||||||
|
if (module.isAndroidModule() || ModuleManager.getInstance(module.project).modules.none { it.isAndroidModule() }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val gradleProjectPath = ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
|
||||||
|
|
||||||
|
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project) ?: return false
|
||||||
|
val externalRootProject = externalProjectDataCache
|
||||||
|
.getRootExternalProject(GradleConstants.SYSTEM_ID, File(gradleProjectPath)) ?: return false
|
||||||
|
|
||||||
|
val externalSourceSets = externalProjectDataCache.findExternalProject(externalRootProject, rootModel.module)
|
||||||
|
if (externalSourceSets.isEmpty()) return false
|
||||||
|
|
||||||
|
for (sourceSet in externalSourceSets.values) {
|
||||||
|
fun ExternalSourceDirectorySet.addSourceRoots() {
|
||||||
|
for (it in gradleOutputDirs) {
|
||||||
|
val path = VfsUtilCore.pathToUrl(it.absolutePath).takeIf { it !in result } ?: continue
|
||||||
|
result.add(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeTests) {
|
||||||
|
sourceSet.sources[ExternalSystemSourceType.TEST]?.addSourceRoots()
|
||||||
|
sourceSet.sources[ExternalSystemSourceType.TEST_RESOURCE]?.addSourceRoots()
|
||||||
|
}
|
||||||
|
if (includeProduction) {
|
||||||
|
sourceSet.sources[ExternalSystemSourceType.SOURCE]?.addSourceRoots()
|
||||||
|
sourceSet.sources[ExternalSystemSourceType.RESOURCE]?.addSourceRoots()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
class FactoryImpl : Factory() {
|
||||||
|
override fun isApplicable(module: Module): Boolean {
|
||||||
|
return ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)
|
||||||
|
&& !module.isMultiplatformModule()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createHandler(module: Module) = AndroidGradleOrderEnumerationHandler(module)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,6 +50,8 @@
|
|||||||
|
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
||||||
|
|
||||||
|
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.android.AndroidGradleOrderEnumerationHandler$FactoryImpl" order="first"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
|||||||
@@ -58,6 +58,8 @@
|
|||||||
|
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
||||||
|
|
||||||
|
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.android.AndroidGradleOrderEnumerationHandler$FactoryImpl" order="first"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
|
||||||
|
|
||||||
|
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.android.AndroidGradleOrderEnumerationHandler$FactoryImpl" order="first"/>
|
||||||
|
|
||||||
<moduleBuilder builderClass="org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder" />
|
<moduleBuilder builderClass="org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder" />
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user