Add underlying property name & type for inline class to kotlinx-metadata
#KT-45635 Fixed
This commit is contained in:
@@ -23,6 +23,12 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
fun ProtoBuf.Class.supertypes(typeTable: TypeTable): List<ProtoBuf.Type> =
|
||||
supertypeList.takeIf(Collection<*>::isNotEmpty) ?: supertypeIdList.map { typeTable[it] }
|
||||
|
||||
fun ProtoBuf.Class.inlineClassUnderlyingType(typeTable: TypeTable): ProtoBuf.Type? = when {
|
||||
hasInlineClassUnderlyingType() -> inlineClassUnderlyingType
|
||||
hasInlineClassUnderlyingTypeId() -> typeTable[inlineClassUnderlyingTypeId]
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun ProtoBuf.Type.Argument.type(typeTable: TypeTable): ProtoBuf.Type? = when {
|
||||
hasType() -> type
|
||||
hasTypeId() -> typeTable[typeId]
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
- Breaking change: deprecate `KotlinClassHeader.bytecodeVersion` and `KotlinClassHeader`'s constructor that takes a bytecode version array.
|
||||
Related to ['KT-41758`](https://youtrack.jetbrains.com/issue/KT-41758).
|
||||
- [`KT-45594`](https://youtrack.jetbrains.com/issue/KT-45594) KClass annotation argument containing array of classes is not read/written correctly
|
||||
- [`KT-45635`](https://youtrack.jetbrains.com/issue/KT-45635) Add underlying property name & type for inline classes
|
||||
|
||||
## 0.2.0
|
||||
|
||||
|
||||
@@ -93,6 +93,13 @@ fun ProtoBuf.Class.accept(
|
||||
v.visitSealedSubclass(c.className(sealedSubclassFqName))
|
||||
}
|
||||
|
||||
if (hasInlineClassUnderlyingPropertyName()) {
|
||||
v.visitInlineClassUnderlyingPropertyName(c[inlineClassUnderlyingPropertyName])
|
||||
}
|
||||
loadInlineClassUnderlyingType(c)?.let { underlyingType ->
|
||||
v.visitInlineClassUnderlyingType(underlyingType.flags)?.let { underlyingType.accept(it, c) }
|
||||
}
|
||||
|
||||
for (versionRequirement in versionRequirementList) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) }
|
||||
}
|
||||
@@ -104,6 +111,18 @@ fun ProtoBuf.Class.accept(
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Class.loadInlineClassUnderlyingType(c: ReadContext): ProtoBuf.Type? {
|
||||
val type = inlineClassUnderlyingType(c.types)
|
||||
if (type != null) return type
|
||||
|
||||
if (!hasInlineClassUnderlyingPropertyName()) return null
|
||||
|
||||
// Kotlin compiler doesn't write underlying type to metadata in case it can be loaded from the underlying property.
|
||||
return propertyList
|
||||
.singleOrNull { it.receiverType(c.types) == null && c[it.name] == c[inlineClassUnderlyingPropertyName] }
|
||||
?.returnType(c.types)
|
||||
}
|
||||
|
||||
fun ProtoBuf.Package.accept(
|
||||
v: KmPackageVisitor,
|
||||
strings: NameResolver,
|
||||
|
||||
@@ -457,6 +457,13 @@ open class ClassWriter(stringTable: StringTable, contextExtensions: List<WriteCo
|
||||
t.addSealedSubclassFqName(c.getClassName(name))
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingPropertyName(name: String) {
|
||||
t.inlineClassUnderlyingPropertyName = c[name]
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
||||
writeType(c, flags) { t.inlineClassUnderlyingType = it.build() }
|
||||
|
||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
writeVersionRequirement(c) { t.addVersionRequirement(it) }
|
||||
|
||||
|
||||
@@ -93,6 +93,16 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
||||
*/
|
||||
val sealedSubclasses: MutableList<ClassName> = ArrayList(0)
|
||||
|
||||
/**
|
||||
* Name of the underlying property, if this class is `inline`.
|
||||
*/
|
||||
var inlineClassUnderlyingPropertyName: String? = null
|
||||
|
||||
/**
|
||||
* Type of the underlying property, if this class is `inline`.
|
||||
*/
|
||||
var inlineClassUnderlyingType: KmType? = null
|
||||
|
||||
/**
|
||||
* Version requirements on this class.
|
||||
*/
|
||||
@@ -140,6 +150,13 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
||||
sealedSubclasses.add(name)
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingPropertyName(name: String) {
|
||||
inlineClassUnderlyingPropertyName = name
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor =
|
||||
KmType(flags).also { inlineClassUnderlyingType = it }
|
||||
|
||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor =
|
||||
KmVersionRequirement().addTo(versionRequirements)
|
||||
|
||||
@@ -163,6 +180,8 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
||||
nestedClasses.forEach(visitor::visitNestedClass)
|
||||
enumEntries.forEach(visitor::visitEnumEntry)
|
||||
sealedSubclasses.forEach(visitor::visitSealedSubclass)
|
||||
inlineClassUnderlyingPropertyName?.let(visitor::visitInlineClassUnderlyingPropertyName)
|
||||
inlineClassUnderlyingType?.let { visitor.visitInlineClassUnderlyingType(it.flags)?.let(it::accept) }
|
||||
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
|
||||
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
|
||||
visitor.visitEnd()
|
||||
|
||||
@@ -132,6 +132,23 @@ abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor
|
||||
delegate?.visitSealedSubclass(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the name of the underlying property, if this class is `inline`.
|
||||
*
|
||||
* @param name the name of the underlying property.
|
||||
*/
|
||||
open fun visitInlineClassUnderlyingPropertyName(name: String) {
|
||||
delegate?.visitInlineClassUnderlyingPropertyName(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the type of the underlying property, if this class is `inline`.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flag.Type] flags
|
||||
*/
|
||||
open fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
||||
delegate?.visitInlineClassUnderlyingType(flags)
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this class.
|
||||
*/
|
||||
|
||||
@@ -767,6 +767,17 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
||||
sb.appendLine(" // sealed subclass: $name")
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingPropertyName(name: String) {
|
||||
sb.appendLine()
|
||||
sb.appendLine(" // underlying property: $name")
|
||||
}
|
||||
|
||||
override fun visitInlineClassUnderlyingType(flags: Flags): KmTypeVisitor? =
|
||||
printType(flags) {
|
||||
sb.appendLine()
|
||||
sb.appendLine(" // underlying type: $it")
|
||||
}
|
||||
|
||||
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
printVersionRequirement { versionRequirements.add(it) }
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ public final value class Z : kotlin/Any {
|
||||
public final val s: kotlin/String
|
||||
public final get
|
||||
|
||||
// underlying property: s
|
||||
|
||||
// underlying type: kotlin/String
|
||||
|
||||
// module name: test-module
|
||||
}
|
||||
// META-INF/test-module.kotlin_module
|
||||
|
||||
Reference in New Issue
Block a user