diff --git a/libraries/kotlinx-metadata/jvm/ChangeLog.md b/libraries/kotlinx-metadata/jvm/ChangeLog.md index 21ed49e0177..dfbcdd849b4 100644 --- a/libraries/kotlinx-metadata/jvm/ChangeLog.md +++ b/libraries/kotlinx-metadata/jvm/ChangeLog.md @@ -1,5 +1,9 @@ # kotlinx-metadata-jvm +## 0.0.3 + +- Support metadata of local delegated properties (see `JvmDeclarationContainerExtensionVisitor.visitLocalDelegatedProperty`) + ## 0.0.2 - Change group ID from `org.jetbrains.kotlin` to `org.jetbrains.kotlinx` diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt index 1d654c07573..23bbc867e43 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt @@ -6,11 +6,8 @@ package kotlinx.metadata.jvm.impl import kotlinx.metadata.* -import kotlinx.metadata.impl.ReadContext -import kotlinx.metadata.impl.WriteContext +import kotlinx.metadata.impl.* import kotlinx.metadata.impl.extensions.MetadataExtensions -import kotlinx.metadata.impl.readAnnotation -import kotlinx.metadata.impl.writeAnnotation import kotlinx.metadata.jvm.* import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull @@ -25,6 +22,26 @@ internal class JvmMetadataExtensions : MetadataExtensions { if (anonymousObjectOriginName != null) { ext.visitAnonymousObjectOriginName(c[anonymousObjectOriginName]) } + + for (property in proto.getExtension(JvmProtoBuf.classLocalVariable)) { + ext.visitLocalDelegatedProperty( + property.flags, c[property.name], property.getPropertyGetterFlags(), property.getPropertySetterFlags() + )?.let { property.accept(it, c) } + } + + ext.visitEnd() + } + + override fun readPackageExtensions(v: KmPackageVisitor, proto: ProtoBuf.Package, c: ReadContext) { + val ext = v.visitExtensions(JvmPackageExtensionVisitor.TYPE) as? JvmPackageExtensionVisitor ?: return + + for (property in proto.getExtension(JvmProtoBuf.packageLocalVariable)) { + ext.visitLocalDelegatedProperty( + property.flags, c[property.name], property.getPropertyGetterFlags(), property.getPropertySetterFlags() + )?.let { property.accept(it, c) } + } + + ext.visitEnd() } override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext) { @@ -86,6 +103,25 @@ internal class JvmMetadataExtensions : MetadataExtensions { override fun visitAnonymousObjectOriginName(internalName: String) { proto.setExtension(JvmProtoBuf.anonymousObjectOriginName, c[internalName]) } + + override fun visitLocalDelegatedProperty( + flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags + ): KmPropertyVisitor = writeProperty(c, flags, name, getterFlags, setterFlags) { + proto.addExtension(JvmProtoBuf.classLocalVariable, it.build()) + } + } + } + + override fun writePackageExtensions( + type: KmExtensionType, proto: ProtoBuf.Package.Builder, c: WriteContext + ): KmPackageExtensionVisitor? { + if (type != JvmPackageExtensionVisitor.TYPE) return null + return object : JvmPackageExtensionVisitor() { + override fun visitLocalDelegatedProperty( + flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags + ): KmPropertyVisitor = writeProperty(c, flags, name, getterFlags, setterFlags) { + proto.addExtension(JvmProtoBuf.packageLocalVariable, it.build()) + } } } diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensions.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensions.kt index cce079c0cc1..59f3d215394 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensions.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensions.kt @@ -9,11 +9,40 @@ import kotlinx.metadata.* import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil /** - * A visitor to visit JVM extensions for a function. + * A visitor containing the common code to visit JVM extensions for Kotlin declaration containers, such as classes and package fragments. + */ +abstract class JvmDeclarationContainerExtensionVisitor @JvmOverloads constructor( + protected open val delegate: JvmDeclarationContainerExtensionVisitor? = null +) : KmDeclarationContainerExtensionVisitor { + /** + * Visits the metadata of a local delegated property used somewhere inside this container (but not in a nested declaration container). + * Note that for classes produced by the Kotlin compiler, such properties will have default accessors. + * + * The order of visited local delegated properties is important. The Kotlin compiler generates the corresponding property's index + * at the call site, so that reflection would be able to load the metadata of the property with that index at runtime. + * If an incorrect index is used, either the `KProperty<*>` object passed to delegate methods will point to the wrong property + * at runtime, or an exception will be thrown. + * + * @param flags property flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag and [Flag.Property] flags + * @param name the name of the property + * @param getterFlags property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag + * and [Flag.PropertyAccessor] flags + * @param setterFlags property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag + * and [Flag.PropertyAccessor] flags + */ + open fun visitLocalDelegatedProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? = + delegate?.visitLocalDelegatedProperty(flags, name, getterFlags, setterFlags) +} + +/** + * A visitor to visit JVM extensions for a class. */ open class JvmClassExtensionVisitor @JvmOverloads constructor( - private val delegate: JvmClassExtensionVisitor? = null -) : KmClassExtensionVisitor { + delegate: JvmClassExtensionVisitor? = null +) : KmClassExtensionVisitor, JvmDeclarationContainerExtensionVisitor(delegate) { + override val delegate: JvmClassExtensionVisitor? + get() = super.delegate as JvmClassExtensionVisitor? + /** * Visits the JVM internal name of the original class this anonymous object is copied from. This method is called for * anonymous objects copied from bodies of inline functions to the use site by the Kotlin compiler. @@ -22,6 +51,13 @@ open class JvmClassExtensionVisitor @JvmOverloads constructor( delegate?.visitAnonymousObjectOriginName(internalName) } + /** + * Visits the end of JVM extensions for the class. + */ + open fun visitEnd() { + delegate?.visitEnd() + } + companion object { /** * The type of this extension visitor. @@ -33,6 +69,33 @@ open class JvmClassExtensionVisitor @JvmOverloads constructor( } } +/** + * A visitor to visit JVM extensions for a package fragment. + */ +open class JvmPackageExtensionVisitor @JvmOverloads constructor( + delegate: JvmPackageExtensionVisitor? = null +) : KmPackageExtensionVisitor, JvmDeclarationContainerExtensionVisitor(delegate) { + override val delegate: JvmPackageExtensionVisitor? + get() = super.delegate as JvmPackageExtensionVisitor? + + /** + * Visits the end of JVM extensions for the package fragment. + */ + open fun visitEnd() { + delegate?.visitEnd() + } + + companion object { + /** + * The type of this extension visitor. + * + * @see KmExtensionType + */ + @JvmField + val TYPE: KmExtensionType = KmExtensionType(JvmPackageExtensionVisitor::class) + } +} + /** * A visitor to visit JVM extensions for a function. */ diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt index 9dcdb202365..38d25358250 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt @@ -35,10 +35,20 @@ data class KmExtensionType(val klass: KClass) */ interface KmExtensionVisitor +/** + * A visitor to visit platform-specific extensions for a declaration container, such as a class or a package fragment. + */ +interface KmDeclarationContainerExtensionVisitor : KmExtensionVisitor + /** * A visitor to visit platform-specific extensions for a class. */ -interface KmClassExtensionVisitor : KmExtensionVisitor +interface KmClassExtensionVisitor : KmDeclarationContainerExtensionVisitor + +/** + * A visitor to visit platform-specific extensions for a package fragment. + */ +interface KmPackageExtensionVisitor : KmDeclarationContainerExtensionVisitor /** * A visitor to visit platform-specific extensions for a function. diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt index a609d58b6dc..e6d36eb5066 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt @@ -14,6 +14,8 @@ import java.util.* interface MetadataExtensions { fun readClassExtensions(v: KmClassVisitor, proto: ProtoBuf.Class, c: ReadContext) + fun readPackageExtensions(v: KmPackageVisitor, proto: ProtoBuf.Package, c: ReadContext) + fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext) fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, c: ReadContext) @@ -26,6 +28,8 @@ interface MetadataExtensions { fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, c: WriteContext): KmClassExtensionVisitor? + fun writePackageExtensions(type: KmExtensionType, proto: ProtoBuf.Package.Builder, c: WriteContext): KmPackageExtensionVisitor? + fun writeFunctionExtensions(type: KmExtensionType, proto: ProtoBuf.Function.Builder, c: WriteContext): KmFunctionExtensionVisitor? fun writePropertyExtensions(type: KmExtensionType, proto: ProtoBuf.Property.Builder, c: WriteContext): KmPropertyExtensionVisitor? diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt index d2d51481b0a..26792058b1a 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt @@ -93,6 +93,10 @@ fun ProtoBuf.Package.accept(v: KmPackageVisitor, strings: NameResolver) { v.visitDeclarations(functionList, propertyList, typeAliasList, c) + for (extension in c.extensions) { + extension.readPackageExtensions(v, this, c) + } + v.visitEnd() } @@ -107,15 +111,8 @@ private fun KmDeclarationContainerVisitor.visitDeclarations( } for (property in properties) { - val flags = property.flags - val defaultAccessorFlags = F.getAccessorFlags( - F.HAS_ANNOTATIONS.get(flags), F.VISIBILITY.get(flags), F.MODALITY.get(flags), false, false, false - ) visitProperty( - flags, - c[property.name], - if (property.hasGetterFlags()) property.getterFlags else defaultAccessorFlags, - if (property.hasSetterFlags()) property.setterFlags else defaultAccessorFlags + property.flags, c[property.name], property.getPropertyGetterFlags(), property.getPropertySetterFlags() )?.let { property.accept(it, c) } } @@ -182,7 +179,7 @@ private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) { v.visitEnd() } -private fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) { +fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) { val c = outer.withTypeParameters(typeParameterList) for (typeParameter in typeParameterList) { @@ -425,3 +422,12 @@ private val ProtoBuf.Type.typeFlags: Flags private val ProtoBuf.TypeParameter.typeParameterFlags: Flags get() = if (reified) 1 else 0 + +fun ProtoBuf.Property.getPropertyGetterFlags(): Flags = + if (hasGetterFlags()) getterFlags else getDefaultPropertyAccessorFlags(flags) + +fun ProtoBuf.Property.getPropertySetterFlags(): Flags = + if (hasSetterFlags()) setterFlags else getDefaultPropertyAccessorFlags(flags) + +private fun getDefaultPropertyAccessorFlags(flags: Flags): Flags = + F.getAccessorFlags(F.HAS_ANNOTATIONS.get(flags), F.VISIBILITY.get(flags), F.MODALITY.get(flags), false, false, false) diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt index 895f35db355..3a03f823147 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt @@ -190,7 +190,7 @@ private fun writeFunction(c: WriteContext, flags: Flags, name: String, output: ( } } -private fun writeProperty( +fun writeProperty( c: WriteContext, flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags, output: (ProtoBuf.Property.Builder) -> Unit ): KmPropertyVisitor = object : KmPropertyVisitor() { val t = ProtoBuf.Property.newBuilder() @@ -480,6 +480,11 @@ open class PackageWriter(stringTable: StringTable) : KmPackageVisitor() { override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? = writeTypeAlias(c, flags, name) { t.addTypeAlias(it) } + override fun visitExtensions(type: KmExtensionType): KmPackageExtensionVisitor? = + c.applySingleExtension(type) { + writePackageExtensions(type, t, c) + } + override fun visitEnd() { c.versionRequirements.serialize()?.let { t.versionRequirementTable = it diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt index 2536086d281..4002259612b 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt @@ -6,7 +6,7 @@ package kotlinx.metadata /** - * A visitor to visit Kotlin declarations, which are containers of other declarations: functions, properties and type aliases. + * A visitor containing the common code to visit Kotlin declaration containers, such as classes and package fragments. */ abstract class KmDeclarationContainerVisitor @JvmOverloads constructor(protected open val delegate: KmDeclarationContainerVisitor? = null) { /** @@ -39,6 +39,13 @@ abstract class KmDeclarationContainerVisitor @JvmOverloads constructor(protected */ open fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? = delegate?.visitTypeAlias(flags, name) + + /** + * Visits the extensions of the given type on the container. + * + * @param type the type of extension visitor to be returned + */ + abstract fun visitExtensions(type: KmExtensionType): KmDeclarationContainerExtensionVisitor? } /** @@ -136,7 +143,7 @@ abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor * * @param type the type of extension visitor to be returned */ - open fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? = + override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? = delegate?.visitExtensions(type) /** @@ -156,6 +163,14 @@ abstract class KmPackageVisitor @JvmOverloads constructor(delegate: KmPackageVis override val delegate: KmPackageVisitor? get() = super.delegate as KmPackageVisitor? + /** + * Visits the extensions of the given type on the package fragment. + * + * @param type the type of extension visitor to be returned + */ + override fun visitExtensions(type: KmExtensionType): KmPackageExtensionVisitor? = + delegate?.visitExtensions(type) + /** * Visits the end of the package fragment. */ diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt index 25c5a5eb85e..e8639cdaf73 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt @@ -509,6 +509,21 @@ private fun StringBuilder.appendFlags(flags: Flags, map: Map) { } } +private fun StringBuilder.appendLocalDelegatedProperties(localDelegatedProperties: List) { + for ((i, sb) in localDelegatedProperties.withIndex()) { + appendln() + appendln(" // local delegated property #$i") + for (line in sb.lineSequence()) { + if (line.isBlank()) continue + // Comment all uncommented lines to not make it look like these properties are declared here + appendln( + if (line.startsWith(" ") && !line.startsWith(" //")) line.replaceFirst(" ", " // ") + else line + ) + } + } +} + interface AbstractPrinter { fun print(klass: T): String } @@ -594,9 +609,21 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? { if (type != JvmClassExtensionVisitor.TYPE) return null return object : JvmClassExtensionVisitor() { + private val localDelegatedProperties = mutableListOf() + override fun visitAnonymousObjectOriginName(internalName: String) { anonymousObjectOriginName = internalName } + + override fun visitLocalDelegatedProperty( + flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags + ): KmPropertyVisitor? = visitProperty( + settings, StringBuilder().also { localDelegatedProperties.add(it) }, flags, name, getterFlags, setterFlags + ) + + override fun visitEnd() { + sb.appendLocalDelegatedProperties(localDelegatedProperties) + } } } @@ -623,6 +650,23 @@ abstract class PackagePrinter(private val settings: KotlinpSettings) : KmPackage override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? = visitTypeAlias(settings, sb, flags, name) + + override fun visitExtensions(type: KmExtensionType): KmPackageExtensionVisitor? { + if (type != JvmPackageExtensionVisitor.TYPE) return null + return object : JvmPackageExtensionVisitor() { + private val localDelegatedProperties = mutableListOf() + + override fun visitLocalDelegatedProperty( + flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags + ): KmPropertyVisitor? = visitProperty( + settings, StringBuilder().also { localDelegatedProperties.add(it) }, flags, name, getterFlags, setterFlags + ) + + override fun visitEnd() { + sb.appendLocalDelegatedProperties(localDelegatedProperties) + } + } + } } class FileFacadePrinter(settings: KotlinpSettings) : PackagePrinter(settings), AbstractPrinter { diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java index 297be0a4cab..96d2f93f1d3 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java @@ -44,6 +44,11 @@ public class KotlinpTestGenerated extends AbstractKotlinpTest { runTest("libraries/tools/kotlinp/testData/LocalClass.kt"); } + @TestMetadata("LocalDelegatedProperties.kt") + public void testLocalDelegatedProperties() throws Exception { + runTest("libraries/tools/kotlinp/testData/LocalDelegatedProperties.kt"); + } + @TestMetadata("MultiFileClass.kt") public void testMultiFileClass() throws Exception { runTest("libraries/tools/kotlinp/testData/MultiFileClass.kt"); diff --git a/libraries/tools/kotlinp/testData/LocalDelegatedProperties.kt b/libraries/tools/kotlinp/testData/LocalDelegatedProperties.kt new file mode 100644 index 00000000000..a9ceba7f87c --- /dev/null +++ b/libraries/tools/kotlinp/testData/LocalDelegatedProperties.kt @@ -0,0 +1,30 @@ +import kotlin.reflect.KProperty + +class Delegate(val value: T? = null) { + operator fun getValue(instance: Any?, property: KProperty<*>): T = value!! +} + +val nonLocal by Delegate() + +val init0 = run { + val local1 by Delegate() + val local2 by Delegate() +} + +val init1 = run { + val local3 by Delegate() +} + +class Class { + init { + val local4 by Delegate>() + } + + fun f() { + val local5 by Delegate?>() + + fun g() { + val local6 by Delegate() + } + } +} diff --git a/libraries/tools/kotlinp/testData/LocalDelegatedProperties.txt b/libraries/tools/kotlinp/testData/LocalDelegatedProperties.txt new file mode 100644 index 00000000000..aba69825e2c --- /dev/null +++ b/libraries/tools/kotlinp/testData/LocalDelegatedProperties.txt @@ -0,0 +1,88 @@ +// Class.class +// ------------------------------------------ +public final class Class : kotlin/Any { + + // signature: ()V + public /* primary */ constructor() + + // signature: f()V + public final fun f(): kotlin/Unit + + // local delegated property #0 + // field: local4:Lkotlin/Array; + // local final /* delegated */ val local4: kotlin/Array + // local final get + + // local delegated property #1 + // field: local5:Ljava/util/List; + // local final /* delegated */ val local5: kotlin/collections/List? + // local final get + + // local delegated property #2 + // field: local6:I + // local final /* delegated */ val local6: kotlin/Int + // local final get +} +// Class$f$1.class +// ------------------------------------------ +lambda { + + // signature: invoke()V + local final fun g(): kotlin/Unit +} +// Delegate.class +// ------------------------------------------ +public final class Delegate : kotlin/Any { + + // signature: (Ljava/lang/Object;)V + public /* primary */ constructor(value: T#0? /* = ... */) + + // signature: getValue(Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public final operator fun getValue(instance: kotlin/Any?, property: kotlin/reflect/KProperty<*>): T#0 + + // field: value:Ljava/lang/Object; + // getter: getValue()Ljava/lang/Object; + public final val value: T#0? + public final get +} +// LocalDelegatedPropertiesKt.class +// ------------------------------------------ +package { + + // field: init0:Lkotlin/Unit; + // getter: getInit0()Lkotlin/Unit; + public final val init0: kotlin/Unit + public final get + + // field: init1:Lkotlin/Unit; + // getter: getInit1()Lkotlin/Unit; + public final val init1: kotlin/Unit + public final get + + // field: nonLocal$delegate:LDelegate; + // getter: getNonLocal()Ljava/lang/String; + public final /* delegated */ val nonLocal: kotlin/String + public final /* non-default */ get + + // local delegated property #0 + // field: local1:D + // local final /* delegated */ val local1: kotlin/Double + // local final get + + // local delegated property #1 + // field: local2:Ljava/lang/Object; + // local final /* delegated */ val local2: kotlin/Any + // local final get + + // local delegated property #2 + // field: local3:Ljava/lang/CharSequence; + // local final /* delegated */ val local3: kotlin/CharSequence? + // local final get +} +// META-INF/test-module.kotlin_module +// ------------------------------------------ +module { + package { + LocalDelegatedPropertiesKt + } +}