org.jetbrains.kotlin.descriptors.ValueClassRepresentation.kt Maven / Gradle / Ivy
/*
* 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 org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.descriptors.ValueClassKind.Inline
import org.jetbrains.kotlin.descriptors.ValueClassKind.MultiField
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
sealed class ValueClassRepresentation {
abstract val underlyingPropertyNamesToTypes: List>
abstract fun containsPropertyWithName(name: Name): Boolean
abstract fun getPropertyTypeByName(name: Name): Type?
fun mapUnderlyingType(transform: (Type) -> Other): ValueClassRepresentation = when (this) {
is InlineClassRepresentation -> InlineClassRepresentation(underlyingPropertyName, transform(underlyingType))
is MultiFieldValueClassRepresentation ->
MultiFieldValueClassRepresentation(underlyingPropertyNamesToTypes.map { (name, type) -> name to transform(type) })
}
}
enum class ValueClassKind { Inline, MultiField }
fun TypeSystemCommonBackendContext.valueClassLoweringKind(
fields: List>,
): ValueClassKind = when {
fields.size > 1 -> MultiField
fields.isEmpty() -> error("Value classes cannot have 0 fields")
else -> {
val type = fields.single().second
with(this) {
when {
type.isNullableType() -> Inline
!type.typeConstructor().isMultiFieldValueClass() -> Inline
else -> MultiField
}
}
}
}
fun createValueClassRepresentation(context: TypeSystemCommonBackendContext, fields: List>) =
when (context.valueClassLoweringKind(fields)) {
Inline -> InlineClassRepresentation(fields[0].first, fields[0].second)
MultiField -> MultiFieldValueClassRepresentation(fields)
}