// transform all composable functions to have an extra synthetic composer // parameter. this will also transform all types and calls to include the extra // parameter. ComposerParamTransformer(pluginContext, //..) .lower(moduleFragment)
// transform calls to the currentComposer to just use the local parameter from the // previous transform ComposerIntrinsicTransformer(pluginContext, decoysEnabled) .lower(moduleFragment)
//file: Foo.kt origin fun Foo() { print("Hello World") } //file: Foo.kt into fun Foo() { print(LiveLiterals$FooKt.getString$arg-0$call-print$fun-Foo()) } object LiveLiterals$FooKt { var String$arg-0$call-print$fun-Foo: String = "Hello World" var State$String$arg-0$call-print$fun-Foo: MutableState<String>? = null fun getString$arg-0$call-print$fun-Foo(): String { val field = this.String$arg-0$call-print$fun-Foo val state = if (field == null) { val tmp = liveLiteral( "String$arg-0$call-print$fun-Foo", this.String$arg-0$call-print$fun-Foo ) this.String$arg-0$call-print$fun-Foo = tmp tmp } else field return field.value } }
// 1.添加$composer参数 val composerParam = fn.addValueParameter { name = KtxNameConventions.COMPOSER_PARAMETER type = composerType.makeNullable() origin = IrDeclarationOrigin.DEFINED isAssignable = true }
// 2.添加$changed[n]参数 val changed = KtxNameConventions.CHANGED_PARAMETER.identifier for (i in 0 until changedParamCount(realParams, fn.thisParamCount)) { fn.addValueParameter( if (i == 0) changed else "$changed$i", context.irBuiltIns.intType ) }
// 3.添加$default[n]参数 if (oldFn.requiresDefaultParameter()) { val defaults = KtxNameConventions.DEFAULT_PARAMETER.identifier for (i in 0 until defaultParamCount(currentParams)) { fn.addValueParameter( if (i == 0) defaults else "$defaults$i", context.irBuiltIns.intType, IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION ) } }
/** * This IR Transform is responsible for the main transformations of the body of a composable * function. * * 1. Control-Flow Group Generation * 2. Default arguments * 3. Composable Function Skipping * 4. Comparison Propagation * 5. Recomposability * 6. Source location information (when enabled) *