org.jetbrains.kotlin.jps.build.KotlinSourceRootProvider.kt Maven / Gradle / Ivy
/*
* 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.jps.build
import com.intellij.openapi.util.io.FileFilters
import org.jetbrains.jps.builders.AdditionalRootsProviderService
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JavaSourceRootProperties
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.jps.model.expectedByModules
import org.jetbrains.kotlin.jps.model.isTestModule
import org.jetbrains.kotlin.jps.model.sourceSetModules
import java.io.File
class KotlinSourceRootProvider : AdditionalRootsProviderService(JavaModuleBuildTargetType.ALL_TYPES) {
override fun getAdditionalRoots(
target: BuildTarget,
dataPaths: BuildDataPaths?
): List {
val moduleBuildTarget = target as? ModuleBuildTarget ?: return listOf()
val module = moduleBuildTarget.module
val result = mutableListOf()
// Add source roots with type KotlinSourceRootType.
//
// Note: `KotlinSourceRootType` cannot be supported directly, since `SourceRootDescriptors` are computed by
// `ModuleBuildTarget.computeAllTargets`. `ModuleBuildTarget` is required for incremental compilation.
// We cannot define our own `ModuleBuildTarget` since it is final and `ModuleBuildTarget` supports only `JavaSourceRootDescriptor`.
// So the only one way to support `KotlinSourceRootType` is to add a fake `JavaSourceRootDescriptor` for each source root with that type.
val kotlinSourceRootType = if (target.isTests) TestSourceKotlinRootType else SourceKotlinRootType
module.getSourceRoots(kotlinSourceRootType).forEach {
result.add(
JavaSourceRootDescriptor(
it.file,
target,
false,
false,
it.properties.packagePrefix,
setOf(),
FileFilters.EVERYTHING,
)
)
}
// new multiplatform model support:
if (target.isTests == module.isTestModule) {
module.sourceSetModules.forEach { sourceSetModule ->
addModuleSourceRoots(result, sourceSetModule, target)
}
}
// legacy multiplatform model support:
module.expectedByModules.forEach { commonModule ->
addModuleSourceRoots(result, commonModule, target)
}
return result
}
private fun addModuleSourceRoots(
result: MutableList,
module: JpsModule,
target: ModuleBuildTarget
) {
for (commonSourceRoot in module.sourceRoots) {
val isCommonTestsRootType = commonSourceRoot.rootType.isTestsRootType
if (isCommonTestsRootType != null && target.isTests == isCommonTestsRootType) {
val javaSourceRootProperties = commonSourceRoot.properties as? JavaSourceRootProperties
result.add(
KotlinIncludedModuleSourceRoot(
commonSourceRoot.file,
target,
javaSourceRootProperties?.isForGeneratedSources ?: false,
false,
javaSourceRootProperties?.packagePrefix ?: "",
setOf()
)
)
}
}
}
}
private val JpsModuleSourceRootType<*>.isTestsRootType
get() = when (this) {
is KotlinSourceRootType -> this == TestSourceKotlinRootType
is KotlinResourceRootType -> this == TestResourceKotlinRootType
// for compatibility:
is JavaSourceRootType -> this == JavaSourceRootType.TEST_SOURCE
is JavaResourceRootType -> this == JavaResourceRootType.TEST_RESOURCE
else -> null
}
class KotlinIncludedModuleSourceRoot(
root: File,
target: ModuleBuildTarget,
isGenerated: Boolean,
isTemp: Boolean,
packagePrefix: String,
excludes: Set
) : JavaSourceRootDescriptor(root, target, isGenerated, isTemp, packagePrefix, excludes, FileFilters.EVERYTHING)