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> =
|
fun ProtoBuf.Class.supertypes(typeTable: TypeTable): List<ProtoBuf.Type> =
|
||||||
supertypeList.takeIf(Collection<*>::isNotEmpty) ?: supertypeIdList.map { typeTable[it] }
|
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 {
|
fun ProtoBuf.Type.Argument.type(typeTable: TypeTable): ProtoBuf.Type? = when {
|
||||||
hasType() -> type
|
hasType() -> type
|
||||||
hasTypeId() -> typeTable[typeId]
|
hasTypeId() -> typeTable[typeId]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
- Breaking change: deprecate `KotlinClassHeader.bytecodeVersion` and `KotlinClassHeader`'s constructor that takes a bytecode version array.
|
- 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).
|
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-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
|
## 0.2.0
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,13 @@ fun ProtoBuf.Class.accept(
|
|||||||
v.visitSealedSubclass(c.className(sealedSubclassFqName))
|
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) {
|
for (versionRequirement in versionRequirementList) {
|
||||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) }
|
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) }
|
||||||
}
|
}
|
||||||
@@ -104,6 +111,18 @@ fun ProtoBuf.Class.accept(
|
|||||||
v.visitEnd()
|
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(
|
fun ProtoBuf.Package.accept(
|
||||||
v: KmPackageVisitor,
|
v: KmPackageVisitor,
|
||||||
strings: NameResolver,
|
strings: NameResolver,
|
||||||
|
|||||||
@@ -457,6 +457,13 @@ open class ClassWriter(stringTable: StringTable, contextExtensions: List<WriteCo
|
|||||||
t.addSealedSubclassFqName(c.getClassName(name))
|
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? =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||||
writeVersionRequirement(c) { t.addVersionRequirement(it) }
|
writeVersionRequirement(c) { t.addVersionRequirement(it) }
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,16 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
*/
|
*/
|
||||||
val sealedSubclasses: MutableList<ClassName> = ArrayList(0)
|
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.
|
* Version requirements on this class.
|
||||||
*/
|
*/
|
||||||
@@ -140,6 +150,13 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
sealedSubclasses.add(name)
|
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 =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor =
|
||||||
KmVersionRequirement().addTo(versionRequirements)
|
KmVersionRequirement().addTo(versionRequirements)
|
||||||
|
|
||||||
@@ -163,6 +180,8 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
|
|||||||
nestedClasses.forEach(visitor::visitNestedClass)
|
nestedClasses.forEach(visitor::visitNestedClass)
|
||||||
enumEntries.forEach(visitor::visitEnumEntry)
|
enumEntries.forEach(visitor::visitEnumEntry)
|
||||||
sealedSubclasses.forEach(visitor::visitSealedSubclass)
|
sealedSubclasses.forEach(visitor::visitSealedSubclass)
|
||||||
|
inlineClassUnderlyingPropertyName?.let(visitor::visitInlineClassUnderlyingPropertyName)
|
||||||
|
inlineClassUnderlyingType?.let { visitor.visitInlineClassUnderlyingType(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()
|
||||||
|
|||||||
@@ -132,6 +132,23 @@ abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor
|
|||||||
delegate?.visitSealedSubclass(name)
|
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.
|
* Visits the version requirement on this class.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -767,6 +767,17 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
|
|||||||
sb.appendLine(" // sealed subclass: $name")
|
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? =
|
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||||
printVersionRequirement { versionRequirements.add(it) }
|
printVersionRequirement { versionRequirements.add(it) }
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ public final value class Z : kotlin/Any {
|
|||||||
public final val s: kotlin/String
|
public final val s: kotlin/String
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
|
// underlying property: s
|
||||||
|
|
||||||
|
// underlying type: kotlin/String
|
||||||
|
|
||||||
// module name: test-module
|
// module name: test-module
|
||||||
}
|
}
|
||||||
// META-INF/test-module.kotlin_module
|
// META-INF/test-module.kotlin_module
|
||||||
|
|||||||
Reference in New Issue
Block a user