Support local delegated properties in kotlinx-metadata-jvm

This commit is contained in:
Alexander Udalov
2018-06-13 19:17:02 +02:00
parent b00f765255
commit fec2c14ea5
12 changed files with 330 additions and 20 deletions
@@ -509,6 +509,21 @@ private fun StringBuilder.appendFlags(flags: Flags, map: Map<Flag, String>) {
}
}
private fun StringBuilder.appendLocalDelegatedProperties(localDelegatedProperties: List<StringBuilder>) {
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<in T : KotlinClassMetadata> {
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<StringBuilder>()
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<StringBuilder>()
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<KotlinClassMetadata.FileFacade> {
@@ -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");
@@ -0,0 +1,30 @@
import kotlin.reflect.KProperty
class Delegate<T>(val value: T? = null) {
operator fun getValue(instance: Any?, property: KProperty<*>): T = value!!
}
val nonLocal by Delegate<String>()
val init0 = run {
val local1 by Delegate<Double>()
val local2 by Delegate<Any>()
}
val init1 = run {
val local3 by Delegate<CharSequence?>()
}
class Class {
init {
val local4 by Delegate<Array<String>>()
}
fun f() {
val local5 by Delegate<List<Unit>?>()
fun g() {
val local6 by Delegate<Int>()
}
}
}
@@ -0,0 +1,88 @@
// Class.class
// ------------------------------------------
public final class Class : kotlin/Any {
// signature: <init>()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<kotlin/String>
// local final get
// local delegated property #1
// field: local5:Ljava/util/List;
// local final /* delegated */ val local5: kotlin/collections/List<kotlin/Unit>?
// 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<T#0 /* T */> : kotlin/Any {
// signature: <init>(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 <root> {
LocalDelegatedPropertiesKt
}
}