Skip to content

Commit e6b9910

Browse files
authored
Merge pull request #345 from DataDog/yl/kcp/kotlin-1.9-back-compact
Enhance compiler plugin binary backward compatibility
2 parents 2b62ffc + 8770031 commit e6b9910

File tree

1 file changed

+89
-24
lines changed
  • dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/kcp

1 file changed

+89
-24
lines changed

dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/kcp/IrExt.kt

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibility
66
import org.jetbrains.kotlin.descriptors.Modality
77
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
88
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
9+
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
910
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
10-
import org.jetbrains.kotlin.ir.declarations.IrFactory
1111
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
1212
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
1313
import org.jetbrains.kotlin.ir.expressions.IrBody
1414
import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression
1515
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
16+
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
1617
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
1718
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
1819
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
@@ -23,30 +24,33 @@ import org.jetbrains.kotlin.ir.util.defaultType
2324
import org.jetbrains.kotlin.name.Name
2425
import org.jetbrains.kotlin.name.SpecialNames
2526
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
27+
import kotlin.reflect.KVisibility
28+
import kotlin.reflect.full.createInstance
29+
import kotlin.reflect.full.primaryConstructor
2630

2731
// Builds Lambda of (T.() -> Unit)
2832
internal fun IrPluginContext.irUnitLambdaExpression(
2933
body: IrBody,
3034
irDeclarationParent: IrDeclarationParent?,
3135
receiverType: IrType
3236
): IrFunctionExpression {
33-
return irFunctionExpression(
37+
return buildCompatIrFunctionExpression(
3438
symbols.irBuiltIns.functionN(0).defaultType,
3539
irSimpleFunction(
3640
name = SpecialNames.ANONYMOUS,
3741
visibility = DescriptorVisibilities.LOCAL,
3842
returnType = symbols.unit.defaultType,
39-
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
43+
origin = getCompatLambdaOrigin(),
4044
body = body
4145
).apply {
4246
irDeclarationParent?.let {
4347
this.parent = irDeclarationParent
4448
}
45-
this.extensionReceiverParameter = irFactory.createValueParameter(
49+
this.extensionReceiverParameter = IrFactoryImpl.createValueParameter(
4650
startOffset,
4751
endOffset,
48-
IrDeclarationOrigin.DEFINED,
49-
symbol = IrValueParameterSymbolImpl(),
52+
getCompatDefinedOrigin(),
53+
symbol = getCompatValueParameterSymbolImpl(),
5054
name = Name.identifier("receiver"),
5155
index = -1,
5256
type = receiverType,
@@ -64,26 +68,13 @@ internal fun IrPluginContext.irUnitLambdaExpression(
6468
)
6569
}
6670

67-
internal fun irFunctionExpression(
68-
type: IrType,
69-
function: IrSimpleFunction
70-
): IrFunctionExpression {
71-
return IrFunctionExpressionImpl(
72-
UNDEFINED_OFFSET,
73-
UNDEFINED_OFFSET,
74-
type,
75-
function,
76-
IrStatementOrigin.LAMBDA
77-
)
78-
}
79-
8071
internal fun irSimpleFunction(
8172
name: Name,
8273
visibility: DescriptorVisibility,
8374
returnType: IrType,
8475
origin: IrDeclarationOrigin,
8576
body: IrBody,
86-
symbol: IrSimpleFunctionSymbol = IrSimpleFunctionSymbolImpl(),
77+
symbol: IrSimpleFunctionSymbol = getCompatSimpleFunctionSymbol(),
8778
modality: Modality = Modality.FINAL,
8879
isInline: Boolean = false,
8980
isExternal: Boolean = false,
@@ -92,10 +83,9 @@ internal fun irSimpleFunction(
9283
isOperator: Boolean = false,
9384
isInfix: Boolean = false,
9485
isExpect: Boolean = false,
95-
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
96-
containerSource: DeserializedContainerSource? = null,
97-
factory: IrFactory = IrFactoryImpl
98-
): IrSimpleFunction = factory.createSimpleFunction(
86+
isFakeOverride: Boolean = origin == getCompatFakeOverrideOrigin(),
87+
containerSource: DeserializedContainerSource? = null
88+
): IrSimpleFunction = IrFactoryImpl.createSimpleFunction(
9989
startOffset = UNDEFINED_OFFSET,
10090
endOffset = UNDEFINED_OFFSET,
10191
origin = origin,
@@ -116,3 +106,78 @@ internal fun irSimpleFunction(
116106
).apply {
117107
this.body = body
118108
}
109+
110+
private fun getCompatLambdaOrigin(): IrDeclarationOriginImpl {
111+
return getCompatDeclarationOrigin("LOCAL_FUNCTION_FOR_LAMBDA") {
112+
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
113+
}
114+
}
115+
116+
private fun getCompatFakeOverrideOrigin(): IrDeclarationOriginImpl {
117+
return getCompatDeclarationOrigin("FAKE_OVERRIDE") {
118+
IrDeclarationOrigin.FAKE_OVERRIDE
119+
}
120+
}
121+
122+
private fun getCompatDefinedOrigin(): IrDeclarationOriginImpl {
123+
return getCompatDeclarationOrigin("DEFINED") {
124+
IrDeclarationOrigin.DEFINED
125+
}
126+
}
127+
128+
private fun getCompatDeclarationOrigin(
129+
name: String,
130+
default: () -> IrDeclarationOriginImpl
131+
): IrDeclarationOriginImpl {
132+
// In Kotlin 1.9, `IrDeclarationOriginImpl` is an abstract class, not in 2.0
133+
return if (IrDeclarationOriginImpl::class.isAbstract) {
134+
val nestedClass = IrDeclarationOrigin::class.nestedClasses
135+
.firstOrNull { it.simpleName == name }
136+
val instance = nestedClass?.objectInstance
137+
instance as IrDeclarationOriginImpl
138+
} else {
139+
default.invoke()
140+
}
141+
}
142+
143+
private fun getCompatLambdaStateOrigin(): IrStatementOriginImpl {
144+
// In Kotlin 1.9, `IrStatementOriginImpl` is an abstract class, not in 2.0
145+
return if (IrStatementOriginImpl::class.isAbstract) {
146+
val lambdaClass = IrStatementOrigin::class.nestedClasses
147+
.firstOrNull { it.simpleName == "LAMBDA" }
148+
val instance = lambdaClass?.objectInstance
149+
return instance as IrStatementOriginImpl
150+
} else {
151+
IrStatementOrigin.LAMBDA
152+
}
153+
}
154+
155+
private fun getCompatSimpleFunctionSymbol(): IrSimpleFunctionSymbol {
156+
return IrSimpleFunctionSymbolImpl::class.createInstance()
157+
}
158+
159+
private fun getCompatValueParameterSymbolImpl(): IrValueParameterSymbolImpl {
160+
return IrValueParameterSymbolImpl::class.createInstance()
161+
}
162+
163+
private fun buildCompatIrFunctionExpression(
164+
type: IrType,
165+
function: IrSimpleFunction
166+
): IrFunctionExpression {
167+
val primaryConstructor = IrFunctionExpressionImpl::class.primaryConstructor
168+
return primaryConstructor?.takeIf {
169+
it.visibility == KVisibility.PUBLIC
170+
}?.call(
171+
UNDEFINED_OFFSET,
172+
UNDEFINED_OFFSET,
173+
type,
174+
function,
175+
getCompatLambdaStateOrigin()
176+
) ?: IrFunctionExpressionImpl(
177+
UNDEFINED_OFFSET,
178+
UNDEFINED_OFFSET,
179+
type,
180+
function,
181+
getCompatLambdaStateOrigin()
182+
)
183+
}

0 commit comments

Comments
 (0)