[FIR2IR] Fix conversion of default vararg arguments for annotations
This commit is contained in:
@@ -316,16 +316,20 @@ class Fir2IrVisitor(
|
|||||||
)
|
)
|
||||||
} else convertToIrExpression(this)
|
} else convertToIrExpression(this)
|
||||||
|
|
||||||
|
private fun convertToIrCall(functionCall: FirFunctionCall, annotationMode: Boolean): IrExpression {
|
||||||
|
val explicitReceiverExpression = convertToIrReceiverExpression(
|
||||||
|
functionCall.explicitReceiver, functionCall.calleeReference
|
||||||
|
)
|
||||||
|
return callGenerator.convertToIrCall(functionCall, functionCall.typeRef, explicitReceiverExpression, annotationMode)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression {
|
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression {
|
||||||
val convertibleCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) {
|
val convertibleCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) {
|
||||||
functionCall.copy().transformSingle(integerApproximator, null)
|
functionCall.copy().transformSingle(integerApproximator, null)
|
||||||
} else {
|
} else {
|
||||||
functionCall
|
functionCall
|
||||||
}
|
}
|
||||||
val explicitReceiverExpression = convertToIrReceiverExpression(
|
return convertToIrCall(functionCall = convertibleCall, annotationMode = false)
|
||||||
functionCall.explicitReceiver, functionCall.calleeReference
|
|
||||||
)
|
|
||||||
return callGenerator.convertToIrCall(convertibleCall, convertibleCall.typeRef, explicitReceiverExpression)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement {
|
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement {
|
||||||
@@ -513,7 +517,7 @@ class Fir2IrVisitor(
|
|||||||
return accept(this@Fir2IrVisitor, null) as IrStatement
|
return accept(this@Fir2IrVisitor, null) as IrStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun convertToIrExpression(expression: FirExpression): IrExpression {
|
internal fun convertToIrExpression(expression: FirExpression, annotationMode: Boolean = false): IrExpression {
|
||||||
return when (expression) {
|
return when (expression) {
|
||||||
is FirBlock -> expression.convertToIrExpressionOrBlock()
|
is FirBlock -> expression.convertToIrExpressionOrBlock()
|
||||||
is FirUnitExpression -> expression.convertWithOffsets { startOffset, endOffset ->
|
is FirUnitExpression -> expression.convertWithOffsets { startOffset, endOffset ->
|
||||||
@@ -522,7 +526,18 @@ class Fir2IrVisitor(
|
|||||||
this.symbolTable.referenceClass(this.irBuiltIns.builtIns.unit)
|
this.symbolTable.referenceClass(this.irBuiltIns.builtIns.unit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> expression.accept(this, null) as IrExpression
|
else -> {
|
||||||
|
val unwrappedExpression = if (expression is FirWrappedArgumentExpression) {
|
||||||
|
expression.expression
|
||||||
|
} else {
|
||||||
|
expression
|
||||||
|
}
|
||||||
|
if (annotationMode && unwrappedExpression is FirFunctionCall) {
|
||||||
|
convertToIrCall(unwrappedExpression, annotationMode)
|
||||||
|
} else {
|
||||||
|
expression.accept(this, null) as IrExpression
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-7
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.toArrayOrPrimitiveArrayType
|
||||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
||||||
@@ -118,7 +119,8 @@ class CallAndReferenceGenerator(
|
|||||||
fun convertToIrCall(
|
fun convertToIrCall(
|
||||||
qualifiedAccess: FirQualifiedAccess,
|
qualifiedAccess: FirQualifiedAccess,
|
||||||
typeRef: FirTypeRef,
|
typeRef: FirTypeRef,
|
||||||
explicitReceiverExpression: IrExpression?
|
explicitReceiverExpression: IrExpression?,
|
||||||
|
annotationMode: Boolean = false
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val type = typeRef.toIrType()
|
val type = typeRef.toIrType()
|
||||||
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type)
|
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type)
|
||||||
@@ -200,7 +202,7 @@ class CallAndReferenceGenerator(
|
|||||||
is IrEnumEntrySymbol -> IrGetEnumValueImpl(startOffset, endOffset, type, symbol)
|
is IrEnumEntrySymbol -> IrGetEnumValueImpl(startOffset, endOffset, type, symbol)
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, qualifiedAccess.calleeReference, type)
|
else -> generateErrorCallExpression(startOffset, endOffset, qualifiedAccess.calleeReference, type)
|
||||||
}
|
}
|
||||||
}.applyCallArguments(qualifiedAccess as? FirCall)
|
}.applyCallArguments(qualifiedAccess as? FirCall, annotationMode)
|
||||||
.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, explicitReceiverExpression)
|
.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, explicitReceiverExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +287,7 @@ class CallAndReferenceGenerator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.applyCallArguments(annotationCall)
|
}.applyCallArguments(annotationCall, annotationMode = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertToGetObject(qualifier: FirResolvedQualifier): IrExpression {
|
fun convertToGetObject(qualifier: FirResolvedQualifier): IrExpression {
|
||||||
@@ -315,7 +317,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrExpression.applyCallArguments(call: FirCall?): IrExpression {
|
internal fun IrExpression.applyCallArguments(call: FirCall?, annotationMode: Boolean): IrExpression {
|
||||||
if (call == null) return this
|
if (call == null) return this
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is IrMemberAccessExpression<*> -> {
|
is IrMemberAccessExpression<*> -> {
|
||||||
@@ -333,7 +335,7 @@ class CallAndReferenceGenerator(
|
|||||||
val argumentMapping = call.argumentMapping
|
val argumentMapping = call.argumentMapping
|
||||||
if (argumentMapping != null && argumentMapping.isNotEmpty()) {
|
if (argumentMapping != null && argumentMapping.isNotEmpty()) {
|
||||||
if (valueParameters != null) {
|
if (valueParameters != null) {
|
||||||
return applyArgumentsWithReorderingIfNeeded(call, argumentMapping, valueParameters)
|
return applyArgumentsWithReorderingIfNeeded(call, argumentMapping, valueParameters, annotationMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ((index, argument) in call.arguments.withIndex()) {
|
for ((index, argument) in call.arguments.withIndex()) {
|
||||||
@@ -367,10 +369,11 @@ class CallAndReferenceGenerator(
|
|||||||
call: FirCall,
|
call: FirCall,
|
||||||
argumentMapping: Map<FirExpression, FirValueParameter>,
|
argumentMapping: Map<FirExpression, FirValueParameter>,
|
||||||
valueParameters: List<FirValueParameter>,
|
valueParameters: List<FirValueParameter>,
|
||||||
|
annotationMode: Boolean
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
// Assuming compile-time constants only inside annotation, we don't need a block to reorder arguments to preserve semantics.
|
// Assuming compile-time constants only inside annotation, we don't need a block to reorder arguments to preserve semantics.
|
||||||
// But, we still need to pick correct indices for named arguments.
|
// But, we still need to pick correct indices for named arguments.
|
||||||
if (call !is FirAnnotationCall &&
|
if (!annotationMode &&
|
||||||
needArgumentReordering(argumentMapping.values, valueParameters)
|
needArgumentReordering(argumentMapping.values, valueParameters)
|
||||||
) {
|
) {
|
||||||
return IrBlockImpl(startOffset, endOffset, type, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL).apply {
|
return IrBlockImpl(startOffset, endOffset, type, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL).apply {
|
||||||
@@ -391,9 +394,21 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for ((argument, parameter) in argumentMapping) {
|
for ((argument, parameter) in argumentMapping) {
|
||||||
val argumentExpression = visitor.convertToIrExpression(argument).applySamConversionIfNeeded(argument, parameter)
|
val argumentExpression =
|
||||||
|
visitor.convertToIrExpression(argument, annotationMode)
|
||||||
|
.applySamConversionIfNeeded(argument, parameter)
|
||||||
putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
|
putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
|
||||||
}
|
}
|
||||||
|
if (annotationMode) {
|
||||||
|
for ((index, parameter) in valueParameters.withIndex()) {
|
||||||
|
if (parameter.isVararg && !argumentMapping.containsValue(parameter)) {
|
||||||
|
val elementType = parameter.returnTypeRef.toIrType()
|
||||||
|
putValueArgument(
|
||||||
|
index, IrVarargImpl(-1, -1, elementType, elementType.toArrayOrPrimitiveArrayType(irBuiltIns))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -347,7 +347,7 @@ internal class ClassMemberGenerator(
|
|||||||
it.dispatchReceiver = visitor.convertToIrExpression(firDispatchReceiver)
|
it.dispatchReceiver = visitor.convertToIrExpression(firDispatchReceiver)
|
||||||
}
|
}
|
||||||
with(callGenerator) {
|
with(callGenerator) {
|
||||||
it.applyCallArguments(this@toIrDelegatingConstructorCall)
|
it.applyCallArguments(this@toIrDelegatingConstructorCall, annotationMode = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
FILE fqName:<root> fileName:/deprecated.kt
|
|
||||||
FUN name:create visibility:public modality:FINAL <> () returnType:kotlin.String
|
|
||||||
BLOCK_BODY
|
|
||||||
RETURN type=kotlin.Nothing from='public final fun create (): kotlin.String declared in <root>'
|
|
||||||
CONST String type=kotlin.String value="OK"
|
|
||||||
FUN name:create visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.String
|
|
||||||
annotations:
|
|
||||||
Deprecated(message = 'Use create() instead()', replaceWith = ReplaceWith(expression = 'create()', imports = <null>), level = <null>)
|
|
||||||
VALUE_PARAMETER name:s index:0 type:kotlin.String
|
|
||||||
BLOCK_BODY
|
|
||||||
RETURN type=kotlin.Nothing from='public final fun create (s: kotlin.String): kotlin.String declared in <root>'
|
|
||||||
CALL 'public final fun create (): kotlin.String declared in <root>' type=kotlin.String origin=null
|
|
||||||
FUN name:create visibility:public modality:FINAL <> (b:kotlin.Boolean) returnType:kotlin.String
|
|
||||||
annotations:
|
|
||||||
Deprecated(message = 'Use create() instead()', replaceWith = <null>, level = <null>)
|
|
||||||
VALUE_PARAMETER name:b index:0 type:kotlin.Boolean
|
|
||||||
BLOCK_BODY
|
|
||||||
RETURN type=kotlin.Nothing from='public final fun create (b: kotlin.Boolean): kotlin.String declared in <root>'
|
|
||||||
CALL 'public final fun create (): kotlin.String declared in <root>' type=kotlin.String origin=null
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun create() = "OK"
|
fun create() = "OK"
|
||||||
|
|||||||
Reference in New Issue
Block a user