0%

Compose Compiler(1) Compose plugin

概览

  • 前端检查
  • ir生成
  • recompose判断

常见注解

  • @Composable
  • @ComposeCompilerApi
  • @InternalComposeApi
  • @DisallowComposableCalls
  • @ReadOnlyComposable
  • @NonRestartableComposable
  • @StableMarker
  • @Immutable
  • @Stable

1. Frontend checker

  • ComposableCallChecker : 检查是否可以调用 @Composable 函数
  • ComposableDeclarationChecker : 检查 @Composable 的位置是否正确
  • ComposableTargetChecker
  • ComposeDiagnosticSuppressor : 屏蔽不必要的编译诊断错误

2. IRCodeLower

Lowering 是编译原理中的概念,在编译过程的每一步,使用不同的 Lower 来来逐步删除高级特征,并生成更低级别特征的 IR。这样做足够多次,最终你会得到一个足够简单的IR,可以编译到汇编级

ComposeIrGenerationExtension.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class ComposeIrGenerationExtension(...) : IrGenerationExtension {

override fun generate(moduleFragment: IrModuleFragment,pluginContext: IrPluginContext) {

ClassStabilityTransformer(pluginContext,//..)
.lower(moduleFragment)

LiveLiteralTransformer( pluginContext, //..)
.lower(moduleFragment)

ComposableFunInterfaceLowering(pluginContext)
.lower(moduleFragment)

// Memoize normal lambdas and wrap composable lambdas
ComposerLambdaMemoization( pluginContext, //..)
.lower(moduleFragment)

CopyDefaultValuesFromExpectLowering()
.lower(moduleFragment)

if (decoysEnabled) { }

// 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)

ComposableTargetAnnotationsTransformer(pluginContext,//..)
.lower(moduleFragment)

// transform calls to the currentComposer to just use the local parameter from the
// previous transform
ComposerIntrinsicTransformer(pluginContext, decoysEnabled)
.lower(moduleFragment)

ComposableFunctionBodyTransformer(pluginContext,//..)
.lower(moduleFragment)

if (decoysEnabled) { }
if (isKlibTarget) { }
if (pluginContext.platform.isJs()) {}
}
}

各种lower代码地址

2.1 ClassStabilityTransformer

判断类型稳定性, 为 Class 添加@StabilityInferred 注解, 并为 Class 生成 $stable 静态变量,服务于 Stability.Runtime 的代码生成。(用于后续compose判断重组代码生成)

2.2 LiveLiteralTransformer

将常量文字表达式转换为读取 MutableState 实例的表达式,以便无需重新编译即可将对常量文字源代码的更改传达给运行时。 这种转变旨在改善开发人员体验,永远不应在发布版本中启用,因为它会显着放慢对性能敏感的代码

在gradle的ComposeOption中 使用useLiveLiterals开启/关闭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//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
}
}

2.3 ComposableFunInterfaceLowering

2.4 ComposerLambdaMemoization

2.5 CopyDefaultValuesFromExpectLowering

2.6 ComposerParamTransformer

@Composable 函数增加 $compsoer 等参数

1
2
3
4
5
6
7
8
9
10
@Composable
fun Counter() {
//..
}

//转换成
@Composable
fun Counter($composer:Composer, $changed: Int) {
//...
}

源码部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 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
)
}
}

2.7 ComposableTargetAnnotationsTransformer

2.8 ComposerIntrinsicTransformer

2.9 ComposableFunctionBodyTransformer

非常复杂的一个trasnfromer, Composable 函数体内生成 startXXXGroup/endXXXGroup/recompose 等相关代码

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 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)
*