kotlinx-metadata: support experimental context receivers
This commit is contained in:
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.kotlinp
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.jvm.*
|
||||
import java.util.*
|
||||
|
||||
private object SpecialCharacters {
|
||||
const val TYPE_ALIAS_MARKER = '^'
|
||||
@@ -18,6 +17,7 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
||||
val typeParams = mutableListOf<String>()
|
||||
val params = mutableListOf<String>()
|
||||
var receiverParameterType: String? = null
|
||||
val contextReceiverTypes = mutableListOf<String>()
|
||||
var returnType: String? = null
|
||||
val versionRequirements = mutableListOf<String>()
|
||||
var jvmSignature: JvmMemberSignature? = null
|
||||
@@ -27,6 +27,10 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||
printType(flags) { receiverParameterType = it }
|
||||
|
||||
@ExperimentalContextReceivers
|
||||
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||
printType(flags) { contextReceiverTypes.add(it) }
|
||||
|
||||
override fun visitTypeParameter(
|
||||
flags: Flags, name: String, id: Int, variance: KmVariance
|
||||
): KmTypeParameterVisitor? =
|
||||
@@ -68,6 +72,9 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
||||
if (jvmSignature != null) {
|
||||
sb.appendLine(" // signature: $jvmSignature")
|
||||
}
|
||||
if (contextReceiverTypes.isNotEmpty()) {
|
||||
sb.appendLine(contextReceiverTypes.joinToString(prefix = " context(", postfix = ")"))
|
||||
}
|
||||
sb.append(" ")
|
||||
sb.appendFlags(flags, FUNCTION_FLAGS_MAP)
|
||||
sb.append("fun ")
|
||||
@@ -96,6 +103,7 @@ private fun visitProperty(
|
||||
object : KmPropertyVisitor() {
|
||||
val typeParams = mutableListOf<String>()
|
||||
var receiverParameterType: String? = null
|
||||
val contextReceiverTypes = mutableListOf<String>()
|
||||
var returnType: String? = null
|
||||
var setterParameter: String? = null
|
||||
val versionRequirements = mutableListOf<String>()
|
||||
@@ -109,6 +117,10 @@ private fun visitProperty(
|
||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||
printType(flags) { receiverParameterType = it }
|
||||
|
||||
@ExperimentalContextReceivers
|
||||
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||
printType(flags) { contextReceiverTypes.add(it) }
|
||||
|
||||
override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||
printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) }
|
||||
|
||||
@@ -169,6 +181,9 @@ private fun visitProperty(
|
||||
if (isMovedFromInterfaceCompanion) {
|
||||
sb.appendLine(" // is moved from interface companion")
|
||||
}
|
||||
if (contextReceiverTypes.isNotEmpty()) {
|
||||
sb.appendLine(contextReceiverTypes.joinToString(prefix = " context(", postfix = ")"))
|
||||
}
|
||||
sb.append(" ")
|
||||
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
|
||||
sb.append(if (Flag.Property.IS_VAR(flags)) "var " else "val ")
|
||||
@@ -711,6 +726,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
||||
private var name: ClassName? = null
|
||||
private val typeParams = mutableListOf<String>()
|
||||
private val supertypes = mutableListOf<String>()
|
||||
private val contextReceiverTypes = mutableListOf<String>()
|
||||
private val versionRequirements = mutableListOf<String>()
|
||||
private var anonymousObjectOriginName: String? = null
|
||||
|
||||
@@ -726,6 +742,9 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
||||
for (versionRequirement in versionRequirements) {
|
||||
result.appendLine("// $versionRequirement")
|
||||
}
|
||||
if (contextReceiverTypes.isNotEmpty()) {
|
||||
result.appendLine(contextReceiverTypes.joinToString(prefix = "context(", postfix = ")"))
|
||||
}
|
||||
result.appendFlags(flags!!, CLASS_FLAGS_MAP)
|
||||
result.append(name)
|
||||
if (typeParams.isNotEmpty()) {
|
||||
@@ -789,6 +808,10 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
||||
sb.appendLine(" // underlying type: $it")
|
||||
}
|
||||
|
||||
@ExperimentalContextReceivers
|
||||
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||
printType(flags) { contextReceiverTypes.add(it) }
|
||||
|
||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
printVersionRequirement { versionRequirements.add(it) }
|
||||
|
||||
|
||||
+5
@@ -34,6 +34,11 @@ public class KotlinpTestGenerated extends AbstractKotlinpTest {
|
||||
runTest("libraries/tools/kotlinp/testData/Annotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ContextReceivers.kt")
|
||||
public void testContextReceivers() throws Exception {
|
||||
runTest("libraries/tools/kotlinp/testData/ContextReceivers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Contracts.kt")
|
||||
public void testContracts() throws Exception {
|
||||
runTest("libraries/tools/kotlinp/testData/Contracts.kt");
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// !LANGUAGE: +ContextReceivers
|
||||
|
||||
interface A
|
||||
interface B
|
||||
|
||||
context(A) class C {
|
||||
context(B) fun f() {}
|
||||
}
|
||||
|
||||
context(A) fun g() {}
|
||||
context(B) val h: Int get() = 42
|
||||
@@ -0,0 +1,50 @@
|
||||
// A.class
|
||||
// ------------------------------------------
|
||||
public abstract interface A : kotlin/Any {
|
||||
|
||||
// module name: test-module
|
||||
}
|
||||
// B.class
|
||||
// ------------------------------------------
|
||||
public abstract interface B : kotlin/Any {
|
||||
|
||||
// module name: test-module
|
||||
}
|
||||
// C.class
|
||||
// ------------------------------------------
|
||||
// requires compiler version 1.6.20 (level=ERROR)
|
||||
context(A)
|
||||
public final class C : kotlin/Any {
|
||||
|
||||
// signature: <init>(LA;)V
|
||||
public constructor()
|
||||
|
||||
// requires compiler version 1.6.20 (level=ERROR)
|
||||
// signature: f(LB;)V
|
||||
context(B)
|
||||
public final fun f(): kotlin/Unit
|
||||
|
||||
// module name: test-module
|
||||
}
|
||||
// ContextReceiversKt.class
|
||||
// ------------------------------------------
|
||||
package {
|
||||
|
||||
// requires compiler version 1.6.20 (level=ERROR)
|
||||
// signature: g(LA;)V
|
||||
context(A)
|
||||
public final fun g(): kotlin/Unit
|
||||
|
||||
// requires compiler version 1.6.20 (level=ERROR)
|
||||
// getter: getH(LB;)I
|
||||
context(B)
|
||||
public final val h: kotlin/Int
|
||||
public final /* non-default */ get
|
||||
}
|
||||
// META-INF/test-module.kotlin_module
|
||||
// ------------------------------------------
|
||||
module {
|
||||
package <root> {
|
||||
ContextReceiversKt
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user