From 6e0bb0b46868eca07572eb4ea91bdde2b414c3de Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 2 Jul 2020 15:15:31 +0300 Subject: [PATCH] JVM: no nullability annotations for inline class '-impl' methods Specialized generated methods for inline classes (toString-impl, hashCode-impl, equals-impl, etc) are inaccessible from Java, and thus don't require nullability annotations. --- .../kotlin/codegen/FunctionCodegen.java | 23 +++++++++++-------- .../FunctionsFromAnyGeneratorImpl.java | 23 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 127d6374ccb..399c10ab7af 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -33,10 +33,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; -import org.jetbrains.kotlin.resolve.DescriptorUtils; -import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt; +import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt; import org.jetbrains.kotlin.resolve.constants.ArrayValue; @@ -219,7 +216,9 @@ public class FunctionCodegen { recordMethodForFunctionIfAppropriate(functionDescriptor, asmMethod); - boolean skipNullabilityAnnotations = (flags & ACC_PRIVATE) != 0 || (flags & ACC_SYNTHETIC) != 0; + boolean skipNullabilityAnnotations = + (flags & ACC_PRIVATE) != 0 || (flags & ACC_SYNTHETIC) != 0 || + InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor); generateMethodAnnotationsIfRequired( functionDescriptor, asmMethod, jvmSignature, mv, isCompatibilityStubInDefaultImpls ? Collections.singletonList(Deprecated.class) : Collections.emptyList(), @@ -533,14 +532,18 @@ public class FunctionCodegen { ? iterator.next() : kind == JvmMethodParameterKind.RECEIVER ? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter() - : isDefaultImpl && kind == JvmMethodParameterKind.THIS ? JvmCodegenUtil.getDirectMember(functionDescriptor) - .getDispatchReceiverParameter() : null; + : kind == JvmMethodParameterKind.THIS && isDefaultImpl + ? JvmCodegenUtil.getDirectMember(functionDescriptor).getDispatchReceiverParameter() + : null; if (annotated != null) { - //noinspection ConstantConditions int parameterIndex = i - syntheticParameterCount; - AnnotationCodegen.forParameter(parameterIndex, mv, memberCodegen, state, skipNullabilityAnnotations) - .genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType(), functionDescriptor, Collections.emptyList()); + AnnotationCodegen + .forParameter(parameterIndex, mv, memberCodegen, state, skipNullabilityAnnotations) + .genAnnotations( + annotated, parameterSignature.getAsmType(), annotated.getReturnType(), functionDescriptor, + Collections.emptyList() + ); } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java index 588ebea55c4..e0f74e102ac 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionsFromAnyGeneratorImpl.java @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.PropertyDescriptor; -import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.psi.KtClassOrObject; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt; @@ -46,6 +45,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { private final GenerationState generationState; private final KotlinTypeMapper typeMapper; private final JvmKotlinType underlyingType; + private final boolean isInErasedInlineClass; public FunctionsFromAnyGeneratorImpl( @NotNull KtClassOrObject declaration, @@ -67,23 +67,27 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { typeMapper.mapType(descriptor), InlineClassesUtilsKt.substitutedUnderlyingType(descriptor.getDefaultType()) ); + this.isInErasedInlineClass = fieldOwnerContext.getContextKind() == OwnerKind.ERASED_INLINE_CLASS; } @Override protected void generateToStringMethod( - @NotNull FunctionDescriptor function, @NotNull List properties + @NotNull FunctionDescriptor function, + @NotNull List properties ) { MethodContext context = fieldOwnerContext.intoFunction(function); JvmDeclarationOrigin methodOrigin = JvmDeclarationOriginKt.OtherOrigin(function); String toStringMethodName = mapFunctionName(function); MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), toStringMethodName, getToStringDesc(), null, null); - if (fieldOwnerContext.getContextKind() != OwnerKind.ERASED_INLINE_CLASS && classDescriptor.isInline()) { + if (!isInErasedInlineClass && classDescriptor.isInline()) { FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper); return; } - visitEndForAnnotationVisitor(mv.visitAnnotation(Type.getDescriptor(NotNull.class), false)); + if (!isInErasedInlineClass) { + visitEndForAnnotationVisitor(mv.visitAnnotation(Type.getDescriptor(NotNull.class), false)); + } if (!generationState.getClassBuilderMode().generateBodies) { FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration()); @@ -144,7 +148,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { String hashCodeMethodName = mapFunctionName(function); MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), hashCodeMethodName, getHashCodeDesc(), null, null); - if (fieldOwnerContext.getContextKind() != OwnerKind.ERASED_INLINE_CLASS && classDescriptor.isInline()) { + if (!isInErasedInlineClass && classDescriptor.isInline()) { FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper); return; } @@ -213,15 +217,14 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator { String equalsMethodName = mapFunctionName(function); MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), equalsMethodName, getEqualsDesc(), null, null); - boolean isErasedInlineClassKind = fieldOwnerContext.getContextKind() == OwnerKind.ERASED_INLINE_CLASS; - if (!isErasedInlineClassKind && classDescriptor.isInline()) { + if (!isInErasedInlineClass && classDescriptor.isInline()) { FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper); return; } - visitEndForAnnotationVisitor( - mv.visitParameterAnnotation(isErasedInlineClassKind ? 1 : 0, Type.getDescriptor(Nullable.class), false) - ); + if (!isInErasedInlineClass) { + visitEndForAnnotationVisitor(mv.visitParameterAnnotation(0, Type.getDescriptor(Nullable.class), false)); + } if (!generationState.getClassBuilderMode().generateBodies) { FunctionCodegen.endVisit(mv, equalsMethodName, getDeclaration());