JVM: Support instantiation of annotations with vararg parameters

when they are instantiated without argument.
 #KT-59033 Fixed
This commit is contained in:
Ilmir Usmanov
2023-06-02 15:38:38 +02:00
committed by teamcity
parent 67090ff10a
commit 95662234d0
17 changed files with 139 additions and 8 deletions
@@ -17,12 +17,12 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
@@ -105,11 +105,36 @@ abstract class AnnotationImplementationTransformer(val context: BackendContext,
destination.symbol.owner.valueParameters.forEachIndexed { index, parameter ->
val valueArg = argumentsByName[parameter.name]
if (parameter.defaultValue == null && valueArg == null)
error(
"Usage of default value argument for this annotation is not yet possible.\n" +
"Please specify value for '${source.type.classOrNull?.owner?.name}.${parameter.name}' explicitly"
)
if (parameter.defaultValue == null && valueArg == null) {
// if parameter is vararg, put an empty array as argument
// The vararg is already lowered to array, so `isVararg` is false.
if (parameter.type.isBoxedArray || parameter.type.isPrimitiveArray() || parameter.type.isUnsignedArray()) {
val arrayType = parameter.type
val arrayConstructorCall =
if (arrayType.isBoxedArray) {
val arrayFunction = context.ir.symbols.arrayOfNulls
IrCallImpl.fromSymbolOwner(source.startOffset, source.endOffset, arrayType, arrayFunction)
} else {
val arrayConstructor = arrayType.classOrNull!!.constructors.single {
it.owner.valueParameters.size == 1 && it.owner.valueParameters.single().type == context.irBuiltIns.intType
}
IrConstructorCallImpl.fromSymbolOwner(source.startOffset, source.endOffset, arrayType, arrayConstructor)
}
arrayConstructorCall.putValueArgument(
0,
IrConstImpl.int(source.startOffset, source.endOffset, context.irBuiltIns.intType, 0)
)
destination.putValueArgument(index, arrayConstructorCall)
return
} else {
error(
"Usage of default value argument for this annotation is not yet possible.\n" +
"Please specify value for '${source.type.classOrNull?.owner?.name}.${parameter.name}' explicitly"
)
}
}
destination.putValueArgument(index, valueArg)
}
}