-
Notifications
You must be signed in to change notification settings - Fork 624
/
NativeTransformer.kt
84 lines (74 loc) · 3.61 KB
/
NativeTransformer.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package io.kotest.framework.multiplatform.embeddablecompiler
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrSingleStatementBuilder
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.addGetter
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
import org.jetbrains.kotlin.ir.builders.irBlock
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.getSimpleFunction
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
class NativeTransformer(messageCollector: MessageCollector, pluginContext: IrPluginContext) : Transformer(messageCollector, pluginContext) {
override fun generateLauncher(specs: Iterable<IrClass>, configs: Iterable<IrClass>, declarationParent: IrDeclarationParent): IrDeclaration {
val launcher = pluginContext.irFactory.buildProperty {
name = Name.identifier(EntryPoint.LauncherValName)
}.apply {
parent = declarationParent
annotations += IrSingleStatementBuilder(
pluginContext,
Scope(this.symbol),
UNDEFINED_OFFSET,
UNDEFINED_OFFSET
).build { irCall(eagerAnnotationConstructor) }
backingField = pluginContext.irFactory.buildField {
type = pluginContext.irBuiltIns.unitType
isFinal = true
isExternal = false
isStatic = true // top level vals must be static
name = Name.identifier(EntryPoint.LauncherValName)
}.also { field ->
field.correspondingPropertySymbol = this@apply.symbol
field.initializer = pluginContext.irFactory.createExpressionBody(startOffset, endOffset) {
this.expression = DeclarationIrBuilder(pluginContext, field.symbol).irBlock {
+callLauncher(launchFn, specs, configs) {
irCall(withTeamCityListenerMethodNameFn).also { withTeamCity ->
withTeamCity.dispatchReceiver = irCall(launcherConstructor)
}
}
}
}
}
addGetter {
returnType = pluginContext.irBuiltIns.unitType
}.also { func ->
func.body = DeclarationIrBuilder(pluginContext, func.symbol).irBlockBody {
}
}
}
return launcher
}
private val launchFn by lazy {
launcherClass.getSimpleFunction(EntryPoint.LaunchMethodName)
?: error("Cannot find function ${EntryPoint.LaunchMethodName}")
}
private val withTeamCityListenerMethodNameFn by lazy {
launcherClass.getSimpleFunction(EntryPoint.WithTeamCityListenerMethodName)
?: error("Cannot find function ${EntryPoint.WithTeamCityListenerMethodName}")
}
private val eagerAnnotationConstructor by lazy {
val annotationName = FqName("kotlin.native.EagerInitialization")
val annotation = pluginContext.referenceClass(annotationName)
?: error("Cannot find eager initialisation annotation class $annotationName")
annotation.constructors.single()
}
}