diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java index 9c204d64ffb..afea19b7fe3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamWrapperCodegen.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.context.FieldOwnerContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; @@ -79,7 +80,8 @@ public class SamWrapperCodegen { this.samType = samType; this.parentCodegen = parentCodegen; visibility = isInsideInline ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE; - classFlags = visibility | ACC_FINAL | ACC_SUPER; + int synth = state.getLanguageVersionSettings().supportsFeature(LanguageFeature.SamWrapperClassesAreSynthetic) ? ACC_SYNTHETIC : 0; + classFlags = visibility | ACC_FINAL | ACC_SUPER | synth; } @NotNull diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index f0869360e3a..04057ffd8f4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -211,10 +211,10 @@ class GenerationState private constructor( val fromConfig = configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS) if (fromConfig != null && target >= fromConfig.minJvmTarget) fromConfig - else if (target < JvmTarget.JVM_1_8) - JvmClosureGenerationScheme.CLASS - else + else if (target >= JvmTarget.JVM_1_8 && languageVersionSettings.supportsFeature(LanguageFeature.SamWrapperClassesAreSynthetic)) JvmClosureGenerationScheme.INDY + else + JvmClosureGenerationScheme.CLASS } val lambdasScheme = run { 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 01a5d8c4541..13bc92b485f 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 @@ -81,7 +81,7 @@ class ClassCodegen private constructor( defineClass( irClass.psiElement, state.classFileVersion, - irClass.flags, + irClass.getFlags(context.state.languageVersionSettings), signature.name, signature.javaGenericSignature, signature.superclassName, @@ -473,10 +473,11 @@ class ClassCodegen private constructor( } } -private val IrClass.flags: Int - get() = origin.flags or getVisibilityAccessFlagForClass() or +private fun IrClass.getFlags(languageVersionSettings: LanguageVersionSettings): Int = + origin.flags or + getVisibilityAccessFlagForClass() or (if (isAnnotatedWithDeprecated) Opcodes.ACC_DEPRECATED else 0) or - (if (hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) Opcodes.ACC_SYNTHETIC else 0) or + getSynthAccessFlag(languageVersionSettings) or when { isAnnotationClass -> Opcodes.ACC_ANNOTATION or Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT isInterface -> Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT @@ -485,6 +486,16 @@ private val IrClass.flags: Int else -> Opcodes.ACC_SUPER or modality.flags } +private fun IrClass.getSynthAccessFlag(languageVersionSettings: LanguageVersionSettings): Int { + if (hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) + return Opcodes.ACC_SYNTHETIC + if (origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION && + languageVersionSettings.supportsFeature(LanguageFeature.SamWrapperClassesAreSynthetic) + ) + return Opcodes.ACC_SYNTHETIC + return 0 +} + private fun IrField.computeFieldFlags(context: JvmBackendContext, languageVersionSettings: LanguageVersionSettings): Int = origin.flags or visibility.flags or (if (isDeprecatedCallable(context) || diff --git a/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericFunInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericFunInterface.txt index 43b745b330f..7eb0d2a7d5a 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericFunInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericFunInterface.txt @@ -16,7 +16,7 @@ synthetic final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public method equals(p0: java.lang.Object): boolean diff --git a/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericSamInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericSamInterface.txt index 03ec0d56cf6..529b0266dc1 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericSamInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/callableRefGenericSamInterface.txt @@ -10,7 +10,7 @@ synthetic final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method get(): java.lang.Object diff --git a/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedFunInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedFunInterface.txt index ba3956bdcc3..b1dc7e49e7b 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedFunInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedFunInterface.txt @@ -5,7 +5,7 @@ public interface<Ljava/lang/Object;> Sam { } @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public method equals(p0: java.lang.Object): boolean diff --git a/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedSamInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedSamInterface.txt index 2102c82f6e1..fcb80dea923 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedSamInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/callableRefSpecializedSamInterface.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method get(): java.lang.Object diff --git a/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface.txt index ddf6ef8d381..9f015803fa1 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface.txt @@ -5,7 +5,7 @@ public interface<Ljava/lang/Object;> Sam { } @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public method equals(p0: java.lang.Object): boolean diff --git a/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface_ir.txt b/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface_ir.txt index dd96882e1a7..e3ddc0db865 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/genericFunInterface_ir.txt @@ -5,7 +5,7 @@ public interface<Ljava/lang/Object;> Sam { } @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function method (p0: kotlin.jvm.functions.Function0): void diff --git a/compiler/testData/codegen/bytecodeListing/sam/genericSamInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/genericSamInterface.txt index efb77081001..730f7bff931 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/genericSamInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/genericSamInterface.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method get(): java.lang.Object diff --git a/compiler/testData/codegen/bytecodeListing/sam/reusedSamWrapperClasses.txt b/compiler/testData/codegen/bytecodeListing/sam/reusedSamWrapperClasses.txt index 17ce13004a7..9a14226085a 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/reusedSamWrapperClasses.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/reusedSamWrapperClasses.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -final class A$sam$java_lang_Runnable$0 { +synthetic final class A$sam$java_lang_Runnable$0 { // source: 'reusedSamWrapperClasses.kt' enclosing class A private synthetic final field function: kotlin.jvm.functions.Function0 diff --git a/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne.txt b/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne.txt index 70908a67f5f..0d97548945f 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -public final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { +public synthetic final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { // source: 'samAdapterAndInlinedOne.kt' public method (p0: kotlin.jvm.functions.Function0): void public synthetic final method run(): void @@ -9,7 +9,7 @@ public final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnabl } @kotlin.Metadata -final class test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { +synthetic final class test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { // source: 'samAdapterAndInlinedOne.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method run(): void diff --git a/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne_ir.txt b/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne_ir.txt index fd4941ff5d0..a0bfcdda134 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/samAdapterAndInlinedOne_ir.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -public final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { +public synthetic final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { // source: 'samAdapterAndInlinedOne.kt' public method (p0: kotlin.jvm.functions.Function0): void public synthetic final method run(): void @@ -9,7 +9,7 @@ public final class test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnabl } @kotlin.Metadata -final class test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { +synthetic final class test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { // source: 'samAdapterAndInlinedOne.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method run(): void diff --git a/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface.txt index 310988b9a98..951fd16be77 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface.txt @@ -5,7 +5,7 @@ public interface<Ljava/lang/Object;> Sam { } @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public method equals(p0: java.lang.Object): boolean diff --git a/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface_ir.txt b/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface_ir.txt index ba9f90c64b8..5ac07a34f51 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/specializedFunInterface_ir.txt @@ -5,7 +5,7 @@ public interface<Ljava/lang/Object;> Sam { } @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function method (p0: kotlin.jvm.functions.Function0): void diff --git a/compiler/testData/codegen/bytecodeListing/sam/specializedSamInterface.txt b/compiler/testData/codegen/bytecodeListing/sam/specializedSamInterface.txt index 3bb5239d280..1f0916f8e52 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/specializedSamInterface.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/specializedSamInterface.txt @@ -1,5 +1,5 @@ @kotlin.Metadata -final class TKt$sam$Sam$0 { +synthetic final class TKt$sam$Sam$0 { // source: 't.kt' method (p0: kotlin.jvm.functions.Function0): void public synthetic final method get(): java.lang.Object diff --git a/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass.txt b/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass.txt index 902a3dba8a5..5db6a593e54 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass.txt @@ -59,7 +59,7 @@ public final class B$runnable2$1 { } @kotlin.Metadata -public final class B$sam$i$java_lang_Runnable$0 { +public synthetic final class B$sam$i$java_lang_Runnable$0 { // source: 'wrapperInlinedFromAnotherClass.kt' enclosing class B private synthetic final field function: kotlin.jvm.functions.Function0 diff --git a/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass_ir.txt b/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass_ir.txt index a244633ffd7..a3cd023104b 100644 --- a/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/sam/wrapperInlinedFromAnotherClass_ir.txt @@ -59,7 +59,7 @@ public final class B$runnable2$1 { } @kotlin.Metadata -public final class B$sam$i$java_lang_Runnable$0 { +public synthetic final class B$sam$i$java_lang_Runnable$0 { // source: 'wrapperInlinedFromAnotherClass.kt' enclosing class B private synthetic final field function: kotlin.jvm.functions.Function0 diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 3d6720c65bd..1e4e72ddfac 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -199,6 +199,7 @@ enum class LanguageFeature( InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), SuspendFunctionsInFunInterfaces(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), + SamWrapperClassesAreSynthetic(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = BUG_FIX) ; val presentableName: String