Skip to content

Commit 06fe771

Browse files
shishkin-pavelKotlinBuild
authored andcommitted
[CMP] CMP-9167 fix
1 parent a9dcaeb commit 06fe771

File tree

2 files changed

+112
-2
lines changed
  • libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle
  • plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower

2 files changed

+112
-2
lines changed

libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ComposeIT.kt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.gradle.kotlin.dsl.getByType
1111
import org.gradle.util.GradleVersion
1212
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
1313
import org.jetbrains.kotlin.gradle.testbase.*
14+
import org.jetbrains.kotlin.gradle.uklibs.applyMultiplatform
1415
import org.jetbrains.kotlin.test.TestMetadata
1516
import org.junit.jupiter.api.DisplayName
1617
import org.junit.jupiter.api.condition.DisabledOnOs
@@ -755,6 +756,90 @@ class ComposeIT : KGPBaseTest() {
755756
}
756757
}
757758

759+
@DisplayName("CMP-9167 verification")
760+
@GradleTest
761+
@OtherGradlePluginTests
762+
fun testComposeDefaultValueParamStubs(
763+
gradleVersion: GradleVersion,
764+
) {
765+
project(
766+
projectName = "empty",
767+
gradleVersion = gradleVersion,
768+
buildOptions = defaultBuildOptions.copy(
769+
nativeOptions = super.defaultBuildOptions.nativeOptions.copy(
770+
version = TestVersions.Kotlin.CURRENT
771+
),
772+
isolatedProjects = BuildOptions.IsolatedProjectsMode.DISABLED
773+
),
774+
dependencyManagement = DependencyManagement.DefaultDependencyManagement(setOf("https://maven.pkg.jetbrains.space/public/p/compose/dev")),
775+
enableGradleDaemonMemoryLimitInMb = 2048,
776+
enableKotlinDaemonMemoryLimitInMb = 2048,
777+
) {
778+
plugins {
779+
id("org.jetbrains.kotlin.plugin.compose")
780+
}
781+
buildScriptInjection {
782+
project.applyMultiplatform {
783+
listOf(
784+
iosArm64(),
785+
iosSimulatorArm64()
786+
).forEach { iosTarget ->
787+
iosTarget.binaries.framework {
788+
baseName = "ComposeApp"
789+
isStatic = true
790+
}
791+
}
792+
jvm()
793+
794+
@OptIn(ExperimentalWasmDsl::class)
795+
wasmJs {
796+
browser()
797+
binaries.library()
798+
}
799+
800+
js {
801+
browser()
802+
binaries.library()
803+
}
804+
sourceSets.commonMain {
805+
compileSource(
806+
//language=kotlin
807+
"""
808+
package com.example
809+
810+
import androidx.compose.runtime.Composable
811+
import kotlin.jvm.JvmInline
812+
813+
@JvmInline
814+
value class ImeAction private constructor(val value: Int) {
815+
companion object {
816+
val Default = ImeAction(0)
817+
}
818+
}
819+
820+
@Composable
821+
fun <T> TextCompose(genericText: (T) -> String, imeAction: ImeAction = ImeAction.Default) {}
822+
""".trimIndent()
823+
)
824+
dependencies {
825+
implementation("org.jetbrains.compose.runtime:runtime:1.9.1")
826+
}
827+
}
828+
}
829+
}
830+
831+
build(":compileKotlinIosSimulatorArm64") {
832+
assertTasksExecuted(":compileKotlinIosSimulatorArm64")
833+
}
834+
build(":compileKotlinWasmJs") {
835+
assertTasksExecuted(":compileKotlinWasmJs")
836+
}
837+
build(":compileKotlinJs") {
838+
assertTasksExecuted(":compileKotlinJs")
839+
}
840+
}
841+
}
842+
758843
private fun Path.appendComposePlugin() {
759844
modify { originalBuildScript ->
760845
"""

plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildFun
3535
import org.jetbrains.kotlin.ir.declarations.*
3636
import org.jetbrains.kotlin.ir.expressions.*
3737
import org.jetbrains.kotlin.ir.expressions.impl.*
38+
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
39+
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
3840
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
3941
import org.jetbrains.kotlin.ir.types.*
4042
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
@@ -609,6 +611,29 @@ class ComposerParamTransformer(
609611
return (transform(DeepCopyPreservingMetadata(symbolRemapper, typeRemapper), null) as T).patchDeclarationParents(initialParent)
610612
}
611613

614+
private fun IrSimpleFunction.toComparableParams(referenceFn: IrSimpleFunction): List<Pair<IrClassifierSymbol, SimpleTypeNullability>?> =
615+
parameters.map {
616+
when (val paramType = it.type) {
617+
is IrSimpleType ->
618+
if (paramType.classifier is IrTypeParameterSymbol) {
619+
val typeParam = paramType.classifier.owner as IrTypeParameter
620+
// if a type parameter is defined on a stub,
621+
// it should be compared with matching original function's type parameter
622+
// instead of comparing each stub's type parameters
623+
val classifier = if (typeParam.parent == this) {
624+
referenceFn.typeParameters[typeParam.index].symbol
625+
} else {
626+
paramType.classifier
627+
}
628+
Pair(classifier, paramType.nullability)
629+
630+
} else {
631+
Pair(paramType.classifier, paramType.nullability)
632+
}
633+
else -> null
634+
}
635+
}
636+
612637
private fun IrSimpleFunction.copyWithComposerParam(): IrSimpleFunction {
613638
assert(parameters.lastOrNull()?.name != ComposeNames.ComposerParameter) {
614639
"Attempted to add composer param to $this, but it has already been added."
@@ -717,9 +742,9 @@ class ComposerParamTransformer(
717742
val parent = fn.parent
718743
if (parent is IrClass || parent is IrFile) {
719744
// checking if any stubs have all same-type parameters and discarding them
720-
val addedParamTypes = mutableSetOf(fn.parameters.map { it.type })
745+
val addedParamTypes = mutableSetOf(fn.toComparableParams(fn))
721746
stubs.forEach { stub ->
722-
val stubParamTypes = stub.parameters.map { it.type }
747+
val stubParamTypes = stub.toComparableParams(fn)
723748
if (addedParamTypes.add(stubParamTypes)) {
724749
parent.addChild(stub)
725750
}

0 commit comments

Comments
 (0)