From e11fda1c49a6e3e18545719c46025a0f63e25ae2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 26 Feb 2019 17:21:33 +0300 Subject: [PATCH] [JS IR BE] Skip external methods in js default arguments stub generators --- .../lower/DefaultArgumentStubGenerator.kt | 38 ++++++++++--------- .../kotlin/ir/backend/js/JsLoweringPhases.kt | 2 +- .../lower/JsDefaultArgumentStubGenerator.kt | 2 +- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index 0d30338a23c..2f68bbf0183 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -42,7 +42,8 @@ val jvmDefaultArgumentStubPhase = makeIrFilePhase( open class DefaultArgumentStubGenerator( open val context: CommonBackendContext, - private val skipInlineMethods: Boolean = true + private val skipInlineMethods: Boolean = true, + private val skipExternalMethods: Boolean = false ) : DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { @@ -57,7 +58,7 @@ open class DefaultArgumentStubGenerator( private val symbols get() = context.ir.symbols private fun lower(irFunction: IrFunction): List { - if (!irFunction.needsDefaultArgumentsLowering(skipInlineMethods)) + if (!irFunction.needsDefaultArgumentsLowering(skipInlineMethods, skipExternalMethods)) return listOf(irFunction) val bodies = irFunction.valueParameters.mapNotNull { it.defaultValue } @@ -67,13 +68,13 @@ open class DefaultArgumentStubGenerator( if (bodies.isEmpty()) { // Fake override - val newIrFunction = irFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FAKE_OVERRIDE, skipInlineMethods) + val newIrFunction = irFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FAKE_OVERRIDE, skipInlineMethods, skipExternalMethods) return listOf(irFunction, newIrFunction) } val newIrFunction = - irFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, skipInlineMethods) + irFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, skipInlineMethods, skipExternalMethods) log { "$irFunction -> $newIrFunction" } val builder = context.createIrBuilder(newIrFunction.symbol) @@ -209,7 +210,8 @@ val DEFAULT_DISPATCH_CALL = object : IrStatementOriginImpl("DEFAULT_DISPATCH_CAL open class DefaultParameterInjector( val context: CommonBackendContext, - private val skipInline: Boolean = true + private val skipInline: Boolean = true, + private val skipExternalMethods: Boolean = false ) : FileLoweringPass { override fun lower(irFile: IrFile) { @@ -219,7 +221,7 @@ open class DefaultParameterInjector( val declaration = expression.symbol.owner as IrFunction - if (!declaration.needsDefaultArgumentsLowering(skipInline)) + if (!declaration.needsDefaultArgumentsLowering(skipInline, skipExternalMethods)) return expression val argumentsCount = argumentCount(expression) @@ -250,7 +252,7 @@ open class DefaultParameterInjector( super.visitCall(expression) val functionDeclaration = expression.symbol.owner - if (!functionDeclaration.needsDefaultArgumentsLowering(skipInline)) + if (!functionDeclaration.needsDefaultArgumentsLowering(skipInline, skipExternalMethods)) return expression val argumentsCount = argumentCount(expression) @@ -293,7 +295,7 @@ open class DefaultParameterInjector( } private fun IrFunction.findSuperMethodWithDefaultArguments(): IrFunction? { - if (!needsDefaultArgumentsLowering(skipInline)) return null + if (!needsDefaultArgumentsLowering(skipInline, skipExternalMethods)) return null if (this !is IrSimpleFunction) return this @@ -309,7 +311,7 @@ open class DefaultParameterInjector( val keyFunction = declaration.findSuperMethodWithDefaultArguments()!! val realFunction = - keyFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, skipInline) + keyFunction.generateDefaultsFunction(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, skipInline, skipExternalMethods) log { "$declaration -> $realFunction" } val maskValues = Array((declaration.valueParameters.size + 31) / 32) { 0 } @@ -389,20 +391,21 @@ class DefaultParameterCleaner constructor(val context: CommonBackendContext) : F } // TODO this implementation is exponential -private fun IrFunction.needsDefaultArgumentsLowering(skipInlineMethods: Boolean): Boolean { +private fun IrFunction.needsDefaultArgumentsLowering(skipInlineMethods: Boolean, skipExternalMethods: Boolean): Boolean { if (isInline && skipInlineMethods) return false - if (isEffectivelyExternal()) return false + if (skipExternalMethods && isEffectivelyExternal()) return false if (valueParameters.any { it.defaultValue != null }) return true if (this !is IrSimpleFunction) return false - return overriddenSymbols.any { it.owner.needsDefaultArgumentsLowering(skipInlineMethods) } + return overriddenSymbols.any { it.owner.needsDefaultArgumentsLowering(skipInlineMethods, skipExternalMethods) } } private fun IrFunction.generateDefaultsFunctionImpl( context: CommonBackendContext, origin: IrDeclarationOrigin, - skipInlineMethods: Boolean + skipInlineMethods: Boolean, + skipExternalMethods: Boolean ): IrFunction { val newFunction = buildFunctionDeclaration(this, origin) @@ -440,13 +443,13 @@ private fun IrFunction.generateDefaultsFunctionImpl( if (origin == IrDeclarationOrigin.FAKE_OVERRIDE) { for (baseFunSymbol in (this as IrSimpleFunction).overriddenSymbols) { val baseFun = baseFunSymbol.owner - if (baseFun.needsDefaultArgumentsLowering(skipInlineMethods)) { + if (baseFun.needsDefaultArgumentsLowering(skipInlineMethods, skipExternalMethods)) { val baseOrigin = if (baseFun.valueParameters.any { it.defaultValue != null }) { IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER } else { IrDeclarationOrigin.FAKE_OVERRIDE } - val defaultsBaseFun = baseFun.generateDefaultsFunction(context, baseOrigin, skipInlineMethods) + val defaultsBaseFun = baseFun.generateDefaultsFunction(context, baseOrigin, skipInlineMethods, skipExternalMethods) (newFunction as IrSimpleFunction).overriddenSymbols.add((defaultsBaseFun as IrSimpleFunction).symbol) } } @@ -504,10 +507,11 @@ private fun buildFunctionDeclaration(irFunction: IrFunction, origin: IrDeclarati private fun IrFunction.generateDefaultsFunction( context: CommonBackendContext, origin: IrDeclarationOrigin, - skipInlineMethods: Boolean + skipInlineMethods: Boolean, + skipExternalMethods: Boolean ): IrFunction = context.ir.defaultParameterDeclarationsCache.getOrPut(this) { - generateDefaultsFunctionImpl(context, origin, skipInlineMethods) + generateDefaultsFunctionImpl(context, origin, skipInlineMethods, skipExternalMethods) } private fun IrFunction.valueParameter(index: Int, name: Name, type: IrType): IrValueParameter { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index e42601b6618..ab3c87630b9 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -225,7 +225,7 @@ private val defaultArgumentStubGeneratorPhase = makeJsModulePhase( ) private val defaultParameterInjectorPhase = makeJsModulePhase( - ::DefaultParameterInjector, + { context -> DefaultParameterInjector(context, skipExternalMethods = true) }, name = "DefaultParameterInjector", description = "Replace callsite with default parameters with corresponding stub function", prerequisite = setOf(callableReferenceLoweringPhase, innerClassesLoweringPhase) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsDefaultArgumentStubGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsDefaultArgumentStubGenerator.kt index 615480ef2fc..ccebb59edee 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsDefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsDefaultArgumentStubGenerator.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : DefaultArgumentStubGenerator(context, true) { +class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : DefaultArgumentStubGenerator(context, true, false) { override fun needSpecialDispatch(irFunction: IrSimpleFunction) = irFunction.isOverridableOrOverrides