Generate $default functions for inline ones in JVM-backend

This commit is contained in:
Mikhael Bogdanov
2018-04-19 13:28:20 +02:00
parent e6c88755e9
commit 97ad3f9ddd
2 changed files with 9 additions and 9 deletions
@@ -55,7 +55,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext): DeclarationContainerLoweringPass { open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true): DeclarationContainerLoweringPass {
override fun lower(irDeclarationContainer: IrDeclarationContainer) { override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat { memberDeclaration -> irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
if (memberDeclaration is IrFunction) if (memberDeclaration is IrFunction)
@@ -71,7 +71,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
private fun lower(irFunction: IrFunction): List<IrFunction> { private fun lower(irFunction: IrFunction): List<IrFunction> {
val functionDescriptor = irFunction.descriptor val functionDescriptor = irFunction.descriptor
if (!functionDescriptor.needsDefaultArgumentsLowering) if (!functionDescriptor.needsDefaultArgumentsLowering(skipInlineMethods))
return listOf(irFunction) return listOf(irFunction)
val bodies = functionDescriptor.valueParameters val bodies = functionDescriptor.valueParameters
@@ -225,14 +225,14 @@ private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
} }
} }
class DefaultParameterInjector constructor(val context: CommonBackendContext): BodyLoweringPass { class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true): BodyLoweringPass {
override fun lower(irBody: IrBody) { override fun lower(irBody: IrBody) {
irBody.transformChildrenVoid(object : IrElementTransformerVoid() { irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
super.visitDelegatingConstructorCall(expression) super.visitDelegatingConstructorCall(expression)
val descriptor = expression.descriptor val descriptor = expression.descriptor
if (!descriptor.needsDefaultArgumentsLowering) if (!descriptor.needsDefaultArgumentsLowering(skipInline))
return expression return expression
val argumentsCount = argumentCount(expression) val argumentsCount = argumentCount(expression)
if (argumentsCount == descriptor.valueParameters.size) if (argumentsCount == descriptor.valueParameters.size)
@@ -257,7 +257,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext): B
super.visitCall(expression) super.visitCall(expression)
val functionDescriptor = expression.descriptor val functionDescriptor = expression.descriptor
if (!functionDescriptor.needsDefaultArgumentsLowering) if (!functionDescriptor.needsDefaultArgumentsLowering(skipInline))
return expression return expression
val argumentsCount = argumentCount(expression) val argumentsCount = argumentCount(expression)
@@ -292,7 +292,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext): B
private fun parametersForCall(expression: IrMemberAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> { private fun parametersForCall(expression: IrMemberAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
val descriptor = expression.descriptor as FunctionDescriptor val descriptor = expression.descriptor as FunctionDescriptor
val keyDescriptor = if (DescriptorUtils.isOverride(descriptor)) val keyDescriptor = if (DescriptorUtils.isOverride(descriptor))
DescriptorUtils.getAllOverriddenDescriptors(descriptor).first { it.needsDefaultArgumentsLowering } DescriptorUtils.getAllOverriddenDescriptors(descriptor).first { it.needsDefaultArgumentsLowering(skipInline) }
else else
descriptor.original descriptor.original
val realFunction = keyDescriptor.generateDefaultsFunction(context) val realFunction = keyDescriptor.generateDefaultsFunction(context)
@@ -344,8 +344,8 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext): B
private fun log(msg: () -> String) = context.log { "DEFAULT-INJECTOR: ${msg()}" } private fun log(msg: () -> String) = context.log { "DEFAULT-INJECTOR: ${msg()}" }
} }
private val CallableMemberDescriptor.needsDefaultArgumentsLowering private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
get() = valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline) valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendContext): IrFunction { private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendContext): IrFunction {
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) { return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
@@ -35,7 +35,7 @@ class JvmLower(val context: JvmBackendContext) {
PropertiesLowering().lower(irFile) PropertiesLowering().lower(irFile)
//Should be before interface lowering //Should be before interface lowering
DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile) DefaultArgumentStubGenerator(context, false).runOnFilePostfix(irFile)
StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile) StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile)
InterfaceLowering(context.state).runOnFilePostfix(irFile) InterfaceLowering(context.state).runOnFilePostfix(irFile)