Generate nullability annotations on this receiver in DefaultImpls. Don't generate nullability annotations in private methods
#KT-36969 Fixed
This commit is contained in:
@@ -105,6 +105,15 @@ public abstract class AnnotationCodegen {
|
||||
@Nullable Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@Nullable KotlinType typeForTypeAnnotations
|
||||
) {
|
||||
genAnnotations(annotated, returnType, typeForTypeAnnotations, null);
|
||||
}
|
||||
|
||||
public void genAnnotations(
|
||||
@Nullable Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@Nullable KotlinType typeForTypeAnnotations,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer
|
||||
) {
|
||||
if (annotated == null) return;
|
||||
|
||||
@@ -139,22 +148,23 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent);
|
||||
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
|
||||
generateTypeAnnotations(annotated, typeForTypeAnnotations);
|
||||
}
|
||||
|
||||
private void generateAdditionalAnnotations(
|
||||
@NotNull Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer
|
||||
) {
|
||||
if (annotated instanceof CallableDescriptor) {
|
||||
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent);
|
||||
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
|
||||
}
|
||||
else if (annotated instanceof FieldDescriptor) {
|
||||
generateAdditionalCallableAnnotations(
|
||||
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent
|
||||
);
|
||||
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent,
|
||||
parameterContainer);
|
||||
}
|
||||
else if (annotated instanceof ClassDescriptor) {
|
||||
generateAdditionalClassAnnotations(annotationDescriptorsAlreadyPresent, (ClassDescriptor) annotated);
|
||||
@@ -164,11 +174,15 @@ public abstract class AnnotationCodegen {
|
||||
private void generateAdditionalCallableAnnotations(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@Nullable Type returnType,
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer
|
||||
) {
|
||||
// No need to annotate privates, synthetic accessors and their parameters
|
||||
if (isInvisibleFromTheOutside(descriptor)) return;
|
||||
if (descriptor instanceof ValueParameterDescriptor && isInvisibleFromTheOutside(descriptor.getContainingDeclaration())) return;
|
||||
if (descriptor instanceof ParameterDescriptor &&
|
||||
isInvisibleFromTheOutside(parameterContainer != null ? parameterContainer : descriptor.getContainingDeclaration())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to annotate annotation methods since they're always non-null
|
||||
if (descriptor instanceof PropertyGetterDescriptor &&
|
||||
|
||||
@@ -492,11 +492,11 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull MemberCodegen<?> memberCodegen,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
generateParameterAnnotations(
|
||||
functionDescriptor, mv, jvmSignature, functionDescriptor.getValueParameters(), innerClassConsumer, state
|
||||
functionDescriptor, mv, jvmSignature, functionDescriptor.getValueParameters(), memberCodegen, state
|
||||
);
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ public class FunctionCodegen {
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull MemberCodegen<?> memberCodegen,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
if (isAccessor(functionDescriptor)) return;
|
||||
@@ -516,6 +516,7 @@ public class FunctionCodegen {
|
||||
|
||||
Asm7UtilKt.visitAnnotableParameterCount(mv, kotlinParameterTypes.size() - syntheticParameterCount);
|
||||
|
||||
boolean isDefaultImpl = OwnerKind.DEFAULT_IMPLS == memberCodegen.context.getContextKind();
|
||||
for (int i = 0; i < kotlinParameterTypes.size(); i++) {
|
||||
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
|
||||
JvmMethodParameterKind kind = parameterSignature.getKind();
|
||||
@@ -528,13 +529,14 @@ public class FunctionCodegen {
|
||||
? iterator.next()
|
||||
: kind == JvmMethodParameterKind.RECEIVER
|
||||
? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter()
|
||||
: null;
|
||||
: isDefaultImpl && kind == JvmMethodParameterKind.THIS ? JvmCodegenUtil.getDirectMember(functionDescriptor)
|
||||
.getDispatchReceiverParameter() : null;
|
||||
|
||||
if (annotated != null) {
|
||||
//noinspection ConstantConditions
|
||||
int parameterIndex = i - syntheticParameterCount;
|
||||
AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state)
|
||||
.genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType());
|
||||
AnnotationCodegen.forParameter(parameterIndex, mv, memberCodegen, state)
|
||||
.genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType(), functionDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ public interface B extends p.A {
|
||||
|
||||
static final class DefaultImpls {
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public static java.lang.String b(p.B $this) { /* compiled code */ }
|
||||
public static java.lang.String b(@org.jetbrains.annotations.NotNull p.B $this) { /* compiled code */ }
|
||||
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public static java.lang.String a(p.B $this) { /* compiled code */ }
|
||||
public static java.lang.String a(@org.jetbrains.annotations.NotNull p.B $this) { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ public final class Component1Kt {
|
||||
@kotlin.Metadata
|
||||
public final class Foo$DefaultImpls {
|
||||
inner class Foo$DefaultImpls
|
||||
public static @org.jetbrains.annotations.Nullable method component1(p0: Foo, @org.jetbrains.annotations.NotNull p1: Result, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object
|
||||
public static @org.jetbrains.annotations.Nullable method component1(@org.jetbrains.annotations.NotNull p0: Foo, @org.jetbrains.annotations.NotNull p1: Result, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
interface Result
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class FieldKt {
|
||||
@kotlin.Metadata
|
||||
public final class Foo$DefaultImpls {
|
||||
inner class Foo$DefaultImpls
|
||||
public static @org.jetbrains.annotations.NotNull method getValue(p0: Foo, @org.jetbrains.annotations.NotNull p1: Result): java.lang.Object
|
||||
public static @org.jetbrains.annotations.NotNull method getValue(@org.jetbrains.annotations.NotNull p0: Foo, @org.jetbrains.annotations.NotNull p1: Result): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
|
||||
+19
-4
@@ -1,18 +1,33 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
interface A
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class Anno
|
||||
|
||||
interface B {
|
||||
fun foo()
|
||||
fun foo(a: String)
|
||||
}
|
||||
|
||||
interface C {
|
||||
val bar: Int
|
||||
}
|
||||
|
||||
@Anno
|
||||
interface D {
|
||||
fun baz() = 5
|
||||
fun baz(p: String) = 5
|
||||
private fun test(a: String) = "123"
|
||||
}
|
||||
|
||||
interface E {
|
||||
class InsideE
|
||||
}
|
||||
}
|
||||
|
||||
@Anno
|
||||
interface F {
|
||||
var bar: String
|
||||
get() = "123"
|
||||
set(value) {}
|
||||
|
||||
private var baz: String
|
||||
get() = "123"
|
||||
set(value) {}
|
||||
}
|
||||
|
||||
+27
-3
@@ -1,9 +1,14 @@
|
||||
@kotlin.Metadata
|
||||
public interface A
|
||||
|
||||
@kotlin.annotation.Retention
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Anno
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface B {
|
||||
public abstract method foo(): void
|
||||
public abstract method foo(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@@ -14,13 +19,15 @@ public interface C {
|
||||
@kotlin.Metadata
|
||||
public final class D$DefaultImpls {
|
||||
inner class D$DefaultImpls
|
||||
public static method baz(p0: D): int
|
||||
public static method baz(@org.jetbrains.annotations.NotNull p0: D, @org.jetbrains.annotations.NotNull p1: java.lang.String): int
|
||||
private static method test(p0: D, p1: java.lang.String): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@Anno
|
||||
public interface D {
|
||||
inner class D$DefaultImpls
|
||||
public abstract method baz(): int
|
||||
public abstract method baz(@org.jetbrains.annotations.NotNull p0: java.lang.String): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@@ -33,3 +40,20 @@ public final class E$InsideE {
|
||||
public interface E {
|
||||
inner class E$InsideE
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class F$DefaultImpls {
|
||||
inner class F$DefaultImpls
|
||||
public static @org.jetbrains.annotations.NotNull method getBar(@org.jetbrains.annotations.NotNull p0: F): java.lang.String
|
||||
private static method getBaz(p0: F): java.lang.String
|
||||
public static method setBar(@org.jetbrains.annotations.NotNull p0: F, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
|
||||
private static method setBaz(p0: F, p1: java.lang.String): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@Anno
|
||||
public interface F {
|
||||
inner class F$DefaultImpls
|
||||
public abstract @org.jetbrains.annotations.NotNull method getBar(): java.lang.String
|
||||
public abstract method setBar(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
fun String.test() {}
|
||||
|
||||
private fun String.testPrivate() {}
|
||||
|
||||
var String.prop
|
||||
get() = "123"
|
||||
set(value) {}
|
||||
|
||||
private var String.propPrivate
|
||||
get() = "123"
|
||||
set(value) {}
|
||||
@@ -0,0 +1,9 @@
|
||||
@kotlin.Metadata
|
||||
public final class ExtensionKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method getProp(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String
|
||||
private final static method getPropPrivate(p0: java.lang.String): java.lang.String
|
||||
public final static method setProp(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
|
||||
private final static method setPropPrivate(p0: java.lang.String, p1: java.lang.String): void
|
||||
public final static method test(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
private final static method testPrivate(p0: java.lang.String): void
|
||||
}
|
||||
+4
-4
@@ -14,8 +14,8 @@ public final class Z {
|
||||
public final static method getInternalExtensionVar-impl$test_module(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): int
|
||||
public final static method getInternalVal-impl$test_module(p0: int): int
|
||||
public final static method getInternalVar-impl$test_module(p0: int): int
|
||||
private final static method getPrivateExtensionVal-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): int
|
||||
private final static method getPrivateExtensionVar-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): int
|
||||
private final static method getPrivateExtensionVal-impl(p0: int, p1: java.lang.String): int
|
||||
private final static method getPrivateExtensionVar-impl(p0: int, p1: java.lang.String): int
|
||||
private final static method getPrivateVal-impl(p0: int): int
|
||||
private final static method getPrivateVar-impl(p0: int): int
|
||||
public final static method getPublicExtensionVal-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): int
|
||||
@@ -27,13 +27,13 @@ public final class Z {
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public final static method internalExtensionFun-impl$test_module(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
|
||||
public final static method internalFun-impl$test_module(p0: int): void
|
||||
private final static method privateExtensionFun-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
|
||||
private final static method privateExtensionFun-impl(p0: int, p1: java.lang.String): void
|
||||
private final static method privateFun-impl(p0: int): void
|
||||
public final static method publicExtensionFun-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
|
||||
public final static method publicFun-impl(p0: int): void
|
||||
public final static method setInternalExtensionVar-impl$test_module(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String, p2: int): void
|
||||
public final static method setInternalVar-impl$test_module(p0: int, p1: int): void
|
||||
private final static method setPrivateExtensionVar-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String, p2: int): void
|
||||
private final static method setPrivateExtensionVar-impl(p0: int, p1: java.lang.String, p2: int): void
|
||||
private final static method setPrivateVar-impl(p0: int, p1: int): void
|
||||
public final static method setPublicExtensionVar-impl(p0: int, @org.jetbrains.annotations.NotNull p1: java.lang.String, p2: int): void
|
||||
public final static method setPublicVar-impl(p0: int, p1: int): void
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
interface A {
|
||||
// There must be no delegation methods for 'log' and 'bar' in C as they are private
|
||||
private val log: String get() = "O"
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
public final class A$DefaultImpls {
|
||||
inner class A$DefaultImpls
|
||||
private static method bar(p0: A): java.lang.String
|
||||
public static @org.jetbrains.annotations.NotNull method foo(p0: A): java.lang.String
|
||||
public static @org.jetbrains.annotations.NotNull method foo(@org.jetbrains.annotations.NotNull p0: A): java.lang.String
|
||||
private static method getLog(p0: A): java.lang.String
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public interface A {
|
||||
@kotlin.Metadata
|
||||
public final class B$DefaultImpls {
|
||||
inner class B$DefaultImpls
|
||||
public static @org.jetbrains.annotations.NotNull method foo(p0: B): java.lang.String
|
||||
public static @org.jetbrains.annotations.NotNull method foo(@org.jetbrains.annotations.NotNull p0: B): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
|
||||
@@ -106,8 +106,8 @@ public abstract class A8 {
|
||||
@kotlin.Metadata
|
||||
public final class I1$DefaultImpls {
|
||||
inner class I1$DefaultImpls
|
||||
public static method contains(p0: I1, p1: java.lang.Object): boolean
|
||||
public static method containsAll(p0: I1, @org.jetbrains.annotations.NotNull p1: java.util.Collection): boolean
|
||||
public static method contains(@org.jetbrains.annotations.NotNull p0: I1, p1: java.lang.Object): boolean
|
||||
public static method containsAll(@org.jetbrains.annotations.NotNull p0: I1, @org.jetbrains.annotations.NotNull p1: java.util.Collection): boolean
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@@ -120,8 +120,8 @@ public interface I1 {
|
||||
@kotlin.Metadata
|
||||
public final class I2$DefaultImpls {
|
||||
inner class I2$DefaultImpls
|
||||
public static method contains(p0: I2, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean
|
||||
public static method containsAll(p0: I2, @org.jetbrains.annotations.NotNull p1: java.util.Collection): boolean
|
||||
public static method contains(@org.jetbrains.annotations.NotNull p0: I2, @org.jetbrains.annotations.NotNull p1: java.lang.String): boolean
|
||||
public static method containsAll(@org.jetbrains.annotations.NotNull p0: I2, @org.jetbrains.annotations.NotNull p1: java.util.Collection): boolean
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
@kotlin.Metadata
|
||||
public final class A$DefaultImpls {
|
||||
inner class A$DefaultImpls
|
||||
public static method a(p0: A): void
|
||||
public static method a(@org.jetbrains.annotations.NotNull p0: A): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
|
||||
+5
@@ -59,6 +59,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/emptyMultifileFacade.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/extension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("immutableCollection.kt")
|
||||
public void testImmutableCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/immutableCollection.kt");
|
||||
|
||||
+5
@@ -59,6 +59,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
runTest("compiler/testData/codegen/bytecodeListing/emptyMultifileFacade.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/extension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("immutableCollection.kt")
|
||||
public void testImmutableCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/immutableCollection.kt");
|
||||
|
||||
Reference in New Issue
Block a user