JVM IR: Don't generate line numbers and null checks in SAM wrapper constructors
This commit is contained in:
committed by
Alexander Udalov
parent
68e2d0d245
commit
8574cb4466
Generated
+5
@@ -4314,6 +4314,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperConstructorNonSynthetic.kt")
|
||||
public void testSamWrapperConstructorNonSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperConstructorNonSynthetic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperForNullInitialization.kt")
|
||||
public void testSamWrapperForNullInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperForNullInitialization.kt");
|
||||
|
||||
+6
-2
@@ -69,6 +69,10 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
protected open fun getWrappedFunctionType(klass: IrClass): IrType =
|
||||
klass.defaultType
|
||||
|
||||
protected open fun IrFunctionBuilder.setConstructorSourceRange(createFor: IrElement) {
|
||||
setSourceRange(createFor)
|
||||
}
|
||||
|
||||
abstract val IrType.needEqualsHashCodeMethods: Boolean
|
||||
|
||||
open val inInlineFunctionScope get() = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
|
||||
@@ -187,10 +191,10 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
}
|
||||
|
||||
subclass.addConstructor {
|
||||
origin = subclass.origin
|
||||
origin = IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION
|
||||
isPrimary = true
|
||||
visibility = wrapperVisibility
|
||||
setSourceRange(createFor)
|
||||
setConstructorSourceRange(createFor)
|
||||
}.apply {
|
||||
val parameter = addValueParameter {
|
||||
name = field.name
|
||||
|
||||
+6
-3
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getNameForReceiverParameter
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SuspensionPointKind
|
||||
import org.jetbrains.kotlin.codegen.coroutines.generateCoroutineSuspendedCheck
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
@@ -48,7 +48,8 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
@@ -285,7 +286,9 @@ class ExpressionCodegen(
|
||||
irFunction.origin.isSynthetic ||
|
||||
// TODO: refine this condition to not generate nullability assertions on parameters
|
||||
// corresponding to captured variables and anonymous object super constructor arguments
|
||||
(irFunction is IrConstructor && irFunction.parentAsClass.isAnonymousObject) ||
|
||||
(irFunction is IrConstructor &&
|
||||
(irFunction.parentAsClass.isAnonymousObject ||
|
||||
irFunction.parentAsClass.origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION)) ||
|
||||
// TODO: Implement this as a lowering, so that we can more easily exclude generated methods.
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
// Although these are accessible from Java, the functions they bridge to already have the assertions.
|
||||
|
||||
+10
@@ -12,6 +12,9 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.rawType
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.IrFunctionBuilder
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
@@ -47,6 +50,13 @@ private class JvmSingleAbstractMethodLowering(context: JvmBackendContext) : Sing
|
||||
override fun getWrappedFunctionType(klass: IrClass): IrType =
|
||||
klass.symbol.rawType(context as JvmBackendContext)
|
||||
|
||||
// The constructor of a SAM wrapper is non-synthetic and should not have line numbers.
|
||||
// Otherwise the debugger will try to step into it.
|
||||
override fun IrFunctionBuilder.setConstructorSourceRange(createFor: IrElement) {
|
||||
startOffset = UNDEFINED_OFFSET
|
||||
endOffset = UNDEFINED_OFFSET
|
||||
}
|
||||
|
||||
private val IrType.isKotlinFunInterface: Boolean
|
||||
get() = getClass()?.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// FILE: J.java
|
||||
|
||||
public class J {
|
||||
public static void g(Runnable r) {
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun nonInlineFun() {
|
||||
val f = {}
|
||||
J.g(f)
|
||||
}
|
||||
|
||||
inline fun inlineFun() {
|
||||
val f = {}
|
||||
J.g(f)
|
||||
}
|
||||
|
||||
// The SAM wrapper constructor is public inside of inline functions.
|
||||
// It has no other flags. In particular, it is not synthetic.
|
||||
// 1 access flags 0x0\n\s*<init>\(Lkotlin/jvm/functions/Function0;\)V
|
||||
// 1 access flags 0x1\n\s*public <init>\(Lkotlin/jvm/functions/Function0;\)V
|
||||
@@ -4386,6 +4386,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperConstructorNonSynthetic.kt")
|
||||
public void testSamWrapperConstructorNonSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperConstructorNonSynthetic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperForNullInitialization.kt")
|
||||
public void testSamWrapperForNullInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperForNullInitialization.kt");
|
||||
|
||||
+5
@@ -4314,6 +4314,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/sam"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperConstructorNonSynthetic.kt")
|
||||
public void testSamWrapperConstructorNonSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperConstructorNonSynthetic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperForNullInitialization.kt")
|
||||
public void testSamWrapperForNullInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperForNullInitialization.kt");
|
||||
|
||||
Reference in New Issue
Block a user