Allow IrConstTransformer to visit and evaluate vararg elements
This commit is contained in:
+25
-7
@@ -55,19 +55,37 @@ class IrConstTransformer(irModuleFragment: IrModuleFragment) : IrElementTransfor
|
||||
}
|
||||
|
||||
private fun transformAnnotations(annotationContainer: IrAnnotationContainer) {
|
||||
annotationContainer.annotations.forEach {
|
||||
for (i in 0 until it.valueArgumentsCount) {
|
||||
val arg = it.getValueArgument(i) ?: continue
|
||||
if (arg.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) {
|
||||
val const = interpreter.interpret(arg).replaceIfError(arg)
|
||||
it.putValueArgument(i, const.convertToConstIfPossible(it.symbol.owner.valueParameters[i].type))
|
||||
annotationContainer.annotations.forEach { annotation ->
|
||||
// TODO this check can be removed after fix with annotation call arguments mapping
|
||||
if ((0 until annotation.valueArgumentsCount).any { annotation.getValueArgument(it) == null }) return@forEach
|
||||
|
||||
for (i in 0 until annotation.valueArgumentsCount) {
|
||||
val arg = annotation.getValueArgument(i) ?: continue
|
||||
when (arg) {
|
||||
is IrVararg -> arg.transformVarArg()
|
||||
else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrVararg.transformVarArg() {
|
||||
for (i in this.elements.indices) {
|
||||
val irVarargElement = this.elements[i] as? IrExpression ?: continue
|
||||
this.putElement(i, irVarargElement.transformSingleArg(this.varargElementType))
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression {
|
||||
if (this.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) {
|
||||
val const = interpreter.interpret(this).replaceIfError(this)
|
||||
return const.convertToConstIfPossible(expectedType)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun IrExpression.convertToConstIfPossible(type: IrType): IrExpression {
|
||||
if (this !is IrConst<*>) return this
|
||||
if (this !is IrConst<*> || type is IrErrorType) return this
|
||||
if (type.isArray()) return this.convertToConstIfPossible((type as IrSimpleType).arguments.single().typeOrNull!!)
|
||||
return this.value.toIrConst(type, this.startOffset, this.endOffset)
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_REFLECT
|
||||
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
|
||||
Vendored
+2
-2
@@ -38,9 +38,9 @@ FILE fqName:<root> fileName:/constExpressionsInAnnotationArguments.kt
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(x = CALL 'public final fun <get-ONE> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY)
|
||||
A(x = '1')
|
||||
BLOCK_BODY
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
annotations:
|
||||
A(x = CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null)
|
||||
A(x = '2')
|
||||
BLOCK_BODY
|
||||
|
||||
Reference in New Issue
Block a user