Fix false-positive on checking unused sourcesets in MPP+Android project
AGP could create 'AndroidSourceSet' that does not participate in any compilation. For this 'AndroidSourceSet's plugin should mark corresponding KotlinSourceSet as orphan and exclude from check. Unfortunately filtering them on KotlinSourceSet does not work, as AGP adds sourcesets into variants lazily. And MPP requires all SourceSets to be created eagerly. This change excludes all KotlinSourceSets created for Android compilation from such check. ^KT-48436 Fixed
This commit is contained in:
+19
-1
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.library.KLIB_PROPERTY_SHORT_NAME
|
||||
import org.jetbrains.kotlin.library.KLIB_PROPERTY_UNIQUE_NAME
|
||||
import org.junit.Assert
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import java.util.jar.JarFile
|
||||
@@ -1624,6 +1623,25 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48436
|
||||
@Test
|
||||
fun testUnusedSourceSetsReportAndroid() = with(Project("new-mpp-android", gradleVersion)) {
|
||||
setupWorkingDir()
|
||||
|
||||
build(
|
||||
"assembleDebug",
|
||||
// https://issuetracker.google.com/issues/152187160
|
||||
options = defaultBuildOptions().copy(androidGradlePluginVersion = AGPVersion.v4_2_0)
|
||||
) {
|
||||
assertSuccessful()
|
||||
assertNotContains(
|
||||
UnusedSourceSetsChecker.WARNING_PREFIX_ONE,
|
||||
UnusedSourceSetsChecker.WARNING_PREFIX_MANY,
|
||||
UnusedSourceSetsChecker.WARNING_INTRO
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIncrementalCompilation() = with(Project("new-mpp-jvm-js-ic", gradleVersion)) {
|
||||
build("build") {
|
||||
|
||||
+4
@@ -20,6 +20,7 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.internal.HasConvention
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension
|
||||
|
||||
@Deprecated("Conventions are deprecated in Gradle")
|
||||
internal inline fun <reified T : Any> Any.addConvention(name: String, plugin: T) {
|
||||
@@ -42,3 +43,6 @@ internal inline fun <reified T : Any> Any.addExtension(name: String, extension:
|
||||
|
||||
internal inline fun <reified T : Any> Any.getExtension(name: String): T? =
|
||||
(this as ExtensionAware).extensions.getByName(name) as T?
|
||||
|
||||
inline val Any.extraProperties: ExtraPropertiesExtension
|
||||
get() = (this as ExtensionAware).extensions.extraProperties
|
||||
|
||||
+8
-3
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||
|
||||
object UnusedSourceSetsChecker {
|
||||
const val WARNING_PREFIX_ONE =
|
||||
@@ -35,11 +37,14 @@ object UnusedSourceSetsChecker {
|
||||
}
|
||||
|
||||
fun checkSourceSets(project: Project) {
|
||||
// TODO once Android compilations are configured eagerly, move this to afterEvaluate { ... } instead of taskGraph.whenReady { ... }
|
||||
project.gradle.taskGraph.whenReady { _ ->
|
||||
project.whenEvaluated {
|
||||
val compilationsBySourceSet = CompilationSourceSetUtil.compilationsBySourceSets(project)
|
||||
val unusedSourceSets = project.kotlinExtension.sourceSets.filter {
|
||||
compilationsBySourceSet[it]?.isEmpty() ?: true
|
||||
// Ignoring Android source sets
|
||||
val isAndroidSourceSet = it.extraProperties.has(IS_ANDROID_SOURCE_SET) &&
|
||||
(it.extraProperties[IS_ANDROID_SOURCE_SET] as Boolean)
|
||||
|
||||
!isAndroidSourceSet && compilationsBySourceSet[it]?.isEmpty() ?: true
|
||||
}
|
||||
if (unusedSourceSets.isNotEmpty()) {
|
||||
reportUnusedSourceSets(project, unusedSourceSets.toSet())
|
||||
|
||||
+10
-1
@@ -16,13 +16,22 @@ import org.jetbrains.kotlin.gradle.plugin.AbstractAndroidProjectHandler.Companio
|
||||
import org.jetbrains.kotlin.gradle.plugin.addConvention
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinSourceSetFactory.Companion.defaultSourceFolder
|
||||
|
||||
internal const val IS_ANDROID_SOURCE_SET = "android-source-set"
|
||||
|
||||
internal fun syncKotlinAndAndroidSourceSets(target: KotlinAndroidTarget) {
|
||||
val project = target.project
|
||||
val android = project.extensions.getByName("android") as BaseExtension
|
||||
val kotlinExtension = project.kotlinExtension
|
||||
|
||||
val createdKotlinSourceSets = mutableSetOf<String>()
|
||||
android.sourceSets.all { androidSourceSet ->
|
||||
val kotlinSourceSetName = kotlinSourceSetNameForAndroidSourceSet(target, androidSourceSet.name)
|
||||
val kotlinSourceSet = project.kotlinExtension.sourceSets.maybeCreate(kotlinSourceSetName)
|
||||
createdKotlinSourceSets.add(kotlinSourceSetName)
|
||||
val kotlinSourceSet = kotlinExtension.sourceSets.maybeCreate(kotlinSourceSetName)
|
||||
|
||||
// Marking KotlinSource set is created for Android compilation to ignore it in UnusedSourceSetChecker
|
||||
kotlinSourceSet.extraProperties.set(IS_ANDROID_SOURCE_SET, true)
|
||||
|
||||
androidSourceSet.addKotlinSources(kotlinSourceSet)
|
||||
|
||||
createDefaultDependsOnEdges(target, kotlinSourceSet, androidSourceSet)
|
||||
|
||||
Reference in New Issue
Block a user