diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 6901ac9c355..9ad15d26a98 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -571,7 +571,7 @@ public class AsmUtil { ) { if (!state.isGenerateNotNullAssertions()) return; - if (!Boolean.TRUE.equals(state.getBindingContext().get(BindingContext.IS_DECLARED_IN_JAVA, descriptor))) return; + if (!isDeclaredInJava(descriptor, state.getBindingContext())) return; JetType type = descriptor.getReturnType(); if (type == null || type.isNullable()) return; @@ -585,6 +585,19 @@ public class AsmUtil { } } + private static boolean isDeclaredInJava(@NotNull CallableDescriptor callableDescriptor, @NotNull BindingContext context) { + CallableDescriptor descriptor = callableDescriptor; + while (true) { + if (Boolean.TRUE.equals(context.get(BindingContext.IS_DECLARED_IN_JAVA, descriptor))) { + return true; + } + CallableDescriptor original = descriptor.getOriginal(); + if (descriptor == original) break; + descriptor = original; + } + return false; + } + public static void pushDefaultValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) { if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { v.aconst(null); diff --git a/compiler/testData/codegen/notNullAssertions/arrayListGet.kt b/compiler/testData/codegen/notNullAssertions/arrayListGet.kt new file mode 100644 index 00000000000..faa7b14f68b --- /dev/null +++ b/compiler/testData/codegen/notNullAssertions/arrayListGet.kt @@ -0,0 +1,9 @@ +import java.util.ArrayList + +fun foo() { + val a = ArrayList() + a.get(0) +} + +fun bar(a: ArrayList) { +} diff --git a/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.java b/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.java new file mode 100644 index 00000000000..07e6b9c7168 --- /dev/null +++ b/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.java @@ -0,0 +1,18 @@ +import org.jetbrains.annotations.NotNull; + +class A { + @NotNull + T foo() { return null; } +} + +class B extends A { + @Override + @NotNull + T foo() { return null; } +} + +class C extends B { + @Override + @NotNull + String foo() { return null; } +} diff --git a/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.kt b/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.kt new file mode 100644 index 00000000000..4a4db6a194f --- /dev/null +++ b/compiler/testData/codegen/notNullAssertions/javaMultipleSubstitutions.kt @@ -0,0 +1,5 @@ +fun bar(a: A, b: B, c: C) { + val sa: String = a.foo() + val sb: String = b.foo() + val sc: String = c.foo() +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/GenerateNotNullAssertionsTest.java b/compiler/tests/org/jetbrains/jet/codegen/GenerateNotNullAssertionsTest.java index 5b9e7834c6d..d2e0a1b53ef 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/GenerateNotNullAssertionsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/GenerateNotNullAssertionsTest.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.asm4.ClassReader; import org.jetbrains.asm4.ClassVisitor; import org.jetbrains.asm4.MethodVisitor; @@ -116,6 +117,28 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase { assertNoIntrinsicsMethodIsCalled("A"); } + public void testArrayListGet() { + setUpEnvironment(true, true); + + loadFile("notNullAssertions/arrayListGet.kt"); + String text = generateToText(); + + assertTrue(text.contains("checkReturnedValueIsNotNull")); + assertTrue(text.contains("checkParameterIsNotNull")); + } + + public void testJavaMultipleSubstitutions() { + File javaClassesTempDirectory = compileJava("notNullAssertions/javaMultipleSubstitutions.java"); + setUpEnvironment(true, true, javaClassesTempDirectory); + + loadFile("notNullAssertions/javaMultipleSubstitutions.kt"); + String text = generateToText(); + + assertEquals(3, StringUtil.getOccurrenceCount(text, "checkReturnedValueIsNotNull")); + assertEquals(3, StringUtil.getOccurrenceCount(text, "checkParameterIsNotNull")); + } + + private void assertNoIntrinsicsMethodIsCalled(String className) { ClassFileFactory classes = generateClassesInFile(); ClassReader reader = new ClassReader(classes.asBytes(className + ".class"));