[IR] Unite inline class and multi-field value class representation
#KT-1179
This commit is contained in:
committed by
teamcity
parent
282ab398c6
commit
28bf83ceac
+10
-5
@@ -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) }
|
||||
}
|
||||
+4
-10
@@ -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?
|
||||
|
||||
Reference in New Issue
Block a user