Repository: JetBrains/kotlin
File: core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt (Kotlin)

Code before:

    override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor()

    internal fun hasNestedClass(name: Name): Boolean =
        name in memberScope.classNames

    private fun computeSubclassesForSealedClass(): Collection<ClassDescriptor> {
        if (modality != Modality.SEALED) return emptyList()

        val fqNames = classProto.sealedSubclassFqNameList
        if (fqNames.isNotEmpty()) {
            return fqNames.mapNotNull { index ->
                c.components.deserializeClass(c.nameResolver.getClassId(index))
            }
        }

        // This is needed because classes compiled with Kotlin 1.0 did not contain the sealed_subclass_fq_name field
        return CliSealedClassInheritorsProvider.computeSealedSubclasses(this, allowSealedInheritorsInDifferentFilesOfSamePackage = false)
    }

    override fun getSealedSubclasses() = sealedSubclasses()

    override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = inlineClassRepresentation()

    private fun computeInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? {
        if (!isInlineClass()) return null

        val propertyName = when {
            classProto.hasInlineClassUnderlyingPropertyName() ->
                c.nameResolver.getName(classProto.inlineClassUnderlyingPropertyName)
            !metadataVersion.isAtLeast(1, 5, 1) -> {
                // Before 1.5, inline classes did not have underlying property name & type in the metadata.
                // However, they were experimental, so supposedly this logic can be removed at some point in the future.
                val constructor = unsubstitutedPrimaryConstructor ?: error("Inline class has no primary constructor: $this")
                constructor.valueParameters.first().name
            }
            else -> error("Inline class has no underlying property name in metadata: $this")
        }

        val type = classProto.inlineClassUnderlyingType(c.typeTable)?.let(c.typeDeserializer::simpleType)
            ?: run {
                val underlyingProperty =
                    memberScope.getContributedVariables(propertyName, NoLookupLocation.FROM_DESERIALIZATION)
                        .singleOrNull { it.extensionReceiverParameter == null }
                        ?: error("Inline class has no underlying property: $this")
                underlyingProperty.type as SimpleType
            }

        return InlineClassRepresentation(propertyName, type)
    }


Review comment (bug):
BTW even though this change doesn't seem to affect anything, it looks a bit incorrect because multi-field _value_ classes (`LanguageFeature.ValueClasses`, the feature which @zhelenskiy is working on) will not be represented in the way inline classes are represented in Kotlin metadata. We'll need at least a list of all primary constructor properties, not just the single one.

But since we haven't started working on, or even discussing, metadata for multi-field value classes, I don't think it matters a lot.

Code after:

    override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor()

    internal fun hasNestedClass(name: Name): Boolean =
        name in memberScope.classNames

    private fun computeSubclassesForSealedClass(): Collection<ClassDescriptor> {
        if (modality != Modality.SEALED) return emptyList()

        val fqNames = classProto.sealedSubclassFqNameList
        if (fqNames.isNotEmpty()) {
            return fqNames.mapNotNull { index ->
                c.components.deserializeClass(c.nameResolver.getClassId(index))
            }
        }

        // This is needed because classes compiled with Kotlin 1.0 did not contain the sealed_subclass_fq_name field
        return CliSealedClassInheritorsProvider.computeSealedSubclasses(this, allowSealedInheritorsInDifferentFilesOfSamePackage = false)
    }

    override fun getSealedSubclasses() = sealedSubclasses()

    override fun getInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? = inlineClassRepresentation()

    private fun computeInlineClassRepresentation(): InlineClassRepresentation<SimpleType>? {
        if (!isInlineOrValueClass()) return null

        val propertyName = when {
            classProto.hasInlineClassUnderlyingPropertyName() ->
                c.nameResolver.getName(classProto.inlineClassUnderlyingPropertyName)
            !metadataVersion.isAtLeast(1, 5, 1) -> {
                // Before 1.5, inline classes did not have underlying property name & type in the metadata.
                // However, they were experimental, so supposedly this logic can be removed at some point in the future.
                val constructor = unsubstitutedPrimaryConstructor ?: error("Inline class has no primary constructor: $this")
                constructor.valueParameters.first().name
            }
            else -> error("Inline class has no underlying property name in metadata: $this")
        }

        val type = classProto.inlineClassUnderlyingType(c.typeTable)?.let(c.typeDeserializer::simpleType)
            ?: run {
                val underlyingProperty =
                    memberScope.getContributedVariables(propertyName, NoLookupLocation.FROM_DESERIALIZATION)
                        .singleOrNull { it.extensionReceiverParameter == null }
                        ?: error("Inline class has no underlying property: $this")
                underlyingProperty.type as SimpleType
            }

        return InlineClassRepresentation(propertyName, type)
    }