[FIR] Introduce valueClassRepresentation to FIR
#KT-1179
This commit is contained in:
committed by
teamcity
parent
28bf83ceac
commit
b6f2513dd2
+6
-10
@@ -6,19 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSignatures
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.declarations.comparators.FirMemberDeclarationComparator
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.addDeclarations
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.moduleName
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.sourceElement
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
@@ -26,8 +20,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeAttributes
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
@@ -208,6 +201,9 @@ fun deserializeClassToSymbol(
|
||||
}
|
||||
it.setSealedClassInheritors(inheritors)
|
||||
}
|
||||
|
||||
it.valueClassRepresentation = computeValueClassRepresentation(it, session)
|
||||
|
||||
(it.annotations as MutableList<FirAnnotation>) +=
|
||||
context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver)
|
||||
|
||||
|
||||
+5
-5
@@ -172,18 +172,18 @@ class FirElementSerializer private constructor(
|
||||
builder.companionObjectName = getSimpleNameIndex(companionObject.name)
|
||||
}
|
||||
|
||||
val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter(session)
|
||||
val representation = (klass as? FirRegularClass)?.inlineClassRepresentation
|
||||
if (representation != null) {
|
||||
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.name)
|
||||
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.underlyingPropertyName)
|
||||
|
||||
val property = callableMembers.single {
|
||||
it is FirProperty && it.receiverTypeRef == null && it.name == representation.name
|
||||
it is FirProperty && it.receiverTypeRef == null && it.name == representation.underlyingPropertyName
|
||||
}
|
||||
if (!property.visibility.isPublicAPI) {
|
||||
if (useTypeTable()) {
|
||||
builder.inlineClassUnderlyingTypeId = typeId(representation.returnTypeRef)
|
||||
builder.inlineClassUnderlyingTypeId = typeId(representation.underlyingType)
|
||||
} else {
|
||||
builder.setInlineClassUnderlyingType(typeProto(representation.returnTypeRef))
|
||||
builder.setInlineClassUnderlyingType(typeProto(representation.underlyingType))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,14 +643,13 @@ fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction(
|
||||
): Pair<IrVariable, IrValueSymbol> =
|
||||
createTemporaryVariable(receiverExpression, conversionScope, "safe_receiver")
|
||||
|
||||
// TODO: implement valueClassRepresentation in FirRegularClass instead. zhelenskiy
|
||||
fun Fir2IrComponents.computeValueClassRepresentation(klass: FirRegularClass): ValueClassRepresentation<IrSimpleType>? {
|
||||
val parameters = klass.getValueClassUnderlyingParameters(session) ?: return null
|
||||
return createValueClassRepresentation(IrTypeSystemContextImpl(irBuiltIns), parameters.map {
|
||||
val type = it.returnTypeRef.toIrType(typeConverter).safeAs<IrSimpleType>()
|
||||
?: error("Value class underlying type is not a simple type: ${klass.render()}")
|
||||
it.name to type
|
||||
})
|
||||
require((klass.valueClassRepresentation != null) == klass.isInline)
|
||||
return klass.valueClassRepresentation?.mapUnderlyingType {
|
||||
with(typeConverter) {
|
||||
it.toIrType() as? IrSimpleType?: error("Value class underlying type is not a simple type: ${klass.render()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirRegularClass.getIrSymbolsForSealedSubclasses(components: Fir2IrComponents): List<IrClassSymbol> {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.InlineClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.ValueClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.createValueClassRepresentation
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
internal fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
|
||||
val unsubstitutedType = unsubstitutedUnderlyingTypeForInlineClass(session) ?: return null
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(
|
||||
mapOf(this.typeConstructor(context) to this), context, approximateIntegerLiterals = true
|
||||
)
|
||||
return substitutor.substituteOrNull(unsubstitutedType)
|
||||
}
|
||||
|
||||
internal fun ConeKotlinType.unsubstitutedUnderlyingTypeForInlineClass(session: FirSession): ConeKotlinType? {
|
||||
val symbol = (this.fullyExpandedType(session) as? ConeLookupTagBasedType)
|
||||
?.lookupTag
|
||||
?.toSymbol(session) as? FirRegularClassSymbol
|
||||
?: return null
|
||||
symbol.ensureResolved(FirResolvePhase.STATUS)
|
||||
return symbol.fir.inlineClassRepresentation?.underlyingType
|
||||
}
|
||||
|
||||
fun computeValueClassRepresentation(klass: FirRegularClass, session: FirSession): ValueClassRepresentation<ConeSimpleKotlinType>? {
|
||||
val parameters = klass.getValueClassUnderlyingParameters(session)?.takeIf { it.isNotEmpty() } ?: return null
|
||||
val fields = parameters.map { it.name to it.returnTypeRef.coneType as ConeSimpleKotlinType }
|
||||
fields.singleOrNull()?.let { (name, type) ->
|
||||
if (isRecursiveSingleFieldValueClass(type, session, mutableSetOf(type))) { // escape stack overflow
|
||||
return InlineClassRepresentation(name, type)
|
||||
}
|
||||
}
|
||||
return createValueClassRepresentation(session.typeContext, fields)
|
||||
}
|
||||
|
||||
private fun FirRegularClass.getValueClassUnderlyingParameters(session: FirSession): List<FirValueParameter>? =
|
||||
if (isInline) primaryConstructorIfAny(session)?.fir?.valueParameters else null
|
||||
|
||||
private fun isRecursiveSingleFieldValueClass(
|
||||
type: ConeSimpleKotlinType,
|
||||
session: FirSession,
|
||||
visited: MutableSet<ConeSimpleKotlinType>
|
||||
): Boolean {
|
||||
val nextType = type.valueClassRepresentationTypeMarkersList(session)?.singleOrNull()?.second ?: return false
|
||||
return !visited.add(nextType) || isRecursiveSingleFieldValueClass(nextType, session, visited)
|
||||
}
|
||||
|
||||
private fun ConeSimpleKotlinType.valueClassRepresentationTypeMarkersList(session: FirSession): List<Pair<Name, ConeSimpleKotlinType>>? {
|
||||
val symbol = this.toSymbol(session) as? FirRegularClassSymbol ?: return null
|
||||
if (!symbol.fir.isInline) return null
|
||||
symbol.fir.valueClassRepresentation?.let { return it.underlyingPropertyNamesToTypes }
|
||||
symbol.ensureResolved(FirResolvePhase.TYPES)
|
||||
val constructorSymbol = symbol.fir.primaryConstructorIfAny(session) ?: return null
|
||||
return constructorSymbol.valueParameterSymbols
|
||||
.onEach { it.ensureResolved(FirResolvePhase.TYPES) }
|
||||
.map { it.name to it.resolvedReturnType as ConeSimpleKotlinType }
|
||||
}
|
||||
+3
@@ -112,6 +112,9 @@ open class FirStatusResolveTransformer(
|
||||
*/
|
||||
if (computationStatus != StatusComputationSession.StatusComputationStatus.Computed) {
|
||||
regularClass.transformStatus(this, statusResolver.resolveStatus(regularClass, containingClass, isLocal = false))
|
||||
if (regularClass.status.isInline) {
|
||||
regularClass.valueClassRepresentation = computeValueClassRepresentation(regularClass, session)
|
||||
}
|
||||
}
|
||||
return transformClass(regularClass, data).also {
|
||||
statusComputationSession.endComputing(regularClass)
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.InlineClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.MultiFieldValueClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.ValueClassRepresentation
|
||||
import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType
|
||||
|
||||
private object FirValueClassRepresentationKey : FirDeclarationDataKey()
|
||||
|
||||
var FirRegularClass.valueClassRepresentation: ValueClassRepresentation<ConeSimpleKotlinType>?
|
||||
by FirDeclarationDataRegistry.data(FirValueClassRepresentationKey)
|
||||
|
||||
val FirRegularClass.inlineClassRepresentation: InlineClassRepresentation<ConeSimpleKotlinType>?
|
||||
get() = valueClassRepresentation as? InlineClassRepresentation<ConeSimpleKotlinType>
|
||||
|
||||
val FirRegularClass.multiFieldValueClassRepresentation: MultiFieldValueClassRepresentation<ConeSimpleKotlinType>?
|
||||
get() = valueClassRepresentation as? MultiFieldValueClassRepresentation<ConeSimpleKotlinType>
|
||||
|
||||
|
||||
@@ -40,12 +40,6 @@ abstract class IrClass :
|
||||
|
||||
abstract var valueClassRepresentation: ValueClassRepresentation<IrSimpleType>?
|
||||
|
||||
val inlineClassRepresentation: InlineClassRepresentation<IrSimpleType>?
|
||||
get() = valueClassRepresentation as? InlineClassRepresentation<IrSimpleType>
|
||||
|
||||
val multiFieldValueClassRepresentation: MultiFieldValueClassRepresentation<IrSimpleType>?
|
||||
get() = valueClassRepresentation as? MultiFieldValueClassRepresentation<IrSimpleType>
|
||||
|
||||
abstract var sealedSubclasses: List<IrClassSymbol>
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.MultiFieldValueClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import java.io.File
|
||||
|
||||
fun <D : IrAttributeContainer> D.copyAttributes(other: IrAttributeContainer?): D = apply {
|
||||
@@ -55,3 +56,10 @@ val IrFunction.isStaticMethodOfClass: Boolean
|
||||
|
||||
val IrFunction.isPropertyAccessor: Boolean
|
||||
get() = this is IrSimpleFunction && correspondingPropertySymbol != null
|
||||
|
||||
|
||||
val IrClass.multiFieldValueClassRepresentation: MultiFieldValueClassRepresentation<IrSimpleType>?
|
||||
get() = valueClassRepresentation as? MultiFieldValueClassRepresentation<IrSimpleType>
|
||||
|
||||
val IrClass.inlineClassRepresentation: InlineClassRepresentation<IrSimpleType>?
|
||||
get() = valueClassRepresentation as? InlineClassRepresentation<IrSimpleType>
|
||||
|
||||
@@ -465,7 +465,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
override fun TypeConstructorMarker.isMultiFieldValueClass(): Boolean =
|
||||
(this as? IrClassSymbol)?.owner?.isMultiFieldValueClass == true
|
||||
|
||||
override fun TypeConstructorMarker.valueClassRepresentationTypeMarkersList(): List<Pair<Name, SimpleTypeMarker>>? =
|
||||
override fun TypeConstructorMarker.getValueClassProperties(): List<Pair<Name, SimpleTypeMarker>>? =
|
||||
(this as? IrClassSymbol)?.owner?.valueClassRepresentation?.underlyingPropertyNamesToTypes
|
||||
|
||||
override fun TypeConstructorMarker.isInnerClass(): Boolean =
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.util
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.inlineClassRepresentation
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
|
||||
fun getInlineClassUnderlyingType(irClass: IrClass): IrSimpleType {
|
||||
|
||||
+1
-1
@@ -18,5 +18,5 @@ class InlineClassRepresentation<Type : SimpleTypeMarker> constructor(
|
||||
|
||||
override fun containsPropertyWithName(name: Name): Boolean = underlyingPropertyName == name
|
||||
|
||||
override fun propertyTypeByName(name: Name): Type? = underlyingType.takeIf { containsPropertyWithName(name) }
|
||||
override fun getPropertyTypeByName(name: Name): Type? = underlyingType.takeIf { containsPropertyWithName(name) }
|
||||
}
|
||||
+1
-1
@@ -17,5 +17,5 @@ class MultiFieldValueClassRepresentation<Type : SimpleTypeMarker>(
|
||||
}
|
||||
|
||||
override fun containsPropertyWithName(name: Name): Boolean = name in map
|
||||
override fun propertyTypeByName(name: Name): Type? = map[name]
|
||||
override fun getPropertyTypeByName(name: Name): Type? = map[name]
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||
|
||||
fun TypeConstructorMarker.isInlineClass(): Boolean
|
||||
fun TypeConstructorMarker.isMultiFieldValueClass(): Boolean
|
||||
fun TypeConstructorMarker.valueClassRepresentationTypeMarkersList(): List<Pair<Name, SimpleTypeMarker>>?
|
||||
fun TypeConstructorMarker.getValueClassProperties(): List<Pair<Name, SimpleTypeMarker>>?
|
||||
fun TypeConstructorMarker.isInnerClass(): Boolean
|
||||
fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker
|
||||
fun KotlinTypeMarker.getUnsubstitutedUnderlyingType(): KotlinTypeMarker?
|
||||
|
||||
@@ -749,7 +749,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return (declarationDescriptor as? ClassDescriptor)?.valueClassRepresentation is MultiFieldValueClassRepresentation
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.valueClassRepresentationTypeMarkersList(): List<Pair<Name, SimpleTypeMarker>>? {
|
||||
override fun TypeConstructorMarker.getValueClassProperties(): List<Pair<Name, SimpleTypeMarker>>? {
|
||||
require(this is TypeConstructor, this::errorMessage)
|
||||
return (declarationDescriptor as? ClassDescriptor)?.valueClassRepresentation?.underlyingPropertyNamesToTypes
|
||||
}
|
||||
|
||||
+1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.inlineClassRepresentation
|
||||
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.psiElement
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.declarations.inlineClassRepresentation
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeNames.RAW_VALUE_ANNOTATION_FQ_NAMES
|
||||
|
||||
Reference in New Issue
Block a user