Reimplement friend task/friend paths using associated compilations

Replace the old ad-hoc task matching mechanism used for connecting the
compilation tasks that need to share internal visibility with an
implementation based on the associate compilations and compilation
outputs rather than `destinationDir`s of the tasks.

The only place that still requires ad-hoc friend paths is the Android
instrumented tests compiling against the JAR of the main variant, not
its classes dirs. Support that with `friendArtifacts`.

Issue #KT-17630 Fixed
Issue #KT-20760 Fixed
This commit is contained in:
Sergey Igushkin
2019-08-23 16:45:55 +03:00
parent c4d9c4cee4
commit d1016f0221
22 changed files with 223 additions and 196 deletions
@@ -2041,4 +2041,31 @@ class NewMultiplatformIT : BaseGradleIT() {
assertNotContains(DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX)
}
}
@Test
fun testAssociateCompilations() = with(Project("new-mpp-associate-compilations")) {
setupWorkingDir()
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
val tasks = listOf("jvm", "js", nativeHostTargetName).map { ":compileIntegrationTestKotlin${it.capitalize()}" }
build(*tasks.toTypedArray()) {
assertSuccessful()
assertTasksExecuted(*tasks.toTypedArray())
// JVM:
checkBytecodeContains(
projectDir.resolve("build/classes/kotlin/jvm/integrationTest/com/example/HelloIntegrationTest.class"),
"Hello.internalFun\$new_mpp_associate_compilations",
"HelloTest.internalTestFun\$new_mpp_associate_compilations"
)
assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations.kotlin_module")
// JS:
assertFileExists("build/classes/kotlin/js/integrationTest/new-mpp-associate-compilations_integrationTest.js")
// Native:
assertFileExists("build/classes/kotlin/$nativeHostTargetName/integrationTest/integrationTest.klib")
}
}
}
@@ -34,9 +34,7 @@ kotlin.target.compilations {
val benchmark by creating {
defaultSourceSet.dependencies {
implementation(main.compileDependencyFiles + main.output.allOutputs)
runtimeOnly(main.runtimeDependencyFiles)
associateWith(main)
implementation(kotlin("reflect"))
}
}
@@ -3,6 +3,7 @@ package com.example
fun main() {
val a = A()
val f = a::f
internalFun()
f()
println("${a::f.name} ran at the speed of light")
}
@@ -2,4 +2,6 @@ package com.example
class A {
fun f(): String = "hello".also(::println)
}
}
fun internalFun() = 1
@@ -0,0 +1,56 @@
plugins {
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
}
repositories {
mavenLocal()
jcenter()
}
kotlin {
sourceSets {
getByName("commonMain") {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
getByName("commonTest") {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
create("commonIntegrationTest")
}
jvm {
compilations["main"].defaultSourceSet.dependencies {
implementation(kotlin("stdlib"))
}
compilations["test"].defaultSourceSet.dependencies {
implementation(kotlin("test-junit"))
}
}
js {
compilations["main"].defaultSourceSet.dependencies {
implementation(kotlin("stdlib-js"))
}
compilations["test"].defaultSourceSet.dependencies {
implementation(kotlin("test-js"))
}
}
mingwX64("mingw64") {}
linuxX64("linux64") {}
macosX64("macos64") {}
targets.matching { it.name != "metadata" }.all {
compilations.create("integrationTest") {
associateWith(compilations["test"])
defaultSourceSet.dependsOn(sourceSets["commonIntegrationTest"])
}
}
}
@@ -0,0 +1,8 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
rootProject.name = "new-mpp-associate-compilations"
@@ -0,0 +1,24 @@
package com.example
import kotlin.test.Test
class HelloIntegrationTest {
@Test
fun test(): Unit = Hello().run {
hello()
internalFun()
HelloTest().run {
test()
internalTestFun()
}
}
@Test
fun secondTest() = Unit
@Test
fun thirdTest() = Unit
}
fun topLevelMemberToMakeTheCompilerGenerateTheModuleFile() = 1
@@ -0,0 +1,6 @@
package com.example
class Hello {
fun hello() = 0
internal fun internalFun() = 1
}
@@ -0,0 +1,19 @@
package com.example
import kotlin.test.Test
class HelloTest {
@Test
fun test(): Unit = Hello().run {
hello()
internalFun()
}
@Test
fun secondTest() = Unit
@Test
fun thirdTest() = Unit
internal fun internalTestFun() = 1
}