[Gradle] Move more task inputs to properties
... move more configuration logic to TaskConfigAction classes. This is to avoid directly accessing tasks to configure them. The TaskConfigAction objects should eventually have access to all information that is required to configure the task, and they should compute the final values of all properties. This will also allow 3P plugins to configure Kotlin tasks, without the need to create KGP internal objects. ^KT-50869 In Progress
This commit is contained in:
+2
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Internal
|
||||
import java.io.File
|
||||
|
||||
open class SubpluginOption(val key: String, private val lazyValue: Lazy<String>) {
|
||||
@@ -64,6 +65,7 @@ open class InternalSubpluginOption(key: String, value: String) : SubpluginOption
|
||||
|
||||
/** Keeps one or more compiler options for one of more compiler plugins. */
|
||||
open class CompilerPluginConfig {
|
||||
@get:Internal
|
||||
protected val optionsByPluginId = mutableMapOf<String, MutableList<SubpluginOption>>()
|
||||
|
||||
fun allOptions(): Map<String, List<SubpluginOption>> = optionsByPluginId
|
||||
|
||||
+157
-293
@@ -9,13 +9,10 @@ import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import com.android.build.gradle.api.BaseVariant
|
||||
import com.android.build.gradle.api.SourceKind
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.util.lang.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.ExternalDependency
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
@@ -24,21 +21,20 @@ import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.process.CommandLineArgumentProvider
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformAction
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isInfoAsWarnings
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isKaptKeepKdocCommentsInStubs
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isKaptVerbose
|
||||
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.ObjectOutputStream
|
||||
@@ -53,17 +49,6 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
override fun apply(target: Project) {
|
||||
target.extensions.create("kapt", KaptExtension::class.java)
|
||||
|
||||
target.configurations.create(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).apply {
|
||||
val kaptDependency = getPluginArtifact().run { "$groupId:$artifactId:${target.getKotlinPluginVersion()}" }
|
||||
dependencies.add(target.dependencies.create(kaptDependency))
|
||||
dependencies.add(
|
||||
target.kotlinDependency(
|
||||
"kotlin-stdlib",
|
||||
target.kotlinExtension.coreLibrariesVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
registry.register(KaptModelBuilder())
|
||||
}
|
||||
|
||||
@@ -82,7 +67,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
|
||||
const val KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME = "kotlinKaptWorkerDependencies"
|
||||
|
||||
private val KAPT_KOTLIN_GENERATED = "kapt.kotlin.generated"
|
||||
val KAPT_KOTLIN_GENERATED = "kapt.kotlin.generated"
|
||||
|
||||
private val CLASSLOADERS_CACHE_SIZE = "kapt.classloaders.cache.size"
|
||||
private val CLASSLOADERS_CACHE_DISABLE_FOR_PROCESSORS = "kapt.classloaders.cache.disableForProcessors"
|
||||
@@ -245,6 +230,8 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
|
||||
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = temporaryKaptDirectory("incrementalData")
|
||||
|
||||
private fun Kapt3SubpluginContext.getKaptClasspathSnapshotDir() = temporaryKaptDirectory("classpath-snapshot")
|
||||
|
||||
private fun Kapt3SubpluginContext.getKaptIncrementalAnnotationProcessingCache() = temporaryKaptDirectory("incApCache")
|
||||
|
||||
private fun Kapt3SubpluginContext.temporaryKaptDirectory(
|
||||
@@ -326,7 +313,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
Callable {
|
||||
// Avoid circular dependency: the stubs task need the Java sources, but the Java sources generated by Kapt should be
|
||||
// excluded, as the Kapt tasks depend on the stubs ones, and having them in the input would lead to a cycle
|
||||
val kaptJavaOutput = kaptTaskProvider.get().destinationDir
|
||||
val kaptJavaOutput = kaptTaskProvider.get().destinationDir.get().asFile
|
||||
androidVariantData.getSourceFolders(SourceKind.JAVA).filter { it.dir != kaptJavaOutput }
|
||||
}
|
||||
)
|
||||
@@ -343,42 +330,21 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
}
|
||||
|
||||
// This method should be called no more than once for each Kapt3SubpluginContext
|
||||
private fun Kapt3SubpluginContext.buildOptions(
|
||||
aptMode: String,
|
||||
private fun Kapt3SubpluginContext.buildOptionsForAptMode(
|
||||
javacOptions: Provider<Map<String, String>>
|
||||
): Provider<List<SubpluginOption>> {
|
||||
disableAnnotationProcessingInJavaTask()
|
||||
|
||||
return project.provider {
|
||||
val pluginOptions = mutableListOf<SubpluginOption>()
|
||||
|
||||
val generatedFilesDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
||||
KaptWithAndroid.androidVariantData(this)?.addJavaSourceFoldersToModel(generatedFilesDir)
|
||||
|
||||
pluginOptions += SubpluginOption("aptMode", aptMode)
|
||||
|
||||
pluginOptions += FilesSubpluginOption("sources", listOf(generatedFilesDir))
|
||||
pluginOptions += FilesSubpluginOption("classes", listOf(getKaptGeneratedClassesDir(project, sourceSetName)))
|
||||
|
||||
pluginOptions += FilesSubpluginOption("incrementalData", listOf(getKaptIncrementalDataDir()))
|
||||
|
||||
val annotationProcessors = kaptExtension.processors
|
||||
if (annotationProcessors.isNotEmpty()) {
|
||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
||||
}
|
||||
|
||||
if (aptMode == "apt") {
|
||||
// apOptions are needed only for "apt" mode
|
||||
pluginOptions += getAPOptions().get()
|
||||
}
|
||||
|
||||
pluginOptions += SubpluginOption("javacArguments", encodeList(javacOptions.get()))
|
||||
|
||||
pluginOptions += SubpluginOption("includeCompileClasspath", includeCompileClasspath.toString())
|
||||
|
||||
addMiscOptions(pluginOptions)
|
||||
|
||||
pluginOptions
|
||||
buildKaptSubpluginOptions(
|
||||
kaptExtension,
|
||||
project,
|
||||
javacOptions.get(),
|
||||
"apt",
|
||||
generatedSourcesDir = listOf(sourcesOutputDir),
|
||||
generatedClassesDir = listOf(getKaptGeneratedClassesDir(project, sourceSetName)),
|
||||
incrementalDataDir = listOf(getKaptIncrementalDataDir()),
|
||||
includeCompileClasspath = includeCompileClasspath,
|
||||
kaptStubsDir = listOf(getKaptStubsDir())
|
||||
) + getAPOptions().get() // apOptions are needed only for "apt" mode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,96 +391,14 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
FilesSubpluginOption(KAPT_KOTLIN_GENERATED, listOf(kotlinSourcesOutputDir))
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.registerSubpluginOptions(
|
||||
taskProvider: TaskProvider<*>,
|
||||
optionsProvider: Provider<List<SubpluginOption>>
|
||||
) {
|
||||
taskProvider.configure { taskInstance ->
|
||||
val container = when (taskInstance) {
|
||||
is KaptGenerateStubsTask -> taskInstance.pluginOptions
|
||||
is KaptWithKotlincTask -> taskInstance.pluginOptions
|
||||
is KaptWithoutKotlincTask -> taskInstance.processorOptions
|
||||
else -> error("Unexpected task ${taskInstance.name} (${taskInstance.javaClass})")
|
||||
}
|
||||
|
||||
|
||||
val compilerPluginId = getCompilerPluginId()
|
||||
|
||||
val options = optionsProvider.get()
|
||||
|
||||
taskInstance.registerSubpluginOptionsAsInputs(compilerPluginId, options)
|
||||
|
||||
for (option in options) {
|
||||
container.addPluginArgument(compilerPluginId, option)
|
||||
}
|
||||
}
|
||||
|
||||
// Also register all the subplugin options from the Kotlin task:
|
||||
project.whenEvaluated {
|
||||
taskProvider.configure { taskInstance ->
|
||||
kotlinCompile.get().pluginOptions.subpluginOptionsByPluginId.forEach { (pluginId, options) ->
|
||||
taskInstance.registerSubpluginOptionsAsInputs("kotlinCompile.$pluginId", options)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun encodeList(options: Map<String, String>): String {
|
||||
val os = ByteArrayOutputStream()
|
||||
val oos = ObjectOutputStream(os)
|
||||
|
||||
oos.writeInt(options.size)
|
||||
for ((key, value) in options.entries) {
|
||||
oos.writeUTF(key)
|
||||
oos.writeUTF(value)
|
||||
}
|
||||
|
||||
oos.flush()
|
||||
return Base64.getEncoder().encodeToString(os.toByteArray())
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.addMiscOptions(pluginOptions: MutableList<SubpluginOption>) {
|
||||
if (kaptExtension.generateStubs) {
|
||||
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
||||
}
|
||||
|
||||
// These option names must match those defined in org.jetbrains.kotlin.kapt.cli.KaptCliOption.
|
||||
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
|
||||
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
|
||||
pluginOptions += SubpluginOption("dumpDefaultParameterValues", "${kaptExtension.dumpDefaultParameterValues}")
|
||||
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
|
||||
pluginOptions += SubpluginOption(
|
||||
"strictMode", // Currently doesn't match KaptCliOption.STRICT_MODE_OPTION, is it a typo introduced in https://github.com/JetBrains/kotlin/commit/c83581e6b8155c6d89da977be6e3cd4af30562e5?
|
||||
"${kaptExtension.strictMode}"
|
||||
)
|
||||
pluginOptions += SubpluginOption("stripMetadata", "${kaptExtension.stripMetadata}")
|
||||
pluginOptions += SubpluginOption("keepKdocCommentsInStubs", "${project.isKaptKeepKdocCommentsInStubs()}")
|
||||
pluginOptions += SubpluginOption("showProcessorStats", "${kaptExtension.showProcessorStats}")
|
||||
pluginOptions += SubpluginOption("detectMemoryLeaks", kaptExtension.detectMemoryLeaks)
|
||||
pluginOptions += SubpluginOption("infoAsWarnings", "${project.isInfoAsWarnings()}")
|
||||
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
|
||||
|
||||
if (project.isKaptVerbose()) {
|
||||
pluginOptions += SubpluginOption("verbose", "true")
|
||||
}
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.createKaptKotlinTask(useWorkerApi: Boolean): TaskProvider<out KaptTask> {
|
||||
val taskClass = if (useWorkerApi) KaptWithoutKotlincTask::class.java else KaptWithKotlincTask::class.java
|
||||
val taskName = getKaptTaskName("kapt")
|
||||
|
||||
var classStructureIfIncremental: Configuration? = null
|
||||
|
||||
if (project.isIncrementalKapt()) {
|
||||
maybeRegisterTransform(project)
|
||||
|
||||
classStructureIfIncremental = project.configurations.create("_classStructure${taskName}")
|
||||
|
||||
// Wrap the `kotlinCompile.classpath` into a file collection, so that, if the classpath is represented by a configuration,
|
||||
// the configuration is not extended (via extendsFrom, which normally happens when one configuration is _added_ into another)
|
||||
// but is instead included as the (lazily) resolved files. This is needed because the class structure configuration doesn't have
|
||||
// the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does.
|
||||
project.dependencies.add(classStructureIfIncremental.name, project.files(project.provider { kotlinCompile.get().libraries }))
|
||||
val taskConfigAction = if (taskClass == KaptWithoutKotlincTask::class.java ) {
|
||||
KaptWithoutKotlincConfigAction(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
} else {
|
||||
KaptWithKotlincConfigAction(kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile, kaptExtension)
|
||||
}
|
||||
|
||||
val kaptClasspathConfiguration = project.configurations.create("kaptClasspath_$taskName")
|
||||
@@ -522,182 +406,97 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
it.isVisible = false
|
||||
it.isCanBeConsumed = false
|
||||
}
|
||||
|
||||
val kaptTaskProvider = project.registerTask(taskName, taskClass, emptyList()) { kaptTask ->
|
||||
kaptTask.useBuildCache = kaptExtension.useBuildCache
|
||||
|
||||
val kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile
|
||||
if (kaptTask is KaptWithoutKotlincTask) {
|
||||
KaptWithoutKotlincTask.Configurator(kotlinCompileTask).configure(kaptTask)
|
||||
} else {
|
||||
KaptWithKotlincTask.Configurator(kotlinCompileTask).configure(kaptTask as KaptWithKotlincTask)
|
||||
PropertiesProvider(project).mapKotlinDaemonProperties(kaptTask)
|
||||
}
|
||||
|
||||
kaptTask.stubsDir.set(getKaptStubsDir())
|
||||
|
||||
kaptTask.destinationDir = sourcesOutputDir
|
||||
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
||||
kaptTask.classesDir = classesOutputDir
|
||||
kaptTask.includeCompileClasspath.set(includeCompileClasspath)
|
||||
|
||||
kaptTask.isIncremental = project.isIncrementalKapt()
|
||||
|
||||
if (kaptTask.isIncremental) {
|
||||
kaptTask.incAptCache.fileValue(getKaptIncrementalAnnotationProcessingCache()).disallowChanges()
|
||||
|
||||
kaptTask.classpathStructure.from(
|
||||
classStructureIfIncremental!!.incoming.artifactView { viewConfig ->
|
||||
viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}.files
|
||||
).disallowChanges()
|
||||
|
||||
if (kaptTask is KaptWithKotlincTask) {
|
||||
kaptTask.pluginOptions.addPluginArgument(
|
||||
getCompilerPluginId(),
|
||||
SubpluginOption(
|
||||
"incrementalCache",
|
||||
lazy { kaptTask.incAptCache.asFile.get().absolutePath }
|
||||
)
|
||||
)
|
||||
taskConfigAction.configureTaskProvider { taskProvider ->
|
||||
if (javaCompile != null) {
|
||||
val androidVariantData = KaptWithAndroid.androidVariantData(this)
|
||||
if (androidVariantData != null) {
|
||||
KaptWithAndroid.registerGeneratedJavaSourceForAndroid(this, project, androidVariantData, taskProvider)
|
||||
androidVariantData.addJavaSourceFoldersToModel(sourcesOutputDir)
|
||||
} else {
|
||||
registerGeneratedJavaSource(taskProvider, javaCompile)
|
||||
}
|
||||
|
||||
disableAnnotationProcessingInJavaTask()
|
||||
}
|
||||
|
||||
kaptTask.kaptClasspath.from(kaptClasspathConfiguration).disallowChanges()
|
||||
kaptTask.kaptExternalClasspath.from(kaptClasspathConfiguration.fileCollection { it is ExternalDependency })
|
||||
kaptTask.kaptClasspathConfigurationNames.value(kaptClasspathConfigurations.map { it.name }).disallowChanges()
|
||||
kotlinCompilation.output.classesDirs.from(taskProvider.flatMap { it.classesDir })
|
||||
|
||||
kotlinCompilation.compileKotlinTaskProvider.configure {
|
||||
(it as AbstractKotlinCompileTool<*>).setSource(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||
}
|
||||
}
|
||||
taskConfigAction.configureTask { task ->
|
||||
task.stubsDir.set(getKaptStubsDir())
|
||||
task.destinationDir.set(sourcesOutputDir)
|
||||
task.kotlinSourcesDestinationDir.set(kotlinSourcesOutputDir)
|
||||
task.classesDir.set(classesOutputDir)
|
||||
|
||||
if (javaCompile != null) {
|
||||
task.defaultJavaSourceCompatibility.set(javaCompile.map { it.sourceCompatibility })
|
||||
}
|
||||
|
||||
if (project.isIncrementalKapt()) {
|
||||
task.incAptCache.fileValue(getKaptIncrementalAnnotationProcessingCache()).disallowChanges()
|
||||
}
|
||||
|
||||
task.kaptClasspath.from(kaptClasspathConfiguration).disallowChanges()
|
||||
task.kaptExternalClasspath.from(kaptClasspathConfiguration.fileCollection { it is ExternalDependency })
|
||||
task.kaptClasspathConfigurationNames.value(kaptClasspathConfigurations.map { it.name }).disallowChanges()
|
||||
|
||||
KaptWithAndroid.androidVariantData(this)?.annotationProcessorOptionProviders?.let {
|
||||
kaptTask.annotationProcessorOptionProviders.add(it)
|
||||
task.annotationProcessorOptionProviders.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
kotlinCompilation.output.classesDirs.from(kaptTaskProvider.map { it.classesDir })
|
||||
|
||||
kotlinCompilation.compileKotlinTaskProvider.configure {
|
||||
(it as AbstractKotlinCompileTool<*>).setSource(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||
}
|
||||
|
||||
if (javaCompile != null) {
|
||||
val androidVariantData = KaptWithAndroid.androidVariantData(this)
|
||||
if (androidVariantData != null) {
|
||||
KaptWithAndroid.registerGeneratedJavaSourceForAndroid(this, project, androidVariantData, kaptTaskProvider)
|
||||
val pluginOptions: Provider<CompilerPluginOptions> = if (taskClass == KaptWithKotlincTask::class.java) {
|
||||
buildOptionsForAptMode(taskConfigAction.getJavaOptions(task.defaultJavaSourceCompatibility))
|
||||
} else {
|
||||
registerGeneratedJavaSource(kaptTaskProvider, javaCompile)
|
||||
check(taskClass == KaptWithoutKotlincTask::class.java)
|
||||
getDslKaptApOptions()
|
||||
}.map {
|
||||
val res = CompilerPluginOptions()
|
||||
it.forEach { res.addPluginArgument(KAPT_SUBPLUGIN_ID, it) }
|
||||
return@map res
|
||||
}
|
||||
|
||||
task.kaptPluginOptions.add(pluginOptions)
|
||||
}
|
||||
|
||||
val dslJavacOptions: Provider<Map<String, String>> = project.provider {
|
||||
kaptExtension.getJavacOptions().toMutableMap().also { result ->
|
||||
if (javaCompile != null && "-source" !in result && "--source" !in result && "--release" !in result) {
|
||||
val atLeast12Java =
|
||||
if (isConfigurationCacheAvailable(project.gradle)) {
|
||||
val currentJavaVersion =
|
||||
JavaVersion.parse(project.providers.systemProperty("java.version").forUseAtConfigurationTime().get())
|
||||
currentJavaVersion.feature >= 12
|
||||
} else {
|
||||
SystemInfo.isJavaVersionAtLeast(12, 0, 0)
|
||||
}
|
||||
val sourceOptionKey = if (atLeast12Java) {
|
||||
"--source"
|
||||
} else {
|
||||
"-source"
|
||||
}
|
||||
result[sourceOptionKey] = javaCompile.get().sourceCompatibility
|
||||
}
|
||||
return if (taskClass == KaptWithoutKotlincTask::class.java) {
|
||||
taskConfigAction as KaptWithoutKotlincConfigAction
|
||||
project.registerTask(taskName, KaptWithoutKotlincTask::class.java, emptyList()).also {
|
||||
taskConfigAction.execute(it)
|
||||
}
|
||||
}
|
||||
|
||||
if (KaptWithKotlincTask::class.java.isAssignableFrom(taskClass)) {
|
||||
val subpluginOptions = buildOptions("apt", dslJavacOptions)
|
||||
registerSubpluginOptions(kaptTaskProvider, subpluginOptions)
|
||||
}
|
||||
|
||||
if (taskClass == KaptWithoutKotlincTask::class.java) {
|
||||
kaptTaskProvider.configure {
|
||||
it as KaptWithoutKotlincTask
|
||||
it.mapDiagnosticLocations = kaptExtension.mapDiagnosticLocations
|
||||
it.annotationProcessorFqNames = kaptExtension.processors.split(',').filter { it.isNotEmpty() }
|
||||
it.javacOptions = dslJavacOptions.get()
|
||||
if (includeCompileClasspath && project.classLoadersCacheSize() > 0) {
|
||||
project.logger.warn(
|
||||
"ClassLoaders cache can't be enabled together with AP discovery in compilation classpath."
|
||||
+ "\nSet 'kapt.include.compile.classpath=false' to disable discovery"
|
||||
)
|
||||
} else {
|
||||
it.classLoadersCacheSize = project.classLoadersCacheSize()
|
||||
}
|
||||
it.disableClassloaderCacheForProcessors = project.disableClassloaderCacheForProcessors()
|
||||
} else {
|
||||
taskConfigAction as KaptWithKotlincConfigAction
|
||||
project.registerTask(taskName, KaptWithKotlincTask::class.java, emptyList()).also {
|
||||
taskConfigAction.execute(it)
|
||||
}
|
||||
|
||||
val subpluginOptions = getDslKaptApOptions()
|
||||
registerSubpluginOptions(kaptTaskProvider, subpluginOptions)
|
||||
}
|
||||
|
||||
kaptTaskProvider.configure { task ->
|
||||
task.onlyIf {
|
||||
it as KaptTask
|
||||
it.includeCompileClasspath.get() || !it.kaptClasspath.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
return kaptTaskProvider
|
||||
}
|
||||
|
||||
private fun maybeRegisterTransform(project: Project) {
|
||||
if (!project.extensions.extraProperties.has("KaptStructureTransformAdded")) {
|
||||
val transformActionClass =
|
||||
if (GradleVersion.current() >= GradleVersion.version("5.4"))
|
||||
StructureTransformAction::class.java
|
||||
else
|
||||
StructureTransformLegacyAction::class.java
|
||||
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "jar")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
|
||||
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "directory")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
|
||||
project.extensions.extraProperties["KaptStructureTransformAdded"] = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): TaskProvider<KaptGenerateStubsTask> {
|
||||
val properties = PropertiesProvider(project)
|
||||
val kaptTaskName = getKaptTaskName("kaptGenerateStubs")
|
||||
val kaptTaskProvider = project.registerTask<KaptGenerateStubsTask>(kaptTaskName)
|
||||
val projectDir = project.projectDir
|
||||
|
||||
val configurator = KaptGenerateStubsTask.Configurator(kotlinCompile, kotlinCompilation, properties)
|
||||
configurator.runAtConfigurationTime(kaptTaskProvider, project)
|
||||
|
||||
kaptTaskProvider.configure { kaptTask ->
|
||||
configurator.configure(kaptTask)
|
||||
|
||||
kaptTask.stubsDir.set(getKaptStubsDir())
|
||||
kaptTask.destinationDirectory.set(getKaptIncrementalDataDir())
|
||||
kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||
|
||||
kaptTask.kaptClasspath.from(kaptClasspathConfigurations)
|
||||
|
||||
properties.mapKotlinTaskProperties(kaptTask)
|
||||
|
||||
if (!includeCompileClasspath) {
|
||||
kaptTask.onlyIf {
|
||||
!(it as KaptGenerateStubsTask).kaptClasspath.isEmpty
|
||||
}
|
||||
}
|
||||
val taskConfig = KaptGenerateStubsConfig(kotlinCompilation, kotlinCompile)
|
||||
taskConfig.configureTask {
|
||||
it.stubsDir.set(getKaptStubsDir())
|
||||
it.destinationDirectory.set(getKaptIncrementalDataDir())
|
||||
it.exclude(
|
||||
"${sourcesOutputDir.relativeTo(projectDir).path}/**",
|
||||
"${kotlinSourcesOutputDir.relativeTo(projectDir).path}/**"
|
||||
)
|
||||
it.kaptClasspath.from(kaptClasspathConfigurations)
|
||||
it.classpathSnapshotProperties.classpathSnapshotDir.fileValue(getKaptClasspathSnapshotDir())
|
||||
}
|
||||
|
||||
taskConfig.execute(kaptTaskProvider)
|
||||
|
||||
project.whenEvaluated {
|
||||
addCompilationSourcesToExternalCompileTask(kotlinCompilation, kaptTaskProvider)
|
||||
}
|
||||
|
||||
val subpluginOptions = buildOptions("stubs", project.provider { kaptExtension.getJavacOptions() })
|
||||
registerSubpluginOptions(kaptTaskProvider, subpluginOptions)
|
||||
|
||||
return kaptTaskProvider
|
||||
}
|
||||
|
||||
@@ -741,7 +540,72 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
||||
JetBrainsSubpluginArtifact(artifactId = KAPT_ARTIFACT_NAME)
|
||||
}
|
||||
|
||||
private val artifactType = Attribute.of("artifactType", String::class.java)
|
||||
internal fun buildKaptSubpluginOptions(
|
||||
kaptExtension: KaptExtension,
|
||||
project: Project,
|
||||
javacOptions: Map<String, String>,
|
||||
aptMode: String,
|
||||
generatedSourcesDir: Iterable<File>,
|
||||
generatedClassesDir: Iterable<File>,
|
||||
incrementalDataDir: Iterable<File>,
|
||||
includeCompileClasspath: Boolean,
|
||||
kaptStubsDir: Iterable<File>,
|
||||
): List<SubpluginOption> {
|
||||
if (kaptExtension.generateStubs) {
|
||||
project.logger.warn("'kapt.generateStubs' is not used by the 'kotlin-kapt' plugin")
|
||||
}
|
||||
|
||||
val pluginOptions = mutableListOf<SubpluginOption>()
|
||||
|
||||
pluginOptions += SubpluginOption("aptMode", aptMode)
|
||||
|
||||
pluginOptions += FilesSubpluginOption("sources", generatedSourcesDir)
|
||||
pluginOptions += FilesSubpluginOption("classes", generatedClassesDir)
|
||||
pluginOptions += FilesSubpluginOption("incrementalData", incrementalDataDir)
|
||||
|
||||
val annotationProcessors = kaptExtension.processors
|
||||
if (annotationProcessors.isNotEmpty()) {
|
||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
||||
}
|
||||
pluginOptions += SubpluginOption("javacArguments", encodeList(javacOptions))
|
||||
pluginOptions += SubpluginOption("includeCompileClasspath", includeCompileClasspath.toString())
|
||||
|
||||
// These option names must match those defined in org.jetbrains.kotlin.kapt.cli.KaptCliOption.
|
||||
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
|
||||
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
|
||||
pluginOptions += SubpluginOption("dumpDefaultParameterValues", "${kaptExtension.dumpDefaultParameterValues}")
|
||||
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
|
||||
pluginOptions += SubpluginOption(
|
||||
"strictMode", // Currently doesn't match KaptCliOption.STRICT_MODE_OPTION, is it a typo introduced in https://github.com/JetBrains/kotlin/commit/c83581e6b8155c6d89da977be6e3cd4af30562e5?
|
||||
"${kaptExtension.strictMode}"
|
||||
)
|
||||
pluginOptions += SubpluginOption("stripMetadata", "${kaptExtension.stripMetadata}")
|
||||
pluginOptions += SubpluginOption("keepKdocCommentsInStubs", "${project.isKaptKeepKdocCommentsInStubs()}")
|
||||
pluginOptions += SubpluginOption("showProcessorTimings", "${kaptExtension.showProcessorStats}")
|
||||
pluginOptions += SubpluginOption("detectMemoryLeaks", kaptExtension.detectMemoryLeaks)
|
||||
pluginOptions += SubpluginOption("infoAsWarnings", "${project.isInfoAsWarnings()}")
|
||||
pluginOptions += FilesSubpluginOption("stubs", kaptStubsDir)
|
||||
|
||||
if (project.isKaptVerbose()) {
|
||||
pluginOptions += SubpluginOption("verbose", "true")
|
||||
}
|
||||
|
||||
return pluginOptions
|
||||
}
|
||||
|
||||
private fun encodeList(options: Map<String, String>): String {
|
||||
val os = ByteArrayOutputStream()
|
||||
val oos = ObjectOutputStream(os)
|
||||
|
||||
oos.writeInt(options.size)
|
||||
for ((key, value) in options.entries) {
|
||||
oos.writeUTF(key)
|
||||
oos.writeUTF(value)
|
||||
}
|
||||
|
||||
oos.flush()
|
||||
return Base64.getEncoder().encodeToString(os.toByteArray())
|
||||
}
|
||||
|
||||
// Don't reference the BaseVariant type in the Kapt plugin signatures, as those type references will fail to link when there's no Android
|
||||
// Gradle plugin on the project's plugin classpath
|
||||
@@ -771,7 +635,7 @@ private object KaptWithAndroid {
|
||||
|
||||
internal fun registerGeneratedJavaSource(kaptTask: TaskProvider<out KaptTask>, javaTaskProvider: TaskProvider<out AbstractCompile>) {
|
||||
javaTaskProvider.configure { javaTask ->
|
||||
val generatedJavaSources = javaTask.project.fileTree(kaptTask.map { it.destinationDir })
|
||||
val generatedJavaSources = javaTask.project.fileTree(kaptTask.flatMap { it.destinationDir })
|
||||
generatedJavaSources.include("**/*.java")
|
||||
javaTask.source(generatedJavaSources)
|
||||
}
|
||||
|
||||
+10
-45
@@ -18,18 +18,18 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.incremental.classpathAsList
|
||||
import org.jetbrains.kotlin.incremental.destinationAsFile
|
||||
import java.io.File
|
||||
@@ -45,38 +45,9 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
objectFactory
|
||||
) {
|
||||
|
||||
internal class Configurator(
|
||||
private val kotlinCompileTaskProvider: TaskProvider<KotlinCompile>,
|
||||
kotlinCompilation: KotlinCompilationData<*>,
|
||||
properties: PropertiesProvider
|
||||
) : KotlinCompile.Configurator<KaptGenerateStubsTask>(kotlinCompilation, properties) {
|
||||
|
||||
override fun configure(task: KaptGenerateStubsTask) {
|
||||
super.configure(task)
|
||||
|
||||
val kotlinCompileTask = kotlinCompileTaskProvider.get()
|
||||
val providerFactory = kotlinCompileTask.project.providers
|
||||
task.useModuleDetection.value(kotlinCompileTask.useModuleDetection).disallowChanges()
|
||||
task.moduleName.value(kotlinCompileTask.moduleName).disallowChanges()
|
||||
task.libraries.from(kotlinCompileTask.libraries)
|
||||
task.kotlinTaskPluginClasspath.from(
|
||||
providerFactory.provider { kotlinCompileTask.pluginClasspath }
|
||||
)
|
||||
task.compileKotlinArgumentsContributor.set(
|
||||
providerFactory.provider {
|
||||
kotlinCompileTask.compilerArgumentsContributor
|
||||
}
|
||||
)
|
||||
task.verbose.set(KaptTask.queryKaptVerboseProperty(task.project))
|
||||
}
|
||||
}
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val stubsDir: DirectoryProperty
|
||||
|
||||
@get:Internal
|
||||
lateinit var generatedSourcesDirs: List<File>
|
||||
|
||||
@get:Internal("Not an input, just passed as kapt args. ")
|
||||
abstract val kaptClasspath: ConfigurableFileCollection
|
||||
|
||||
@@ -84,11 +55,6 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
@Input
|
||||
fun getIfKaptClasspathIsPresent() = !kaptClasspath.isEmpty
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
@Suppress("unused")
|
||||
internal abstract val kotlinTaskPluginClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Input
|
||||
abstract val verbose: Property<Boolean>
|
||||
|
||||
@@ -105,8 +71,7 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
|
||||
private fun File.isSourceRootAllowed(): Boolean =
|
||||
!destinationDirectory.get().asFile.isParentOf(this) &&
|
||||
!stubsDir.asFile.get().isParentOf(this) &&
|
||||
generatedSourcesDirs.none { it.isParentOf(this) }
|
||||
!stubsDir.asFile.get().isParentOf(this)
|
||||
|
||||
override fun skipCondition(): Boolean = sources.isEmpty && javaSources.isEmpty
|
||||
|
||||
@@ -123,10 +88,10 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
override val scriptSources: FileCollection = objectFactory.fileCollection()
|
||||
abstract override val scriptSources: FileCollection
|
||||
|
||||
@get:Internal
|
||||
override val androidLayoutResources: FileCollection = objectFactory.fileCollection()
|
||||
abstract override val androidLayoutResources: FileCollection
|
||||
|
||||
override val incrementalProps: List<FileCollection>
|
||||
get() = listOf(
|
||||
@@ -159,11 +124,11 @@ abstract class KaptGenerateStubsTask @Inject constructor(
|
||||
)
|
||||
)
|
||||
|
||||
val pluginOptionsWithKapt = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
|
||||
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
|
||||
val pluginOptionsWithKapt = pluginOptions.toSingleCompilerPluginOptions().withWrappedKaptOptions(withApClasspath = kaptClasspath)
|
||||
args.pluginOptions = (pluginOptionsWithKapt.arguments).toTypedArray()
|
||||
|
||||
args.verbose = verbose.get()
|
||||
args.classpathAsList = this.libraries.filter { it.exists() }.toList()
|
||||
args.destinationAsFile = this.destinationDirectory.get().asFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-60
@@ -19,13 +19,11 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.ClasspathSnapshot
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptClasspathChanges
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChanges
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.UnknownSnapshot
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskConfigurator
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.jar.JarFile
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -36,30 +34,6 @@ abstract class KaptTask @Inject constructor(
|
||||
TaskWithLocalState,
|
||||
UsesKotlinJavaToolchain {
|
||||
|
||||
open class Configurator<T: KaptTask>(protected val kotlinCompileTask: KotlinCompile) : TaskConfigurator<T> {
|
||||
override fun configure(task: T) {
|
||||
val objectFactory = task.project.objects
|
||||
|
||||
task.compilerClasspath.from({ kotlinCompileTask.defaultCompilerClasspath })
|
||||
task.classpath.from(kotlinCompileTask.libraries)
|
||||
task.compiledSources.from(
|
||||
kotlinCompileTask.destinationDirectory,
|
||||
Callable { kotlinCompileTask.javaOutputDir.takeIf { it.isPresent } }
|
||||
).disallowChanges()
|
||||
task.sourceSetName.value(kotlinCompileTask.sourceSetName).disallowChanges()
|
||||
task.localStateDirectories.from(Callable { task.incAptCache.orNull }).disallowChanges()
|
||||
task.source.from(
|
||||
objectFactory.fileCollection().from(
|
||||
kotlinCompileTask.javaSources,
|
||||
task.stubsDir
|
||||
).asFileTree
|
||||
.matching { it.include("**/*.java") }
|
||||
.filter { f -> task.isRootAllowed(f) }
|
||||
).disallowChanges()
|
||||
task.verbose.set(queryKaptVerboseProperty(task.project))
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
|
||||
@@ -95,6 +69,9 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:InputFiles
|
||||
abstract val classpathStructure: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
abstract val kaptPluginOptions: ListProperty<CompilerPluginOptions>
|
||||
|
||||
/**
|
||||
* Output directory that contains caches necessary to support incremental annotation processing.
|
||||
*/
|
||||
@@ -102,13 +79,14 @@ abstract class KaptTask @Inject constructor(
|
||||
abstract val incAptCache: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
internal lateinit var classesDir: File
|
||||
internal abstract val classesDir: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var destinationDir: File
|
||||
abstract val destinationDir: DirectoryProperty
|
||||
|
||||
/** Used in the model builder only. */
|
||||
@get:OutputDirectory
|
||||
lateinit var kotlinSourcesDestinationDir: File
|
||||
abstract val kotlinSourcesDestinationDir: DirectoryProperty
|
||||
|
||||
@get:Nested
|
||||
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
|
||||
@@ -176,37 +154,8 @@ abstract class KaptTask @Inject constructor(
|
||||
@get:Input
|
||||
abstract val verbose: Property<Boolean>
|
||||
|
||||
private fun isRootAllowed(file: File): Boolean =
|
||||
file.exists() &&
|
||||
!isAncestor(destinationDir, file) &&
|
||||
!isAncestor(classesDir, file)
|
||||
|
||||
//Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache
|
||||
private fun isAncestor(dir: File, file: File): Boolean {
|
||||
val path = file.canonicalPath
|
||||
val prefix = dir.canonicalPath
|
||||
val pathLength = path.length
|
||||
val prefixLength = prefix.length
|
||||
//TODO
|
||||
val caseSensitive = true
|
||||
return if (prefixLength == 0) {
|
||||
true
|
||||
} else if (prefixLength > pathLength) {
|
||||
false
|
||||
} else if (!path.regionMatches(0, prefix, 0, prefixLength, ignoreCase = !caseSensitive)) {
|
||||
return false
|
||||
} else if (pathLength == prefixLength) {
|
||||
return true
|
||||
} else {
|
||||
val lastPrefixChar: Char = prefix.get(prefixLength - 1)
|
||||
var slashOrSeparatorIdx = prefixLength
|
||||
if (lastPrefixChar == '/' || lastPrefixChar == File.separatorChar) {
|
||||
slashOrSeparatorIdx = prefixLength - 1
|
||||
}
|
||||
val next1 = path[slashOrSeparatorIdx]
|
||||
return !(next1 != '/' && next1 != File.separatorChar)
|
||||
}
|
||||
}
|
||||
@get:Internal
|
||||
abstract val defaultJavaSourceCompatibility: Property<String>
|
||||
|
||||
protected fun checkAnnotationProcessorClasspath() {
|
||||
if (!includeCompileClasspath.get()) return
|
||||
|
||||
+10
-19
@@ -35,21 +35,6 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
CompilerArgumentAwareWithInput<K2JVMCompilerArguments>,
|
||||
CompileUsingKotlinDaemonWithNormalization {
|
||||
|
||||
class Configurator(kotlinCompileTask: KotlinCompile): KaptTask.Configurator<KaptWithKotlincTask>(kotlinCompileTask) {
|
||||
override fun configure(task: KaptWithKotlincTask) {
|
||||
super.configure(task)
|
||||
task.pluginClasspath.from(kotlinCompileTask.pluginClasspath)
|
||||
task.compileKotlinArgumentsContributor.set(
|
||||
task.project.provider { kotlinCompileTask.compilerArgumentsContributor }
|
||||
)
|
||||
task.javaPackagePrefix.set(task.project.provider { kotlinCompileTask.javaPackagePrefix })
|
||||
task.reportingSettings.set(task.project.provider { kotlinCompileTask.reportingSettings() })
|
||||
}
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal val pluginOptions = CompilerPluginOptions()
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val pluginClasspath: ConfigurableFileCollection
|
||||
@@ -59,6 +44,10 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
objectFactory.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
|
||||
)
|
||||
|
||||
/** Used only as task input, actual values come from [compileKotlinArgumentsContributor]. */
|
||||
@get:Nested
|
||||
internal abstract val additionalPluginOptionsAsInputs: ListProperty<CompilerPluginOptions>
|
||||
|
||||
override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
|
||||
|
||||
abstract override val kotlinDaemonJvmArguments: ListProperty<String>
|
||||
@@ -74,8 +63,7 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
))
|
||||
|
||||
args.pluginClasspaths = pluginClasspath.toPathsArray()
|
||||
|
||||
val pluginOptionsWithKapt: CompilerPluginOptions = pluginOptions.withWrappedKaptOptions(
|
||||
val pluginOptionsWithKapt: CompilerPluginOptions = kaptPluginOptions.toSingleCompilerPluginOptions().withWrappedKaptOptions(
|
||||
withApClasspath = kaptClasspath,
|
||||
changedFiles = changedFiles,
|
||||
classpathChanges = classpathChanges,
|
||||
@@ -95,8 +83,11 @@ abstract class KaptWithKotlincTask @Inject constructor(
|
||||
private var classpathChanges: List<String> = emptyList()
|
||||
private var processIncrementally = false
|
||||
|
||||
private val javaPackagePrefix = objectFactory.property(String::class.java)
|
||||
private val reportingSettings = objectFactory.property(ReportingSettings::class.java)
|
||||
@get:Internal
|
||||
internal abstract val javaPackagePrefix: Property<String>
|
||||
|
||||
@get:Internal
|
||||
internal abstract val reportingSettings: Property<ReportingSettings>
|
||||
|
||||
@TaskAction
|
||||
fun compile(inputChanges: InputChanges) {
|
||||
|
||||
+22
-27
@@ -9,6 +9,7 @@ import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.*
|
||||
@@ -20,13 +21,12 @@ import org.gradle.workers.IsolationMode
|
||||
import org.gradle.workers.WorkAction
|
||||
import org.gradle.workers.WorkParameters
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.ClassLoadersCache
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.classloaders.rootOrSelf
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptIncrementalChanges
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinAndroidPluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.slf4j.LoggerFactory
|
||||
@@ -42,16 +42,6 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
private val workerExecutor: WorkerExecutor
|
||||
) : KaptTask(objectFactory) {
|
||||
|
||||
class Configurator(kotlinCompileTask: KotlinCompile): KaptTask.Configurator<KaptWithoutKotlincTask>(kotlinCompileTask) {
|
||||
override fun configure(task: KaptWithoutKotlincTask) {
|
||||
super.configure(task)
|
||||
task.addJdkClassesToClasspath.value(
|
||||
task.project.providers.provider { task.project.plugins.none { it is AbstractKotlinAndroidPluginWrapper } }
|
||||
).disallowChanges()
|
||||
task.kaptJars.from(task.project.configurations.getByName(KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME)).disallowChanges()
|
||||
}
|
||||
}
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
abstract val kaptJars: ConfigurableFileCollection
|
||||
@@ -66,16 +56,13 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
var mapDiagnosticLocations: Boolean = false
|
||||
|
||||
@get:Input
|
||||
lateinit var annotationProcessorFqNames: List<String>
|
||||
|
||||
@get:Internal
|
||||
internal val processorOptions = CompilerPluginOptions()
|
||||
abstract val annotationProcessorFqNames: ListProperty<String>
|
||||
|
||||
@get:Input
|
||||
lateinit var javacOptions: Map<String, String>
|
||||
abstract val javacOptions: MapProperty<String, String>
|
||||
|
||||
@get:Input
|
||||
internal abstract val addJdkClassesToClasspath: Property<Boolean>
|
||||
abstract val addJdkClassesToClasspath: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
internal val projectDir = project.projectDir
|
||||
@@ -84,11 +71,9 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
val kaptProcessJvmArgs: ListProperty<String> = objectFactory.listProperty<String>().convention(emptyList())
|
||||
|
||||
private fun getAnnotationProcessorOptions(): Map<String, String> {
|
||||
val options = processorOptions.subpluginOptionsByPluginId[Kapt3GradleSubplugin.KAPT_SUBPLUGIN_ID] ?: return emptyMap()
|
||||
|
||||
val result = mutableMapOf<String, String>()
|
||||
for (option in options) {
|
||||
result[option.key] = option.value
|
||||
kaptPluginOptions.toSingleCompilerPluginOptions().subpluginOptionsByPluginId[Kapt3GradleSubplugin.KAPT_SUBPLUGIN_ID]?.forEach {
|
||||
result[it.key] = it.value
|
||||
}
|
||||
annotationProcessorOptionProviders.forEach { providers ->
|
||||
(providers as List<*>).forEach { provider ->
|
||||
@@ -104,6 +89,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
@TaskAction
|
||||
fun compile(inputChanges: InputChanges) {
|
||||
logger.info("Running kapt annotation processing using the Gradle Worker API")
|
||||
checkProcessorCachingSetup()
|
||||
checkAnnotationProcessorClasspath()
|
||||
|
||||
val incrementalChanges = getIncrementalChanges(inputChanges)
|
||||
@@ -137,16 +123,16 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
incAptCache.orNull?.asFile,
|
||||
classpathChanges.toList(),
|
||||
|
||||
destinationDir,
|
||||
classesDir,
|
||||
destinationDir.get().asFile,
|
||||
classesDir.get().asFile,
|
||||
stubsDir.asFile.get(),
|
||||
|
||||
kaptClasspath.files.toList(),
|
||||
kaptExternalClasspath.files.toList(),
|
||||
annotationProcessorFqNames,
|
||||
annotationProcessorFqNames.get(),
|
||||
|
||||
getAnnotationProcessorOptions(),
|
||||
javacOptions,
|
||||
javacOptions.get(),
|
||||
|
||||
kaptFlagsForWorker,
|
||||
|
||||
@@ -154,7 +140,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
)
|
||||
|
||||
// Skip annotation processing if no annotation processors were provided.
|
||||
if (annotationProcessorFqNames.isEmpty() && kaptClasspath.isEmpty()) {
|
||||
if (annotationProcessorFqNames.get().isEmpty() && kaptClasspath.isEmpty()) {
|
||||
logger.info("No annotation processors provided. Skip KAPT processing.")
|
||||
return
|
||||
}
|
||||
@@ -259,6 +245,15 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||
).run()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkProcessorCachingSetup() {
|
||||
if (includeCompileClasspath.get() && classLoadersCacheSize > 0) {
|
||||
logger.warn(
|
||||
"ClassLoaders cache can't be enabled together with AP discovery in compilation classpath."
|
||||
+ "\nSet 'kapt.include.compile.classpath=false' to disable discovery"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.internal.tasks
|
||||
|
||||
import org.gradle.api.Task
|
||||
|
||||
/** Classes that participate in task configuration should implement this interface. */
|
||||
interface TaskConfigurator<T : Task> {
|
||||
fun configure(task: T)
|
||||
}
|
||||
+3
-3
@@ -39,9 +39,9 @@ class KaptModelBuilder : ToolingModelBuilder {
|
||||
true
|
||||
)
|
||||
) KaptSourceSet.KaptSourceSetType.TEST else KaptSourceSet.KaptSourceSetType.PRODUCTION,
|
||||
destinationDir,
|
||||
kotlinSourcesDestinationDir,
|
||||
classesDir
|
||||
destinationDir.get().asFile,
|
||||
kotlinSourcesDestinationDir.get().asFile,
|
||||
classesDir.get().asFile
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+47
-100
@@ -36,11 +36,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
|
||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.*
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.tooling.includeKotlinToolingMetadataInApk
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
@@ -67,7 +67,7 @@ abstract class KotlinCompilationProcessor<out T : AbstractKotlinCompileTool<*>>(
|
||||
protected val project: Project
|
||||
get() = kotlinCompilation.project
|
||||
|
||||
protected val defaultKotlinDestinationDir: File
|
||||
protected val defaultKotlinDestinationDir: Provider<Directory>
|
||||
get() {
|
||||
val kotlinExt = project.topLevelExtension
|
||||
val targetSubDirectory =
|
||||
@@ -75,7 +75,7 @@ abstract class KotlinCompilationProcessor<out T : AbstractKotlinCompileTool<*>>(
|
||||
"" // In single-target projects, don't add the target name part to this path
|
||||
else
|
||||
kotlinCompilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||
return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationPurpose}")
|
||||
return project.layout.buildDirectory.dir("classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationPurpose}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,23 +103,10 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
||||
}
|
||||
|
||||
private fun prepareKotlinCompileTask(): TaskProvider<out T> =
|
||||
registerKotlinCompileTask(register = ::doRegisterTask).also { task ->
|
||||
doRegisterTask(project, kotlinCompilation.compileKotlinTaskName).also { task ->
|
||||
kotlinCompilation.output.classesDirs.from(task.flatMap { it.destinationDirectory })
|
||||
}
|
||||
|
||||
protected fun registerKotlinCompileTask(
|
||||
name: String = kotlinCompilation.compileKotlinTaskName,
|
||||
register: (Project, String, (T) -> Unit) -> TaskProvider<out T>
|
||||
): TaskProvider<out T> {
|
||||
logger.kotlinDebug("Creating kotlin compile task $name")
|
||||
|
||||
return register(project, name) {
|
||||
it.description = taskDescription
|
||||
it.destinationDirectory.set(defaultKotlinDestinationDir)
|
||||
it.libraries.from({ kotlinCompilation.compileDependencyFiles })
|
||||
}
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
addKotlinDirectoriesToJavaSourceSet()
|
||||
doTargetSpecificProcessing()
|
||||
@@ -165,7 +152,15 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun doRegisterTask(project: Project, taskName: String, configureAction: (T) -> (Unit)): TaskProvider<out T>
|
||||
protected fun applyStandardTaskConfiguration(taskConfiguration: AbstractKotlinCompileConfig<*>) {
|
||||
taskConfiguration.configureTask {
|
||||
it.description = taskDescription
|
||||
it.destinationDirectory.convention(defaultKotlinDestinationDir)
|
||||
it.libraries.from({ kotlinCompilation.compileDependencyFiles })
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun doRegisterTask(project: Project, taskName: String): TaskProvider<out T>
|
||||
}
|
||||
|
||||
internal class Kotlin2JvmSourceSetProcessor(
|
||||
@@ -174,12 +169,11 @@ internal class Kotlin2JvmSourceSetProcessor(
|
||||
) : KotlinSourceSetProcessor<KotlinCompile>(
|
||||
tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
|
||||
) {
|
||||
override fun doRegisterTask(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
configureAction: (KotlinCompile) -> (Unit)
|
||||
): TaskProvider<out KotlinCompile> =
|
||||
tasksProvider.registerKotlinJVMTask(project, taskName, kotlinCompilation, configureAction)
|
||||
override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out KotlinCompile> {
|
||||
val configAction = KotlinCompileConfig(kotlinCompilation)
|
||||
applyStandardTaskConfiguration(configAction)
|
||||
return tasksProvider.registerKotlinJVMTask(project, taskName, kotlinCompilation.kotlinOptions, configAction)
|
||||
}
|
||||
|
||||
override fun doTargetSpecificProcessing() {
|
||||
ifKaptEnabled(project) {
|
||||
@@ -232,12 +226,11 @@ internal class Kotlin2JsSourceSetProcessor(
|
||||
taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.",
|
||||
kotlinCompilation = kotlinCompilation
|
||||
) {
|
||||
override fun doRegisterTask(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
configureAction: (Kotlin2JsCompile) -> (Unit)
|
||||
): TaskProvider<out Kotlin2JsCompile> =
|
||||
tasksProvider.registerKotlinJSTask(project, taskName, kotlinCompilation, configureAction)
|
||||
override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out Kotlin2JsCompile> {
|
||||
val configAction = Kotlin2JsCompileConfig(kotlinCompilation)
|
||||
applyStandardTaskConfiguration(configAction)
|
||||
return tasksProvider.registerKotlinJSTask(project, taskName, kotlinCompilation.kotlinOptions, configAction)
|
||||
}
|
||||
|
||||
override fun doTargetSpecificProcessing() {
|
||||
project.tasks.named(kotlinCompilation.compileAllTaskName).configure {
|
||||
@@ -298,27 +291,10 @@ internal class KotlinJsIrSourceSetProcessor(
|
||||
tasksProvider, taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.",
|
||||
kotlinCompilation = kotlinCompilation
|
||||
) {
|
||||
override fun doRegisterTask(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
configureAction: (Kotlin2JsCompile) -> (Unit)
|
||||
): TaskProvider<out Kotlin2JsCompile> =
|
||||
tasksProvider.registerKotlinJSTask(project, taskName, kotlinCompilation, configureAction)
|
||||
|
||||
private fun registerJsLink(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
mode: KotlinJsBinaryMode,
|
||||
configureAction: (Kotlin2JsCompile) -> Unit
|
||||
): TaskProvider<out KotlinJsIrLink> {
|
||||
return tasksProvider.registerKotlinJsIrTask(
|
||||
project,
|
||||
taskName,
|
||||
kotlinCompilation
|
||||
) { task ->
|
||||
task.mode = mode
|
||||
configureAction(task)
|
||||
}
|
||||
override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out Kotlin2JsCompile> {
|
||||
val configAction = Kotlin2JsCompileConfig(kotlinCompilation)
|
||||
applyStandardTaskConfiguration(configAction)
|
||||
return tasksProvider.registerKotlinJSTask(project, taskName, kotlinCompilation.kotlinOptions, configAction)
|
||||
}
|
||||
|
||||
override fun doTargetSpecificProcessing() {
|
||||
@@ -331,14 +307,14 @@ internal class KotlinJsIrSourceSetProcessor(
|
||||
compilation.binaries
|
||||
.withType(JsIrBinary::class.java)
|
||||
.all { binary ->
|
||||
registerKotlinCompileTask(
|
||||
binary.linkTaskName
|
||||
) { project, name, action ->
|
||||
registerJsLink(project, name, binary.mode) { compileTask ->
|
||||
action(compileTask)
|
||||
compileTask.dependsOn(kotlinTask)
|
||||
}
|
||||
val configAction = KotlinJsIrLinkConfig(compilation)
|
||||
applyStandardTaskConfiguration(configAction)
|
||||
configAction.configureTask { task ->
|
||||
task.modeProperty.set(binary.mode)
|
||||
task.dependsOn(kotlinTask)
|
||||
}
|
||||
|
||||
tasksProvider.registerKotlinJsIrTask(project, binary.linkTaskName, configAction)
|
||||
}
|
||||
|
||||
project.whenEvaluated {
|
||||
@@ -369,13 +345,11 @@ internal class KotlinCommonSourceSetProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
// protected abstract fun doRegisterTask(project: Project, taskName: String, configureAction: (T) -> (Unit)): TaskHolder<out T>
|
||||
override fun doRegisterTask(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
configureAction: (KotlinCompileCommon) -> (Unit)
|
||||
): TaskProvider<out KotlinCompileCommon> =
|
||||
tasksProvider.registerKotlinCommonTask(project, taskName, kotlinCompilation, configureAction)
|
||||
override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out KotlinCompileCommon> {
|
||||
val configAction = KotlinCompileCommonConfig(kotlinCompilation)
|
||||
applyStandardTaskConfiguration(configAction)
|
||||
return tasksProvider.registerKotlinCommonTask(project, taskName, kotlinCompilation.kotlinOptions, configAction)
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class AbstractKotlinPlugin(
|
||||
@@ -683,7 +657,7 @@ internal open class KotlinAndroidPlugin(
|
||||
companion object {
|
||||
const val MINIMAL_SUPPORTED_AGP_VERSION = "3.6.4"
|
||||
fun androidTargetHandler(): AbstractAndroidProjectHandler {
|
||||
val tasksProvider = AndroidTasksProvider()
|
||||
val tasksProvider = KotlinTasksProvider()
|
||||
|
||||
if (androidPluginVersion != null) {
|
||||
if (compareVersionNumbers(androidPluginVersion, MINIMAL_SUPPORTED_AGP_VERSION) < 0) {
|
||||
@@ -957,15 +931,15 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool
|
||||
|
||||
val defaultSourceSet = project.kotlinExtension.sourceSets.maybeCreate(compilation.defaultSourceSetName)
|
||||
|
||||
val kotlinTaskName = compilation.compileKotlinTaskName
|
||||
|
||||
tasksProvider.registerKotlinJVMTask(project, kotlinTaskName, compilation) {
|
||||
it.parentKotlinOptionsImpl.set(rootKotlinOptions)
|
||||
|
||||
val configAction = KotlinCompileConfig(compilation)
|
||||
configAction.configureTask { task ->
|
||||
task.parentKotlinOptionsImpl.value(rootKotlinOptions).disallowChanges()
|
||||
task.useModuleDetection.value(true).disallowChanges()
|
||||
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
||||
it.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName"))
|
||||
it.description = "Compiles the $variantDataName kotlin."
|
||||
task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName"))
|
||||
task.description = "Compiles the $variantDataName kotlin."
|
||||
}
|
||||
tasksProvider.registerKotlinJVMTask(project, compilation.compileKotlinTaskName, compilation.kotlinOptions, configAction)
|
||||
|
||||
// Register the source only after the task is created, because the task is required for that:
|
||||
compilation.source(defaultSourceSet)
|
||||
@@ -1026,33 +1000,6 @@ private fun SourceSet.clearJavaSrcDirs() {
|
||||
java.setSrcDirs(emptyList<File>())
|
||||
}
|
||||
|
||||
internal fun Task.registerSubpluginOptionsAsInputs(subpluginId: String, subpluginOptions: List<SubpluginOption>) {
|
||||
// There might be several options with the same key. We group them together
|
||||
// and add an index to the Gradle input property name to resolve possible duplication:
|
||||
val pluginOptionsGrouped = subpluginOptions.groupBy { it.key }
|
||||
for ((optionKey, optionsGroup) in pluginOptionsGrouped) {
|
||||
optionsGroup.forEachIndexed { index, option ->
|
||||
val indexSuffix = if (optionsGroup.size > 1) ".$index" else ""
|
||||
when (option) {
|
||||
is InternalSubpluginOption -> Unit
|
||||
|
||||
is CompositeSubpluginOption -> {
|
||||
val subpluginIdWithWrapperKey = "$subpluginId.$optionKey$indexSuffix"
|
||||
registerSubpluginOptionsAsInputs(subpluginIdWithWrapperKey, option.originalOptions)
|
||||
}
|
||||
|
||||
is FilesSubpluginOption -> when (option.kind) {
|
||||
FilesOptionKind.INTERNAL -> Unit
|
||||
}.run { /* exhaustive when */ }
|
||||
|
||||
else -> {
|
||||
inputs.property("$subpluginId." + option.key + indexSuffix, Callable { option.value })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//copied from BasePlugin.getLocalVersion
|
||||
internal val androidPluginVersion by lazy {
|
||||
try {
|
||||
|
||||
+3
-9
@@ -100,19 +100,13 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
|
||||
KotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
|
||||
|
||||
val buildMetricReporter = BuildMetricsReporterService.registerIfAbsent(project)
|
||||
|
||||
buildMetricReporter?.also { BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it) }
|
||||
BuildMetricsReporterService.registerIfAbsent(project)?.also {
|
||||
BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it)
|
||||
}
|
||||
|
||||
HttpReportService.registerIfAbsent(project, kotlinPluginVersion)
|
||||
?.also { BuildEventsListenerRegistryHolder.getInstance(project).listenerRegistry.onTaskCompletion(it) }
|
||||
|
||||
project.tasks.withType(AbstractKotlinCompile::class.java).configureEach {
|
||||
if (buildMetricReporter != null) {
|
||||
it.buildMetricsReporterService.set(buildMetricReporter)
|
||||
}
|
||||
}
|
||||
|
||||
project.createKotlinExtension(projectExtensionClass).apply {
|
||||
coreLibrariesVersion = kotlinPluginVersion
|
||||
|
||||
|
||||
-31
@@ -36,37 +36,6 @@ import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
internal fun PropertiesProvider.mapKotlinTaskProperties(task: AbstractKotlinCompile<*>) {
|
||||
if (task is KotlinCompile) {
|
||||
incrementalJvm?.let { task.incremental = it }
|
||||
usePreciseJavaTracking?.let {
|
||||
task.usePreciseJavaTracking = it
|
||||
}
|
||||
task.classpathSnapshotProperties.useClasspathSnapshot.value(useClasspathSnapshot).disallowChanges()
|
||||
useFir?.let {
|
||||
if (it == true) {
|
||||
task.kotlinOptions.useFir = true
|
||||
}
|
||||
}
|
||||
task.jvmTargetValidationMode.set(jvmTargetValidationMode)
|
||||
task.useKotlinAbiSnapshot.value(useKotlinAbiSnapshot).disallowChanges()
|
||||
}
|
||||
|
||||
if (task is Kotlin2JsCompile) {
|
||||
incrementalJs?.let { task.incremental = it }
|
||||
incrementalJsKlib?.let { task.incrementalJsKlib = it }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun PropertiesProvider.mapKotlinDaemonProperties(task: CompileUsingKotlinDaemon) {
|
||||
kotlinDaemonJvmArgs?.let {
|
||||
task.kotlinDaemonJvmArguments.set(it.split("\\s+".toRegex()))
|
||||
}
|
||||
if (!task.compilerExecutionStrategy.isPresent) {
|
||||
task.compilerExecutionStrategy.set(kotlinCompilerExecutionStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
internal class PropertiesProvider private constructor(private val project: Project) {
|
||||
private val localProperties: Properties by lazy {
|
||||
Properties().apply {
|
||||
|
||||
+2
-9
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
|
||||
/**
|
||||
* This class encapsulated logic which should be invoked during not before the script evaluation is ready and
|
||||
@@ -45,14 +44,8 @@ internal class RunOnceAfterEvaluated(private val name: String, private val actio
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.runOnceAfterEvaluated(name: String, task: TaskProvider<*>, action: () -> (Unit)) {
|
||||
internal fun Project.runOnceAfterEvaluated(name: String, action: () -> (Unit)) {
|
||||
val runOnce = RunOnceAfterEvaluated(name, action)
|
||||
runOnceAfterEvaluated(runOnce, task)
|
||||
}
|
||||
|
||||
internal fun Project.runOnceAfterEvaluated(runOnce: RunOnceAfterEvaluated, task: TaskProvider<*>) {
|
||||
whenEvaluated { runOnce.onEvaluated() }
|
||||
task.configure {
|
||||
runOnce.onConfigure()
|
||||
}
|
||||
runOnce.onConfigure()
|
||||
}
|
||||
|
||||
+11
-11
@@ -49,14 +49,20 @@ class SubpluginEnvironment(
|
||||
|
||||
val subpluginOptionsProvider = subplugin.applyToCompilation(kotlinCompilation)
|
||||
val subpluginId = subplugin.getCompilerPluginId()
|
||||
val compilerOptions = subpluginOptionsProvider.map { subpluginOptions ->
|
||||
val options = CompilerPluginOptions()
|
||||
subpluginOptions.forEach { opt ->
|
||||
options.addPluginArgument(subpluginId, opt)
|
||||
}
|
||||
options
|
||||
}
|
||||
|
||||
val configureKotlinTask: (KotlinCompile<*>) -> Unit = {
|
||||
val pluginOptions = it.getPluginOptions()
|
||||
val subpluginOptions = subpluginOptionsProvider.get()
|
||||
for (option in subpluginOptions) {
|
||||
pluginOptions.addPluginArgument(subpluginId, option)
|
||||
when (it) {
|
||||
is AbstractKotlinCompile<*> -> it.pluginOptions.add(compilerOptions)
|
||||
is KotlinNativeCompile -> it.compilerPluginOptions.addPluginArgument(compilerOptions.get())
|
||||
else -> error("Unexpected task ${it.name}, class: ${it.javaClass}")
|
||||
}
|
||||
it.registerSubpluginOptionsAsInputs(subpluginId, subpluginOptions)
|
||||
}
|
||||
|
||||
kotlinCompilation.compileKotlinTaskProvider.configure(configureKotlinTask)
|
||||
@@ -75,12 +81,6 @@ class SubpluginEnvironment(
|
||||
return appliedSubplugins
|
||||
}
|
||||
|
||||
private fun KotlinCompile<*>.getPluginOptions(): CompilerPluginOptions = when (this) {
|
||||
is AbstractKotlinCompile<*> -> pluginOptions
|
||||
is KotlinNativeCompile -> compilerPluginOptions
|
||||
else -> error("Unexpected task ${this.name}, class: ${this.javaClass}")
|
||||
}
|
||||
|
||||
private fun Project.addMavenDependency(configuration: String, artifact: SubpluginArtifact) {
|
||||
val artifactVersion = artifact.version ?: kotlinPluginVersion
|
||||
val mavenCoordinate = "${artifact.groupId}:${artifact.artifactId}:$artifactVersion"
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||
@@ -76,7 +77,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
|
||||
get() {
|
||||
val pluginOptionsTask = compilerPluginOptionsTask.value ?: return null
|
||||
return when (pluginOptionsTask) {
|
||||
is AbstractKotlinCompile<*> -> pluginOptionsTask.pluginOptions
|
||||
is AbstractKotlinCompile<*> -> pluginOptionsTask.pluginOptions.toSingleCompilerPluginOptions()
|
||||
is AbstractKotlinNativeCompile<*, *, *> -> pluginOptionsTask.compilerPluginOptions
|
||||
else -> error("Unexpected task: $pluginOptionsTask")
|
||||
}.arguments
|
||||
|
||||
+10
-17
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
@@ -46,18 +46,6 @@ abstract class KotlinJsIrLink @Inject constructor(
|
||||
workerExecutor
|
||||
) {
|
||||
|
||||
class Configurator(compilation: KotlinCompilationData<*>) : Kotlin2JsCompile.Configurator<KotlinJsIrLink>(compilation) {
|
||||
|
||||
override fun configure(task: KotlinJsIrLink) {
|
||||
super.configure(task)
|
||||
|
||||
task.entryModule.fileProvider(
|
||||
(compilation as KotlinJsIrCompilation).output.classesDirs.elements.map { it.single().asFile }
|
||||
).disallowChanges()
|
||||
task.destinationDirectory.fileProvider(task.outputFileProperty.map { it.parentFile }).disallowChanges()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
// Not check sources, only klib module
|
||||
disallowSourceChanges()
|
||||
@@ -88,11 +76,16 @@ abstract class KotlinJsIrLink @Inject constructor(
|
||||
@get:Input
|
||||
val outputGranularity: KotlinJsIrOutputGranularity = propertiesProvider.jsIrOutputGranularity
|
||||
|
||||
// Link tasks are not affected by compiler plugin
|
||||
override val pluginClasspath: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
@get:Internal
|
||||
@get:Deprecated("Please use modeProperty instead.")
|
||||
var mode: KotlinJsBinaryMode
|
||||
get() = modeProperty.get()
|
||||
set(value) {
|
||||
modeProperty.set(value)
|
||||
}
|
||||
|
||||
@Input
|
||||
lateinit var mode: KotlinJsBinaryMode
|
||||
@get:Input
|
||||
internal abstract val modeProperty: Property<KotlinJsBinaryMode>
|
||||
|
||||
private val buildDir = project.buildDir
|
||||
|
||||
|
||||
+54
-2
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilerPluginConfig
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
|
||||
class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
|
||||
@@ -24,8 +27,10 @@ class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
copyOptionsFrom(options)
|
||||
}
|
||||
|
||||
val subpluginOptionsByPluginId = optionsByPluginId
|
||||
@get:Internal
|
||||
internal val subpluginOptionsByPluginId = optionsByPluginId
|
||||
|
||||
@get:Internal
|
||||
val arguments: List<String>
|
||||
get() = optionsByPluginId.flatMap { (pluginId, subplubinOptions) ->
|
||||
subplubinOptions.map { option ->
|
||||
@@ -33,6 +38,10 @@ class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
fun addPluginArgument(options: CompilerPluginOptions) {
|
||||
copyOptionsFrom(options)
|
||||
}
|
||||
|
||||
operator fun plus(options: CompilerPluginConfig?): CompilerPluginOptions {
|
||||
if (options == null) return this
|
||||
val newOptions = CompilerPluginOptions()
|
||||
@@ -42,9 +51,52 @@ class CompilerPluginOptions() : CompilerPluginConfig() {
|
||||
return newOptions
|
||||
}
|
||||
|
||||
@Input
|
||||
fun getAsTaskInputArgs(): Map<String, String> {
|
||||
val result = mutableMapOf<String, String>()
|
||||
subpluginOptionsByPluginId.forEach { (id, subpluginOptions) ->
|
||||
result += computeForSubpluginId(id, subpluginOptions)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun computeForSubpluginId(subpluginId: String, subpluginOptions: List<SubpluginOption>): Map<String, String> {
|
||||
// There might be several options with the same key. We group them together
|
||||
// and add an index to the Gradle input property name to resolve possible duplication:
|
||||
val result = mutableMapOf<String, String>()
|
||||
val pluginOptionsGrouped = subpluginOptions.groupBy { it.key }
|
||||
for ((optionKey, optionsGroup) in pluginOptionsGrouped) {
|
||||
optionsGroup.forEachIndexed { index, option ->
|
||||
val indexSuffix = if (optionsGroup.size > 1) ".$index" else ""
|
||||
when (option) {
|
||||
is InternalSubpluginOption -> return@forEachIndexed
|
||||
|
||||
is CompositeSubpluginOption -> {
|
||||
val subpluginIdWithWrapperKey = "$subpluginId.$optionKey$indexSuffix"
|
||||
result += computeForSubpluginId(subpluginIdWithWrapperKey, option.originalOptions)
|
||||
}
|
||||
|
||||
is FilesSubpluginOption -> when (option.kind) {
|
||||
FilesOptionKind.INTERNAL -> Unit
|
||||
}.run { /* exhaustive when */ }
|
||||
|
||||
else -> {
|
||||
result["$subpluginId." + option.key + indexSuffix] = option.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun copyOptionsFrom(options: CompilerPluginConfig) {
|
||||
options.allOptions().forEach { entry ->
|
||||
optionsByPluginId[entry.key] = entry.value.toMutableList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ListProperty<CompilerPluginOptions>.toSingleCompilerPluginOptions(): CompilerPluginOptions {
|
||||
val values = this.orNull ?: return CompilerPluginOptions()
|
||||
return values.reduceOrNull(CompilerPluginOptions::plus) ?: CompilerPluginOptions()
|
||||
}
|
||||
-43
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Provider
|
||||
@@ -32,13 +31,6 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
||||
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.utils.propertyWithConvention
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -51,41 +43,6 @@ abstract class KotlinCompileCommon @Inject constructor(
|
||||
) : AbstractKotlinCompile<K2MetadataCompilerArguments>(objectFactory),
|
||||
KotlinCommonCompile {
|
||||
|
||||
class Configurator(compilation: KotlinCompilationData<*>) : AbstractKotlinCompile.Configurator<KotlinCompileCommon>(compilation) {
|
||||
override fun configure(task: KotlinCompileCommon) {
|
||||
super.configure(task)
|
||||
task.refinesMetadataPaths.from(getRefinesMetadataPaths(task.project)).disallowChanges()
|
||||
task.expectActualLinker
|
||||
.value(task.project.provider { (compilation as? KotlinCommonCompilation)?.isKlibCompilation == true || compilation is KotlinMetadataCompilationData })
|
||||
.disallowChanges()
|
||||
}
|
||||
|
||||
private fun getRefinesMetadataPaths(project: Project): Provider<Iterable<File>> {
|
||||
return project.provider {
|
||||
when (compilation) {
|
||||
is KotlinCompilation<*> -> {
|
||||
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||
val metadataTarget = compilation.owner as KotlinTarget
|
||||
defaultKotlinSourceSet.dependsOnClosure
|
||||
.mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||
.flatten()
|
||||
}
|
||||
is AbstractKotlinFragmentMetadataCompilationData -> {
|
||||
val fragment = compilation.fragment
|
||||
project.files(
|
||||
fragment.refinesClosure.map {
|
||||
val compilation = compilation.metadataCompilationRegistry.getForFragmentOrNull(it)
|
||||
?: return@map project.files()
|
||||
compilation.output.classesDirs
|
||||
}
|
||||
)
|
||||
}
|
||||
else -> error("unexpected compilation type")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val compilerRunner: Provider<GradleCompilerRunner> =
|
||||
objectFactory.propertyWithConvention(
|
||||
gradleCompileTaskProvider.map {
|
||||
|
||||
+13
-179
@@ -10,7 +10,6 @@ import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.file.*
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.logging.Logger
|
||||
@@ -46,21 +45,17 @@ import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.incremental.*
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskConfigurator
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
||||
import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform
|
||||
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
|
||||
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportMode
|
||||
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotDisabled
|
||||
@@ -261,42 +256,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
) : AbstractKotlinCompileTool<T>(objectFactory),
|
||||
CompileUsingKotlinDaemonWithNormalization {
|
||||
|
||||
open class Configurator<T : AbstractKotlinCompile<*>>(protected val compilation: KotlinCompilationData<*>) : TaskConfigurator<T> {
|
||||
override fun configure(task: T) {
|
||||
val project = task.project
|
||||
task.friendPaths.from(project.provider { compilation.friendPaths })
|
||||
|
||||
if (compilation is KotlinCompilation<*>) {
|
||||
task.friendSourceSets.set(project.provider { compilation.associateWithClosure.map { it.name } })
|
||||
// FIXME support compiler plugins with PM20
|
||||
task.pluginClasspath.from(project.configurations.getByName(compilation.pluginConfigurationName))
|
||||
}
|
||||
task.moduleName.set(project.provider { compilation.moduleName })
|
||||
task.sourceSetName.set(project.provider { compilation.compilationPurpose })
|
||||
task.multiPlatformEnabled.value(
|
||||
project.provider {
|
||||
project.plugins.any {
|
||||
it is KotlinPlatformPluginBase ||
|
||||
it is AbstractKotlinMultiplatformPluginWrapper ||
|
||||
it is AbstractKotlinPm20PluginWrapper
|
||||
}
|
||||
}
|
||||
).disallowChanges()
|
||||
task.taskBuildCacheableOutputDirectory.value(getKotlinBuildDir(task).map { it.dir("cacheable") }).disallowChanges()
|
||||
task.taskBuildLocalStateDirectory.value(getKotlinBuildDir(task).map { it.dir("local-state") }).disallowChanges()
|
||||
|
||||
task.localStateDirectories.from(task.taskBuildLocalStateDirectory).disallowChanges()
|
||||
|
||||
PropertiesProvider(task.project).mapKotlinDaemonProperties(task)
|
||||
}
|
||||
|
||||
private fun getKotlinBuildDir(task: T): Provider<Directory> =
|
||||
task.project.layout.buildDirectory.dir("$KOTLIN_BUILD_DIR_NAME/${task.name}")
|
||||
|
||||
protected fun getClasspathSnapshotDir(task: T): Provider<Directory> =
|
||||
getKotlinBuildDir(task).map { it.dir("classpath-snapshot") }
|
||||
}
|
||||
|
||||
init {
|
||||
cacheOnlyIfEnabledForKotlin()
|
||||
}
|
||||
@@ -312,7 +271,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
|
||||
// avoid creating directory in getter: this can lead to failure in parallel build
|
||||
@get:LocalState
|
||||
internal val taskBuildLocalStateDirectory: DirectoryProperty = objectFactory.directoryProperty()
|
||||
internal abstract val taskBuildLocalStateDirectory: DirectoryProperty
|
||||
|
||||
@get:Internal
|
||||
internal val buildHistoryFile
|
||||
@@ -342,7 +301,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
internal fun reportingSettings() = buildMetricsReporterService.orNull?.parameters?.reportingSettings ?: ReportingSettings()
|
||||
|
||||
@get:Input
|
||||
internal val useModuleDetection: Property<Boolean> = objectFactory.property(Boolean::class.java).value(false)
|
||||
internal abstract val useModuleDetection: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
protected val multiModuleICSettings: MultiModuleICSettings
|
||||
@@ -350,10 +309,10 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
|
||||
@get:NormalizeLineEndings
|
||||
@get:Classpath
|
||||
open val pluginClasspath: ConfigurableFileCollection = objectFactory.fileCollection()
|
||||
abstract val pluginClasspath: ConfigurableFileCollection
|
||||
|
||||
@get:Internal
|
||||
internal val pluginOptions = CompilerPluginOptions()
|
||||
@get:Nested
|
||||
internal abstract val pluginOptions: ListProperty<CompilerPluginOptions>
|
||||
|
||||
|
||||
/**
|
||||
@@ -368,7 +327,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
internal val javaOutputDir: DirectoryProperty = objectFactory.directoryProperty()
|
||||
|
||||
@get:Internal
|
||||
internal val sourceSetName: Property<String> = objectFactory.property(String::class.java)
|
||||
internal abstract val sourceSetName: Property<String>
|
||||
|
||||
@get:InputFiles
|
||||
@get:IgnoreEmptyDirectories
|
||||
@@ -378,7 +337,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
internal val commonSourceSet: ConfigurableFileCollection = objectFactory.fileCollection()
|
||||
|
||||
@get:Input
|
||||
internal val moduleName: Property<String> = objectFactory.property(String::class.java)
|
||||
internal abstract val moduleName: Property<String>
|
||||
|
||||
@get:Internal
|
||||
val abiSnapshotFile
|
||||
@@ -394,12 +353,10 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
internal val friendSourceSets = objectFactory.listProperty(String::class.java)
|
||||
|
||||
@get:Internal // takes part in the compiler arguments
|
||||
val friendPaths: ConfigurableFileCollection = objectFactory.fileCollection()
|
||||
abstract val friendPaths: ConfigurableFileCollection
|
||||
|
||||
private val kotlinLogger by lazy { GradleKotlinLogger(logger) }
|
||||
|
||||
abstract override val kotlinDaemonJvmArguments: ListProperty<String>
|
||||
|
||||
@get:Internal
|
||||
protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objectFactory
|
||||
.property(
|
||||
@@ -473,8 +430,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
|
||||
protected open fun skipCondition(): Boolean = sources.isEmpty
|
||||
|
||||
private val projectDir = project.rootProject.projectDir
|
||||
|
||||
@get:Internal
|
||||
protected open val incrementalProps: List<FileCollection>
|
||||
get() = listOfNotNull(
|
||||
@@ -489,7 +444,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
) {
|
||||
val allKotlinSources = sources.asFileTree.files
|
||||
|
||||
logger.kotlinDebug { "All kotlin sources: ${allKotlinSources.pathsAsStringRelativeTo(projectDir)}" }
|
||||
logger.kotlinDebug { "All kotlin sources: ${allKotlinSources.pathsAsStringRelativeTo(gradleCompileTaskProvider.get().projectDir.get())}" }
|
||||
|
||||
if (!inputChanges.isIncremental && skipCondition()) {
|
||||
// Skip running only if non-incremental run. Otherwise, we may need to do some cleanup.
|
||||
@@ -542,7 +497,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
|
||||
)
|
||||
|
||||
@get:Input
|
||||
internal val multiPlatformEnabled: Property<Boolean> = objectFactory.property(Boolean::class.java)
|
||||
internal abstract val multiPlatformEnabled: Property<Boolean>
|
||||
|
||||
@get:Internal
|
||||
internal val abstractKotlinCompileArgumentsContributor by lazy {
|
||||
@@ -568,8 +523,7 @@ open class KotlinCompileArgumentsProvider<T : AbstractKotlinCompile<out CommonCo
|
||||
val isMultiplatform: Boolean = taskProvider.multiPlatformEnabled.get()
|
||||
private val pluginData = taskProvider.kotlinPluginData?.orNull
|
||||
val pluginClasspath: FileCollection = listOfNotNull(taskProvider.pluginClasspath, pluginData?.classpath).reduce(FileCollection::plus)
|
||||
val pluginOptions: CompilerPluginOptions =
|
||||
listOfNotNull(taskProvider.pluginOptions, pluginData?.options).reduce(CompilerPluginOptions::plus)
|
||||
val pluginOptions: CompilerPluginOptions = taskProvider.pluginOptions.toSingleCompilerPluginOptions() + pluginData?.options
|
||||
}
|
||||
|
||||
class KotlinJvmCompilerArgumentsProvider
|
||||
@@ -596,101 +550,8 @@ abstract class KotlinCompile @Inject constructor(
|
||||
KotlinJvmCompile,
|
||||
UsesKotlinJavaToolchain {
|
||||
|
||||
internal open class Configurator<T : KotlinCompile>(
|
||||
kotlinCompilation: KotlinCompilationData<*>,
|
||||
private val properties: PropertiesProvider
|
||||
) : AbstractKotlinCompile.Configurator<T>(kotlinCompilation) {
|
||||
|
||||
companion object {
|
||||
private const val TRANSFORMS_REGISTERED = "_kgp_internal_kotlin_compile_transforms_registered"
|
||||
|
||||
val ARTIFACT_TYPE_ATTRIBUTE: Attribute<String> = Attribute.of("artifactType", String::class.java)
|
||||
private const val DIRECTORY_ARTIFACT_TYPE = "directory"
|
||||
private const val JAR_ARTIFACT_TYPE = "jar"
|
||||
const val CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE = "classpath-entry-snapshot"
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for configuration of the task. This method must be called during build configuration, not during task configuration
|
||||
* (which typically happens after build configuration). The reason is that some actions must be performed early (e.g., creating
|
||||
* configurations should be done early to avoid issues with composite builds (https://issuetracker.google.com/183952598)).
|
||||
*/
|
||||
fun runAtConfigurationTime(taskProvider: TaskProvider<T>, project: Project) {
|
||||
if (properties.useClasspathSnapshot) {
|
||||
registerTransformsOnce(project)
|
||||
project.configurations.create(classpathSnapshotConfigurationName(taskProvider.name)).apply {
|
||||
project.dependencies.add(name, project.files(project.provider { taskProvider.get().libraries }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerTransformsOnce(project: Project) {
|
||||
if (project.extensions.extraProperties.has(TRANSFORMS_REGISTERED)) {
|
||||
return
|
||||
}
|
||||
project.extensions.extraProperties[TRANSFORMS_REGISTERED] = true
|
||||
|
||||
val buildMetricsReporterService = BuildMetricsReporterService.registerIfAbsent(project)
|
||||
project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) {
|
||||
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE)
|
||||
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir)
|
||||
buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) }
|
||||
}
|
||||
project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) {
|
||||
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE)
|
||||
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir)
|
||||
buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun classpathSnapshotConfigurationName(taskName: String) = "_kgp_internal_${taskName}_classpath_snapshot"
|
||||
|
||||
override fun configure(task: T) {
|
||||
super.configure(task)
|
||||
|
||||
val compileJavaTaskProvider = when (compilation) {
|
||||
is KotlinJvmCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinWithJavaCompilation -> compilation.compileJavaTaskProvider
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (compileJavaTaskProvider != null) {
|
||||
task.associatedJavaCompileTaskTargetCompatibility.set(
|
||||
compileJavaTaskProvider.map { it.targetCompatibility }
|
||||
)
|
||||
task.associatedJavaCompileTaskSources.from(
|
||||
compileJavaTaskProvider.map { javaTask ->
|
||||
javaTask.source
|
||||
}
|
||||
)
|
||||
task.associatedJavaCompileTaskName.set(
|
||||
compileJavaTaskProvider.map { it.name }
|
||||
)
|
||||
}
|
||||
task.moduleName.set(task.project.provider {
|
||||
task.kotlinOptions.moduleName ?: task.parentKotlinOptionsImpl.orNull?.moduleName ?: compilation.moduleName
|
||||
})
|
||||
|
||||
if (properties.useClasspathSnapshot) {
|
||||
val classpathSnapshot = task.project.configurations.getByName(classpathSnapshotConfigurationName(task.name))
|
||||
task.classpathSnapshotProperties.classpathSnapshot.from(
|
||||
classpathSnapshot.incoming.artifactView {
|
||||
it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
}.files
|
||||
)
|
||||
val classpathSnapshotDir = getClasspathSnapshotDir(task)
|
||||
task.classpathSnapshotProperties.classpathSnapshotDir.value(classpathSnapshotDir).disallowChanges()
|
||||
} else {
|
||||
task.classpathSnapshotProperties.classpath.from(task.project.provider { task.libraries })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
internal val parentKotlinOptionsImpl: Property<KotlinJvmOptions> = objectFactory.property(KotlinJvmOptions::class.java)
|
||||
@get:Internal("Takes part in compiler args.")
|
||||
internal abstract val parentKotlinOptionsImpl: Property<KotlinJvmOptions>
|
||||
|
||||
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
|
||||
*
|
||||
@@ -1070,33 +931,6 @@ abstract class Kotlin2JsCompile @Inject constructor(
|
||||
incremental = true
|
||||
}
|
||||
|
||||
open class Configurator<T : Kotlin2JsCompile>(compilation: KotlinCompilationData<*>) :
|
||||
AbstractKotlinCompile.Configurator<T>(compilation) {
|
||||
|
||||
override fun configure(task: T) {
|
||||
super.configure(task)
|
||||
|
||||
task.outputFileProperty.value(
|
||||
task.project.provider {
|
||||
task.kotlinOptions.outputFile?.let(::File)
|
||||
?: task.destinationDirectory.locationOnly.get().asFile.resolve("${compilation.ownModuleName}.js")
|
||||
}
|
||||
).disallowChanges()
|
||||
task.optionalOutputFile.fileProvider(
|
||||
task.outputFileProperty.flatMap { outputFile ->
|
||||
task.project.provider {
|
||||
outputFile.takeUnless { task.kotlinOptions.isProduceUnzippedKlib() }
|
||||
}
|
||||
}
|
||||
).disallowChanges()
|
||||
val libraryCacheService = task.project.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"${LibraryFilterCachingService::class.java.canonicalName}_${LibraryFilterCachingService::class.java.classLoader.hashCode()}",
|
||||
LibraryFilterCachingService::class.java
|
||||
) {}
|
||||
task.libraryCache.set(libraryCacheService).also { task.libraryCache.disallowChanges() }
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class LibraryFilterCachingService : BuildService<BuildServiceParameters.None>, AutoCloseable {
|
||||
internal data class LibraryFilterCacheKey(val dependency: File, val irEnabled: Boolean, val preIrDisabled: Boolean)
|
||||
|
||||
|
||||
+20
-95
@@ -21,12 +21,9 @@ import org.gradle.api.Task
|
||||
import org.gradle.api.UnknownTaskException
|
||||
import org.gradle.api.tasks.TaskCollection
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.runOnceAfterEvaluated
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.*
|
||||
|
||||
/**
|
||||
* Registers the task with [name] and [type] and initialization script [body]
|
||||
@@ -92,114 +89,42 @@ internal inline fun <reified T : Task> Project.locateOrRegisterTask(
|
||||
|
||||
internal open class KotlinTasksProvider {
|
||||
open fun registerKotlinJVMTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: KotlinCompilationData<*>,
|
||||
configureAction: (KotlinCompile) -> (Unit)
|
||||
project: Project, taskName: String, kotlinOptions: KotlinCommonOptions, configuration: KotlinCompileConfig
|
||||
): TaskProvider<out KotlinCompile> {
|
||||
val properties = PropertiesProvider(project)
|
||||
val kotlinCompile = project.registerTask(
|
||||
name,
|
||||
KotlinCompile::class.java,
|
||||
constructorArgs = listOf(compilation.kotlinOptions)
|
||||
)
|
||||
|
||||
val configurator = KotlinCompile.Configurator<KotlinCompile>(compilation, properties)
|
||||
configurator.runAtConfigurationTime(kotlinCompile, project)
|
||||
|
||||
kotlinCompile.configure {
|
||||
configureAction(it)
|
||||
configurator.configure(it)
|
||||
return project.registerTask(taskName, KotlinCompile::class.java, constructorArgs = listOf(kotlinOptions)).also {
|
||||
configuration.execute(it)
|
||||
}
|
||||
configure(kotlinCompile, project, properties, compilation)
|
||||
|
||||
return kotlinCompile
|
||||
}
|
||||
|
||||
fun registerKotlinJSTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: KotlinCompilationData<*>,
|
||||
configureAction: (Kotlin2JsCompile) -> Unit
|
||||
project: Project, taskName: String, kotlinOptions: KotlinCommonOptions, configuration: Kotlin2JsCompileConfig
|
||||
): TaskProvider<out Kotlin2JsCompile> {
|
||||
val properties = PropertiesProvider(project)
|
||||
val result = project.registerTask(
|
||||
name,
|
||||
return project.registerTask(
|
||||
taskName,
|
||||
Kotlin2JsCompile::class.java,
|
||||
constructorArgs = listOf(compilation.kotlinOptions)
|
||||
) {
|
||||
configureAction(it)
|
||||
Kotlin2JsCompile.Configurator<Kotlin2JsCompile>(compilation).configure(it)
|
||||
constructorArgs = listOf(kotlinOptions)
|
||||
).also {
|
||||
configuration.execute(it)
|
||||
}
|
||||
configure(result, project, properties, compilation)
|
||||
return result
|
||||
}
|
||||
|
||||
fun registerKotlinJsIrTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: KotlinCompilationData<*>,
|
||||
configureAction: (KotlinJsIrLink) -> Unit
|
||||
project: Project, taskName: String, configuration: KotlinJsIrLinkConfig
|
||||
): TaskProvider<out KotlinJsIrLink> {
|
||||
val properties = PropertiesProvider(project)
|
||||
val result = project.registerTask(
|
||||
name,
|
||||
KotlinJsIrLink::class.java
|
||||
) {
|
||||
it.compilation = compilation
|
||||
configureAction(it)
|
||||
KotlinJsIrLink.Configurator(compilation).configure(it)
|
||||
return project.registerTask(taskName, KotlinJsIrLink::class.java).also {
|
||||
configuration.execute(it)
|
||||
}
|
||||
configure(result, project, properties, compilation)
|
||||
return result
|
||||
}
|
||||
|
||||
fun registerKotlinCommonTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: KotlinCompilationData<*>,
|
||||
configureAction: (KotlinCompileCommon) -> (Unit)
|
||||
project: Project, taskName: String, kotlinOptions: KotlinCommonOptions, configuration: KotlinCompileCommonConfig
|
||||
): TaskProvider<out KotlinCompileCommon> {
|
||||
val properties = PropertiesProvider(project)
|
||||
val result = project.registerTask(
|
||||
name,
|
||||
return project.registerTask(
|
||||
taskName,
|
||||
KotlinCompileCommon::class.java,
|
||||
constructorArgs = listOf(compilation.kotlinOptions)
|
||||
) {
|
||||
configureAction(it)
|
||||
KotlinCompileCommon.Configurator(compilation).configure(it)
|
||||
}
|
||||
configure(result, project, properties, compilation)
|
||||
return result
|
||||
}
|
||||
|
||||
open fun configure(
|
||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||
project: Project,
|
||||
propertiesProvider: PropertiesProvider,
|
||||
compilation: KotlinCompilationData<*>
|
||||
) {
|
||||
project.runOnceAfterEvaluated("apply properties and language settings to ${kotlinTaskHolder.name}", kotlinTaskHolder) {
|
||||
propertiesProvider.mapKotlinTaskProperties(kotlinTaskHolder.get())
|
||||
|
||||
applyLanguageSettingsToKotlinOptions(
|
||||
compilation.languageSettings,
|
||||
(kotlinTaskHolder.get() as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidTasksProvider : KotlinTasksProvider() {
|
||||
override fun configure(
|
||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||
project: Project,
|
||||
propertiesProvider: PropertiesProvider,
|
||||
compilation: KotlinCompilationData<*>
|
||||
) {
|
||||
super.configure(kotlinTaskHolder, project, propertiesProvider, compilation)
|
||||
kotlinTaskHolder.configure {
|
||||
it.useModuleDetection.set(true)
|
||||
constructorArgs = listOf(kotlinOptions)
|
||||
).also {
|
||||
configuration.execute(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.tasks.configuration
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.Directory
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
/**
|
||||
* Configuration for the base compile task, [org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile].
|
||||
*
|
||||
* This contains all data necessary to configure the tasks, and should avoid exposing global state (project, extensions, other tasks)
|
||||
* to the task instance as much as possible.
|
||||
*/
|
||||
internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile<*>>(
|
||||
project: Project,
|
||||
) : TaskConfigAction<TASK>(project) {
|
||||
|
||||
constructor(compilation: KotlinCompilationData<*>) : this(compilation.project) {
|
||||
val ext = compilation.project.topLevelExtension
|
||||
|
||||
configureTaskProvider { taskProvider ->
|
||||
project.runOnceAfterEvaluated("apply properties and language settings to ${taskProvider.name}") {
|
||||
taskProvider.configure {
|
||||
applyLanguageSettingsToKotlinOptions(
|
||||
compilation.languageSettings, (it as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configureTask { task ->
|
||||
task.friendPaths.from({ compilation.friendPaths })
|
||||
if (compilation is KotlinCompilation<*>) {
|
||||
task.friendSourceSets.value(providers.provider { compilation.associateWithClosure.map { it.name } })
|
||||
.disallowChanges()
|
||||
task.pluginClasspath.from(compilation.project.configurations.getByName(compilation.pluginConfigurationName))
|
||||
}
|
||||
task.moduleName.set(providers.provider { compilation.moduleName })
|
||||
task.sourceSetName.value(providers.provider { compilation.compilationPurpose })
|
||||
task.multiPlatformEnabled.value(
|
||||
providers.provider {
|
||||
compilation.project.plugins.any {
|
||||
it is KotlinPlatformPluginBase ||
|
||||
it is AbstractKotlinMultiplatformPluginWrapper ||
|
||||
it is AbstractKotlinPm20PluginWrapper
|
||||
}
|
||||
}
|
||||
)
|
||||
val propertiesProvider = project.kotlinPropertiesProvider
|
||||
|
||||
task.taskBuildCacheableOutputDirectory
|
||||
.value(getKotlinBuildDir(task).map { it.dir("cacheable") })
|
||||
.disallowChanges()
|
||||
task.taskBuildLocalStateDirectory
|
||||
.value(getKotlinBuildDir(task).map { it.dir("local-state") })
|
||||
.disallowChanges()
|
||||
|
||||
task.localStateDirectories.from(task.taskBuildLocalStateDirectory).disallowChanges()
|
||||
BuildMetricsReporterService.registerIfAbsent(project)?.let {
|
||||
task.buildMetricsReporterService.value(it)
|
||||
}
|
||||
|
||||
propertiesProvider.kotlinDaemonJvmArgs?.let { kotlinDaemonJvmArgs ->
|
||||
task.kotlinDaemonJvmArguments.set(providers.provider {
|
||||
kotlinDaemonJvmArgs.split("\\s+".toRegex())
|
||||
})
|
||||
}
|
||||
task.compilerExecutionStrategy.value(propertiesProvider.kotlinCompilerExecutionStrategy)
|
||||
|
||||
// Default values
|
||||
task.incremental = false
|
||||
task.useModuleDetection.convention(false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getKotlinBuildDir(task: TASK): Provider<Directory> =
|
||||
task.project.layout.buildDirectory.dir("$KOTLIN_BUILD_DIR_NAME/${task.name}")
|
||||
|
||||
protected fun getClasspathSnapshotDir(task: TASK): Provider<Directory> =
|
||||
getKotlinBuildDir(task).map { it.dir("classpath-snapshot") }
|
||||
}
|
||||
|
||||
internal abstract class TaskConfigAction<TASK : Task>(protected val project: Project) {
|
||||
|
||||
protected val objectFactory: ObjectFactory = project.objects
|
||||
protected val providers: ProviderFactory = project.providers
|
||||
protected val propertiesProvider = project.kotlinPropertiesProvider
|
||||
|
||||
private var executed = false
|
||||
|
||||
// Collect all task configurations, and run them later (in order they were added).
|
||||
private val taskConfigActions = ArrayDeque<(TaskProvider<TASK>) -> Unit>()
|
||||
|
||||
fun configureTaskProvider(configAction: (TaskProvider<TASK>) -> Unit) {
|
||||
check(!executed) {
|
||||
"Task has already been configured. Configuration actions should be added to this object before `this.execute` method runs."
|
||||
}
|
||||
taskConfigActions.addLast(configAction)
|
||||
}
|
||||
|
||||
fun configureTask(configAction: (TASK) -> Unit) {
|
||||
configureTaskProvider { taskProvider ->
|
||||
taskProvider.configure(configAction)
|
||||
}
|
||||
}
|
||||
|
||||
fun execute(taskProvider: TaskProvider<TASK>) {
|
||||
executed = true
|
||||
taskConfigActions.forEach {
|
||||
it(taskProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.tasks.configuration
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.util.lang.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.*
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.classLoadersCacheSize
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.disableClassloaderCacheForProcessors
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isIncludeCompileClasspath
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isIncrementalKapt
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformAction
|
||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinAndroidPluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||
import org.jetbrains.kotlin.gradle.utils.listProperty
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal open class KaptConfigAction<TASK : KaptTask>(
|
||||
project: Project,
|
||||
protected val ext: KaptExtension,
|
||||
) : TaskConfigAction<TASK>(project) {
|
||||
|
||||
internal constructor(kotlinCompileTask: KotlinCompile, ext: KaptExtension) : this(kotlinCompileTask.project, ext) {
|
||||
configureTaskProvider { taskProvider ->
|
||||
val kaptClasspathSnapshot = getKaptClasspathSnapshot(taskProvider)
|
||||
|
||||
taskProvider.configure { task ->
|
||||
task.classpath.from(kotlinCompileTask.libraries)
|
||||
task.compiledSources.from(
|
||||
kotlinCompileTask.destinationDirectory,
|
||||
Callable { kotlinCompileTask.javaOutputDir.takeIf { it.isPresent } })
|
||||
.disallowChanges()
|
||||
task.sourceSetName.value(kotlinCompileTask.sourceSetName).disallowChanges()
|
||||
|
||||
val kaptSources = objectFactory
|
||||
.fileCollection()
|
||||
.from(kotlinCompileTask.javaSources, task.stubsDir)
|
||||
.asFileTree
|
||||
.matching { it.include("**/*.java") }
|
||||
.filter {
|
||||
it.exists() &&
|
||||
!isAncestor(task.destinationDir.get().asFile, it) &&
|
||||
!isAncestor(task.classesDir.get().asFile, it)
|
||||
}
|
||||
task.source.from(kaptSources).disallowChanges()
|
||||
task.verbose.set(KaptTask.queryKaptVerboseProperty(project))
|
||||
task.compilerClasspath.from(providers.provider { kotlinCompileTask.defaultCompilerClasspath })
|
||||
|
||||
task.isIncremental = project.isIncrementalKapt()
|
||||
task.useBuildCache = ext.useBuildCache
|
||||
|
||||
task.includeCompileClasspath.set(ext.includeCompileClasspath ?: project.isIncludeCompileClasspath())
|
||||
task.classpathStructure.from(kaptClasspathSnapshot)
|
||||
|
||||
task.localStateDirectories.from(Callable { task.incAptCache.orNull })
|
||||
task.onlyIf {
|
||||
it as KaptTask
|
||||
it.includeCompileClasspath.get() || !it.kaptClasspath.isEmpty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getKaptClasspathSnapshot(taskProvider: TaskProvider<TASK>): FileCollection? {
|
||||
return if (project.isIncrementalKapt()) {
|
||||
maybeRegisterTransform(project)
|
||||
|
||||
val classStructureConfiguration = project.configurations.detachedConfiguration()
|
||||
|
||||
// Wrap the `kotlinCompile.classpath` into a file collection, so that, if the classpath is represented by a configuration,
|
||||
// the configuration is not extended (via extendsFrom, which normally happens when one configuration is _added_ into another)
|
||||
// but is instead included as the (lazily) resolved files. This is needed because the class structure configuration doesn't have
|
||||
// the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does.
|
||||
classStructureConfiguration.dependencies.add(project.dependencies.create(project.files(project.provider { taskProvider.get().classpath })))
|
||||
classStructureConfiguration.incoming.artifactView { viewConfig ->
|
||||
viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}.files
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun maybeRegisterTransform(project: Project) {
|
||||
if (!project.extensions.extraProperties.has("KaptStructureTransformAdded")) {
|
||||
val transformActionClass =
|
||||
if (GradleVersion.current() >= GradleVersion.version("5.4"))
|
||||
StructureTransformAction::class.java
|
||||
else
|
||||
StructureTransformLegacyAction::class.java
|
||||
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "jar")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
|
||||
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
|
||||
transformSpec.from.attribute(artifactType, "directory")
|
||||
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
|
||||
}
|
||||
|
||||
project.extensions.extraProperties["KaptStructureTransformAdded"] = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getJavaOptions(defaultJavaSourceCompatibility: Provider<String>): Provider<Map<String, String>> {
|
||||
return providers.provider {
|
||||
ext.getJavacOptions().toMutableMap().also { result ->
|
||||
if ("-source" in result || "--source" in result || "--release" in result) return@also
|
||||
|
||||
if (defaultJavaSourceCompatibility.isPresent) {
|
||||
val atLeast12Java =
|
||||
if (isConfigurationCacheAvailable(project.gradle)) {
|
||||
val currentJavaVersion =
|
||||
JavaVersion.parse(project.providers.systemProperty("java.version").forUseAtConfigurationTime().get())
|
||||
currentJavaVersion.feature >= 12
|
||||
} else {
|
||||
SystemInfo.isJavaVersionAtLeast(12, 0, 0)
|
||||
}
|
||||
val sourceOptionKey = if (atLeast12Java) {
|
||||
"--source"
|
||||
} else {
|
||||
"-source"
|
||||
}
|
||||
result[sourceOptionKey] = defaultJavaSourceCompatibility.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache
|
||||
private fun isAncestor(dir: File, file: File): Boolean {
|
||||
val path = file.canonicalPath
|
||||
val prefix = dir.canonicalPath
|
||||
val pathLength = path.length
|
||||
val prefixLength = prefix.length
|
||||
val caseSensitive = true
|
||||
return if (prefixLength == 0) {
|
||||
true
|
||||
} else if (prefixLength > pathLength) {
|
||||
false
|
||||
} else if (!path.regionMatches(0, prefix, 0, prefixLength, ignoreCase = !caseSensitive)) {
|
||||
return false
|
||||
} else if (pathLength == prefixLength) {
|
||||
return true
|
||||
} else {
|
||||
val lastPrefixChar: Char = prefix.get(prefixLength - 1)
|
||||
var slashOrSeparatorIdx = prefixLength
|
||||
if (lastPrefixChar == '/' || lastPrefixChar == File.separatorChar) {
|
||||
slashOrSeparatorIdx = prefixLength - 1
|
||||
}
|
||||
val next1 = path[slashOrSeparatorIdx]
|
||||
return !(next1 != '/' && next1 != File.separatorChar)
|
||||
}
|
||||
}
|
||||
|
||||
internal class KaptWithoutKotlincConfigAction(kotlinCompileTask: KotlinCompile, ext: KaptExtension) :
|
||||
KaptConfigAction<KaptWithoutKotlincTask>(kotlinCompileTask, ext) {
|
||||
|
||||
init {
|
||||
initKaptWorkersConfiguration(project.topLevelExtension)
|
||||
|
||||
configureTask { task ->
|
||||
task.addJdkClassesToClasspath.set(
|
||||
project.providers.provider {
|
||||
project.plugins.none { it is AbstractKotlinAndroidPluginWrapper }
|
||||
}
|
||||
)
|
||||
task.kaptJars.from(project.configurations.getByName(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME))
|
||||
task.mapDiagnosticLocations = ext.mapDiagnosticLocations
|
||||
task.annotationProcessorFqNames.set(providers.provider { ext.processors.split(',').filter { it.isNotEmpty() } })
|
||||
task.disableClassloaderCacheForProcessors = project.disableClassloaderCacheForProcessors()
|
||||
task.classLoadersCacheSize = project.classLoadersCacheSize()
|
||||
task.javacOptions.set(getJavaOptions(task.defaultJavaSourceCompatibility))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initKaptWorkersConfiguration(kotlinExt: KotlinTopLevelExtension) {
|
||||
project.configurations.findByName(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME)
|
||||
?: project.configurations.create(Kapt3GradleSubplugin.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME).apply {
|
||||
dependencies.addAllLater(project.listProperty {
|
||||
val kaptDependency = "org.jetbrains.kotlin:kotlin-annotation-processing-gradle:${project.getKotlinPluginVersion()}"
|
||||
listOf(
|
||||
project.dependencies.create(kaptDependency),
|
||||
project.kotlinDependency(
|
||||
"kotlin-stdlib",
|
||||
kotlinExt.coreLibrariesVersion
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class KaptWithKotlincConfigAction(kotlinCompileTask: KotlinCompile, ext: KaptExtension) :
|
||||
KaptConfigAction<KaptWithKotlincTask>(kotlinCompileTask, ext) {
|
||||
|
||||
init {
|
||||
configureTask { task ->
|
||||
if (project.isIncrementalKapt()) {
|
||||
val incAptCacheOption = task.incAptCache.locationOnly.map { incAptCacheDir ->
|
||||
CompilerPluginOptions().also {
|
||||
it.addPluginArgument(
|
||||
KAPT_SUBPLUGIN_ID, SubpluginOption("incrementalCache", lazy { incAptCacheDir.asFile.absolutePath })
|
||||
)
|
||||
}
|
||||
}
|
||||
task.kaptPluginOptions.add(incAptCacheOption)
|
||||
}
|
||||
|
||||
task.pluginClasspath.from(kotlinCompileTask.pluginClasspath)
|
||||
task.additionalPluginOptionsAsInputs.value(kotlinCompileTask.pluginOptions).disallowChanges()
|
||||
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
|
||||
task.javaPackagePrefix.set(providers.provider { kotlinCompileTask.javaPackagePrefix })
|
||||
task.reportingSettings.set(providers.provider { kotlinCompileTask.reportingSettings() })
|
||||
propertiesProvider.kotlinDaemonJvmArgs?.let {
|
||||
task.kotlinDaemonJvmArguments.value(it.split("\\s+".toRegex())).disallowChanges()
|
||||
}
|
||||
task.compilerExecutionStrategy.value(propertiesProvider.kotlinCompilerExecutionStrategy).disallowChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val artifactType = Attribute.of("artifactType", String::class.java)
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.tasks.configuration
|
||||
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID
|
||||
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isIncludeCompileClasspath
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
|
||||
import org.jetbrains.kotlin.gradle.internal.KaptTask
|
||||
import org.jetbrains.kotlin.gradle.internal.buildKaptSubpluginOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal class KaptGenerateStubsConfig(compilation: KotlinCompilationData<*>, kotlinTaskProvider: TaskProvider<KotlinCompile>) :
|
||||
BaseKotlinCompileConfig<KaptGenerateStubsTask>(compilation) {
|
||||
|
||||
private val kaptExtension: KaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
||||
|
||||
init {
|
||||
configureTask { task ->
|
||||
val kotlinCompileTask = kotlinTaskProvider.get()
|
||||
task.useModuleDetection.value(kotlinCompileTask.useModuleDetection).disallowChanges()
|
||||
task.moduleName.value(kotlinCompileTask.moduleName).disallowChanges()
|
||||
task.libraries.from({ kotlinCompileTask.libraries })
|
||||
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
|
||||
task.verbose.set(KaptTask.queryKaptVerboseProperty(project))
|
||||
|
||||
task.pluginOptions.add(buildOptions(task))
|
||||
|
||||
if (!isIncludeCompileClasspath()) {
|
||||
task.onlyIf {
|
||||
!(it as KaptGenerateStubsTask).kaptClasspath.isEmpty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isIncludeCompileClasspath() = kaptExtension.includeCompileClasspath ?: project.isIncludeCompileClasspath()
|
||||
|
||||
private fun buildOptions(task: KaptGenerateStubsTask): Provider<CompilerPluginOptions> {
|
||||
val javacOptions = project.provider { kaptExtension.getJavacOptions() }
|
||||
return project.provider {
|
||||
val compilerPluginOptions = CompilerPluginOptions()
|
||||
buildKaptSubpluginOptions(
|
||||
kaptExtension,
|
||||
project,
|
||||
javacOptions.get(),
|
||||
aptMode = "stubs",
|
||||
generatedSourcesDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
generatedClassesDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
incrementalDataDir = objectFactory.fileCollection().from(task.destinationDirectory.asFile),
|
||||
includeCompileClasspath = isIncludeCompileClasspath(),
|
||||
kaptStubsDir = objectFactory.fileCollection().from(task.stubsDir.asFile)
|
||||
).forEach {
|
||||
compilerPluginOptions.addPluginArgument(KAPT_SUBPLUGIN_ID, it)
|
||||
}
|
||||
return@provider compilerPluginOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.tasks.configuration
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import java.io.File
|
||||
|
||||
internal typealias Kotlin2JsCompileConfig = BaseKotlin2JsCompileConfig<Kotlin2JsCompile>
|
||||
|
||||
internal open class BaseKotlin2JsCompileConfig<TASK : Kotlin2JsCompile>(
|
||||
compilation: KotlinCompilationData<*>
|
||||
) : AbstractKotlinCompileConfig<TASK>(compilation) {
|
||||
|
||||
init {
|
||||
val libraryCacheService = project.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"${Kotlin2JsCompile.LibraryFilterCachingService::class.java.canonicalName}_${Kotlin2JsCompile.LibraryFilterCachingService::class.java.classLoader.hashCode()}",
|
||||
Kotlin2JsCompile.LibraryFilterCachingService::class.java
|
||||
) {}
|
||||
|
||||
configureTask { task ->
|
||||
task.incremental = propertiesProvider.incrementalJs ?: true
|
||||
task.incrementalJsKlib = propertiesProvider.incrementalJsKlib ?: true
|
||||
|
||||
task.outputFileProperty.value(task.project.provider {
|
||||
task.kotlinOptions.outputFile?.let(::File)
|
||||
?: task.destinationDirectory.locationOnly.get().asFile.resolve("${compilation.ownModuleName}.js")
|
||||
}).disallowChanges()
|
||||
|
||||
task.optionalOutputFile.fileProvider(task.outputFileProperty.flatMap { outputFile ->
|
||||
task.project.provider {
|
||||
outputFile.takeUnless { task.kotlinOptions.isProduceUnzippedKlib() }
|
||||
}
|
||||
}).disallowChanges()
|
||||
task.libraryCache.set(libraryCacheService).also { task.libraryCache.disallowChanges() }
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.tasks.configuration
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
|
||||
import java.io.File
|
||||
|
||||
internal class KotlinCompileCommonConfig(
|
||||
private val compilation: KotlinCompilationData<*>,
|
||||
) : AbstractKotlinCompileConfig<KotlinCompileCommon>(compilation) {
|
||||
init {
|
||||
configureTask { task ->
|
||||
task.expectActualLinker.value(
|
||||
providers.provider {
|
||||
(compilation as? KotlinCommonCompilation)?.isKlibCompilation == true || compilation is KotlinMetadataCompilationData
|
||||
}
|
||||
).disallowChanges()
|
||||
task.refinesMetadataPaths.from(getRefinesMetadataPaths(project)).disallowChanges()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRefinesMetadataPaths(project: Project): Provider<Iterable<File>> {
|
||||
return project.provider {
|
||||
when (compilation) {
|
||||
is KotlinCompilation<*> -> {
|
||||
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||
val metadataTarget = compilation.owner as KotlinTarget
|
||||
defaultKotlinSourceSet.dependsOnClosure
|
||||
.mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||
.flatten()
|
||||
}
|
||||
is AbstractKotlinFragmentMetadataCompilationData -> {
|
||||
val fragment = compilation.fragment
|
||||
project.files(
|
||||
fragment.refinesClosure.minus(fragment).map {
|
||||
val compilation = compilation.metadataCompilationRegistry.getForFragmentOrNull(it)
|
||||
?: return@map project.files()
|
||||
compilation.output.classesDirs
|
||||
}
|
||||
)
|
||||
}
|
||||
else -> error("unexpected compilation type")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.gradle.tasks.configuration
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_BUILD_DIR_NAME
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile>
|
||||
|
||||
internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotlinCompileConfig<TASK> {
|
||||
|
||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||
constructor(compilation: KotlinCompilationData<*>) : super(compilation) {
|
||||
val javaTaskProvider = when (compilation) {
|
||||
is KotlinJvmCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider
|
||||
is KotlinWithJavaCompilation<*> -> compilation.compileJavaTaskProvider
|
||||
else -> null
|
||||
}
|
||||
|
||||
configureTaskProvider { taskProvider ->
|
||||
val snapshotConfiguration = runAtConfigurationTime(taskProvider)
|
||||
|
||||
taskProvider.configure { task ->
|
||||
javaTaskProvider?.let {
|
||||
task.associatedJavaCompileTaskTargetCompatibility.value(javaTaskProvider.map { it.targetCompatibility })
|
||||
task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source })
|
||||
task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
|
||||
}
|
||||
task.moduleName.value(providers.provider {
|
||||
(compilation.kotlinOptions as? KotlinJvmOptions)?.moduleName ?: task.parentKotlinOptionsImpl.orNull?.moduleName
|
||||
?: compilation.moduleName
|
||||
})
|
||||
|
||||
task.incremental = propertiesProvider.incrementalJvm ?: true
|
||||
|
||||
if (propertiesProvider.useFir == true) {
|
||||
task.kotlinOptions.useFir = true
|
||||
}
|
||||
task.usePreciseJavaTracking = propertiesProvider.usePreciseJavaTracking ?: true
|
||||
task.jvmTargetValidationMode.set(propertiesProvider.jvmTargetValidationMode)
|
||||
task.classpathSnapshotProperties.useClasspathSnapshot.value(propertiesProvider.useClasspathSnapshot)
|
||||
task.useKotlinAbiSnapshot.value(propertiesProvider.useKotlinAbiSnapshot).disallowChanges()
|
||||
|
||||
if (snapshotConfiguration != null) {
|
||||
val snapshotFiles = snapshotConfiguration.incoming.artifactView {
|
||||
it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
}.files
|
||||
task.classpathSnapshotProperties.classpathSnapshot.from(snapshotFiles).disallowChanges()
|
||||
task.classpathSnapshotProperties.classpathSnapshotDir
|
||||
.value(getClasspathSnapshotDir(task))
|
||||
.disallowChanges()
|
||||
} else {
|
||||
task.classpathSnapshotProperties.classpath.from(task.project.provider { task.libraries })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TRANSFORMS_REGISTERED = "_kgp_internal_kotlin_compile_transforms_registered"
|
||||
|
||||
val ARTIFACT_TYPE_ATTRIBUTE: Attribute<String> = Attribute.of("artifactType", String::class.java)
|
||||
private const val DIRECTORY_ARTIFACT_TYPE = "directory"
|
||||
private const val JAR_ARTIFACT_TYPE = "jar"
|
||||
const val CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE = "classpath-entry-snapshot"
|
||||
}
|
||||
|
||||
private fun registerTransformsOnce(project: Project) {
|
||||
if (project.extensions.extraProperties.has(TRANSFORMS_REGISTERED)) {
|
||||
return
|
||||
}
|
||||
project.extensions.extraProperties[TRANSFORMS_REGISTERED] = true
|
||||
|
||||
val buildMetricsReporterService = BuildMetricsReporterService.registerIfAbsent(project)
|
||||
project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) {
|
||||
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE)
|
||||
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir)
|
||||
buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) }
|
||||
}
|
||||
project.dependencies.registerTransform(ClasspathEntrySnapshotTransform::class.java) {
|
||||
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE)
|
||||
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
|
||||
it.parameters.gradleUserHomeDir.set(project.gradle.gradleUserHomeDir)
|
||||
buildMetricsReporterService?.apply { it.parameters.buildMetricsReporterService.set(this) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for configuration of the task. This method must be called during build configuration, not during task configuration
|
||||
* (which typically happens after build configuration). The reason is that some actions must be performed early (e.g., creating
|
||||
* configurations should be done early to avoid issues with composite builds (https://issuetracker.google.com/183952598)).
|
||||
*/
|
||||
private fun runAtConfigurationTime(taskProvider: TaskProvider<TASK>): Configuration? {
|
||||
return if (propertiesProvider.useClasspathSnapshot) {
|
||||
registerTransformsOnce(project)
|
||||
project.configurations.detachedConfiguration(
|
||||
project.dependencies.create(objectFactory.fileCollection().from(taskProvider.get().libraries))
|
||||
)
|
||||
} else null
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.gradle.tasks.configuration
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
|
||||
|
||||
internal open class KotlinJsIrLinkConfig(
|
||||
compilation: KotlinJsIrCompilation
|
||||
) : BaseKotlin2JsCompileConfig<KotlinJsIrLink>(compilation) {
|
||||
|
||||
init {
|
||||
configureTask { task ->
|
||||
// Link tasks are not affected by compiler plugin, so set to empty
|
||||
task.pluginClasspath.setFrom(objectFactory.fileCollection())
|
||||
|
||||
task.entryModule.fileProvider(compilation.output.classesDirs.elements.map { it.single().asFile }).disallowChanges()
|
||||
task.compilation = compilation
|
||||
task.destinationDirectory.fileProvider(task.outputFileProperty.map { it.parentFile })
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user