JVM_IR: fix default argument stub visibility.
Match the rules from the old backend: 1. Private and inline only methods get package private default argument stubs. 2. Everything else is public.
This commit is contained in:
committed by
Alexander Udalov
parent
7f319c18de
commit
1b1dff9191
+25
-10
@@ -49,7 +49,8 @@ open class DefaultArgumentStubGenerator(
|
||||
}
|
||||
|
||||
private fun lower(irFunction: IrFunction): List<IrFunction> {
|
||||
val newIrFunction = irFunction.generateDefaultsFunction(context, skipInlineMethods, skipExternalMethods)
|
||||
val visibility = defaultArgumentStubVisibility(irFunction)
|
||||
val newIrFunction = irFunction.generateDefaultsFunction(context, skipInlineMethods, skipExternalMethods, visibility)
|
||||
?: return listOf(irFunction)
|
||||
if (newIrFunction.origin == IrDeclarationOrigin.FAKE_OVERRIDE) {
|
||||
return listOf(irFunction, newIrFunction)
|
||||
@@ -185,6 +186,8 @@ open class DefaultArgumentStubGenerator(
|
||||
error("This method should be overridden")
|
||||
}
|
||||
|
||||
protected open fun defaultArgumentStubVisibility(function: IrFunction) = Visibilities.PUBLIC
|
||||
|
||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||
}
|
||||
|
||||
@@ -271,8 +274,8 @@ open class DefaultParameterInjector(
|
||||
val startOffset = expression.startOffset
|
||||
val endOffset = expression.endOffset
|
||||
val declaration = expression.symbol.owner
|
||||
|
||||
val stubOverride = declaration.generateDefaultsFunction(context, skipInline, skipExternalMethods) ?: return null
|
||||
val visibility = defaultArgumentStubVisibility(declaration)
|
||||
val stubOverride = declaration.generateDefaultsFunction(context, skipInline, skipExternalMethods, visibility) ?: return null
|
||||
// We *have* to resolve the fake override here since on the JVM, a default stub for a function implemented
|
||||
// in an interface does not leave an abstract method after being moved to DefaultImpls (see InterfaceLowering).
|
||||
// Calling the fake override on an implementation of that interface would then result in a call to a method
|
||||
@@ -319,6 +322,8 @@ open class DefaultParameterInjector(
|
||||
protected open fun nullConst(startOffset: Int, endOffset: Int, type: IrType): IrExpression =
|
||||
IrConstImpl.defaultValueForType(startOffset, endOffset, type)
|
||||
|
||||
protected open fun defaultArgumentStubVisibility(function: IrFunction) = Visibilities.PUBLIC
|
||||
|
||||
private fun log(msg: () -> String) = context.log { "DEFAULT-INJECTOR: ${msg()}" }
|
||||
}
|
||||
|
||||
@@ -333,7 +338,8 @@ class DefaultParameterCleaner constructor(val context: CommonBackendContext) : F
|
||||
private fun IrFunction.generateDefaultsFunction(
|
||||
context: CommonBackendContext,
|
||||
skipInlineMethods: Boolean,
|
||||
skipExternalMethods: Boolean
|
||||
skipExternalMethods: Boolean,
|
||||
visibility: Visibility
|
||||
): IrFunction? {
|
||||
if (skipInlineMethods && isInline) return null
|
||||
if (skipExternalMethods && isExternalOrInheritedFromExternal()) return null
|
||||
@@ -341,10 +347,15 @@ private fun IrFunction.generateDefaultsFunction(
|
||||
if (this is IrSimpleFunction) {
|
||||
// If this is an override of a function with default arguments, produce a fake override of a default stub.
|
||||
val overriddenStubs = overriddenSymbols.mapNotNull {
|
||||
it.owner.generateDefaultsFunction(context, skipInlineMethods, skipExternalMethods)?.symbol as IrSimpleFunctionSymbol?
|
||||
it.owner.generateDefaultsFunction(
|
||||
context,
|
||||
skipInlineMethods,
|
||||
skipExternalMethods,
|
||||
visibility
|
||||
)?.symbol as IrSimpleFunctionSymbol?
|
||||
}
|
||||
if (overriddenStubs.isNotEmpty()) {
|
||||
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE).also {
|
||||
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE, visibility).also {
|
||||
(it as IrSimpleFunction).overriddenSymbols.addAll(overriddenStubs)
|
||||
context.ir.defaultParameterDeclarationsCache[this] = it
|
||||
}
|
||||
@@ -361,14 +372,18 @@ private fun IrFunction.generateDefaultsFunction(
|
||||
// Since this bug causes the metadata serializer to write the "has default value" flag into compiled
|
||||
// binaries, it's way too late to fix it. Hence the workaround.
|
||||
if (valueParameters.any { it.defaultValue != null }) {
|
||||
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER).also {
|
||||
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, visibility).also {
|
||||
context.ir.defaultParameterDeclarationsCache[this] = it
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContext, newOrigin: IrDeclarationOrigin): IrFunction {
|
||||
private fun IrFunction.generateDefaultsFunctionImpl(
|
||||
context: CommonBackendContext,
|
||||
newOrigin: IrDeclarationOrigin,
|
||||
newVisibility: Visibility
|
||||
): IrFunction {
|
||||
val newFunction = when (this) {
|
||||
is IrConstructor ->
|
||||
buildConstructor {
|
||||
@@ -377,7 +392,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContex
|
||||
isExternal = false
|
||||
isPrimary = false
|
||||
isExpect = false
|
||||
visibility = Visibilities.PUBLIC
|
||||
visibility = newVisibility
|
||||
}
|
||||
is IrSimpleFunction ->
|
||||
buildFunWithDescriptorForInlining(descriptor) {
|
||||
@@ -387,7 +402,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(context: CommonBackendContex
|
||||
modality = Modality.FINAL
|
||||
isExternal = false
|
||||
isTailrec = false
|
||||
visibility = Visibilities.PUBLIC
|
||||
visibility = newVisibility
|
||||
}
|
||||
else -> throw IllegalStateException("Unknown function type")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user