diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AssociatedCompilationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AssociatedCompilationIT.kt new file mode 100644 index 00000000000..28ebce8bfe7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AssociatedCompilationIT.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2010-2023 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 + +import org.gradle.api.logging.LogLevel +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.testbase.* +import org.jetbrains.kotlin.gradle.util.replaceFirst +import org.jetbrains.kotlin.gradle.util.replaceText +import org.junit.jupiter.api.DisplayName + +@DisplayName("Incremental scenarios with associated compilation") +class AssociatedCompilationIT : KGPBaseTest() { + override val defaultBuildOptions: BuildOptions + get() = super.defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) + + @JvmGradlePluginTests + @DisplayName("Rebuild forced if associated compilation changes") + @GradleTest + fun testRebuildOnAssociatedCompilationChange(gradleVersion: GradleVersion) { + val project = getBaseProject(gradleVersion) + + val testSrc = project.kotlinSourcesDir("integrationTest").resolve("test.kt") + val utilSrc = project.kotlinSourcesDir("main").resolve("util.kt") + + project.build("compileIntegrationTestKotlin") { + assertCompiledKotlinSources(listOf(testSrc, utilSrc).relativizeTo(project.projectPath), output) + } + + project.buildGradle.replaceFirst("associateWith(getByName(\"main\"))", "") + + project.buildAndFail("compileIntegrationTestKotlin") { + assertTasksFailed(":compileIntegrationTestKotlin") + assertOutputContains("Cannot access 'fun doWork(): Int': it is internal in file") + } + } + + @JvmGradlePluginTests + @DisplayName("Rebuild after used internal ABI change in associated compilation") + @GradleTest + fun testRebuildOnUsedApiChangeInAssociatedCompilation(gradleVersion: GradleVersion) { + val project = getBaseProject(gradleVersion) + + val testSrc = project.kotlinSourcesDir("integrationTest").resolve("test.kt") + val utilSrc = project.kotlinSourcesDir("main").resolve("util.kt") + + project.build("compileIntegrationTestKotlin") + utilSrc.replaceFirst("fun doWork() = 4", "fun doWork() = \"okay\"") + + project.build("compileIntegrationTestKotlin") { + assertCompiledKotlinSources(listOf(testSrc, utilSrc).relativizeTo(project.projectPath), output) + } + } + + @JvmGradlePluginTests + @DisplayName("No rebuild after private ABI change in associated compilation") + @GradleTest + fun testNoRebuildOnPrivateChangeInAssociatedCompilation(gradleVersion: GradleVersion) { + val project = getBaseProject(gradleVersion) + + val utilSrc = project.kotlinSourcesDir("main").resolve("util.kt") + + project.build("compileIntegrationTestKotlin") + utilSrc.append("private val bar = 2") + + project.build("compileIntegrationTestKotlin") { + assertCompiledKotlinSources(listOf(utilSrc).relativizeTo(project.projectPath), output) + } + } + + @JvmGradlePluginTests + @DisplayName("No rebuild after unused ABI change in associated compilation") + @GradleTest + fun testNoRebuildOnUnusedInternalChangeInAssociatedCompilation(gradleVersion: GradleVersion) { + val project = getBaseProject(gradleVersion) + + val utilSrc = project.kotlinSourcesDir("main").resolve("util.kt") + + project.build("compileIntegrationTestKotlin") + utilSrc.append("internal val bar = 2") + + project.build("compileIntegrationTestKotlin") { + assertCompiledKotlinSources(listOf(utilSrc).relativizeTo(project.projectPath), output) + } + } + + private fun getBaseProject(gradleVersion: GradleVersion): TestProject { + return project("kt-61918-associate-with-incremental", gradleVersion) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/build.gradle new file mode 100644 index 00000000000..275f5040253 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/build.gradle @@ -0,0 +1,23 @@ +plugins { + id "org.jetbrains.kotlin.jvm" +} + +repositories { + mavenLocal() + mavenCentral() +} + +kotlin.target.compilations { + create("integrationTest") { + defaultSourceSet { + dependencies { + implementation(getByName("main").compileDependencyFiles + getByName("main").output.classesDirs) + } + } + } + + //force task instantiation: + tasks.getByName("compileIntegrationTestKotlin") + + named("integrationTest").configure { associateWith(getByName("main")) } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/integrationTest/kotlin/test.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/integrationTest/kotlin/test.kt new file mode 100644 index 00000000000..7786a948206 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/integrationTest/kotlin/test.kt @@ -0,0 +1 @@ +val result = doWork() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/main/kotlin/util.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/main/kotlin/util.kt new file mode 100644 index 00000000000..c711cf15947 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kt-61918-associate-with-incremental/src/main/kotlin/util.kt @@ -0,0 +1 @@ +internal fun doWork() = 4 diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt index 2f4cd49390b..18a1eb68c95 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt @@ -102,6 +102,16 @@ abstract class AbstractKotlinCompile @Inject constr internal open fun isIncrementalCompilationEnabled(): Boolean = incremental + // This allows us to treat friendPaths as Input rather than InputFiles + @get:Input + internal val friendPathsSet: Set + get() { + val buildDirFile = projectLayout.buildDirectory.asFile.get() + return friendPaths + .filter { it.exists() } + .map { it.normalize().relativeTo(buildDirFile).path }.toSet() + } + @Deprecated("Scheduled for removal with Kotlin 2.0", ReplaceWith("moduleName")) @get:Input abstract val ownModuleName: Property