diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 43ce22b24c0..b3319ef32b8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -558,7 +558,7 @@ public class FunctionCodegen { mv.visitLabel(methodEntry); context.setMethodStartLabel(methodEntry); - if (!KotlinTypeMapper.isAccessor(functionDescriptor)) { + if (!strategy.skipNotNullAssertionsForParameters()) { genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap); } @@ -1383,6 +1383,11 @@ public class FunctionCodegen { iv.areturn(delegateMethod.getReturnType()); } + + @Override + public boolean skipNotNullAssertionsForParameters() { + return false; + } } ); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java index d11e209f615..9c6bd696c00 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java @@ -34,6 +34,8 @@ public abstract class FunctionGenerationStrategy { @NotNull MemberCodegen parentCodegen ); + public abstract boolean skipNotNullAssertionsForParameters(); + public MethodVisitor wrapMethodVisitor(@NotNull MethodVisitor mv, int access, @NotNull String name, @NotNull String desc) { return mv; } @@ -76,6 +78,12 @@ public abstract class FunctionGenerationStrategy { doGenerateBody(codegen, signature); } + @Override + public boolean skipNotNullAssertionsForParameters() { + // Assume the strategy injects non-null checks for parameters by default + return false; + } + public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 6e3d16e280e..2168bafc397 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -671,6 +671,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } iv.areturn(componentType); } + + @Override + public boolean skipNotNullAssertionsForParameters() { + return false; + } }); } @@ -719,6 +724,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.areturn(thisDescriptorType); } + @Override + public boolean skipNotNullAssertionsForParameters() { + return false; + } + private void pushCapturedFieldsOnStack(InstructionAdapter iv, MutableClosure closure) { ClassDescriptor captureThis = closure.getCaptureThis(); if (captureThis != null) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticInCompanionObjectGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticInCompanionObjectGenerator.kt index fb6f3fbc2f5..00703c8fa64 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticInCompanionObjectGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticInCompanionObjectGenerator.kt @@ -44,6 +44,8 @@ class JvmStaticInCompanionObjectGenerator( Synthetic(originElement, staticFunctionDescriptor), staticFunctionDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) { + override fun skipNotNullAssertionsForParameters(): Boolean = true + override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { val iv = codegen.v val classDescriptor = descriptor.containingDeclaration as ClassDescriptor diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 3348073079e..6f57bf7ab66 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -719,6 +719,11 @@ public abstract class MemberCodegen) { throw IllegalStateException("shouldn't be called") } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index e06cabb4bcd..0765c3ad29a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -531,6 +531,10 @@ class CoroutineCodegenForNamedFunction private constructor( private const val COROUTINE_LAMBDA_PARAMETER_PREFIX = "p$" private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy() { + override fun skipNotNullAssertionsForParameters(): kotlin.Boolean { + error("This functions must not be called") + } + override fun generateBody( mv: MethodVisitor, frameMap: FrameMap, diff --git a/compiler/testData/codegen/bytecodeText/kt7188.kt b/compiler/testData/codegen/bytecodeText/kt7188.kt new file mode 100644 index 00000000000..63d853e0b7e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/kt7188.kt @@ -0,0 +1,46 @@ +// WITH_RUNTIME +// TARGET_BACKEND: JVM + +// FILE: Dummy.kt +// Empty body to trigger multifile test mode + +// FILE: Test.kt +class TestMethod { + companion object { + @JvmStatic + fun test(s0: String, s1: String?) = s0 + (s1 ?: "null") + } +} + +class TestMethodOverloads { + companion object { + @JvmStatic + @JvmOverloads + fun test(s0: String = "s0", s1: String = "s1", s2: String = "s2") = s0 + s1 + s2 + } +} + +class TestProperty { + companion object { + @JvmStatic + var prop: String = "Blah" + } +} + +class TestAccessor { + companion object { + var prop: String = "Blah" @JvmStatic set + } +} + +// @TestMethod.class: +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V + +// @TestMethodOverloads.class: +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V + +// @TestProperty.class: +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V + +// @TestAccessor.class: +// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index ddf677db5c1..98d9b81a934 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -282,6 +282,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("kt7188.kt") + public void testKt7188() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt7188.kt"); + doTest(fileName); + } + @TestMetadata("kt7769.kt") public void testKt7769() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt7769.kt");