MPP: Attach all classes/resources directories to the runtime classpath (KT-30710)
This commit is contained in:
@@ -9,9 +9,11 @@ import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
||||
import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData
|
||||
import com.intellij.openapi.externalSystem.model.project.AbstractNamedData
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.gradle.KotlinModule
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||
@@ -53,4 +55,10 @@ class KotlinTargetData(name: String) : AbstractNamedData(GradleConstants.SYSTEM_
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinTargetData::class.java, ProjectKeys.MODULE.processingWeight + 1)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinOutputPathsData(val paths: MultiMap<ExternalSystemSourceType, String>) : AbstractExternalEntityData(GradleConstants.SYSTEM_ID) {
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinOutputPathsData::class.java, ProjectKeys.CONTENT_ROOT.processingWeight + 1)
|
||||
}
|
||||
}
|
||||
+2
@@ -110,6 +110,8 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
recordOutputDir(it, it, compilation.resourceType, moduleData, moduleOutputsMap, gradleOutputMap)
|
||||
}
|
||||
}
|
||||
|
||||
dataNode.createChild(KotlinOutputPathsData.KEY, KotlinOutputPathsData(gradleOutputMap.copy()))
|
||||
}
|
||||
if (outputDirs.any { FileUtil.isAncestor(ideaOutDir, File(it), false) }) {
|
||||
excludeOutDir(ideModule, ideaOutDir)
|
||||
|
||||
+82
@@ -5,15 +5,97 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.gradle.execution
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getExternalProjectInfo
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModuleRootModel
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import org.jetbrains.kotlin.idea.caches.project.isMPPModule
|
||||
import org.jetbrains.kotlin.idea.caches.project.isNewMPPModule
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinOutputPathsData
|
||||
import org.jetbrains.plugins.gradle.execution.GradleOrderEnumeratorHandler
|
||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
|
||||
open class KotlinGradleOrderEnumerationHandler(module: Module) : GradleOrderEnumeratorHandler(module) {
|
||||
private companion object {
|
||||
private val PRODUCTION_SOURCE_TYPES = listOf(
|
||||
ExternalSystemSourceType.SOURCE,
|
||||
ExternalSystemSourceType.RESOURCE,
|
||||
ExternalSystemSourceType.SOURCE_GENERATED
|
||||
)
|
||||
|
||||
private val TEST_SOURCE_TYPES = listOf(
|
||||
ExternalSystemSourceType.TEST,
|
||||
ExternalSystemSourceType.TEST_RESOURCE,
|
||||
ExternalSystemSourceType.TEST_GENERATED
|
||||
)
|
||||
}
|
||||
|
||||
override fun shouldIncludeTestsFromDependentModulesToTestClasspath(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun addCustomModuleRoots(
|
||||
type: OrderRootType,
|
||||
rootModel: ModuleRootModel,
|
||||
result: MutableCollection<String>,
|
||||
includeProduction: Boolean,
|
||||
includeTests: Boolean
|
||||
): Boolean {
|
||||
if (super.addCustomModuleRoots(type, rootModel, result, includeProduction, includeTests)) {
|
||||
// The code below works as a fallback when the default implementation fails
|
||||
return true
|
||||
}
|
||||
|
||||
val module = rootModel.module.takeIf { it.isNewMPPModule } ?: return false
|
||||
val projectPath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return false
|
||||
val externalProjectInfo = getExternalProjectInfo(module.project, GradleConstants.SYSTEM_ID, projectPath) ?: return false
|
||||
val moduleData = GradleProjectResolverUtil.findModule(externalProjectInfo.externalProjectStructure, projectPath) ?: return false
|
||||
|
||||
val sourceSetData = ExternalSystemApiUtil.getChildren(moduleData, GradleSourceSetData.KEY)
|
||||
.filter { it.data.internalName == module.name }
|
||||
|
||||
if (sourceSetData.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val existingRoots = result.toMutableSet()
|
||||
var hasNewRoots = false
|
||||
|
||||
fun appendPaths(paths: Collection<String>) {
|
||||
for (path in paths) {
|
||||
val url = VfsUtilCore.pathToUrl(path)
|
||||
if (existingRoots.add(url)) {
|
||||
result.add(url)
|
||||
if (!hasNewRoots) {
|
||||
hasNewRoots = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun appendPaths(outputPaths: KotlinOutputPathsData, configurations: List<ExternalSystemSourceType>) {
|
||||
configurations.forEach { appendPaths(outputPaths.paths[it]) }
|
||||
}
|
||||
|
||||
for (data in sourceSetData) {
|
||||
for (outputPaths in ExternalSystemApiUtil.findAll(data, KotlinOutputPathsData.KEY)) {
|
||||
if (includeProduction) {
|
||||
appendPaths(outputPaths.data, PRODUCTION_SOURCE_TYPES)
|
||||
}
|
||||
if (includeTests) {
|
||||
appendPaths(outputPaths.data, TEST_SOURCE_TYPES)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasNewRoots
|
||||
}
|
||||
|
||||
open class Factory : GradleOrderEnumeratorHandler.FactoryImpl() {
|
||||
override fun isApplicable(module: Module): Boolean {
|
||||
return module.isMPPModule
|
||||
|
||||
+33
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.roots.*
|
||||
import com.intellij.openapi.roots.impl.ModulesOrderEnumerator
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.idea.codeInsight.gradle.MultiplePluginVersionGradleImportingTestCase
|
||||
import org.jetbrains.kotlin.idea.util.sourceRoots
|
||||
@@ -66,6 +68,37 @@ class NewMultiplatformKaptProjectImportingTest : MultiplePluginVersionGradleImpo
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRuntimeClasspath() {
|
||||
configureByFiles()
|
||||
|
||||
val projectPath = this.projectPath
|
||||
|
||||
val expectedRoots = listOf(
|
||||
"build/tmp/kapt3/classes/main",
|
||||
"build/classes/java/main",
|
||||
"build/classes/kotlin/jvm/main",
|
||||
"build/processedResources/jvm/main"
|
||||
).map {
|
||||
File(projectPath, it).apply { mkdirs() }
|
||||
}
|
||||
|
||||
importProject()
|
||||
|
||||
val jvmMainModule = ModuleManager.getInstance(project).modules.first { it.name == "project_jvmMain" }
|
||||
|
||||
val enumerator = ModulesOrderEnumerator(listOf(jvmMainModule))
|
||||
val roots = enumerator.classesRoots
|
||||
|
||||
fun isRootPresent(file: File) = roots.any { it.path == file.path }
|
||||
|
||||
val missingRoots = expectedRoots.filter { !isRootPresent(it) }
|
||||
|
||||
assert(missingRoots.isEmpty()) {
|
||||
"Missing roots found: " + missingRoots.joinToString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun importProject() {
|
||||
val isCreateEmptyContentRootDirectories = currentExternalProjectSettings.isCreateEmptyContentRootDirectories
|
||||
currentExternalProjectSettings.isCreateEmptyContentRootDirectories = true
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
apply from: "include.gradle"
|
||||
def kotlinVersion = gradleKotlinPluginVersion('1.3.40-eap-67')
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm('jvm') { withJava() }
|
||||
}
|
||||
Reference in New Issue
Block a user