Revert "AbstractKotlinCompileTool class now also implements PatternFilterable"

This reverts commit 0025bf9ed3.
This commit is contained in:
Yahor Berdnikau
2022-03-23 19:03:17 +01:00
parent 46f44763ac
commit d5e5513dfd
16 changed files with 319 additions and 332 deletions
@@ -306,7 +306,6 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
build(":mylibrary:assembleDebug") {
assertEquals(
listOf(
"baseLibrary/build/tmp/kapt3/stubs/debug/error/NonExistentClass.java",
"mylibrary/src/main/java/com/example/lib/ExampleParcel.java",
"baseLibrary/src/main/java/com/example/lib2/basemodule/BaseClassParcel.java",
).map { projectPath.resolve(it).toRealPath().toString() }.toSet(),
@@ -33,7 +33,6 @@ 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.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
@@ -577,7 +576,8 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
kotlinCompilation.output.classesDirs.from(kaptTaskProvider.map { it.classesDir })
kotlinCompilation.compileKotlinTaskProvider.configure {
(it as AbstractKotlinCompileTool<*>).setSource(sourcesOutputDir, kotlinSourcesOutputDir)
it as SourceTask
it.source(sourcesOutputDir, kotlinSourcesOutputDir)
}
if (javaCompile != null) {
@@ -16,8 +16,9 @@
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.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
@@ -28,6 +29,8 @@ 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.FilteringSourceRootsContainer
import org.jetbrains.kotlin.gradle.tasks.SourceRoots
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile
@@ -36,12 +39,10 @@ import javax.inject.Inject
@CacheableTask
abstract class KaptGenerateStubsTask @Inject constructor(
workerExecutor: WorkerExecutor,
objectFactory: ObjectFactory
) : KotlinCompile(
workerExecutor: WorkerExecutor
): KotlinCompile(
KotlinJvmOptionsImpl(),
workerExecutor,
objectFactory
workerExecutor
) {
internal class Configurator(
@@ -70,10 +71,23 @@ abstract class KaptGenerateStubsTask @Inject constructor(
kotlinCompileTask.compilerArgumentsContributor
}
)
task.jvmSourceRoots.set(
providerFactory.provider {
kotlinCompileTask.getSourceRoots().let { compileTaskSourceRoots ->
SourceRoots.ForJvm(
compileTaskSourceRoots.kotlinSourceFiles.filter { task.isSourceRootAllowed(it) },
compileTaskSourceRoots.javaSourceRoots.filter { task.isSourceRootAllowed(it) }
)
}
}
)
task.verbose.set(KaptTask.queryKaptVerboseProperty(task.project))
}
}
@field:Transient
override val sourceRootsContainer = FilteringSourceRootsContainer(objects, { isSourceRootAllowed(it) })
@get:OutputDirectory
abstract val stubsDir: DirectoryProperty
@@ -104,45 +118,28 @@ abstract class KaptGenerateStubsTask @Inject constructor(
@get:Incremental
abstract val additionalSources: ConfigurableFileCollection
private fun File.isSourceRootAllowed(): Boolean =
!destinationDirectory.get().asFile.isParentOf(this) &&
!stubsDir.asFile.get().isParentOf(this) &&
generatedSourcesDirs.none { it.isParentOf(this) }
override fun setSource(vararg source: Any) {
super.setSource(sourceRootsContainer.add(sources))
}
override fun skipCondition(): Boolean = sources.isEmpty && javaSources.isEmpty
override fun setSource(source: Any) {
super.setSource(sourceRootsContainer.set(sources))
}
// Task need to run even if there is no Kotlin sources, but only Java
@get:Incremental
@get:InputFiles
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
override val sources: FileCollection = super.sources
.asFileTree
.matching { patternFilterable ->
patternFilterable.include { it.isDirectory || it.file.isSourceRootAllowed() }
}
override val javaSources: FileCollection = super.javaSources
.asFileTree
.matching { patternFilterable ->
patternFilterable.include { it.isDirectory || it.file.isSourceRootAllowed() }
}
// TODO: prevent querying destinationDirectory on configuration time
private fun isSourceRootAllowed(source: File): Boolean =
!destinationDirectory.get().asFile.isParentOf(source) &&
!stubsDir.asFile.get().isParentOf(source) &&
generatedSourcesDirs.none { it.isParentOf(source) }
@get:Internal
internal abstract val compileKotlinArgumentsContributor: Property<CompilerArgumentsContributor<K2JVMCompilerArguments>>
override fun setupCompilerArgs(
args: K2JVMCompilerArguments,
defaultsOnly: Boolean,
ignoreClasspathResolutionErrors: Boolean
) {
compileKotlinArgumentsContributor.get().contributeArguments(
args,
compilerArgumentsConfigurationFlags(
defaultsOnly,
ignoreClasspathResolutionErrors
)
)
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
compileKotlinArgumentsContributor.get().contributeArguments(args, compilerArgumentsConfigurationFlags(
defaultsOnly,
ignoreClasspathResolutionErrors
))
val pluginOptionsWithKapt = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
@@ -151,4 +148,9 @@ abstract class KaptGenerateStubsTask @Inject constructor(
args.classpathAsList = this.classpath.filter { it.exists() }.toList()
args.destinationAsFile = this.destinationDirectory.get().asFile
}
@get:Internal
internal abstract val jvmSourceRoots: Property<SourceRoots.ForJvm>
override fun getSourceRoots(): SourceRoots.ForJvm = jvmSourceRoots.get()
}
@@ -1,10 +1,10 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionTask
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -31,16 +31,20 @@ import javax.inject.Inject
@CacheableTask
abstract class KaptTask @Inject constructor(
objectFactory: ObjectFactory
) : DefaultTask(),
) : ConventionTask(),
TaskWithLocalState,
UsesKotlinJavaToolchain {
open class Configurator<T: KaptTask>(protected val kotlinCompileTask: KotlinCompile) : TaskConfigurator<T> {
override fun configure(task: T) {
val objectFactory = task.project.objects
val providerFactory = task.project.providers
task.compilerClasspath.from({ kotlinCompileTask.defaultCompilerClasspath })
task.classpath.from(kotlinCompileTask.classpath)
task.kotlinSourceRoots.value(
providerFactory.provider { kotlinCompileTask.sourceRootsContainer.sourceRoots }
).disallowChanges()
task.compiledSources.from(
kotlinCompileTask.destinationDirectory,
Callable { kotlinCompileTask.javaOutputDir.takeIf { it.isPresent } }
@@ -48,10 +52,7 @@ abstract class KaptTask @Inject constructor(
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
objectFactory.fileCollection().from(task.kotlinSourceRoots, task.stubsDir).asFileTree
.matching { it.include("**/*.java") }
.filter { f -> task.isRootAllowed(f) }
).disallowChanges()
@@ -152,6 +153,9 @@ abstract class KaptTask @Inject constructor(
@get:Internal
var useBuildCache: Boolean = false
@get:Internal
abstract val kotlinSourceRoots: ListProperty<File>
/** Needed for the model builder. */
@get:Internal
abstract val sourceSetName: Property<String>
@@ -8,10 +8,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import groovy.lang.Closure
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.internal.plugins.DslObject
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.util.ConfigureUtil
@@ -24,6 +26,7 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.handleHierarchicalStructureFlagsMigration
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.registerDefaultVariantFactories
@@ -38,7 +41,6 @@ import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset
import org.jetbrains.kotlin.gradle.targets.native.tasks.artifact.registerKotlinArtifactsExtension
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.*
@@ -185,7 +187,7 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
(sourceSet.languageSettings as? DefaultLanguageSettingsBuilder)?.run {
compilerPluginOptionsTask = lazy {
val associatedCompilation = primaryCompilationsBySourceSet[sourceSet] ?: metadataCompilation
project.tasks.getByName(associatedCompilation.compileKotlinTaskName) as AbstractKotlinCompileTool<*>
project.tasks.getByName(associatedCompilation.compileKotlinTaskName) as SourceTask
}
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.sources
import org.gradle.api.InvalidUserDataException
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.SourceTask
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersion
@@ -15,7 +16,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
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.project.model.LanguageSettings
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
@@ -70,7 +70,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
/* A Kotlin task that is responsible for code analysis of the owner of this language settings builder. */
@Transient // not needed during Gradle Instant Execution
var compilerPluginOptionsTask: Lazy<AbstractKotlinCompileTool<*>?> = lazyOf(null)
var compilerPluginOptionsTask: Lazy<SourceTask?> = lazyOf(null)
val compilerPluginArguments: List<String>?
get() {
@@ -78,7 +78,7 @@ class KotlinJsDcePlugin : Plugin<Project> {
dceTask.configure {
it.classpath.from(configuration)
it.destinationDirectory.set(it.dceOptions.outputDirectory?.let { File(it) } ?: outputDir)
it.setSource(kotlinTask.map { task -> (task as Kotlin2JsCompile).outputFileProperty })
it.setSource((kotlinTask.get() as Kotlin2JsCompile).outputFileProperty)
}
}
}
@@ -101,10 +101,9 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
),
listOf(compilation)
) { task ->
val entryFileProvider = binary.linkSyncTask.flatMap { syncTask ->
binary.linkTask.map {
syncTask.destinationDir.resolve(it.outputFileProperty.get().name)
}
val entryFileProvider = binary.linkSyncTask.map {
it.destinationDir
.resolve(binary.linkTask.get().outputFileProperty.get().name)
}
webpackMajorVersion.choose(
@@ -7,7 +7,6 @@ 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.tasks.*
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.toHexString
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
@@ -57,18 +57,6 @@ abstract class KotlinJsIrLink @Inject constructor(
}
}
init {
// Not check sources, only klib module
disallowSourceChanges()
}
@get:Internal
override val sources: FileCollection = super.sources
override fun skipCondition(): Boolean {
return !entryModule.get().asFile.exists()
}
@Transient
@get:Internal
internal lateinit var compilation: KotlinCompilationData<*>
@@ -93,6 +81,10 @@ abstract class KotlinJsIrLink @Inject constructor(
@Input
lateinit var mode: KotlinJsBinaryMode
// Not check sources, only klib module
@get:Internal
abstract override val sources: ConfigurableFileCollection
private val buildDir = project.buildDir
@get:SkipWhenEmpty
@@ -101,24 +93,23 @@ abstract class KotlinJsIrLink @Inject constructor(
@get:PathSensitive(PathSensitivity.RELATIVE)
internal abstract val entryModule: DirectoryProperty
@get:Internal
override val destinationDirectory: DirectoryProperty = objectFactory.directoryProperty()
@get:OutputDirectory
val normalizedDestinationDirectory: DirectoryProperty = objectFactory
.directoryProperty()
.apply {
override val destinationDirectory: DirectoryProperty
get() = objectFactory.directoryProperty().apply {
set(
destinationDirectory.map { dir ->
if (kotlinOptions.outputFile != null) {
projectLayout.dir(outputFileProperty.map { it.parentFile }).get()
destinationDirectory.flatMap { dir ->
if (kotlinOptions.outputFile == null) {
objectFactory.property(dir)
} else {
dir
projectLayout.dir(outputFileProperty.map { it.parentFile })
}
}
)
}
override fun skipCondition(): Boolean {
return !entryModule.get().asFile.exists()
}
@get:Internal
val rootCacheDirectory by lazy {
buildDir.resolve("klib/cache")
@@ -136,11 +136,7 @@ constructor(
binary.linkSyncTaskName
) { task ->
task.from(
project.layout.file(
binary.linkTask.flatMap { linkTask ->
linkTask.normalizedDestinationDirectory.map { it.asFile }
}
)
project.layout.file(binary.linkTask.flatMap { it.destinationDirectory.map { it.asFile } })
)
task.from(project.tasks.named(compilation.processResourcesTaskName))
@@ -18,7 +18,6 @@ import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
@@ -133,10 +132,7 @@ abstract class AbstractKotlinNativeCompile<
T : KotlinCommonToolOptions,
K : KotlinNativeCompilationData<*>,
M : CommonToolArguments
>
@Inject constructor(
private val objectFactory: ObjectFactory
): AbstractKotlinCompileTool<M>(objectFactory) {
> : AbstractKotlinCompileTool<M>() {
@get:Internal
abstract val compilation: K
@@ -153,6 +149,9 @@ abstract class AbstractKotlinNativeCompile<
@get:Internal
abstract val baseName: String
@get:Internal
protected val objects = project.objects
@get:Internal
protected val konanTarget by project.provider {
compilation.konanTarget
@@ -163,7 +162,7 @@ abstract class AbstractKotlinNativeCompile<
// Avoid resolving these dependencies during task graph construction when we can't build the target:
if (konanTarget.enabledOnCurrentHost)
compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project)
else objectFactory.fileCollection()
else objects.fileCollection()
}
@get:Classpath
@@ -173,7 +172,7 @@ abstract class AbstractKotlinNativeCompile<
@Deprecated("For native tasks use 'libraries' instead", ReplaceWith("libraries"))
override val classpath: ConfigurableFileCollection
get() = objectFactory.fileCollection().from(libraries)
get() = objects.fileCollection().from(libraries)
@get:Input
val target: String by project.provider { compilation.konanTarget.name }
@@ -210,7 +209,7 @@ abstract class AbstractKotlinNativeCompile<
@get:Internal
open val outputFile: Provider<File>
get() = destinationDirectory.flatMap {
get() = destinationDirectory.map {
val prefix = outputKind.prefix(konanTarget)
val suffix = outputKind.suffix(konanTarget)
val filename = "$prefix${baseName}$suffix".let {
@@ -223,7 +222,7 @@ abstract class AbstractKotlinNativeCompile<
}
}
objectFactory.property(it.file(filename).asFile)
it.file(filename).asFile
}
// endregion
@@ -310,9 +309,8 @@ abstract class KotlinNativeCompile
constructor(
@Internal
@Transient // can't be serialized for Gradle configuration cache
final override val compilation: KotlinNativeCompilationData<*>,
objectFactory: ObjectFactory
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>, StubK2NativeCompilerArguments>(objectFactory),
final override val compilation: KotlinNativeCompilationData<*>
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>, StubK2NativeCompilerArguments>(),
KotlinCompile<KotlinCommonOptions> {
@get:Input
@@ -465,9 +463,8 @@ abstract class KotlinNativeLink
@Inject
constructor(
@Internal
val binary: NativeBinary,
objectFactory: ObjectFactory
) : AbstractKotlinNativeCompile<KotlinCommonToolOptions, KotlinNativeCompilation, StubK2NativeCompilerArguments>(objectFactory) {
val binary: NativeBinary
) : AbstractKotlinNativeCompile<KotlinCommonToolOptions, KotlinNativeCompilation, StubK2NativeCompilerArguments>() {
@get:Internal
final override val compilation: KotlinNativeCompilation
get() = binary.compilation
@@ -477,13 +474,17 @@ constructor(
// Frameworks actively uses symlinks.
// Gradle build cache transforms symlinks into regular files https://guides.gradle.org/using-build-cache/#symbolic_links
outputs.cacheIf { outputKind != FRAMEWORK }
this.setSource(compilation.compileKotlinTask.outputFile)
includes.clear() // we need to include non '.kt' or '.kts' files
disallowSourceChanges()
}
override val destinationDirectory: DirectoryProperty = objectFactory.directoryProperty().apply {
@Internal // Taken into account by getSources().
val intermediateLibrary: Provider<File> = project.provider { compilation.compileKotlinTask.outputFile.get() }
override val sources: ConfigurableFileCollection = objects
.fileCollection()
.from(intermediateLibrary)
.apply { disallowChanges() }
override val destinationDirectory: DirectoryProperty = objects.directoryProperty().apply {
set(binary.outputDirectory)
}
@@ -552,7 +553,7 @@ constructor(
if (it is AbstractNativeLibrary) {
project.configurations.getByName(it.exportConfigurationName)
} else {
objectFactory.fileCollection()
objects.fileCollection()
}
}
}
@@ -651,7 +652,7 @@ constructor(
binaryOptions,
isStaticFramework,
exportLibraries.files.filterKlibsPassedToCompiler(),
sources.asFileTree.files.toList(),
listOf(intermediateLibrary.get()),
externalDependenciesArgs + cacheArgs
)
@@ -18,7 +18,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
import org.gradle.api.tasks.*
import org.gradle.work.InputChanges
@@ -47,10 +46,8 @@ import javax.inject.Inject
@CacheableTask
abstract class KotlinCompileCommon @Inject constructor(
override val kotlinOptions: KotlinMultiplatformCommonOptions,
workerExecutor: WorkerExecutor,
objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2MetadataCompilerArguments>(objectFactory),
KotlinCommonCompile {
workerExecutor: WorkerExecutor
) : AbstractKotlinCompile<K2MetadataCompilerArguments>(), KotlinCommonCompile {
class Configurator(compilation: KotlinCompilationData<*>) : AbstractKotlinCompile.Configurator<KotlinCompileCommon>(compilation) {
override fun configure(task: KotlinCompileCommon) {
@@ -88,7 +85,7 @@ abstract class KotlinCompileCommon @Inject constructor(
}
override val compilerRunner: Provider<GradleCompilerRunner> =
objectFactory.propertyWithConvention(
objects.propertyWithConvention(
gradleCompileTaskProvider.map {
GradleCompilerRunnerWithWorkers(
it,
@@ -104,6 +101,9 @@ abstract class KotlinCompileCommon @Inject constructor(
override fun createCompilerArgs(): K2MetadataCompilerArguments =
K2MetadataCompilerArguments()
override fun getSourceRoots(): SourceRoots =
SourceRoots.KotlinOnly.create(sources, sourceFilesExtensions.get())
override fun setupCompilerArgs(args: K2MetadataCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
args.apply { fillDefaultValues() }
super.setupCompilerArgs(args, defaultsOnly = defaultsOnly, ignoreClasspathResolutionErrors = ignoreClasspathResolutionErrors)
@@ -132,14 +132,14 @@ abstract class KotlinCompileCommon @Inject constructor(
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:InputFiles
internal val refinesMetadataPaths: ConfigurableFileCollection = objectFactory.fileCollection()
internal val refinesMetadataPaths: ConfigurableFileCollection = objects.fileCollection()
@get:Internal
internal val expectActualLinker = objectFactory.property(Boolean::class.java)
internal val expectActualLinker = objects.property(Boolean::class.java)
override fun callCompilerAsync(
args: K2MetadataCompilerArguments,
kotlinSources: Set<File>,
sourceRoots: SourceRoots,
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
) {
@@ -152,7 +152,7 @@ abstract class KotlinCompileCommon @Inject constructor(
outputFiles = allOutputFiles()
)
compilerRunner.runMetadataCompilerAsync(
kotlinSources.toList(),
sourceRoots.kotlinSourceFiles.files.toList(),
commonSourceSet.files.toList(),
args,
environment
@@ -16,12 +16,11 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.*
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import org.jetbrains.kotlin.cli.common.arguments.DevModeOverwritingStrategies
import org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments
@@ -32,22 +31,18 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptionsImpl
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
import org.jetbrains.kotlin.gradle.utils.canonicalPathWithoutExtension
import org.jetbrains.kotlin.gradle.utils.fileExtensionCasePermutations
import java.io.File
import javax.inject.Inject
@CacheableTask
abstract class KotlinJsDce @Inject constructor(
objectFactory: ObjectFactory
) : AbstractKotlinCompileTool<K2JSDceArguments>(objectFactory),
KotlinJsDce {
abstract class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), KotlinJsDce {
init {
cacheOnlyIfEnabledForKotlin()
include("js".fileExtensionCasePermutations().map { "**/*.$it" })
}
@get:Internal
internal val objects = project.objects
override fun createCompilerArgs(): K2JSDceArguments = K2JSDceArguments()
override fun setupCompilerArgs(args: K2JSDceArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
@@ -75,18 +70,9 @@ abstract class KotlinJsDce @Inject constructor(
@Input
var jvmArgs = mutableListOf<String>()
// Source could be empty, while classpath not
@get:Incremental
@get:InputFiles
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
override val sources: FileCollection = super.sources
@get:Incremental
@get:InputFiles
abstract override val classpath: ConfigurableFileCollection
private val buildDir = project.layout.buildDirectory
private val buildDir by lazy {
project.buildDir
}
private val isDevMode
get() = dceOptions.devMode || "-dev-mode" in dceOptions.freeCompilerArgs
@@ -109,7 +95,7 @@ abstract class KotlinJsDce @Inject constructor(
} else {
classpath.asFileTree.files
}
// TODO: use PatternFilterable here!
val inputFiles = sources.asFileTree.files.plus(classpathFiles)
.filter { !kotlinFilesOnly || isDceCandidate(it) }
.map { it.path }
@@ -134,7 +120,7 @@ abstract class KotlinJsDce @Inject constructor(
K2JSDce::class.java.name,
defaultCompilerClasspath,
log,
buildDir.get().asFile,
buildDir,
jvmArgs
)
throwGradleExceptionIfError(exitCode, KotlinCompilerExecutionStrategy.OUT_OF_PROCESS)
@@ -0,0 +1,109 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logger
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.utils.isJavaFile
import org.jetbrains.kotlin.gradle.utils.isKotlinFile
import org.jetbrains.kotlin.gradle.utils.isParentOf
import java.io.File
import java.util.concurrent.Callable
internal sealed class SourceRoots(val kotlinSourceFiles: FileCollection) {
private companion object {
fun dumpPaths(files: Iterable<File>): String =
"[${files.map { it.canonicalPath }.sorted().joinToString(prefix = "\n\t", separator = ",\n\t")}]"
}
open fun log(taskName: String, logger: Logger) {
logger.kotlinDebug { "$taskName source roots: ${dumpPaths(kotlinSourceFiles.files)}" }
}
class ForJvm constructor(
kotlinSourceFiles: FileCollection,
val javaSourceRoots: FileCollection
) : SourceRoots(kotlinSourceFiles) {
companion object {
fun create(
taskSource: FileCollection,
sourceRoots: FilteringSourceRootsContainer,
sourceFilesExtensions: List<String>
): ForJvm {
return ForJvm(
taskSource.filter { it.isKotlinFile(sourceFilesExtensions) },
sourceRoots.sourceRoots.filterJavaRoots(
taskSource.filter { it.isJavaFile() }
)
)
}
private fun FileCollection.filterJavaRoots(
sourceDirs: FileCollection
): FileCollection = filter { sourceRoot ->
sourceDirs.asSequence().map { it.parentFile }.any { sourceRoot.isParentOf(it) }
}
}
override fun log(taskName: String, logger: Logger) {
super.log(taskName, logger)
logger.kotlinDebug { "$taskName java source roots: ${dumpPaths(javaSourceRoots.files)}" }
}
}
class KotlinOnly(kotlinSourceFiles: FileCollection) : SourceRoots(kotlinSourceFiles) {
companion object {
fun create(
taskSource: FileCollection,
sourceFilesExtensions: List<String>
) = KotlinOnly(
taskSource.filter { it.isKotlinFile(sourceFilesExtensions) }
)
}
}
}
internal class FilteringSourceRootsContainer(
private val objectFactory: ObjectFactory,
val filter: (File) -> Boolean = { true }
) {
private val sourceContainers: MutableList<Any> = mutableListOf()
private fun getFilteredSourceRootsFrom(any: Any) = objectFactory.fileCollection().from(Callable {
val resultItems = mutableListOf<Any>()
fun getRootsFrom(item: Any?) {
when (item) {
is SourceDirectorySet -> resultItems.add(item.sourceDirectories)
is Callable<*> -> getRootsFrom(item.call())
is Provider<*> -> if (item.isPresent) getRootsFrom(item.get())
is FileCollection -> resultItems.add(item)
is Iterable<*> -> item.forEach { getRootsFrom(it) }
is Array<*> -> item.forEach { getRootsFrom(it) }
is Any /* not null */ -> resultItems.add(item)
}
}
getRootsFrom(any)
resultItems
}).filter(filter)
val sourceRoots: FileCollection
get() = getFilteredSourceRootsFrom(sourceContainers)
fun clear() {
sourceContainers.clear()
}
fun set(source: Any): FileCollection {
clear()
return add(source)
}
fun add(vararg sources: Any): FileCollection {
sourceContainers.addAll(sources.toList())
return getFilteredSourceRootsFrom(sources)
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle.tasks
import groovy.lang.Closure
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
@@ -20,12 +19,10 @@ import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.util.PatternFilterable
import org.gradle.api.tasks.util.PatternSet
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
@@ -60,10 +57,13 @@ 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.ChangedFiles
import org.jetbrains.kotlin.incremental.ClasspathChanges
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotDisabled
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnabled.*
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnabled.IncrementalRun.*
import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles
import org.jetbrains.kotlin.incremental.IncrementalCompilerRunner
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.utils.JsLibraryUtils
@@ -77,44 +77,24 @@ const val USING_JVM_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JVM incremen
const val USING_JS_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JS incremental compilation"
const val USING_JS_IR_BACKEND_MESSAGE = "Using Kotlin/JS IR backend"
abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constructor(
objectFactory: ObjectFactory
) : DefaultTask(),
PatternFilterable,
abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
: DefaultTask(),
//PatternFilterable,
CompilerArgumentAwareWithInput<T>,
TaskWithLocalState {
private val patternFilterable = PatternSet()
init {
patternFilterable.include(
DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS.flatMap { ext -> ext.fileExtensionCasePermutations().map { "**/*.$it" } }
)
}
private val sourceFiles = objectFactory.fileCollection()
@get:InputFiles
@get:SkipWhenEmpty
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
open val sources: FileCollection = objectFactory.fileCollection()
.from(
{ sourceFiles.asFileTree.matching(patternFilterable) }
)
@Deprecated("Use PatternFilterable methods to configure sources")
@get:Input
val sourceFilesExtensions: ListProperty<String> = objectFactory
.listProperty(String::class.java)
.convention(DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS)
abstract val sources: ConfigurableFileCollection
/**
* Sets the source for this task.
* The given source object is evaluated as per [org.gradle.api.Project.files].
*/
open fun setSource(source: Any) {
sourceFiles.from(source)
sources.from(source)
}
/**
@@ -122,57 +102,7 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constr
* The given source object is evaluated as per [org.gradle.api.Project.files].
*/
open fun setSource(vararg source: Any) {
sourceFiles.from(source)
}
fun disallowSourceChanges() {
sourceFiles.disallowChanges()
}
@Internal
final override fun getIncludes(): MutableSet<String> = patternFilterable.includes
@Internal
final override fun getExcludes(): MutableSet<String> = patternFilterable.excludes
final override fun setIncludes(includes: Iterable<String>): PatternFilterable = also {
patternFilterable.setIncludes(includes)
}
final override fun setExcludes(excludes: Iterable<String>): PatternFilterable = also {
patternFilterable.setExcludes(excludes)
}
final override fun include(vararg includes: String?): PatternFilterable = also {
patternFilterable.include(*includes)
}
final override fun include(includes: Iterable<String>): PatternFilterable = also {
patternFilterable.include(includes)
}
final override fun include(includeSpec: Spec<FileTreeElement>): PatternFilterable = also {
patternFilterable.include(includeSpec)
}
final override fun include(includeSpec: Closure<*>): PatternFilterable = also {
patternFilterable.include(includeSpec)
}
final override fun exclude(vararg excludes: String?): PatternFilterable = also {
patternFilterable.exclude(*excludes)
}
final override fun exclude(excludes: Iterable<String>): PatternFilterable = also {
patternFilterable.exclude(excludes)
}
final override fun exclude(excludeSpec: Spec<FileTreeElement>): PatternFilterable = also {
patternFilterable.exclude(excludeSpec)
}
final override fun exclude(excludeSpec: Closure<*>): PatternFilterable = also {
patternFilterable.exclude(excludeSpec)
sources.from(source)
}
@get:Classpath
@@ -257,9 +187,7 @@ abstract class GradleCompileTaskProvider @Inject constructor(
)
}
abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constructor(
objectFactory: ObjectFactory
) : AbstractKotlinCompileTool<T>(objectFactory),
abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotlinCompileTool<T>(),
CompileUsingKotlinDaemonWithNormalization {
open class Configurator<T : AbstractKotlinCompile<*>>(protected val compilation: KotlinCompilationData<*>) : TaskConfigurator<T> {
@@ -310,13 +238,16 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
@get:Inject
internal abstract val fileSystemOperations: FileSystemOperations
@get:Internal
protected val objects: ObjectFactory = project.objects
// avoid creating directory in getter: this can lead to failure in parallel build
@get:OutputDirectory
internal val taskBuildCacheableOutputDirectory: DirectoryProperty = objectFactory.directoryProperty()
internal val taskBuildCacheableOutputDirectory: DirectoryProperty = objects.directoryProperty()
// avoid creating directory in getter: this can lead to failure in parallel build
@get:LocalState
internal val taskBuildLocalStateDirectory: DirectoryProperty = objectFactory.directoryProperty()
internal val taskBuildLocalStateDirectory: DirectoryProperty = objects.directoryProperty()
@get:Internal
internal val buildHistoryFile
@@ -346,18 +277,20 @@ 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 val useModuleDetection: Property<Boolean> = objects.property(Boolean::class.java).value(false)
@get:Internal
protected val multiModuleICSettings: MultiModuleICSettings
get() = MultiModuleICSettings(buildHistoryFile.get().asFile, useModuleDetection.get())
@get:Classpath
open val pluginClasspath: ConfigurableFileCollection = objectFactory.fileCollection()
open val pluginClasspath: ConfigurableFileCollection = objects.fileCollection()
@get:Internal
internal val pluginOptions = CompilerPluginOptions()
@get:Input
val sourceFilesExtensions: ListProperty<String> = objects.listProperty(String::class.java).value(DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS)
/**
* Plugin Data provided by [KpmCompilerPlugin]
@@ -369,52 +302,52 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
// Input is needed to force rebuild even if source files are not changed
@get:Input
internal val coroutines: Property<Coroutines> = objectFactory.property(Coroutines::class.java)
internal val coroutines: Property<Coroutines> = objects.property(Coroutines::class.java)
@get:Internal
internal val javaOutputDir: DirectoryProperty = objectFactory.directoryProperty()
internal val javaOutputDir: DirectoryProperty = objects.directoryProperty()
@get:Internal
internal val sourceSetName: Property<String> = objectFactory.property(String::class.java)
internal val sourceSetName: Property<String> = objects.property(String::class.java)
@get:InputFiles
@get:IgnoreEmptyDirectories
@get:Incremental
@get:PathSensitive(PathSensitivity.RELATIVE)
internal val commonSourceSet: ConfigurableFileCollection = objectFactory.fileCollection()
internal val commonSourceSet: ConfigurableFileCollection = objects.fileCollection()
@get:Input
internal val moduleName: Property<String> = objectFactory.property(String::class.java)
internal val moduleName: Property<String> = objects.property(String::class.java)
@get:Internal
val abiSnapshotFile
get() = taskBuildCacheableOutputDirectory.file(IncrementalCompilerRunner.ABI_SNAPSHOT_FILE_NAME)
@get:Input
val abiSnapshotRelativePath: Property<String> = objectFactory.property(String::class.java).value(
val abiSnapshotRelativePath: Property<String> = objects.property(String::class.java).value(
//TODO update to support any jar changes
"$name/${IncrementalCompilerRunner.ABI_SNAPSHOT_FILE_NAME}"
)
@get:Internal
internal val friendSourceSets = objectFactory.listProperty(String::class.java)
internal val friendSourceSets = objects.listProperty(String::class.java)
@get:Internal // takes part in the compiler arguments
val friendPaths: ConfigurableFileCollection = objectFactory.fileCollection()
val friendPaths: ConfigurableFileCollection = objects.fileCollection()
private val kotlinLogger by lazy { GradleKotlinLogger(logger) }
abstract override val kotlinDaemonJvmArguments: ListProperty<String>
@get:Internal
protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objectFactory
protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objects
.property(
objectFactory.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
objects.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
)
@get:Internal
internal open val compilerRunner: Provider<GradleCompilerRunner> =
objectFactory.propertyWithConvention(
objects.propertyWithConvention(
gradleCompileTaskProvider.map {
GradleCompilerRunner(
it,
@@ -477,7 +410,8 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
buildMetricsReporterService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) }
}
protected open fun skipCondition(): Boolean = sources.isEmpty
protected open fun skipCondition(): Boolean =
getSourceRoots().kotlinSourceFiles.isEmpty()
private val projectDir = project.rootProject.projectDir
@@ -493,7 +427,8 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
) {
val allKotlinSources = sources.asFileTree.files
val sourceRoots = getSourceRoots()
val allKotlinSources = sourceRoots.kotlinSourceFiles
logger.kotlinDebug { "All kotlin sources: ${allKotlinSources.pathsAsStringRelativeTo(projectDir)}" }
@@ -503,12 +438,13 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
return
}
sourceRoots.log(this.name, logger)
val args = prepareCompilerArguments()
taskBuildCacheableOutputDirectory.get().asFile.mkdirs()
taskBuildLocalStateDirectory.get().asFile.mkdirs()
callCompilerAsync(
args,
allKotlinSources,
sourceRoots,
inputChanges,
taskOutputsBackup
)
@@ -536,19 +472,22 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
}
}
@Internal
internal abstract fun getSourceRoots(): SourceRoots
/**
* Compiler might be executed asynchronously. Do not do anything requiring end of compilation after this function is called.
* @see [GradleKotlinCompilerWork]
*/
internal abstract fun callCompilerAsync(
args: T,
kotlinSources: Set<File>,
sourceRoots: SourceRoots,
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
)
@get:Input
internal val multiPlatformEnabled: Property<Boolean> = objectFactory.property(Boolean::class.java)
internal val multiPlatformEnabled: Property<Boolean> = objects.property(Boolean::class.java)
@get:Internal
internal val abstractKotlinCompileArgumentsContributor by lazy {
@@ -597,9 +536,8 @@ internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T>
@CacheableTask
abstract class KotlinCompile @Inject constructor(
override val kotlinOptions: KotlinJvmOptions,
workerExecutor: WorkerExecutor,
private val objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2JVMCompilerArguments>(objectFactory),
workerExecutor: WorkerExecutor
) : AbstractKotlinCompile<K2JVMCompilerArguments>(),
KotlinJvmCompile,
UsesKotlinJavaToolchain {
@@ -697,7 +635,16 @@ abstract class KotlinCompile @Inject constructor(
}
@get:Internal
internal val parentKotlinOptionsImpl: Property<KotlinJvmOptions> = objectFactory.property(KotlinJvmOptions::class.java)
internal val parentKotlinOptionsImpl: Property<KotlinJvmOptions> = objects.property(KotlinJvmOptions::class.java)
@get:Internal
@field:Transient
internal open val sourceRootsContainer = FilteringSourceRootsContainer(objects)
private val jvmSourceRoots by project.provider {
// serialize in the task state for configuration caching; avoid building anew in task execution, as it may access the project model
SourceRoots.ForJvm.create(sources, sourceRootsContainer, sourceFilesExtensions.get())
}
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
*
@@ -744,29 +691,23 @@ abstract class KotlinCompile @Inject constructor(
}
override val incrementalProps: List<FileCollection>
get() = listOf(
sources,
javaSources,
commonSourceSet,
classpathSnapshotProperties.classpath,
classpathSnapshotProperties.classpathSnapshot
)
get() = listOf(sources, commonSourceSet, classpathSnapshotProperties.classpath, classpathSnapshotProperties.classpathSnapshot)
// Exclude classpathSnapshotDir from TaskOutputsBackup (see TaskOutputsBackup's kdoc for more info). */
override val taskOutputsBackupExcludes: List<File>
get() = classpathSnapshotProperties.classpathSnapshotDir.orNull?.asFile?.let { listOf(it) } ?: emptyList()
@get:Internal
internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objectFactory
internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objects
.propertyWithNewInstance({ this })
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast()
@get:Internal
override val compilerRunner: Provider<GradleCompilerRunner> = objectFactory.propertyWithConvention(
override val compilerRunner: Provider<GradleCompilerRunner> = objects.propertyWithConvention(
// From Gradle 6.6 better to replace flatMap with provider.zip()
defaultKotlinJavaToolchain.flatMap { toolchain ->
objectFactory.property(gradleCompileTaskProvider.map {
objects.property(gradleCompileTaskProvider.map {
GradleCompilerRunnerWithWorkers(
it,
toolchain.currentJvmJdkToolsJar.orNull,
@@ -821,13 +762,17 @@ abstract class KotlinCompile @Inject constructor(
KotlinJvmCompilerArgumentsContributor(KotlinJvmCompilerArgumentsProvider(this))
}
override fun getSourceRoots(): SourceRoots.ForJvm = jvmSourceRoots
override fun callCompilerAsync(
args: K2JVMCompilerArguments,
kotlinSources: Set<File>,
sourceRoots: SourceRoots,
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
) {
validateKotlinAndJavaHasSameTargetCompatibility(args, kotlinSources)
sourceRoots as SourceRoots.ForJvm
validateKotlinAndJavaHasSameTargetCompatibility(args, sourceRoots)
val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors)
val outputItemCollector = OutputItemsCollectorImpl()
@@ -846,7 +791,7 @@ abstract class KotlinCompile @Inject constructor(
)
} else null
@Suppress("ConvertArgumentToSet", "DEPRECATION")
@Suppress("ConvertArgumentToSet")
val environment = GradleCompilerEnvironment(
defaultCompilerClasspath, messageCollector, outputItemCollector,
// In the incremental compiler, outputFiles will be cleaned on rebuild. However, because classpathSnapshotDir is not included in
@@ -858,12 +803,10 @@ abstract class KotlinCompile @Inject constructor(
incrementalCompilationEnvironment = icEnv,
kotlinScriptExtensions = sourceFilesExtensions.get().toTypedArray()
)
logger.info("Kotlin source files: ${kotlinSources.joinToString()}")
logger.info("Java source files: ${javaSources.files.joinToString()}")
compilerRunner.runJvmCompilerAsync(
kotlinSources.toList(),
sourceRoots.kotlinSourceFiles.files.toList(),
commonSourceSet.toList(),
javaSources.files, // we need here only directories where Java sources are located
sourceRoots.javaSourceRoots,
javaPackagePrefix,
args,
environment,
@@ -872,12 +815,8 @@ abstract class KotlinCompile @Inject constructor(
)
}
private fun validateKotlinAndJavaHasSameTargetCompatibility(
args: K2JVMCompilerArguments,
kotlinSources: Set<File>
) {
val mixedSourcesArePresent = !associatedJavaCompileTaskSources.isEmpty &&
kotlinSources.isNotEmpty()
private fun validateKotlinAndJavaHasSameTargetCompatibility(args: K2JVMCompilerArguments, sourceRoots: SourceRoots.ForJvm) {
val mixedSourcesArePresent = !associatedJavaCompileTaskSources.isEmpty && !sourceRoots.kotlinSourceFiles.isEmpty
if (mixedSourcesArePresent) {
associatedJavaCompileTaskTargetCompatibility.orNull?.let { targetCompatibility ->
val normalizedJavaTarget = when (targetCompatibility) {
@@ -915,7 +854,7 @@ abstract class KotlinCompile @Inject constructor(
if (it is AbstractCompile &&
it !is JavaCompile &&
it !is AbstractKotlinCompile<*> &&
javaOutputDir.get().asFile.isParentOf(it.destinationDirectory.get().asFile)
javaOutputDir.get().asFile.isParentOf(it.destinationDir)
) {
illegalTaskOrNull = illegalTaskOrNull ?: it
}
@@ -924,7 +863,7 @@ abstract class KotlinCompile @Inject constructor(
val illegalTask = illegalTaskOrNull!!
logger.info(
"Kotlin inter-project IC is disabled: " +
"unknown task '$illegalTask' destination dir ${illegalTask.destinationDirectory.get().asFile} " +
"unknown task '$illegalTask' destination dir ${illegalTask.destinationDir} " +
"intersects with java destination dir $javaOutputDir"
)
}
@@ -932,34 +871,15 @@ abstract class KotlinCompile @Inject constructor(
}
}
private val javaSourceFiles = objectFactory.fileCollection()
private fun javaFilesPatternFilter(patternFilterable: PatternFilterable) {
patternFilterable.include(
"java".fileExtensionCasePermutations().map { "**/*.$it" }
)
}
@get:Incremental
@get:InputFiles
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
open val javaSources: FileCollection = objectFactory.fileCollection()
.from(
javaSourceFiles
.asFileTree
.matching(::javaFilesPatternFilter)
)
// override setSource to track Java sources as well
// override setSource to track source directory sets and files (for generated android folders)
override fun setSource(source: Any) {
javaSourceFiles.from(source)
sourceRootsContainer.set(source)
super.setSource(source)
}
// override source to track Java sources as well
// override source to track source directory sets and files (for generated android folders)
override fun setSource(vararg source: Any) {
javaSourceFiles.from(*source)
sourceRootsContainer.add(*source)
super.setSource(*source)
}
@@ -993,8 +913,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
override val kotlinOptions: KotlinJsOptions,
objectFactory: ObjectFactory,
workerExecutor: WorkerExecutor
) : AbstractKotlinCompile<K2JSCompilerArguments>(objectFactory),
KotlinJsCompile {
) : AbstractKotlinCompile<K2JSCompilerArguments>(), KotlinJsCompile {
init {
incremental = true
@@ -1078,7 +997,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
abstract val optionalOutputFile: RegularFileProperty
override val compilerRunner: Provider<GradleCompilerRunner> =
objectFactory.propertyWithConvention(
objects.propertyWithConvention(
gradleCompileTaskProvider.map {
GradleCompilerRunnerWithWorkers(
it,
@@ -1112,6 +1031,8 @@ abstract class Kotlin2JsCompile @Inject constructor(
(kotlinOptions as KotlinJsOptionsImpl).updateArguments(args)
}
override fun getSourceRoots() = SourceRoots.KotlinOnly.create(sources, sourceFilesExtensions.get())
@get:InputFiles
@get:IgnoreEmptyDirectories
@get:Incremental
@@ -1200,11 +1121,14 @@ abstract class Kotlin2JsCompile @Inject constructor(
override fun callCompilerAsync(
args: K2JSCompilerArguments,
kotlinSources: Set<File>,
sourceRoots: SourceRoots,
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
) {
sourceRoots as SourceRoots.KotlinOnly
logger.debug("Calling compiler")
//destinationDir.mkdirs()
if (kotlinOptions.isIrBackendEnabled()) {
logger.info(USING_JS_IR_BACKEND_MESSAGE)
@@ -1250,7 +1174,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
)
processArgs(args)
compilerRunner.runJsCompilerAsync(
kotlinSources.toList(),
sourceRoots.kotlinSourceFiles.files.toList(),
commonSourceSet.toList(),
args,
environment,
@@ -18,32 +18,6 @@ internal fun File.isJavaFile() =
internal fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
!isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
/**
* Create all possible case-sensitive permutations for given [String].
*
* Useful to create for [org.gradle.api.tasks.util.PatternFilterable] Ant-style patterns.
*/
@OptIn(ExperimentalStdlibApi::class)
internal fun String.fileExtensionCasePermutations(): List<String> {
val lowercaseInput = lowercase()
val length = lowercaseInput.length
// number of permutations is 2^n
val max = 1 shl length
val result = mutableListOf<String>()
var combination: CharArray
for (i in 0 until max) {
combination = lowercaseInput.toCharArray()
for (j in 0 until length) {
// If j-th bit is set, we convert it to upper case
if (((i shr j) and 1) == 1) {
combination[j] = combination[j].uppercaseChar()
}
}
result.add(String(combination))
}
return result
}
internal fun File.relativeOrCanonical(base: File): String =
relativeToOrNull(base)?.path ?: canonicalPath