diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index bba4150b6de..a8d0438151a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; +import org.jetbrains.kotlin.resolve.inline.InlineUtil; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver; @@ -287,7 +288,9 @@ public class ClosureCodegen extends MemberCodegen { if (builder == null) return; ProtoBuf.Function functionProto = builder.build(); - WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0, av -> { + boolean publicAbi = InlineUtil.isInPublicInlineScope(frontendFunDescriptor); + + WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0, av -> { writeAnnotationData(av, serializer, functionProto); return Unit.INSTANCE; }); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodeFragmentCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodeFragmentCodegen.kt index 67696d79764..8fd3e239b3c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodeFragmentCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodeFragmentCodegen.kt @@ -79,7 +79,7 @@ class CodeFragmentCodegen private constructor( } override fun generateKotlinMetadataAnnotation() { - writeSyntheticClassMetadata(v, state) + writeSyntheticClassMetadata(v, state, false) } private fun genConstructor() { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 9c6afccca8a..75b3bd06ad7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; +import org.jetbrains.kotlin.resolve.inline.InlineUtil; import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; @@ -304,7 +305,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { protected void generateKotlinMetadataAnnotation() { ProtoBuf.Class classProto = serializer.classProto(descriptor).build(); - WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.CLASS, 0, av -> { + boolean publicAbi = InlineUtil.isInPublicInlineScope(descriptor); + + WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.CLASS, publicAbi, 0, av -> { writeAnnotationData(av, serializer, classProto); return Unit.INSTANCE; }); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt index 16255dec118..36389ed7fc3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt @@ -141,7 +141,7 @@ class InterfaceImplBodyCodegen( override fun generateKotlinMetadataAnnotation() { (v as InterfaceImplClassBuilder).stopCounting() - writeSyntheticClassMetadata(v, state) + writeSyntheticClassMetadata(v, state, false) } override fun done() { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt index 8becdf49b50..67c2112a274 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt @@ -391,7 +391,7 @@ class MultifileClassCodegenImpl( facadeClassType: Type, kotlinPackageFqName: FqName ) { - writeKotlinMetadata(classBuilder, state, KotlinClassHeader.Kind.MULTIFILE_CLASS, flags) { av -> + writeKotlinMetadata(classBuilder, state, KotlinClassHeader.Kind.MULTIFILE_CLASS, false, flags) { av -> val arv = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME) for (internalName in partInternalNames) { arv.visit(null, internalName) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt index 5a87cb1cb3d..d097dcec827 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassPartCodegen.kt @@ -96,7 +96,7 @@ class MultifileClassPartCodegen( val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0 - writeKotlinMetadata(v, state, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART, extraFlags) { av -> + writeKotlinMetadata(v, state, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART, false, extraFlags) { av -> DescriptorAsmUtil.writeAnnotationData(av, serializer, packageProto) av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, facadeClassType.internalName) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 0cd60d0c0fb..34315fb3f4c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -107,7 +107,7 @@ public class PackagePartCodegen extends MemberCodegen { protected void generateKotlinMetadataAnnotation() { Pair serializedPart = serializePackagePartMembers(this, packagePartType); - WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> { + WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, false, 0, av -> { writeAnnotationData(av, serializedPart.getFirst(), serializedPart.getSecond()); FqName kotlinPackageFqName = element.getPackageFqName(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt index ffab7bde6f3..28b94c2973a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.PropertyImportedFromObject import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny +import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.isUnderlyingPropertyOfInlineClass import org.jetbrains.kotlin.resolve.jvm.AsmTypes.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin @@ -209,7 +210,7 @@ class PropertyReferenceCodegen( } override fun generateKotlinMetadataAnnotation() { - writeSyntheticClassMetadata(v, state) + writeSyntheticClassMetadata(v, state, InlineUtil.isInPublicInlineScope(classDescriptor)) } fun putInstanceOnStack(receiverValue: StackValue?): StackValue { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java index c56570165b5..737e57091ff 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java @@ -138,7 +138,7 @@ public class SamWrapperCodegen { ); cv.visitSource(file.getName(), null); - WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv, state); + WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv, state, isInsideInline); generateInnerClassInformation(file, asmType, cv); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.kt index 4f471562b69..3e27b2dcdfc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ScriptCodegen.kt @@ -69,7 +69,7 @@ class ScriptCodegen private constructor( override fun generateKotlinMetadataAnnotation() { val serializer = DescriptorSerializer.create(scriptDescriptor, JvmSerializerExtension(v.serializationBindings, state), null) val classProto = serializer.classProto(scriptDescriptor).build() - writeKotlinMetadata(v, state, KotlinClassHeader.Kind.CLASS, JvmAnnotationNames.METADATA_SCRIPT_FLAG) { av -> + writeKotlinMetadata(v, state, KotlinClassHeader.Kind.CLASS, false, JvmAnnotationNames.METADATA_SCRIPT_FLAG) { av -> DescriptorAsmUtil.writeAnnotationData(av, serializer, classProto) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 109c5f2162e..5cde95d370e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -1012,7 +1012,15 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { ClassDescriptor classDescriptor = (ClassDescriptor) type.getConstructor().getDeclarationDescriptor(); assert classDescriptor != null : "because it's enum"; - WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber); + boolean isPublicAbi = false; + for (FunctionDescriptor descriptor : functionsStack) { + if (descriptor.isInline()) { + isPublicAbi = !DescriptorVisibilities.isPrivate(descriptor.getVisibility()); + break; + } + } + + WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber, isPublicAbi); for (ConstantValue constant : switchCodegenProvider.getAllConstants(expression)) { if (constant instanceof NullValue) continue; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt index f3b22692860..c45c182dec8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt @@ -654,7 +654,7 @@ private fun generateLambdaForRunSuspend( visitEnd() } - writeSyntheticClassMetadata(lambdaBuilder, state) + writeSyntheticClassMetadata(lambdaBuilder, state, false) lambdaBuilder.done() return lambdaBuilder.thisName diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index a1eb4e62e66..121e7715d68 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.indexOrMinusOne +import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm @@ -742,7 +743,8 @@ class CoroutineCodegenForNamedFunction private constructor( } override fun generateKotlinMetadataAnnotation() { - writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { av -> + val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor) + writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av -> val serializer = DescriptorSerializer.createForLambda(JvmSerializerExtension(v.serializationBindings, state)) val functionProto = serializer.functionProto( diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 9149c06488e..ef88393b311 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -118,6 +118,10 @@ class AnonymousObjectTransformer( override fun visitEnd() {} }, ClassReader.SKIP_FRAMES) + val header = metadataReader.createHeader() + assert(isSameModule || (header != null && isPublicAbi(header))) { + "Trying to inline an anonymous object which is not part of the public ABI: ${oldObjectType.className}" + } // When regenerating objects in inline lambdas, keep the old SMAP and don't remap the line numbers to // save time. The result is effectively the same anyway. @@ -198,7 +202,6 @@ class AnonymousObjectTransformer( visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access) } - val header = metadataReader.createHeader() if (header != null) { writeTransformedMetadata(header, classBuilder) } @@ -229,7 +232,9 @@ class AnonymousObjectTransformer( } private fun writeTransformedMetadata(header: KotlinClassHeader, classBuilder: ClassBuilder) { - writeKotlinMetadata(classBuilder, state, header.kind, header.extraInt) action@{ av -> + // The transformed anonymous object becomes part of the public ABI if it is inside of a public inline function. + val publicAbi = inliningContext.callSiteInfo.isInPublicInlineScope + writeKotlinMetadata(classBuilder, state, header.kind, publicAbi, header.extraInt and JvmAnnotationNames.METADATA_PUBLIC_ABI_FLAG.inv()) action@{ av -> val (newProto, newStringTable) = transformMetadata(header) ?: run { val data = header.data val strings = header.strings @@ -242,6 +247,11 @@ class AnonymousObjectTransformer( } } + private fun isPublicAbi(header: KotlinClassHeader): Boolean = + // The public abi flag was only introduced in metadata version 1.6.0, before then we have to skip this check. + !header.metadataVersion.isAtLeast(1, 6, 0) || + header.extraInt and JvmAnnotationNames.METADATA_PUBLIC_ABI_FLAG != 0 + private fun transformMetadata(header: KotlinClassHeader): Pair? { val data = header.data ?: return null val strings = header.strings ?: return null @@ -317,7 +327,7 @@ class AnonymousObjectTransformer( InlineCallSiteInfo( transformationInfo.oldClassName, Method(sourceNode.name, if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc), - inliningContext.callSiteInfo.isInlineOrInsideInline, + inliningContext.callSiteInfo.inlineScopeVisibility, inliningContext.callSiteInfo.file, inliningContext.callSiteInfo.lineNumber ), diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt index 47f83068ca7..cd45da13b82 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt @@ -74,7 +74,7 @@ class PsiSourceCompilerForInline( return InlineCallSiteInfo( parentCodegen.className, signature.asmMethod, - context.functionDescriptor.isInlineOrInsideInline(), + context.functionDescriptor.getInlineCallSiteVisibility(), callElement.containingFile, CodegenUtil.getLineNumberForElement(callElement, false) ?: 0 ) @@ -416,8 +416,11 @@ class PsiSourceCompilerForInline( } fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean = - if (this is FunctionDescriptor && isInline) true - else containingDeclaration?.isInlineOrInsideInline() == true + getInlineCallSiteVisibility() != null + +fun DeclarationDescriptor.getInlineCallSiteVisibility(): DescriptorVisibility? = + if (this is FunctionDescriptor && isInline) visibility + else containingDeclaration?.getInlineCallSiteVisibility() fun getDeclarationLabels(lambdaOrFun: PsiElement?, descriptor: DeclarationDescriptor): Set { val result = HashSet() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index 01714c89330..248d89b749b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.incremental.components.LocationInfo import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.ScopeKind @@ -24,10 +26,16 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode class InlineCallSiteInfo( val ownerClassName: String, val method: Method, - val isInlineOrInsideInline: Boolean, + val inlineScopeVisibility: DescriptorVisibility?, val file: PsiFile?, val lineNumber: Int -) +) { + val isInlineOrInsideInline: Boolean + get() = inlineScopeVisibility != null + + val isInPublicInlineScope: Boolean + get() = inlineScopeVisibility != null && !DescriptorVisibilities.isPrivate(inlineScopeVisibility) +} interface SourceCompilerForInline { val state: GenerationState diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java index 5448f2a68c2..800775b98c0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/MappingClassesForWhenByEnumCodegen.java @@ -57,7 +57,8 @@ public class MappingClassesForWhenByEnumCodegen { generateFields(cb, mappings); generateInitialization(cb, mappings); - WriteAnnotationUtilKt.writeSyntheticClassMetadata(cb, state); + boolean publicAbi = mappings.stream().anyMatch(WhenByEnumsMapping::isPublicAbi); + WriteAnnotationUtilKt.writeSyntheticClassMetadata(cb, state, publicAbi); cb.done(); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/WhenByEnumsMapping.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/WhenByEnumsMapping.java index 9b92224d004..a723bd1f7be 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/WhenByEnumsMapping.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/WhenByEnumsMapping.java @@ -32,16 +32,19 @@ public class WhenByEnumsMapping { private final String outerClassInternalNameForExpression; private final String mappingsClassInternalName; private final int fieldNumber; + private final boolean isPublicAbi; public WhenByEnumsMapping( @NotNull ClassDescriptor enumClassDescriptor, @NotNull String outerClassInternalNameForExpression, - int fieldNumber + int fieldNumber, + boolean isPublicAbi ) { this.enumClassDescriptor = enumClassDescriptor; this.outerClassInternalNameForExpression = outerClassInternalNameForExpression; this.mappingsClassInternalName = outerClassInternalNameForExpression + MAPPINGS_CLASS_NAME_POSTFIX; this.fieldNumber = fieldNumber; + this.isPublicAbi = isPublicAbi; } public int getIndexByEntry(@NotNull EnumValue value) { @@ -80,6 +83,10 @@ public class WhenByEnumsMapping { return mappingsClassInternalName; } + public boolean isPublicAbi() { + return isPublicAbi; + } + @NotNull public Iterable> enumValuesToIntMapping() { return map.entrySet(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt index c33ddbc0573..351a6e6772d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt @@ -27,6 +27,7 @@ fun writeKotlinMetadata( cb: ClassBuilder, state: GenerationState, kind: KotlinClassHeader.Kind, + publicAbi: Boolean, extraFlags: Int, action: (AnnotationVisitor) -> Unit ) { @@ -43,6 +44,9 @@ fun writeKotlinMetadata( if (state.languageVersionSettings.getFlag(JvmAnalysisFlags.strictMetadataVersionSemantics)) { flags = flags or JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG } + if (publicAbi) { + flags = flags or JvmAnnotationNames.METADATA_PUBLIC_ABI_FLAG + } if (flags != 0) { av.visit(JvmAnnotationNames.METADATA_EXTRA_INT_FIELD_NAME, flags) } @@ -50,8 +54,8 @@ fun writeKotlinMetadata( av.visitEnd() } -fun writeSyntheticClassMetadata(cb: ClassBuilder, state: GenerationState) { - writeKotlinMetadata(cb, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { _ -> +fun writeSyntheticClassMetadata(cb: ClassBuilder, state: GenerationState, publicAbi: Boolean) { + writeKotlinMetadata(cb, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { _ -> // Do nothing } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java index 4d151d00a59..9365dd7e263 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java @@ -74,6 +74,17 @@ public class InlineUtil { return isInlineOrContainingInline(descriptor.getContainingDeclaration()); } + public static boolean isInPublicInlineScope(@Nullable DeclarationDescriptor descriptor) { + if (descriptor == null) return false; + if (isInline(descriptor)) { + if (!(descriptor instanceof DeclarationDescriptorWithVisibility)) + return false; + DescriptorVisibility visibility = ((DeclarationDescriptorWithVisibility) descriptor).getVisibility(); + return !DescriptorVisibilities.isPrivate(visibility); + } + return isInPublicInlineScope(descriptor.getContainingDeclaration()); + } + public static boolean checkNonLocalReturnUsage( @NotNull DeclarationDescriptor fromFunction, @NotNull KtExpression startExpression, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index d0702ea45eb..92036164571 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -136,6 +136,8 @@ class JvmBackendContext( val directInvokedLambdas = mutableListOf() + val publicAbiSymbols = mutableSetOf() + init { state.mapInlineClass = { descriptor -> typeMapper.mapType(referenceClass(descriptor).defaultType) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 85fc839337a..5933fab5b97 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope import org.jetbrains.kotlin.backend.jvm.ir.isSyntheticSingleton import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.buildAssertionsDisabledField @@ -258,7 +259,17 @@ class ClassCodegen private constructor( extraFlags = extraFlags or JvmAnnotationNames.METADATA_SCRIPT_FLAG } - writeKotlinMetadata(visitor, state, kind, extraFlags) { av -> + // There are three kinds of classes which are regenerated during inlining. + // 1) Anonymous classes which are in the scope of an inline function. + // 2) SAM wrappers used in an inline function. These are identified by name, since they + // can be reused in different functions and are thus generated in the enclosing top-level + // class instead of inside of an inline function. + // 3) WhenMapping classes used from inline functions. These are collected in + // `JvmBackendContext.publicAbiSymbols` in `MappedEnumWhenLowering`. + val isPublicAbi = irClass.symbol in context.publicAbiSymbols || irClass.isInlineSamWrapper || + type.isAnonymousClass && irClass.isInPublicInlineScope + + writeKotlinMetadata(visitor, state, kind, isPublicAbi, extraFlags) { av -> if (metadata != null) { metadataSerializer.serialize(metadata)?.let { (proto, stringTable) -> DescriptorAsmUtil.writeAnnotationData(av, proto, stringTable) @@ -454,6 +465,9 @@ class ClassCodegen private constructor( private val IrClass.isAnonymousInnerClass: Boolean get() = isSamWrapper || name.isSpecial // NB '' is treated as anonymous inner class here + private val IrClass.isInlineSamWrapper: Boolean + get() = isSamWrapper && visibility == DescriptorVisibilities.PUBLIC + private val IrClass.isSamWrapper: Boolean get() = origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION @@ -579,3 +593,7 @@ private fun storeSerializedIr(av: AnnotationVisitor, serializedIr: ByteArray) { } partsVisitor.visitEnd() } + +// From `isAnonymousClass` in inlineCodegenUtils.kt +private val Type.isAnonymousClass: Boolean + get() = internalName.substringAfterLast("$", "").toIntOrNull() != null diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index ae3d9c07841..4407e236821 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.jvm.ir.getKtFile +import org.jetbrains.kotlin.backend.jvm.ir.inlineScopeVisibility import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledReturnType import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.state.GenerationState @@ -16,7 +17,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.incremental.components.LocationInfo import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrLoop @@ -48,7 +50,7 @@ class IrSourceCompilerForInline( return InlineCallSiteInfo( root.classCodegen.type.internalName, root.signature.asmMethod, - root.irFunction.isInlineOrInsideInline(), + root.irFunction.inlineScopeVisibility, root.irFunction.fileParent.getKtFile(), callElement.psiElement?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0 ) @@ -131,12 +133,4 @@ class IrSourceCompilerForInline( } } -private tailrec fun IrDeclaration.isInlineOrInsideInline(): Boolean { - val original = (this as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration ?: this - if (original is IrSimpleFunction && original.isInline) return true - val parent = original.parent - if (parent !is IrDeclaration) return false - return parent.isInlineOrInsideInline() -} - internal fun IrLoop.nonLocalReturnLabel(forBreak: Boolean): String = "${label!!}\$${if (forBreak) "break" else "continue"}" diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index b382e6828d0..dfc53348106 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.ir.IrBuiltIns @@ -48,6 +49,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME +import org.jetbrains.kotlin.utils.addToStdlib.safeAs /** * Perform as much type erasure as is significant for JVM signature generation. @@ -419,3 +421,25 @@ val IrClass.isSyntheticSingleton: Boolean || origin == JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL || origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE) && primaryConstructor!!.valueParameters.isEmpty() + +// Map declarations to original declarations before lowering. +private val IrDeclaration.original: IrDeclaration + get() = (this as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration ?: this + +// Declarations in the scope of an externally visible inline function are implicitly part of the +// public ABI of a Kotlin module. This function returns the visibility of a containing inline function +// (determined *before* lowering), or null if the given declaration is not in the scope of an inline function. +val IrDeclaration.inlineScopeVisibility: DescriptorVisibility? + get() { + var owner = original + while (true) { + if (owner is IrFunction && owner.isInline) { + return owner.visibility + } + owner = owner.parent.safeAs()?.original ?: return null + } + } + +// True for declarations which are in the scope of an externally visible inline function. +val IrDeclaration.isInPublicInlineScope: Boolean + get() = inlineScopeVisibility?.let(DescriptorVisibilities::isPrivate) == false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MappedEnumWhenLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MappedEnumWhenLowering.kt index 6b3be5319cd..bbbc402ea92 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MappedEnumWhenLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MappedEnumWhenLowering.kt @@ -5,18 +5,20 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.lower.EnumWhenLowering import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.addField import org.jetbrains.kotlin.ir.builders.declarations.buildClass import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.expressions.IrExpression @@ -25,6 +27,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal val enumWhenPhase = makeIrFilePhase( ::MappedEnumWhenLowering, @@ -57,7 +60,7 @@ internal val enumWhenPhase = makeIrFilePhase( // The latter would not need to be recompiled if new entries were added before `X` // at the negligible cost of an additional initializer per run + one array read per call. // -private class MappedEnumWhenLowering(context: CommonBackendContext) : EnumWhenLowering(context) { +private class MappedEnumWhenLowering(context: JvmBackendContext) : EnumWhenLowering(context) { private val intArray = context.irBuiltIns.primitiveArrayForType.getValue(context.irBuiltIns.intType) private val intArrayConstructor = intArray.constructors.single { it.owner.valueParameters.size == 1 } private val intArrayGet = intArray.functions.single { it.owner.name == OperatorNameConventions.GET } @@ -68,8 +71,14 @@ private class MappedEnumWhenLowering(context: CommonBackendContext) : EnumWhenLo // of the classes in which they are used. This field tracks which container is the innermost one. private var state: EnumMappingState? = null + private class EnumMappingClass( + val field: IrField, + val ordinals: MutableMap = mutableMapOf(), + var isPublicAbi: Boolean = false, + ) + private inner class EnumMappingState { - val mappings = mutableMapOf, IrField>>() + val mappings = mutableMapOf() val mappingsClass by lazy { context.irFactory.buildClass { name = Name.identifier("WhenMappings") @@ -79,39 +88,46 @@ private class MappedEnumWhenLowering(context: CommonBackendContext) : EnumWhenLo } } - fun getMappingForClass(enumClass: IrClass): Pair, IrField> = + fun getMappingForClass(enumClass: IrClass): EnumMappingClass = mappings.getOrPut(enumClass) { - mutableMapOf() to mappingsClass.addField { + EnumMappingClass(mappingsClass.addField { name = Name.identifier("\$EnumSwitchMapping\$${mappings.size}") type = intArray.defaultType origin = JvmLoweredDeclarationOrigin.ENUM_MAPPINGS_FOR_WHEN isFinal = true isStatic = true - } + }) } + + val isPublicAbi: Boolean + get() = mappings.values.any { it.isPublicAbi } } override fun mapConstEnumEntry(entry: IrEnumEntry): Int { - val (mapping) = state!!.getMappingForClass(entry.parentAsClass) + val mapping = state!!.getMappingForClass(entry.parentAsClass).ordinals // Index 0 (default value for integers) is reserved for unknown ordinals. return mapping.getOrPut(entry) { mapping.size + 1 } } override fun mapRuntimeEnumEntry(builder: IrBuilderWithScope, subject: IrExpression): IrExpression = builder.irCall(intArrayGet).apply { - val (_, field) = state!!.getMappingForClass(subject.type.getClass()!!) - dispatchReceiver = builder.irGetField(null, field) + val mapping = state!!.getMappingForClass(subject.type.getClass()!!) + + mapping.isPublicAbi = mapping.isPublicAbi || + (builder.scope.scopeOwnerSymbol.owner.safeAs()?.isInPublicInlineScope ?: false) + + dispatchReceiver = builder.irGetField(null, mapping.field) putValueArgument(0, super.mapRuntimeEnumEntry(builder, subject)) } override fun visitClassNew(declaration: IrClass): IrStatement { val oldState = state - state = EnumMappingState() + val mappingState = EnumMappingState() + state = mappingState super.visitClassNew(declaration) - for ((enum, mappingAndField) in state!!.mappings) { - val (mapping, field) = mappingAndField - val builder = context.createIrBuilder(state!!.mappingsClass.symbol) + for ((enum, mapping) in mappingState.mappings) { + val builder = context.createIrBuilder(mappingState.mappingsClass.symbol) val enumValues = enum.functions.single { it.name.toString() == "values" && it.dispatchReceiverParameter == null @@ -120,10 +136,10 @@ private class MappedEnumWhenLowering(context: CommonBackendContext) : EnumWhenLo && it.returnType.isBoxedArray && it.returnType.getArrayElementType(context.irBuiltIns).classOrNull == enum.symbol } - field.initializer = builder.irExprBody(builder.irBlock { + mapping.field.initializer = builder.irExprBody(builder.irBlock { val enumSize = irCall(refArraySize).apply { dispatchReceiver = irCall(enumValues) } val result = irTemporary(irCall(intArrayConstructor).apply { putValueArgument(0, enumSize) }) - for ((entry, index) in mapping) { + for ((entry, index) in mapping.ordinals) { val runtimeEntry = IrGetEnumValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, enum.defaultType, entry.symbol) +irCall(intArraySet).apply { dispatchReceiver = irGet(result) @@ -135,8 +151,13 @@ private class MappedEnumWhenLowering(context: CommonBackendContext) : EnumWhenLo }) } - if (state!!.mappings.isNotEmpty()) { - declaration.declarations += state!!.mappingsClass.apply { parent = declaration } + if (mappingState.mappings.isNotEmpty()) { + declaration.declarations += mappingState.mappingsClass.apply { + parent = declaration + if (mappingState.isPublicAbi) { + (context as JvmBackendContext).publicAbiSymbols += symbol + } + } } state = oldState return declaration diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 93a6db73d4f..3f3e759d250 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -44,6 +44,7 @@ public final class JvmAnnotationNames { public static final int METADATA_JVM_IR_FLAG = 1 << 4; public static final int METADATA_JVM_IR_STABLE_ABI_FLAG = 1 << 5; public static final int METADATA_FIR_FLAG = 1 << 6; + public static final int METADATA_PUBLIC_ABI_FLAG = 1 << 7; public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value"); diff --git a/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt b/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt index 1bac9414ddd..dfe79ab9a1f 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt +++ b/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt @@ -76,6 +76,8 @@ public annotation class Metadata( * * 5 - this class file has stable metadata and ABI. This is used only for class files compiled with JVM IR (see flag #4) or FIR (#6), * and prevents metadata incompatibility diagnostics from being reported where the class is used. * * 6 - this class file is compiled with the new Kotlin compiler frontend (FIR). + * * 7 - this class is used in the scope of an inline function and implicitly part of the public ABI. Only valid from + * metadata version 1.6.0. */ @SinceKotlin("1.1") @get:JvmName("xi") diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableCodegenExtension.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableCodegenExtension.kt index 1a269af41ab..f10d3f81998 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableCodegenExtension.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableCodegenExtension.kt @@ -28,12 +28,12 @@ import org.jetbrains.kotlin.codegen.writeSyntheticClassMetadata import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.incremental.components.NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.LockBasedStorageManager @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.Variance import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Type -import java.io.FileDescriptor open class ParcelableCodegenExtension : ParcelableExtensionBase, ExpressionCodegenExtension { @Deprecated( @@ -315,7 +314,7 @@ open class ParcelableCodegenExtension : ParcelableExtensionBase, ExpressionCodeg codegen.v.visitInnerClass(creatorAsmType.internalName, containerAsmType.internalName, "Creator", ACC_PUBLIC or ACC_STATIC) codegenForCreator.v.visitInnerClass(creatorAsmType.internalName, containerAsmType.internalName, "Creator", ACC_PUBLIC or ACC_STATIC) - writeSyntheticClassMetadata(classBuilderForCreator, codegen.state) + writeSyntheticClassMetadata(classBuilderForCreator, codegen.state, InlineUtil.isInPublicInlineScope(parcelableClass)) writeCreatorConstructor(codegenForCreator, creatorClass, creatorAsmType) writeNewArrayMethod(codegenForCreator, parcelableClass, parcelableCreatorClassType, creatorClass, parcelerObject) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt index d4f0aed0797..30c023253ae 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/JVMCodegenUtil.kt @@ -658,7 +658,7 @@ internal fun createSingletonLambda( areturn(kSerializerType) } - writeSyntheticClassMetadata(lambdaClassBuilder, lambdaCodegen.state) + writeSyntheticClassMetadata(lambdaClassBuilder, lambdaCodegen.state, false) lambdaClassBuilder.done() return lambdaType diff --git a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt index 4f65535c98f..33d54c3c65c 100644 --- a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt +++ b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature @@ -329,7 +330,7 @@ open class ParcelizeCodegenExtension : ParcelizeExtensionBase, ExpressionCodegen codegen.v.visitInnerClass(creatorAsmType.internalName, containerAsmType.internalName, "Creator", ACC_PUBLIC or ACC_STATIC) codegenForCreator.v.visitInnerClass(creatorAsmType.internalName, containerAsmType.internalName, "Creator", ACC_PUBLIC or ACC_STATIC) - writeSyntheticClassMetadata(classBuilderForCreator, codegen.state) + writeSyntheticClassMetadata(classBuilderForCreator, codegen.state, InlineUtil.isInPublicInlineScope(parcelableClass)) writeCreatorConstructor(codegenForCreator, creatorClass, creatorAsmType) writeNewArrayMethod(codegenForCreator, parcelableClass, parcelableCreatorClassType, creatorClass, parcelerObject)