JVM_IR: make CallableReferenceLowering a bit shorter
This commit is contained in:
+86
-222
@@ -31,21 +31,15 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.isPrimaryInlineClassConstructor
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
@@ -88,13 +82,11 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
val callee = expression.symbol.owner
|
||||
if (callee.isInlineFunctionCall(context)) {
|
||||
//TODO: more wise filtering
|
||||
callee.valueParameters.forEach { valueParameter ->
|
||||
for (valueParameter in callee.valueParameters) {
|
||||
if (valueParameter.isInlineParameter()) {
|
||||
expression.getValueArgument(valueParameter.index)?.let {
|
||||
if (isInlineIrExpression(it)) {
|
||||
(it as IrBlock).statements.filterIsInstance<IrFunctionReference>().forEach { reference ->
|
||||
inlineLambdaReferences.add(reference)
|
||||
}
|
||||
inlineLambdaReferences += (it as IrBlock).statements.filterIsInstance<IrFunctionReference>()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,7 +95,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
|
||||
val argumentsCount = expression.valueArgumentsCount
|
||||
// Change calls to FunctionN with large N to varargs calls.
|
||||
val newCall = if (argumentsCount > MAX_ARGCOUNT_WITHOUT_VARARG &&
|
||||
val newCall = if (argumentsCount >= FunctionInvokeDescriptor.Factory.BIG_ARITY &&
|
||||
callee.parentAsClass.defaultType.isFunctionOrKFunction()
|
||||
) {
|
||||
val vararg = IrVarargImpl(
|
||||
@@ -145,8 +137,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
|
||||
val currentDeclarationParent = allScopes.map { it.irElement }.last { it is IrDeclarationParent } as IrDeclarationParent
|
||||
val loweredFunctionReference = FunctionReferenceBuilder(currentDeclarationParent, expression).build()
|
||||
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset)
|
||||
return irBuilder.irBlock(expression) {
|
||||
return context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol).irBlock(expression) {
|
||||
+loweredFunctionReference.functionReferenceClass
|
||||
+irCall(loweredFunctionReference.functionReferenceConstructor.symbol).apply {
|
||||
expression.getArguments().forEachIndexed { index, argument ->
|
||||
@@ -158,6 +149,14 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
})
|
||||
}
|
||||
|
||||
private val arrayGetFun by lazy {
|
||||
context.irBuiltIns.arrayClass.owner.functions.find { it.name.asString() == "get" }!!
|
||||
}
|
||||
|
||||
private val arraySizeProperty by lazy {
|
||||
context.irBuiltIns.arrayClass.owner.properties.find { it.name.toString() == "size" }!!
|
||||
}
|
||||
|
||||
private class BuiltFunctionReference(
|
||||
val functionReferenceClass: IrClass,
|
||||
val functionReferenceConstructor: IrConstructor
|
||||
@@ -182,7 +181,6 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
}
|
||||
|
||||
private lateinit var functionReferenceClass: IrClass
|
||||
private lateinit var functionReferenceThis: IrValueParameterSymbol
|
||||
private lateinit var argumentToFieldMap: Map<IrValueParameter, IrField>
|
||||
|
||||
private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA
|
||||
@@ -196,13 +194,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
val functionReferenceClassSuperTypes: MutableList<IrType> = mutableListOf(functionReferenceOrLambda.owner.defaultType)
|
||||
|
||||
val numberOfParameters = unboundCalleeParameters.size
|
||||
useVararg = (numberOfParameters > MAX_ARGCOUNT_WITHOUT_VARARG)
|
||||
useVararg = (numberOfParameters >= FunctionInvokeDescriptor.Factory.BIG_ARITY)
|
||||
|
||||
val functionClassSymbol = if (useVararg)
|
||||
context.ir.symbols.functionN
|
||||
else
|
||||
context.ir.symbols.getJvmFunctionClass(numberOfParameters)
|
||||
val functionClass = functionClassSymbol.owner
|
||||
val functionParameterTypes = unboundCalleeParameters.map { it.type }
|
||||
val functionClassTypeParameters = if (useVararg)
|
||||
listOf(returnType)
|
||||
@@ -236,88 +233,53 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = "${callee.name.safeName()}\$${functionReferenceCount++}".synthesizedName
|
||||
kind = ClassKind.CLASS
|
||||
visibility = Visibilities.PUBLIC
|
||||
modality = Modality.FINAL
|
||||
}.apply {
|
||||
parent = referenceParent
|
||||
superTypes.addAll(functionReferenceClassSuperTypes)
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
}
|
||||
|
||||
functionReferenceThis = functionReferenceClass.thisReceiver!!.symbol
|
||||
|
||||
argumentToFieldMap = boundCalleeParameters.associate {
|
||||
it to buildField(it.name.safeName(), it.type)
|
||||
}
|
||||
|
||||
val constructor = createConstructor()
|
||||
functionReferenceClass.declarations.add(constructor)
|
||||
|
||||
val superInvokeFunction = functionClass.functions.find { it.name.asString() == "invoke" }!!
|
||||
val invokeMethod = createInvokeMethod(superInvokeFunction)
|
||||
functionReferenceClass.declarations.add(invokeMethod)
|
||||
createInvokeMethod(functionClassSymbol.owner.functions.find { it.name.asString() == "invoke" }!!)
|
||||
|
||||
if (!isLambda) {
|
||||
val getSignatureMethod =
|
||||
createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!)
|
||||
val getNameMethod =
|
||||
createGetNameMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getName" }!!)
|
||||
val getOwnerMethod =
|
||||
createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!)
|
||||
|
||||
val suspendInvokeMethod =
|
||||
if (suspendFunctionClass != null) {
|
||||
val suspendInvokeFunction =
|
||||
suspendFunctionClass.functions.find { it.name.asString() == "invoke" }!!
|
||||
createInvokeMethod(suspendInvokeFunction)
|
||||
} else null
|
||||
|
||||
functionReferenceClass.declarations.add(getSignatureMethod)
|
||||
functionReferenceClass.declarations.add(getNameMethod)
|
||||
functionReferenceClass.declarations.add(getOwnerMethod)
|
||||
suspendInvokeMethod?.let { functionReferenceClass.declarations.add(it) }
|
||||
createGetSignatureMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getSignature"}!!)
|
||||
createGetNameMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getName" }!!)
|
||||
createGetOwnerMethod(functionReferenceOrLambda.owner.functions.find { it.name.asString() == "getOwner" }!!)
|
||||
if (suspendFunctionClass != null) {
|
||||
createInvokeMethod(suspendFunctionClass.functions.find { it.name.asString() == "invoke" }!!)
|
||||
}
|
||||
}
|
||||
|
||||
return BuiltFunctionReference(functionReferenceClass, constructor)
|
||||
}
|
||||
|
||||
private fun createConstructor(): IrConstructor =
|
||||
buildConstructor {
|
||||
functionReferenceClass.addConstructor {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
visibility = Visibilities.PUBLIC
|
||||
returnType = functionReferenceClass.defaultType
|
||||
isPrimary = true
|
||||
}.apply {
|
||||
val constructor = this
|
||||
parent = functionReferenceClass
|
||||
|
||||
val boundArgsSet = boundCalleeParameters.toSet()
|
||||
for (param in callee.explicitParameters) {
|
||||
if (param in boundArgsSet) {
|
||||
val newParam = param.copyTo(
|
||||
constructor,
|
||||
index = valueParameters.size,
|
||||
type = param.type.substitute(typeArgumentsMap)
|
||||
)
|
||||
valueParameters.add(newParam)
|
||||
}
|
||||
for (param in boundCalleeParameters) {
|
||||
valueParameters += param.copyTo(
|
||||
this,
|
||||
index = valueParameters.size,
|
||||
type = param.type.substitute(typeArgumentsMap)
|
||||
)
|
||||
}
|
||||
|
||||
val kFunctionRefConstructorSymbol =
|
||||
functionReferenceOrLambda.constructors.filter { it.owner.valueParameters.size == if (isLambda) 1 else 2 }.single()
|
||||
|
||||
val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
|
||||
body = irBuilder.irBlockBody {
|
||||
+IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||
kFunctionRefConstructorSymbol, kFunctionRefConstructorSymbol.descriptor
|
||||
).apply {
|
||||
val const =
|
||||
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundCalleeParameters.size)
|
||||
putValueArgument(0, const)
|
||||
|
||||
body = context.createIrBuilder(symbol).irBlockBody(startOffset, endOffset) {
|
||||
+irDelegatingConstructorCall(kFunctionRefConstructorSymbol.owner).apply {
|
||||
putValueArgument(0, irInt(unboundCalleeParameters.size))
|
||||
if (!isLambda) {
|
||||
val irReceiver = valueParameters.firstOrNull()
|
||||
val receiver = boundCalleeParameters.singleOrNull()
|
||||
@@ -333,7 +295,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
//TODO don't write receiver again: use it from base class
|
||||
boundCalleeParameters.forEachIndexed { index, it ->
|
||||
+irSetField(
|
||||
irGet(functionReferenceThis.owner),
|
||||
irGet(functionReferenceClass.thisReceiver!!),
|
||||
argumentToFieldMap[it]!!,
|
||||
irGet(valueParameters[index])
|
||||
)
|
||||
@@ -342,61 +304,27 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.invokeInlineClassConstructor(irConstructor: IrConstructor): IrBody {
|
||||
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||
val param = irConstructor.valueParameters[0].copyTo(this)
|
||||
valueParameters.add(param)
|
||||
val from = irConstructor.valueParameters[0].type
|
||||
val to = irConstructor.returnType
|
||||
val call = irBuilder.irCall(context.ir.symbols.unsafeCoerceIntrinsicSymbol, to, listOf(from, to)).apply {
|
||||
putValueArgument(0, irBuilder.irGet(param))
|
||||
}
|
||||
return irBuilder.irExprBody(call)
|
||||
}
|
||||
|
||||
private fun createInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
|
||||
buildFun {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = Name.identifier("invoke")
|
||||
visibility = Visibilities.PUBLIC
|
||||
returnType = callee.returnType
|
||||
isSuspend = superFunction.isSuspend
|
||||
}.apply {
|
||||
val function = this
|
||||
parent = functionReferenceClass
|
||||
overriddenSymbols.add(superFunction.symbol)
|
||||
buildOverride(superFunction, callee.returnType).apply {
|
||||
annotations.addAll(callee.annotations)
|
||||
|
||||
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
|
||||
|
||||
if (callee.isPrimaryInlineClassConstructor) {
|
||||
body = invokeInlineClassConstructor(callee as IrConstructor)
|
||||
return this
|
||||
}
|
||||
|
||||
val unboundArgsSet = unboundCalleeParameters.toSet()
|
||||
if (useVararg) {
|
||||
valueParameters.add(superFunction.valueParameters[0].copyTo(function))
|
||||
valueParameters.add(superFunction.valueParameters[0].copyTo(this))
|
||||
} else {
|
||||
for (param in callee.explicitParameters) {
|
||||
if (param in unboundArgsSet) {
|
||||
val newParam = param.copyTo(
|
||||
function,
|
||||
index = valueParameters.size,
|
||||
type = param.type.substitute(typeArgumentsMap)
|
||||
)
|
||||
valueParameters.add(newParam)
|
||||
}
|
||||
for (param in unboundCalleeParameters) {
|
||||
valueParameters += param.copyTo(
|
||||
this,
|
||||
index = valueParameters.size,
|
||||
type = param.type.substitute(typeArgumentsMap)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
val arrayGetFun = context.irBuiltIns.arrayClass.owner.functions.find { it.name.asString() == "get" }!!
|
||||
if (useVararg) {
|
||||
val varargParam = valueParameters.single()
|
||||
val arraySizeProperty = context.irBuiltIns.arrayClass.owner.properties.find { it.name.toString() == "size" }!!
|
||||
+irIfThen(
|
||||
irNotEquals(
|
||||
irCall(arraySizeProperty.getter!!).apply {
|
||||
@@ -422,11 +350,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
!unboundArgsSet.contains(parameter) ->
|
||||
// Bound parameter - read from field.
|
||||
irGetField(irGet(dispatchReceiverParameter!!), argumentToFieldMap[parameter]!!)
|
||||
function.isSuspend && unboundIndex == valueParameters.size ->
|
||||
|
||||
isSuspend && unboundIndex == valueParameters.size ->
|
||||
// For suspend functions the last argument is continuation and it is implicit.
|
||||
// irCall(getContinuationSymbol, listOf(ourSymbol.descriptor.returnType!!))
|
||||
TODO()
|
||||
// irCall(getContinuationSymbol,
|
||||
// listOf(ourSymbol.descriptor.returnType!!))
|
||||
|
||||
useVararg -> {
|
||||
val type = parameter.type
|
||||
val varargParam = valueParameters.single()
|
||||
@@ -446,14 +375,12 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
+irGet(argValue)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
||||
else ->
|
||||
irGet(valueParameters[unboundIndex++])
|
||||
}
|
||||
}
|
||||
putArgument(callee, parameter, argument)
|
||||
}
|
||||
|
||||
if (!useVararg) assert(unboundIndex == valueParameters.size) { "Not all arguments of <invoke> are used" }
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -461,113 +388,56 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
}
|
||||
|
||||
private fun buildField(fieldName: Name, fieldType: IrType): IrField =
|
||||
buildField {
|
||||
functionReferenceClass.addField {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = fieldName
|
||||
type = fieldType
|
||||
visibility = JavaVisibilities.PACKAGE_VISIBILITY
|
||||
isFinal = true
|
||||
}.also {
|
||||
it.parent = functionReferenceClass
|
||||
functionReferenceClass.declarations.add(it)
|
||||
}
|
||||
|
||||
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
|
||||
buildFun {
|
||||
private fun buildOverride(superFunction: IrSimpleFunction, newReturnType: IrType = superFunction.returnType): IrSimpleFunction =
|
||||
functionReferenceClass.addFunction {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = Name.identifier("getSignature")
|
||||
returnType = superFunction.returnType
|
||||
origin = functionReferenceClass.origin
|
||||
name = superFunction.name
|
||||
returnType = newReturnType
|
||||
visibility = superFunction.visibility
|
||||
modality = superFunction.modality
|
||||
isSuspend = superFunction.isSuspend
|
||||
}.apply {
|
||||
val function = this
|
||||
parent = functionReferenceClass
|
||||
overriddenSymbols.add(superFunction.symbol)
|
||||
dispatchReceiverParameter = functionReferenceClass.thisReceiver!!.copyTo(function)
|
||||
|
||||
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
+irReturn(
|
||||
IrConstImpl.string(
|
||||
-1, -1, context.irBuiltIns.stringType,
|
||||
PropertyReferenceCodegen.getSignatureString(
|
||||
irFunctionReference.symbol.descriptor, this@CallableReferenceLowering.context.state
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
overriddenSymbols += superFunction.symbol
|
||||
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(this)
|
||||
}
|
||||
|
||||
private val IrFunction.originalName: Name
|
||||
get() = (metadata as? MetadataSource.Function)?.descriptor?.name ?: name
|
||||
|
||||
private fun createGetNameMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
|
||||
buildFun {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = Name.identifier("getName")
|
||||
returnType = superFunction.returnType
|
||||
visibility = superFunction.visibility
|
||||
modality = superFunction.modality
|
||||
}.apply {
|
||||
val function = this
|
||||
parent = functionReferenceClass
|
||||
overriddenSymbols.add(superFunction.symbol)
|
||||
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
|
||||
|
||||
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
+irReturn(
|
||||
IrConstImpl.string(-1, -1, context.irBuiltIns.stringType, callee.originalName.asString())
|
||||
)
|
||||
}
|
||||
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||
val state = context.state
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run {
|
||||
// TODO do not use descriptors
|
||||
irExprBody(irString(PropertyReferenceCodegen.getSignatureString(irFunctionReference.symbol.descriptor, state)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction =
|
||||
buildFun {
|
||||
setSourceRange(functionReferenceClass)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = Name.identifier("getOwner")
|
||||
returnType = superFunction.returnType
|
||||
visibility = superFunction.visibility
|
||||
modality = superFunction.modality
|
||||
}.apply {
|
||||
val function = this
|
||||
parent = functionReferenceClass
|
||||
overriddenSymbols.add(superFunction.symbol)
|
||||
dispatchReceiverParameter = functionReferenceClass.thisReceiver?.copyTo(function)
|
||||
|
||||
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||
+irReturn(
|
||||
generateCallableReferenceDeclarationContainer()
|
||||
)
|
||||
}
|
||||
private fun createGetNameMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run {
|
||||
irExprBody(irString(callee.originalName.asString()))
|
||||
}
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.generateCallableReferenceDeclarationContainer(): IrExpression {
|
||||
val globalContext = this@CallableReferenceLowering.context
|
||||
private fun createGetOwnerMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||
val globalContext = context
|
||||
val state = globalContext.state
|
||||
val irContainer = callee.parent
|
||||
|
||||
val isContainerPackage =
|
||||
((irContainer as? IrClass)?.origin == IrDeclarationOrigin.FILE_CLASS) || irContainer is IrPackageFragment
|
||||
|
||||
val type = when {
|
||||
irContainer is IrClass ->
|
||||
// TODO: getDefaultType() here is wrong and won't work for arrays
|
||||
state.typeMapper.mapType(irContainer.defaultType.toKotlinType())
|
||||
|
||||
// // TODO: this code is only needed for property references, which are not yet supported.
|
||||
// descriptor is VariableDescriptorWithAccessors -> {
|
||||
// assert(false) { "VariableDescriptorWithAccessors" }
|
||||
// globalContext.state.bindingContext.get(
|
||||
// CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, descriptor
|
||||
// )!!
|
||||
// }
|
||||
|
||||
val type = when (irContainer) {
|
||||
// TODO: getDefaultType() here is wrong and won't work for arrays
|
||||
is IrClass -> state.typeMapper.mapType(irContainer.defaultType.toKotlinType())
|
||||
else -> state.typeMapper.mapOwner(callee.descriptor)
|
||||
}
|
||||
|
||||
@@ -580,22 +450,20 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
CrIrType(type)
|
||||
)
|
||||
|
||||
return if (isContainerPackage) {
|
||||
// Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
|
||||
// but there's no nice API to obtain that name here yet
|
||||
// TODO: write the referenced declaration's module name and use it in reflection
|
||||
val module = IrConstImpl.string(
|
||||
-1, -1, globalContext.irBuiltIns.stringType,
|
||||
state.moduleName
|
||||
)
|
||||
irCall(globalContext.ir.symbols.getOrCreateKotlinPackage).apply {
|
||||
putValueArgument(0, clazzRef)
|
||||
putValueArgument(1, module)
|
||||
}
|
||||
} else {
|
||||
irCall(globalContext.ir.symbols.getOrCreateKotlinClass).apply {
|
||||
putValueArgument(0, clazzRef)
|
||||
}
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run {
|
||||
irExprBody(if (isContainerPackage) {
|
||||
irCall(globalContext.ir.symbols.getOrCreateKotlinPackage).apply {
|
||||
putValueArgument(0, clazzRef)
|
||||
// Note that this name is not used in reflection. There should be the name of the referenced declaration's
|
||||
// module instead, but there's no nice API to obtain that name here yet
|
||||
// TODO: write the referenced declaration's module name and use it in reflection
|
||||
putValueArgument(1, irString(state.moduleName))
|
||||
}
|
||||
} else {
|
||||
irCall(globalContext.ir.symbols.getOrCreateKotlinClass).apply {
|
||||
putValueArgument(0, clazzRef)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -607,8 +475,4 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
Name.identifier("$${name.substring(1, name.length - 1)}")
|
||||
} else this
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_ARGCOUNT_WITHOUT_VARARG = 22
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -44,7 +45,7 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
|
||||
val invokeFunctions = irClass.filterDeclarations<IrSimpleFunction> { it.name.toString() == "invoke" }
|
||||
if (invokeFunctions.isEmpty() ||
|
||||
invokeFunctions.any { it.valueParameters.size > 0 && it.valueParameters.last().varargElementType != null } ||
|
||||
invokeFunctions.all { it.valueParameters.size + (if (it.extensionReceiverParameter != null) 1 else 0) <= CallableReferenceLowering.MAX_ARGCOUNT_WITHOUT_VARARG }
|
||||
invokeFunctions.all { it.valueParameters.size + (if (it.extensionReceiverParameter != null) 1 else 0) < FunctionInvokeDescriptor.Factory.BIG_ARITY }
|
||||
) {
|
||||
// No need to add a new vararg invoke method
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user