JVM_IR: set dispatchReceiverParameter of imported JvmStatic object methods to null
This commit is contained in:
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.ir.util.isFunction
|
||||
import org.jetbrains.kotlin.ir.util.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME
|
||||
|
||||
/**
|
||||
@@ -120,3 +117,7 @@ fun JvmBackendContext.createJvmIrBuilder(
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
) = JvmIrBuilder(this, symbol, startOffset, endOffset)
|
||||
|
||||
|
||||
fun IrDeclaration.isInCurrentModule(): Boolean =
|
||||
getPackageFragment() is IrFile
|
||||
+31
-5
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
||||
@@ -18,6 +16,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInCurrentModule
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
@@ -192,6 +191,14 @@ private class MakeCallsStatic(
|
||||
) : IrElementTransformerVoid() {
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
if (expression.symbol.owner.isJvmStaticInSingleton() && expression.dispatchReceiver != null) {
|
||||
// Imported functions do not have their receiver parameter nulled by SingletonObjectJvmStaticLowering,
|
||||
// so we have to do it here.
|
||||
// TODO: would be better handled by lowering imported declarations.
|
||||
val callee = expression.symbol.owner as IrSimpleFunction
|
||||
val newCallee = if (!callee.isInCurrentModule()) {
|
||||
callee.copyRemovingDispatchReceiver() // TODO: cache these
|
||||
} else callee
|
||||
|
||||
return context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).irBlock(expression) {
|
||||
// OldReceiver has to be evaluated for its side effects.
|
||||
val oldReceiver = super.visitExpression(expression.dispatchReceiver!!)
|
||||
@@ -205,15 +212,34 @@ private class MakeCallsStatic(
|
||||
)
|
||||
|
||||
+super.visitExpression(oldReceiverVoid)
|
||||
expression.dispatchReceiver = null
|
||||
+super.visitCall(expression)
|
||||
+super.visitCall(
|
||||
irCall(expression, newFunction = newCallee).apply { dispatchReceiver = null }
|
||||
)
|
||||
}
|
||||
}
|
||||
return super.visitCall(expression)
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.copyRemovingDispatchReceiver(): IrSimpleFunction {
|
||||
val newDescriptor = WrappedSimpleFunctionDescriptor(descriptor)
|
||||
return IrFunctionImpl(
|
||||
startOffset, endOffset, origin,
|
||||
IrSimpleFunctionSymbolImpl(newDescriptor),
|
||||
name,
|
||||
visibility, modality, returnType, isInline, isExternal, isTailrec, isSuspend
|
||||
).also {
|
||||
newDescriptor.bind(it)
|
||||
it.parent = parent
|
||||
it.correspondingPropertySymbol = correspondingPropertySymbol
|
||||
it.annotations.addAll(annotations)
|
||||
it.copyParameterDeclarationsFrom(this)
|
||||
it.dispatchReceiverParameter = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isJvmStaticFunction(declaration: IrDeclaration): Boolean =
|
||||
declaration is IrSimpleFunction &&
|
||||
(declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) ||
|
||||
declaration.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true)
|
||||
|
||||
|
||||
+3
-1
@@ -94,7 +94,9 @@ private class StaticDefaultCallLowering(
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val callee = expression.symbol.owner
|
||||
if (callee.origin !== IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER || callee.dispatchReceiverParameter == null) {
|
||||
if (callee.origin !== IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||
expression.dispatchReceiver == null
|
||||
) {
|
||||
return super.visitCall(expression)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
// FILE: 1.kt
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (A.test() != "OK") return "fail 1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
object A {
|
||||
|
||||
@JvmStatic fun test(b: String = "OK") : String {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: A.kt
|
||||
|
||||
|
||||
+5
@@ -15240,6 +15240,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/default.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultCrossFile.kt")
|
||||
public void testDefaultCrossFile() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/defaultCrossFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumCompanion.kt")
|
||||
public void testEnumCompanion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/enumCompanion.kt");
|
||||
|
||||
+5
@@ -15240,6 +15240,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/default.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultCrossFile.kt")
|
||||
public void testDefaultCrossFile() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/defaultCrossFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumCompanion.kt")
|
||||
public void testEnumCompanion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/enumCompanion.kt");
|
||||
|
||||
+5
@@ -14125,6 +14125,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/default.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultCrossFile.kt")
|
||||
public void testDefaultCrossFile() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/defaultCrossFile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumCompanion.kt")
|
||||
public void testEnumCompanion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/enumCompanion.kt");
|
||||
|
||||
Reference in New Issue
Block a user