JVM SamWrapperClassesAreSynthetic language feature

KT-44278 KT-26060 KT-42621
This commit is contained in:
Dmitry Petrov
2021-02-08 18:11:59 +03:00
parent 052f6929c9
commit 7564c9bb8c
19 changed files with 39 additions and 25 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext; import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
@@ -79,7 +80,8 @@ public class SamWrapperCodegen {
this.samType = samType; this.samType = samType;
this.parentCodegen = parentCodegen; this.parentCodegen = parentCodegen;
visibility = isInsideInline ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE; 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 @NotNull
@@ -211,10 +211,10 @@ class GenerationState private constructor(
val fromConfig = configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS) val fromConfig = configuration.get(JVMConfigurationKeys.SAM_CONVERSIONS)
if (fromConfig != null && target >= fromConfig.minJvmTarget) if (fromConfig != null && target >= fromConfig.minJvmTarget)
fromConfig fromConfig
else if (target < JvmTarget.JVM_1_8) else if (target >= JvmTarget.JVM_1_8 && languageVersionSettings.supportsFeature(LanguageFeature.SamWrapperClassesAreSynthetic))
JvmClosureGenerationScheme.CLASS
else
JvmClosureGenerationScheme.INDY JvmClosureGenerationScheme.INDY
else
JvmClosureGenerationScheme.CLASS
} }
val lambdasScheme = run { val lambdasScheme = run {
@@ -81,7 +81,7 @@ class ClassCodegen private constructor(
defineClass( defineClass(
irClass.psiElement, irClass.psiElement,
state.classFileVersion, state.classFileVersion,
irClass.flags, irClass.getFlags(context.state.languageVersionSettings),
signature.name, signature.name,
signature.javaGenericSignature, signature.javaGenericSignature,
signature.superclassName, signature.superclassName,
@@ -473,10 +473,11 @@ class ClassCodegen private constructor(
} }
} }
private val IrClass.flags: Int private fun IrClass.getFlags(languageVersionSettings: LanguageVersionSettings): Int =
get() = origin.flags or getVisibilityAccessFlagForClass() or origin.flags or
getVisibilityAccessFlagForClass() or
(if (isAnnotatedWithDeprecated) Opcodes.ACC_DEPRECATED else 0) 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 { when {
isAnnotationClass -> Opcodes.ACC_ANNOTATION or Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT isAnnotationClass -> Opcodes.ACC_ANNOTATION or Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT
isInterface -> 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 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 = private fun IrField.computeFieldFlags(context: JvmBackendContext, languageVersionSettings: LanguageVersionSettings): Int =
origin.flags or visibility.flags or origin.flags or visibility.flags or
(if (isDeprecatedCallable(context) || (if (isDeprecatedCallable(context) ||
@@ -16,7 +16,7 @@ synthetic final class<Lkotlin/jvm/internal/FunctionReferenceImpl;Lkotlin/jvm/fun
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public <null> method equals(p0: java.lang.Object): boolean public <null> method equals(p0: java.lang.Object): boolean
@@ -10,7 +10,7 @@ synthetic final class<Lkotlin/jvm/internal/FunctionReferenceImpl;Lkotlin/jvm/fun
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method get(): java.lang.Object public synthetic final <null> method get(): java.lang.Object
@@ -5,7 +5,7 @@ public interface<<T:Ljava/lang/Object;>Ljava/lang/Object;> Sam {
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public <null> method equals(p0: java.lang.Object): boolean public <null> method equals(p0: java.lang.Object): boolean
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method get(): java.lang.Object public synthetic final <null> method get(): java.lang.Object
@@ -5,7 +5,7 @@ public interface<<T:Ljava/lang/Object;>Ljava/lang/Object;> Sam {
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public <null> method equals(p0: java.lang.Object): boolean public <null> method equals(p0: java.lang.Object): boolean
@@ -5,7 +5,7 @@ public interface<<T:Ljava/lang/Object;>Ljava/lang/Object;> Sam {
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method get(): java.lang.Object public synthetic final <null> method get(): java.lang.Object
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
final class A$sam$java_lang_Runnable$0 { synthetic final class A$sam$java_lang_Runnable$0 {
// source: 'reusedSamWrapperClasses.kt' // source: 'reusedSamWrapperClasses.kt'
enclosing class A enclosing class A
private synthetic final field function: kotlin.jvm.functions.Function0 private synthetic final field function: kotlin.jvm.functions.Function0
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
public final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { public synthetic final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 {
// source: 'samAdapterAndInlinedOne.kt' // source: 'samAdapterAndInlinedOne.kt'
public <null> method <init>(p0: kotlin.jvm.functions.Function0): void public <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method run(): void public synthetic final <null> method run(): void
@@ -9,7 +9,7 @@ public final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnabl
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { synthetic final class<null> test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 {
// source: 'samAdapterAndInlinedOne.kt' // source: 'samAdapterAndInlinedOne.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method run(): void public synthetic final <null> method run(): void
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
public final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 { public synthetic final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnable$0 {
// source: 'samAdapterAndInlinedOne.kt' // source: 'samAdapterAndInlinedOne.kt'
public <null> method <init>(p0: kotlin.jvm.functions.Function0): void public <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method run(): void public synthetic final <null> method run(): void
@@ -9,7 +9,7 @@ public final class<null> test/SamAdapterAndInlinedOneKt$sam$i$java_lang_Runnabl
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 { synthetic final class<null> test/SamAdapterAndInlinedOneKt$sam$java_lang_Runnable$0 {
// source: 'samAdapterAndInlinedOne.kt' // source: 'samAdapterAndInlinedOne.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method run(): void public synthetic final <null> method run(): void
@@ -5,7 +5,7 @@ public interface<<T:Ljava/lang/Object;>Ljava/lang/Object;> Sam {
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public <null> method equals(p0: java.lang.Object): boolean public <null> method equals(p0: java.lang.Object): boolean
@@ -5,7 +5,7 @@ public interface<<T:Ljava/lang/Object;>Ljava/lang/Object;> Sam {
} }
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function public final @org.jetbrains.annotations.NotNull <()Lkotlin/Function<*>;> method getFunctionDelegate(): kotlin.Function
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
@@ -1,5 +1,5 @@
@kotlin.Metadata @kotlin.Metadata
final class<null> TKt$sam$Sam$0 { synthetic final class<null> TKt$sam$Sam$0 {
// source: 't.kt' // source: 't.kt'
<null> method <init>(p0: kotlin.jvm.functions.Function0): void <null> method <init>(p0: kotlin.jvm.functions.Function0): void
public synthetic final <null> method get(): java.lang.Object public synthetic final <null> method get(): java.lang.Object
@@ -59,7 +59,7 @@ public final class B$runnable2$1 {
} }
@kotlin.Metadata @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' // source: 'wrapperInlinedFromAnotherClass.kt'
enclosing class B enclosing class B
private synthetic final field function: kotlin.jvm.functions.Function0 private synthetic final field function: kotlin.jvm.functions.Function0
@@ -59,7 +59,7 @@ public final class B$runnable2$1 {
} }
@kotlin.Metadata @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' // source: 'wrapperInlinedFromAnotherClass.kt'
enclosing class B enclosing class B
private synthetic final field function: kotlin.jvm.functions.Function0 private synthetic final field function: kotlin.jvm.functions.Function0
@@ -199,6 +199,7 @@ enum class LanguageFeature(
InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE),
JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER),
SuspendFunctionsInFunInterfaces(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 val presentableName: String