diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt index c65442dde88..06ff14b168b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt @@ -55,6 +55,19 @@ open class IncrementalCompilationJvmMultiProjectIT : BaseIncrementalCompilationM override val defaultProjectName: String = "incrementalMultiproject" + @DisplayName("'inspectClassesForKotlinIC' task is added to execution plan") + @GradleTest + open fun testInspectClassesForKotlinICTask(gradleVersion: GradleVersion) { + defaultProject(gradleVersion) { + build("assemble") { + assertTasksExecuted( + ":lib:inspectClassesForKotlinIC", + ":app:inspectClassesForKotlinIC" + ) + } + } + } + // todo: do the same for js backend @DisplayName("Duplicated class") @GradleTest @@ -180,6 +193,18 @@ class IncrementalCompilationClasspathSnapshotJvmMultiProjectIT : IncrementalComp override val defaultBuildOptions = super.defaultBuildOptions.copy(useGradleClasspathSnapshot = true) + @DisplayName("'inspectClassesForKotlinIC' task is added to execution plan") + override fun testInspectClassesForKotlinICTask(gradleVersion: GradleVersion) { + defaultProject(gradleVersion) { + build("assemble") { + assertTasksSkipped( + ":lib:inspectClassesForKotlinIC", + ":app:inspectClassesForKotlinIC" + ) + } + } + } + @DisplayName("Lib: Non ABI change in method body") @GradleTest override fun testNonAbiChangeInLib_changeMethodBody(gradleVersion: GradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index d27cdd9f65b..fb490afb03d 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder import org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.Companion.kotlinSourceSetNameForAndroidSourceSet +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor import org.jetbrains.kotlin.gradle.plugin.internal.MavenPluginConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.* @@ -388,12 +389,60 @@ internal abstract class AbstractKotlinPlugin( rewriteMppDependenciesInPom(target) configureProjectGlobalSettings(project) + configureClassInspectionForIC(project) registry.register(KotlinModelBuilder(kotlinPluginVersion, null)) project.components.addAll(target.components) } + protected open fun configureClassInspectionForIC(project: Project) { + // Check if task was already added by one of plugin implementations + if (project.tasks.names.contains(INSPECT_IC_CLASSES_TASK_NAME)) return + + val classesTask = project.locateTask(JavaPlugin.CLASSES_TASK_NAME) + val jarTask = project.locateTask(JavaPlugin.JAR_TASK_NAME) + + if (classesTask == null || jarTask == null) { + project.logger.info( + "Could not configure class inspection task " + + "(classes task = ${classesTask?.javaClass?.canonicalName}, " + + "jar task = ${classesTask?.javaClass?.canonicalName}" + ) + return + } + + val inspectTask = project.registerTask(INSPECT_IC_CLASSES_TASK_NAME) { inspectTask -> + inspectTask.archivePath.set(jarTask.map { it.archivePathCompatible.canonicalPath }) + inspectTask.archivePath.disallowChanges() + + inspectTask.sourceSetName.set(SourceSet.MAIN_SOURCE_SET_NAME) + inspectTask.sourceSetName.disallowChanges() + + inspectTask.classesListFile.set( + project.layout.file( + (project.kotlinExtension as KotlinSingleJavaTargetExtension) + .target + .defaultArtifactClassesListFile + ) + ) + inspectTask.classesListFile.disallowChanges() + + val sourceSetClassesDir = project.gradle + .variantImplementationFactory() + .getInstance(project) + .sourceSetsIfAvailable + ?.findByName(SourceSet.MAIN_SOURCE_SET_NAME) + ?.output + ?.classesDirs + ?: project.objects.fileCollection() + inspectTask.sourceSetOutputClassesDir.from(sourceSetClassesDir).disallowChanges() + + inspectTask.dependsOn(classesTask) + } + classesTask.configure { it.finalizedBy(inspectTask) } + } + private fun rewritePom(pom: MavenPom, rewriter: PomDependenciesRewriter, shouldRewritePom: Provider) { pom.withXml { xml -> if (shouldRewritePom.get()) @@ -424,9 +473,10 @@ internal abstract class AbstractKotlinPlugin( } companion object { + private const val INSPECT_IC_CLASSES_TASK_NAME = "inspectClassesForKotlinIC" + fun configureProjectGlobalSettings(project: Project) { customizeKotlinDependencies(project) - configureClassInspectionForIC(project) project.setupGeneralKotlinExtensionParameters() } @@ -439,49 +489,6 @@ internal abstract class AbstractKotlinPlugin( configureAttributes(target) } - private fun configureClassInspectionForIC(project: Project) { - val classesTask = project.locateTask(JavaPlugin.CLASSES_TASK_NAME) - val jarTask = project.locateTask(JavaPlugin.JAR_TASK_NAME) - - if (classesTask == null || jarTask == null) { - project.logger.info( - "Could not configure class inspection task " + - "(classes task = ${classesTask?.javaClass?.canonicalName}, " + - "jar task = ${classesTask?.javaClass?.canonicalName}" - ) - return - } - val inspectTask = project.registerTask("inspectClassesForKotlinIC") { inspectTask -> - inspectTask.archivePath.set(jarTask.map { it.archivePathCompatible.canonicalPath }) - inspectTask.archivePath.disallowChanges() - - inspectTask.sourceSetName.set(SourceSet.MAIN_SOURCE_SET_NAME) - inspectTask.sourceSetName.disallowChanges() - - inspectTask.classesListFile.set( - project.layout.file( - (project.kotlinExtension as KotlinSingleJavaTargetExtension) - .target - .defaultArtifactClassesListFile - ) - ) - inspectTask.classesListFile.disallowChanges() - - val sourceSetClassesDir = project.gradle - .variantImplementationFactory() - .getInstance(project) - .sourceSetsIfAvailable - ?.findByName(SourceSet.MAIN_SOURCE_SET_NAME) - ?.output - ?.classesDirs - ?: project.objects.fileCollection() - inspectTask.sourceSetOutputClassesDir.from(sourceSetClassesDir).disallowChanges() - - inspectTask.dependsOn(classesTask) - } - classesTask.configure { it.finalizedBy(inspectTask) } - } - internal fun setUpJavaSourceSets( kotlinTarget: KotlinTarget, duplicateJavaSourceSetsAsKotlinSourceSets: Boolean = true @@ -613,6 +620,13 @@ internal open class KotlinPlugin( project.pluginManager.apply(ScriptingGradleSubplugin::class.java) } + + override fun configureClassInspectionForIC(project: Project) { + // For new IC this task is not needed + if (!project.kotlinPropertiesProvider.useClasspathSnapshot) { + super.configureClassInspectionForIC(project) + } + } } internal open class KotlinCommonPlugin(