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) {
|
private fun transformAnnotations(annotationContainer: IrAnnotationContainer) {
|
||||||
annotationContainer.annotations.forEach {
|
annotationContainer.annotations.forEach { annotation ->
|
||||||
for (i in 0 until it.valueArgumentsCount) {
|
// TODO this check can be removed after fix with annotation call arguments mapping
|
||||||
val arg = it.getValueArgument(i) ?: continue
|
if ((0 until annotation.valueArgumentsCount).any { annotation.getValueArgument(it) == null }) return@forEach
|
||||||
if (arg.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) {
|
|
||||||
val const = interpreter.interpret(arg).replaceIfError(arg)
|
for (i in 0 until annotation.valueArgumentsCount) {
|
||||||
it.putValueArgument(i, const.convertToConstIfPossible(it.symbol.owner.valueParameters[i].type))
|
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 {
|
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!!)
|
if (type.isArray()) return this.convertToConstIfPossible((type as IrSimpleType).arguments.single().typeOrNull!!)
|
||||||
return this.value.toIrConst(type, this.startOffset, this.endOffset)
|
return this.value.toIrConst(type, this.startOffset, this.endOffset)
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// 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
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
annotations:
|
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
|
BLOCK_BODY
|
||||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
annotations:
|
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
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user