Generate nullability annotations on this receiver in DefaultImpls. Don't generate nullability annotations in private methods

#KT-36969 Fixed
This commit is contained in:
Mikhail Bogdanov
2020-06-08 11:57:16 +02:00
parent 5bdf3d5757
commit b8f0ad2111
17 changed files with 121 additions and 37 deletions
@@ -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);
}
}
}
@@ -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 */ }
}
}
@@ -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
View File
@@ -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
View File
@@ -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
}
+12
View File
@@ -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
}
@@ -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,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,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
View File
@@ -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
@@ -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");
@@ -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");