diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 44df66c5807..f75f6872237 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -597,18 +597,33 @@ public class AsmUtil { // Private method is not accessible from other classes, no assertions needed if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) return; - for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) { - JetType type = parameter.getReturnType(); - if (type == null || isNullableType(type)) continue; + ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); + if (receiverParameter != null) { + genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, "$receiver"); + } - int index = frameMap.getIndex(parameter); - Type asmType = state.getTypeMapper().mapType(type); - if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { - v.load(index, asmType); - v.visitLdcInsn(parameter.getName().asString()); - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkParameterIsNotNull", - "(Ljava/lang/Object;Ljava/lang/String;)V", false); - } + for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) { + genParamAssertion(v, state.getTypeMapper(), frameMap, parameter, parameter.getName().asString()); + } + } + + private static void genParamAssertion( + @NotNull InstructionAdapter v, + @NotNull JetTypeMapper typeMapper, + @NotNull FrameMap frameMap, + @NotNull CallableDescriptor parameter, + @NotNull String name + ) { + JetType type = parameter.getReturnType(); + if (type == null || isNullableType(type)) return; + + int index = frameMap.getIndex(parameter); + Type asmType = typeMapper.mapType(type); + if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { + v.load(index, asmType); + v.visitLdcInsn(name); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkParameterIsNotNull", + "(Ljava/lang/Object;Ljava/lang/String;)V", false); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 73592206aab..29c15d7ae74 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -731,7 +731,13 @@ public class FunctionCodegen { } for (JvmMethodParameterSignature parameter : signature.getValueParameters()) { - if (parameter.getKind() != JvmMethodParameterKind.VALUE) { + if (parameter.getKind() == JvmMethodParameterKind.RECEIVER) { + ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter(); + if (receiverParameter != null) { + frameMap.enter(receiverParameter, state.getTypeMapper().mapType(receiverParameter)); + } + } + else if (parameter.getKind() != JvmMethodParameterKind.VALUE) { frameMap.enterTemp(parameter.getAsmType()); } } diff --git a/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/Test.java b/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/Test.java new file mode 100644 index 00000000000..47310b9a80a --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/Test.java @@ -0,0 +1,17 @@ +public class Test { + public static String invokeFoo() { + try { + _DefaultPackage.foo(null); + } + catch (IllegalArgumentException e) { + try { + _DefaultPackage.getBar(null); + } + catch (IllegalArgumentException f) { + return "OK"; + } + } + + return "Fail: assertion must have been fired"; + } +} diff --git a/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/extension.kt b/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/extension.kt new file mode 100644 index 00000000000..465cb26e91a --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/extension.kt @@ -0,0 +1,7 @@ +fun Any.foo() { } + +val Any.bar: String get() = "" + +fun box(): String { + return Test.invokeFoo() +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/GenerationUtils.java b/compiler/tests/org/jetbrains/kotlin/codegen/GenerationUtils.java index 8ba76751bef..19cae5201e5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/GenerationUtils.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/GenerationUtils.java @@ -22,6 +22,8 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.codegen.state.GenerationState; +import org.jetbrains.kotlin.codegen.state.Progress; +import org.jetbrains.kotlin.diagnostics.DiagnosticSink; import org.jetbrains.kotlin.psi.JetFile; import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil; @@ -58,8 +60,12 @@ public class GenerationUtils { @NotNull List files ) { analysisResult.throwIfError(); - GenerationState state = new GenerationState(project, ClassBuilderFactories.TEST, analysisResult.getModuleDescriptor(), - analysisResult.getBindingContext(), files); + GenerationState state = new GenerationState( + project, ClassBuilderFactories.TEST, Progress.DEAF, + analysisResult.getModuleDescriptor(), analysisResult.getBindingContext(), + files, false, false, GenerationState.GenerateClassFilter.GENERATE_ALL, + false, false, null, null, DiagnosticSink.DO_NOTHING, null + ); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); return state; } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index f262a15cb0b..9832e5a50f9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -30,7 +30,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithJava") @TestDataPath("$PROJECT_ROOT") -@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxWithJavaCodegenTestGenerated.PlatformStatic.class, BlackBoxWithJavaCodegenTestGenerated.Properties.class}) +@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxWithJavaCodegenTestGenerated.NotNullAssertions.class, BlackBoxWithJavaCodegenTestGenerated.PlatformStatic.class, BlackBoxWithJavaCodegenTestGenerated.Properties.class}) @RunWith(JUnit3RunnerWithInners.class) public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithJava() throws Exception { @@ -84,6 +84,23 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } + @TestMetadata("compiler/testData/codegen/boxWithJava/notNullAssertions") + @TestDataPath("$PROJECT_ROOT") + @InnerTestClasses({}) + @RunWith(JUnit3RunnerWithInners.class) + public static class NotNullAssertions extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInNotNullAssertions() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/notNullAssertions"), Pattern.compile("^([^\\.]+)$"), true); + } + + @TestMetadata("extensionReceiverParameter") + public void testExtensionReceiverParameter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/notNullAssertions/extensionReceiverParameter/"); + doTestWithJava(fileName); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithJava/platformStatic") @TestDataPath("$PROJECT_ROOT") @InnerTestClasses({})