[IR] Unite inline class and multi-field value class representation

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-03-10 00:02:35 +03:00
committed by teamcity
parent 282ab398c6
commit 28bf83ceac
69 changed files with 2464 additions and 3598 deletions
@@ -8,10 +8,15 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
class InlineClassRepresentation<Type : SimpleTypeMarker>(
class InlineClassRepresentation<Type : SimpleTypeMarker> constructor(
val underlyingPropertyName: Name,
val underlyingType: Type,
) {
inline fun <Other : SimpleTypeMarker> mapUnderlyingType(transform: (Type) -> Other): InlineClassRepresentation<Other> =
InlineClassRepresentation(underlyingPropertyName, transform(underlyingType))
}
) : ValueClassRepresentation<Type>() {
override val underlyingPropertyNamesToTypes: List<Pair<Name, Type>>
get() = listOf(underlyingPropertyName to underlyingType)
override fun containsPropertyWithName(name: Name): Boolean = underlyingPropertyName == name
override fun propertyTypeByName(name: Name): Type? = underlyingType.takeIf { containsPropertyWithName(name) }
}
@@ -9,19 +9,13 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
class MultiFieldValueClassRepresentation<Type : SimpleTypeMarker>(
val underlyingPropertyNamesToTypes: List<Pair<Name, Type>>
) {
init {
require(underlyingPropertyNamesToTypes.size > 1) { "MultiFieldValueClassRepresentation has at least 2 properties" }
}
override val underlyingPropertyNamesToTypes: List<Pair<Name, Type>>
) : ValueClassRepresentation<Type>() {
private val map = underlyingPropertyNamesToTypes.toMap().also {
require(it.size == underlyingPropertyNamesToTypes.size) { "Some properties have the same names" }
}
fun containsPropertyWithName(name: Name): Boolean = name in map
fun propertyTypeByName(name: Name): Type? = map[name]
inline fun <Other : SimpleTypeMarker> mapUnderlyingType(transform: (Type) -> Other): MultiFieldValueClassRepresentation<Other> =
MultiFieldValueClassRepresentation(underlyingPropertyNamesToTypes.map { (key, value) -> key to transform(value) })
override fun containsPropertyWithName(name: Name): Boolean = name in map
override fun propertyTypeByName(name: Name): Type? = map[name]
}
@@ -0,0 +1,49 @@
/*
* 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<Type : SimpleTypeMarker> {
abstract val underlyingPropertyNamesToTypes: List<Pair<Name, Type>>
abstract fun containsPropertyWithName(name: Name): Boolean
abstract fun getPropertyTypeByName(name: Name): Type?
fun <Other : SimpleTypeMarker> mapUnderlyingType(transform: (Type) -> Other): ValueClassRepresentation<Other> = 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 <Type : SimpleTypeMarker> TypeSystemCommonBackendContext.valueClassLoweringKind(
fields: List<Pair<Name, Type>>,
): 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 <Type : SimpleTypeMarker> createValueClassRepresentation(context: TypeSystemCommonBackendContext, fields: List<Pair<Name, Type>>) =
when (context.valueClassLoweringKind(fields)) {
Inline -> InlineClassRepresentation(fields[0].first, fields[0].second)
MultiField -> MultiFieldValueClassRepresentation(fields)
}
@@ -31,6 +31,8 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any?
fun TypeConstructorMarker.isInlineClass(): Boolean
fun TypeConstructorMarker.isMultiFieldValueClass(): Boolean
fun TypeConstructorMarker.valueClassRepresentationTypeMarkersList(): List<Pair<Name, SimpleTypeMarker>>?
fun TypeConstructorMarker.isInnerClass(): Boolean
fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker
fun KotlinTypeMarker.getUnsubstitutedUnderlyingType(): KotlinTypeMarker?