kotlinx-metadata: support experimental context receivers
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- kotlinx-metadata-jvm can no longer be used on JVM 1.6, and now requires JVM 1.8 or later.
|
- kotlinx-metadata-jvm can no longer be used on JVM 1.6, and now requires JVM 1.8 or later.
|
||||||
- Add `Flag.Type.IS_DEFINITELY_NON_NULL`.
|
- Add `Flag.Type.IS_DEFINITELY_NON_NULL`.
|
||||||
|
- Add `KmClass.contextReceiverTypes`, `KmFunction.contextReceiverTypes`, `KmProperty.contextReceiverTypes`
|
||||||
|
- The API is experimental and requires `@ExperimentalContextReceivers` on the usages.
|
||||||
|
|
||||||
## 0.4.2
|
## 0.4.2
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
|
|||||||
/**
|
/**
|
||||||
* Visits the JVM signature of a synthetic method which is generated when a delegated property's delegate object is
|
* Visits the JVM signature of a synthetic method which is generated when a delegated property's delegate object is
|
||||||
* optimized out, e.g. because it is constant; in that case, a copy of that object can be obtained on demand by calling
|
* optimized out, e.g. because it is constant; in that case, a copy of that object can be obtained on demand by calling
|
||||||
* this method. It takes up to two arguments - the property's receivers.
|
* this method. It takes the property's receivers as arguments.
|
||||||
*
|
*
|
||||||
* Example: `JvmMethodSignature("getX$delegate", "(LMyClass;)LMyDelegate;")`
|
* Example: `JvmMethodSignature("getX$delegate", "(LMyClass;)LMyDelegate;")`
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlinx.metadata
|
||||||
|
|
||||||
|
@RequiresOptIn(
|
||||||
|
"The API uses experimental feature \"context receivers\" (see KEEP-259) and may be changed or removed in any future release."
|
||||||
|
)
|
||||||
|
annotation class ExperimentalContextReceivers
|
||||||
@@ -46,6 +46,7 @@ class ReadContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
fun ProtoBuf.Class.accept(
|
fun ProtoBuf.Class.accept(
|
||||||
v: KmClassVisitor,
|
v: KmClassVisitor,
|
||||||
strings: NameResolver,
|
strings: NameResolver,
|
||||||
@@ -100,6 +101,10 @@ fun ProtoBuf.Class.accept(
|
|||||||
v.visitInlineClassUnderlyingType(underlyingType.typeFlags)?.let { underlyingType.accept(it, c) }
|
v.visitInlineClassUnderlyingType(underlyingType.typeFlags)?.let { underlyingType.accept(it, c) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (contextReceiverType in contextReceiverTypes(c.types)) {
|
||||||
|
v.visitContextReceiverType(contextReceiverType.typeFlags)?.let { contextReceiverType.accept(it, c) }
|
||||||
|
}
|
||||||
|
|
||||||
for (versionRequirement in versionRequirementList) {
|
for (versionRequirement in versionRequirementList) {
|
||||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) }
|
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) }
|
||||||
}
|
}
|
||||||
@@ -214,6 +219,7 @@ private fun ProtoBuf.Constructor.accept(v: KmConstructorVisitor, c: ReadContext)
|
|||||||
v.visitEnd()
|
v.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) {
|
private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) {
|
||||||
val c = outer.withTypeParameters(typeParameterList)
|
val c = outer.withTypeParameters(typeParameterList)
|
||||||
|
|
||||||
@@ -225,6 +231,10 @@ private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) {
|
|||||||
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (contextReceiverType in contextReceiverTypes(c.types)) {
|
||||||
|
v.visitContextReceiverType(contextReceiverType.typeFlags)?.let { contextReceiverType.accept(it, c) }
|
||||||
|
}
|
||||||
|
|
||||||
for (parameter in valueParameterList) {
|
for (parameter in valueParameterList) {
|
||||||
v.visitValueParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
v.visitValueParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
||||||
}
|
}
|
||||||
@@ -248,6 +258,7 @@ private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) {
|
|||||||
v.visitEnd()
|
v.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) {
|
fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) {
|
||||||
val c = outer.withTypeParameters(typeParameterList)
|
val c = outer.withTypeParameters(typeParameterList)
|
||||||
|
|
||||||
@@ -259,6 +270,10 @@ fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) {
|
|||||||
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (contextReceiverType in contextReceiverTypes(c.types)) {
|
||||||
|
v.visitContextReceiverType(contextReceiverType.typeFlags)?.let { contextReceiverType.accept(it, c) }
|
||||||
|
}
|
||||||
|
|
||||||
if (hasSetterValueParameter()) {
|
if (hasSetterValueParameter()) {
|
||||||
val parameter = setterValueParameter
|
val parameter = setterValueParameter
|
||||||
v.visitSetterParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
v.visitSetterParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
||||||
|
|||||||
@@ -158,6 +158,10 @@ private fun writeFunction(c: WriteContext, flags: Flags, name: String, output: (
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
writeType(c, flags) { t.receiverType = it.build() }
|
writeType(c, flags) { t.receiverType = it.build() }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
writeType(c, flags) { t.addContextReceiverType(it) }
|
||||||
|
|
||||||
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor? =
|
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor? =
|
||||||
writeValueParameter(c, flags, name) { t.addValueParameter(it) }
|
writeValueParameter(c, flags, name) { t.addValueParameter(it) }
|
||||||
|
|
||||||
@@ -195,6 +199,10 @@ fun writeProperty(
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
writeType(c, flags) { t.receiverType = it.build() }
|
writeType(c, flags) { t.receiverType = it.build() }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
writeType(c, flags) { t.addContextReceiverType(it) }
|
||||||
|
|
||||||
override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor? =
|
override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor? =
|
||||||
writeValueParameter(c, flags, name) { t.setterValueParameter = it.build() }
|
writeValueParameter(c, flags, name) { t.setterValueParameter = it.build() }
|
||||||
|
|
||||||
@@ -464,6 +472,10 @@ open class ClassWriter(stringTable: StringTable, contextExtensions: List<WriteCo
|
|||||||
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
||||||
writeType(c, flags) { t.inlineClassUnderlyingType = it.build() }
|
writeType(c, flags) { t.inlineClassUnderlyingType = it.build() }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
writeType(c, flags) { t.addContextReceiverType(it) }
|
||||||
|
|
||||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||||
writeVersionRequirement(c) { t.addVersionRequirement(it) }
|
writeVersionRequirement(c) { t.addVersionRequirement(it) }
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,12 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
*/
|
*/
|
||||||
var inlineClassUnderlyingType: KmType? = null
|
var inlineClassUnderlyingType: KmType? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of context receivers of the class.
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
val contextReceiverTypes: MutableList<KmType> = ArrayList(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version requirements on this class.
|
* Version requirements on this class.
|
||||||
*/
|
*/
|
||||||
@@ -157,6 +163,10 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor =
|
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor =
|
||||||
KmType(flags).also { inlineClassUnderlyingType = it }
|
KmType(flags).also { inlineClassUnderlyingType = it }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
KmType(flags).addTo(contextReceiverTypes)
|
||||||
|
|
||||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor =
|
||||||
KmVersionRequirement().addTo(versionRequirements)
|
KmVersionRequirement().addTo(versionRequirements)
|
||||||
|
|
||||||
@@ -168,6 +178,7 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
*
|
*
|
||||||
* @param visitor the visitor which will visit data in this class
|
* @param visitor the visitor which will visit data in this class
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
fun accept(visitor: KmClassVisitor) {
|
fun accept(visitor: KmClassVisitor) {
|
||||||
visitor.visit(flags, name)
|
visitor.visit(flags, name)
|
||||||
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
||||||
@@ -182,6 +193,7 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
sealedSubclasses.forEach(visitor::visitSealedSubclass)
|
sealedSubclasses.forEach(visitor::visitSealedSubclass)
|
||||||
inlineClassUnderlyingPropertyName?.let(visitor::visitInlineClassUnderlyingPropertyName)
|
inlineClassUnderlyingPropertyName?.let(visitor::visitInlineClassUnderlyingPropertyName)
|
||||||
inlineClassUnderlyingType?.let { visitor.visitInlineClassUnderlyingType(it.flags)?.let(it::accept) }
|
inlineClassUnderlyingType?.let { visitor.visitInlineClassUnderlyingType(it.flags)?.let(it::accept) }
|
||||||
|
contextReceiverTypes.forEach { visitor.visitContextReceiverType(it.flags)?.let(it::accept) }
|
||||||
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
||||||
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
|
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
|
||||||
visitor.visitEnd()
|
visitor.visitEnd()
|
||||||
@@ -360,6 +372,12 @@ class KmFunction(
|
|||||||
*/
|
*/
|
||||||
var receiverParameterType: KmType? = null
|
var receiverParameterType: KmType? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of context receivers of the function.
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
val contextReceiverTypes: MutableList<KmType> = ArrayList(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value parameters of the function.
|
* Value parameters of the function.
|
||||||
*/
|
*/
|
||||||
@@ -389,6 +407,10 @@ class KmFunction(
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor =
|
||||||
KmType(flags).also { receiverParameterType = it }
|
KmType(flags).also { receiverParameterType = it }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
KmType(flags).addTo(contextReceiverTypes)
|
||||||
|
|
||||||
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor =
|
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor =
|
||||||
KmValueParameter(flags, name).addTo(valueParameters)
|
KmValueParameter(flags, name).addTo(valueParameters)
|
||||||
|
|
||||||
@@ -409,9 +431,11 @@ class KmFunction(
|
|||||||
*
|
*
|
||||||
* @param visitor the visitor which will visit data in this function
|
* @param visitor the visitor which will visit data in this function
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
fun accept(visitor: KmFunctionVisitor) {
|
fun accept(visitor: KmFunctionVisitor) {
|
||||||
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
||||||
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
|
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
|
||||||
|
contextReceiverTypes.forEach { visitor.visitContextReceiverType(it.flags)?.let(it::accept) }
|
||||||
valueParameters.forEach { visitor.visitValueParameter(it.flags, it.name)?.let(it::accept) }
|
valueParameters.forEach { visitor.visitValueParameter(it.flags, it.name)?.let(it::accept) }
|
||||||
visitor.visitReturnType(returnType.flags)?.let(returnType::accept)
|
visitor.visitReturnType(returnType.flags)?.let(returnType::accept)
|
||||||
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
||||||
@@ -447,6 +471,12 @@ class KmProperty(
|
|||||||
*/
|
*/
|
||||||
var receiverParameterType: KmType? = null
|
var receiverParameterType: KmType? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of context receivers of the property.
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
val contextReceiverTypes: MutableList<KmType> = ArrayList(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value parameter of the setter of this property, if this is a `var` property.
|
* Value parameter of the setter of this property, if this is a `var` property.
|
||||||
*/
|
*/
|
||||||
@@ -471,6 +501,10 @@ class KmProperty(
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor =
|
||||||
KmType(flags).also { receiverParameterType = it }
|
KmType(flags).also { receiverParameterType = it }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
KmType(flags).addTo(contextReceiverTypes)
|
||||||
|
|
||||||
override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor =
|
override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor =
|
||||||
KmValueParameter(flags, name).also { setterParameter = it }
|
KmValueParameter(flags, name).also { setterParameter = it }
|
||||||
|
|
||||||
@@ -488,9 +522,11 @@ class KmProperty(
|
|||||||
*
|
*
|
||||||
* @param visitor the visitor which will visit data in this property
|
* @param visitor the visitor which will visit data in this property
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
fun accept(visitor: KmPropertyVisitor) {
|
fun accept(visitor: KmPropertyVisitor) {
|
||||||
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
|
||||||
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
|
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
|
||||||
|
contextReceiverTypes.forEach { visitor.visitContextReceiverType(it.flags)?.let(it::accept) }
|
||||||
setterParameter?.let { visitor.visitSetterParameter(it.flags, it.name)?.let(it::accept) }
|
setterParameter?.let { visitor.visitSetterParameter(it.flags, it.name)?.let(it::accept) }
|
||||||
visitor.visitReturnType(returnType.flags)?.let(returnType::accept)
|
visitor.visitReturnType(returnType.flags)?.let(returnType::accept)
|
||||||
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
||||||
|
|||||||
@@ -149,6 +149,15 @@ abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor
|
|||||||
open fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
open fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
||||||
delegate?.visitInlineClassUnderlyingType(flags)
|
delegate?.visitInlineClassUnderlyingType(flags)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the type of a context receiver of the class.
|
||||||
|
*
|
||||||
|
* @param flags type flags, consisting of [Flag.Type] flags
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
open fun visitContextReceiverType(flags: Flags): KmTypeVisitor? =
|
||||||
|
delegate?.visitContextReceiverType(flags)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits the version requirement on this class.
|
* Visits the version requirement on this class.
|
||||||
*/
|
*/
|
||||||
@@ -319,6 +328,15 @@ abstract class KmFunctionVisitor @JvmOverloads constructor(private val delegate:
|
|||||||
open fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
open fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
delegate?.visitReceiverParameterType(flags)
|
delegate?.visitReceiverParameterType(flags)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the type of a context receiver of the function.
|
||||||
|
*
|
||||||
|
* @param flags type flags, consisting of [Flag.Type] flags
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
open fun visitContextReceiverType(flags: Flags): KmTypeVisitor? =
|
||||||
|
delegate?.visitContextReceiverType(flags)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits a value parameter of the function.
|
* Visits a value parameter of the function.
|
||||||
*
|
*
|
||||||
@@ -391,6 +409,15 @@ abstract class KmPropertyVisitor @JvmOverloads constructor(private val delegate:
|
|||||||
open fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
open fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
delegate?.visitReceiverParameterType(flags)
|
delegate?.visitReceiverParameterType(flags)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the type of a context receiver of the property.
|
||||||
|
*
|
||||||
|
* @param flags type flags, consisting of [Flag.Type] flags
|
||||||
|
*/
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
open fun visitContextReceiverType(flags: Flags): KmTypeVisitor? =
|
||||||
|
delegate?.visitContextReceiverType(flags)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits a value parameter of the setter of this property, if this is a `var` property.
|
* Visits a value parameter of the setter of this property, if this is a `var` property.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.kotlinp
|
|||||||
|
|
||||||
import kotlinx.metadata.*
|
import kotlinx.metadata.*
|
||||||
import kotlinx.metadata.jvm.*
|
import kotlinx.metadata.jvm.*
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
private object SpecialCharacters {
|
private object SpecialCharacters {
|
||||||
const val TYPE_ALIAS_MARKER = '^'
|
const val TYPE_ALIAS_MARKER = '^'
|
||||||
@@ -18,6 +17,7 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
|||||||
val typeParams = mutableListOf<String>()
|
val typeParams = mutableListOf<String>()
|
||||||
val params = mutableListOf<String>()
|
val params = mutableListOf<String>()
|
||||||
var receiverParameterType: String? = null
|
var receiverParameterType: String? = null
|
||||||
|
val contextReceiverTypes = mutableListOf<String>()
|
||||||
var returnType: String? = null
|
var returnType: String? = null
|
||||||
val versionRequirements = mutableListOf<String>()
|
val versionRequirements = mutableListOf<String>()
|
||||||
var jvmSignature: JvmMemberSignature? = null
|
var jvmSignature: JvmMemberSignature? = null
|
||||||
@@ -27,6 +27,10 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
printType(flags) { receiverParameterType = it }
|
printType(flags) { receiverParameterType = it }
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
printType(flags) { contextReceiverTypes.add(it) }
|
||||||
|
|
||||||
override fun visitTypeParameter(
|
override fun visitTypeParameter(
|
||||||
flags: Flags, name: String, id: Int, variance: KmVariance
|
flags: Flags, name: String, id: Int, variance: KmVariance
|
||||||
): KmTypeParameterVisitor? =
|
): KmTypeParameterVisitor? =
|
||||||
@@ -68,6 +72,9 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
|
|||||||
if (jvmSignature != null) {
|
if (jvmSignature != null) {
|
||||||
sb.appendLine(" // signature: $jvmSignature")
|
sb.appendLine(" // signature: $jvmSignature")
|
||||||
}
|
}
|
||||||
|
if (contextReceiverTypes.isNotEmpty()) {
|
||||||
|
sb.appendLine(contextReceiverTypes.joinToString(prefix = " context(", postfix = ")"))
|
||||||
|
}
|
||||||
sb.append(" ")
|
sb.append(" ")
|
||||||
sb.appendFlags(flags, FUNCTION_FLAGS_MAP)
|
sb.appendFlags(flags, FUNCTION_FLAGS_MAP)
|
||||||
sb.append("fun ")
|
sb.append("fun ")
|
||||||
@@ -96,6 +103,7 @@ private fun visitProperty(
|
|||||||
object : KmPropertyVisitor() {
|
object : KmPropertyVisitor() {
|
||||||
val typeParams = mutableListOf<String>()
|
val typeParams = mutableListOf<String>()
|
||||||
var receiverParameterType: String? = null
|
var receiverParameterType: String? = null
|
||||||
|
val contextReceiverTypes = mutableListOf<String>()
|
||||||
var returnType: String? = null
|
var returnType: String? = null
|
||||||
var setterParameter: String? = null
|
var setterParameter: String? = null
|
||||||
val versionRequirements = mutableListOf<String>()
|
val versionRequirements = mutableListOf<String>()
|
||||||
@@ -109,6 +117,10 @@ private fun visitProperty(
|
|||||||
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
|
||||||
printType(flags) { receiverParameterType = it }
|
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? =
|
override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||||
printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) }
|
printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) }
|
||||||
|
|
||||||
@@ -169,6 +181,9 @@ private fun visitProperty(
|
|||||||
if (isMovedFromInterfaceCompanion) {
|
if (isMovedFromInterfaceCompanion) {
|
||||||
sb.appendLine(" // is moved from interface companion")
|
sb.appendLine(" // is moved from interface companion")
|
||||||
}
|
}
|
||||||
|
if (contextReceiverTypes.isNotEmpty()) {
|
||||||
|
sb.appendLine(contextReceiverTypes.joinToString(prefix = " context(", postfix = ")"))
|
||||||
|
}
|
||||||
sb.append(" ")
|
sb.append(" ")
|
||||||
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
|
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
|
||||||
sb.append(if (Flag.Property.IS_VAR(flags)) "var " else "val ")
|
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 var name: ClassName? = null
|
||||||
private val typeParams = mutableListOf<String>()
|
private val typeParams = mutableListOf<String>()
|
||||||
private val supertypes = mutableListOf<String>()
|
private val supertypes = mutableListOf<String>()
|
||||||
|
private val contextReceiverTypes = mutableListOf<String>()
|
||||||
private val versionRequirements = mutableListOf<String>()
|
private val versionRequirements = mutableListOf<String>()
|
||||||
private var anonymousObjectOriginName: String? = null
|
private var anonymousObjectOriginName: String? = null
|
||||||
|
|
||||||
@@ -726,6 +742,9 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
|||||||
for (versionRequirement in versionRequirements) {
|
for (versionRequirement in versionRequirements) {
|
||||||
result.appendLine("// $versionRequirement")
|
result.appendLine("// $versionRequirement")
|
||||||
}
|
}
|
||||||
|
if (contextReceiverTypes.isNotEmpty()) {
|
||||||
|
result.appendLine(contextReceiverTypes.joinToString(prefix = "context(", postfix = ")"))
|
||||||
|
}
|
||||||
result.appendFlags(flags!!, CLASS_FLAGS_MAP)
|
result.appendFlags(flags!!, CLASS_FLAGS_MAP)
|
||||||
result.append(name)
|
result.append(name)
|
||||||
if (typeParams.isNotEmpty()) {
|
if (typeParams.isNotEmpty()) {
|
||||||
@@ -789,6 +808,10 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
|||||||
sb.appendLine(" // underlying type: $it")
|
sb.appendLine(" // underlying type: $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalContextReceivers
|
||||||
|
override fun visitContextReceiverType(flags: Flags): KmTypeVisitor =
|
||||||
|
printType(flags) { contextReceiverTypes.add(it) }
|
||||||
|
|
||||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||||
printVersionRequirement { versionRequirements.add(it) }
|
printVersionRequirement { versionRequirements.add(it) }
|
||||||
|
|
||||||
|
|||||||
+5
@@ -34,6 +34,11 @@ public class KotlinpTestGenerated extends AbstractKotlinpTest {
|
|||||||
runTest("libraries/tools/kotlinp/testData/Annotations.kt");
|
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")
|
@TestMetadata("Contracts.kt")
|
||||||
public void testContracts() throws Exception {
|
public void testContracts() throws Exception {
|
||||||
runTest("libraries/tools/kotlinp/testData/Contracts.kt");
|
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