Internal visibility between common source sets in Gradle (KT-37264)

In KotlinCompileCommon, pass the friendPaths and refinesPaths arguments

In KotlinNativeCompilation, add both friend and refined dependencies as
friends for now.

In getVisibleSourceSetsFromAssociateCompilations, exclude the metadata
compilations to avoid incorrect results (those compilations don't have
proper kotlin

Issue #KT-37264 Fixed
This commit is contained in:
Sergey Igushkin
2020-03-05 23:26:36 +03:00
parent 3858c8e1f8
commit 90f4f5db26
7 changed files with 56 additions and 2 deletions
@@ -11,6 +11,8 @@ fun libCommonMainTopLevelFun(): Int {
return 2 return 2
} }
fun libCommonMainInternalFun() = Unit
fun main() { fun main() {
} }
@@ -4,6 +4,7 @@ actual class LibCommonMainExpect : LibCommonMainIface {
actual fun libCommonMainExpectFun(): Unit { actual fun libCommonMainExpectFun(): Unit {
println("actualized in jvmAndJsMain") println("actualized in jvmAndJsMain")
libCommonMainTopLevelFun() libCommonMainTopLevelFun()
libCommonMainInternalFun()
} }
fun additionalFunInJvmAndJsActual() { fun additionalFunInJvmAndJsActual() {
@@ -2,4 +2,5 @@ package com.h0tk3y.hmpp.klib.demo
fun main() { fun main() {
libCommonMainTopLevelFun() libCommonMainTopLevelFun()
libCommonMainInternalFun()
} }
@@ -12,6 +12,7 @@ actual class LibCommonMainExpect : LibCommonMainIface {
println("actualized in iosMain") println("actualized in iosMain")
libCommonMainTopLevelFun() libCommonMainTopLevelFun()
println(CArrayPointer::class) println(CArrayPointer::class)
libCommonMainInternalFun()
} }
fun additionalFunInLinuxActual() { fun additionalFunInLinuxActual() {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle.plugin.mpp package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
@@ -12,6 +13,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
interface KotlinMetadataCompilation<T : KotlinCommonOptions> : KotlinCompilation<T> interface KotlinMetadataCompilation<T : KotlinCommonOptions> : KotlinCompilation<T>
@@ -27,4 +29,11 @@ class KotlinCommonCompilation(
get() = PropertiesProvider(target.project).enableGranularSourceSetsMetadata == true && !forceCompilationToKotlinMetadata get() = PropertiesProvider(target.project).enableGranularSourceSetsMetadata == true && !forceCompilationToKotlinMetadata
internal var forceCompilationToKotlinMetadata: Boolean = false internal var forceCompilationToKotlinMetadata: Boolean = false
override val friendArtifacts: FileCollection
get() = super.friendArtifacts.plus(run {
val project = target.project
val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(target.project, defaultSourceSet)
project.files(friendSourceSets.mapNotNull { target.compilations.findByName(it.name)?.output?.classesDirs })
})
} }
@@ -11,6 +11,7 @@ import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
@@ -18,6 +19,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
@@ -96,4 +99,17 @@ class KotlinNativeCompilation(
class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, name: String) : class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, name: String) :
AbstractKotlinNativeCompilation(target, HostManager.host, name), AbstractKotlinNativeCompilation(target, HostManager.host, name),
KotlinMetadataCompilation<KotlinCommonOptions> KotlinMetadataCompilation<KotlinCommonOptions> {
override val friendArtifacts: FileCollection
get() = super.friendArtifacts.plus(run {
val project = target.project
val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(project, defaultSourceSet).toMutableSet().apply {
// TODO: implement proper dependsOn/refines compiler args for Kotlin/Native and pass the dependsOn klibs separately;
// But for now, those dependencies don't have any special semantics, so passing all them as friends works, too
addAll(defaultSourceSet.getSourceSetHierarchy())
remove(defaultSourceSet)
}
project.files(friendSourceSets.mapNotNull { target.compilations.findByName(it.name)?.output?.classesDirs })
})
}
@@ -18,6 +18,9 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
@@ -27,8 +30,10 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataCompilation import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
import org.jetbrains.kotlin.incremental.ChangedFiles import org.jetbrains.kotlin.incremental.ChangedFiles
import java.io.File import java.io.File
@@ -65,11 +70,30 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
with(args) { with(args) {
classpath = classpathList.joinToString(File.pathSeparator) classpath = classpathList.joinToString(File.pathSeparator)
destination = destinationDir.canonicalPath destination = destinationDir.canonicalPath
friendPaths = this@KotlinCompileCommon.friendPaths
refinesPaths = refinesMetadataPaths.map { it.absolutePath }.toTypedArray()
} }
kotlinOptionsImpl.updateArguments(args) kotlinOptionsImpl.updateArguments(args)
} }
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
val target = taskData.compilation.target
return sourceSets
.mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs }
.flatten()
}
private val defaultKotlinSourceSet: KotlinSourceSet
get() = taskData.compilation.defaultSourceSet
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
internal val refinesMetadataPaths by project.provider {
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.getSourceSetHierarchy().minus(defaultKotlinSourceSet))
}
override fun callCompilerAsync(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) { override fun callCompilerAsync(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
val messageCollector = GradlePrintingMessageCollector(logger) val messageCollector = GradlePrintingMessageCollector(logger)
val outputItemCollector = OutputItemsCollectorImpl() val outputItemCollector = OutputItemsCollectorImpl()