[Commonizer] Encapsulate interning inside of CIR entities: CirClassType

This commit is contained in:
Dmitriy Dolovov
2021-03-05 00:11:36 +03:00
parent c6d8cddcd9
commit 36294352ef
10 changed files with 72 additions and 89 deletions
@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir package org.jetbrains.kotlin.descriptors.commonizer.cir
import kotlinx.metadata.KmType import kotlinx.metadata.KmType
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
typealias CirTypeSignature = String typealias CirTypeSignature = String
@@ -94,6 +97,26 @@ abstract class CirClassType : CirClassOrTypeAliasType(), CirHasVisibility {
} }
super.appendDescriptionTo(builder, shortNameOnly = outerType != null) super.appendDescriptionTo(builder, shortNameOnly = outerType != null)
} }
companion object {
fun createInterned(
classId: CirEntityId,
outerType: CirClassType?,
visibility: Visibility,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirClassType = interner.intern(
CirClassTypeInternedImpl(
classifierId = classId,
outerType = outerType,
visibility = visibility,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
)
private val interner = Interner<CirClassTypeInternedImpl>()
}
} }
/** /**
@@ -130,3 +153,39 @@ private data class CirTypeParameterTypeInternedImpl(
override val index: Int, override val index: Int,
override val isMarkedNullable: Boolean override val isMarkedNullable: Boolean
) : CirTypeParameterType() ) : CirTypeParameterType()
private class CirClassTypeInternedImpl(
override val classifierId: CirEntityId,
override val outerType: CirClassType?,
override val visibility: Visibility, // visibility of the class descriptor
override val arguments: List<CirTypeProjection>,
override val isMarkedNullable: Boolean,
) : CirClassType() {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = hashCode(classifierId)
.appendHashCode(outerType)
.appendHashCode(visibility)
.appendHashCode(arguments)
.appendHashCode(isMarkedNullable)
override fun hashCode(): Int {
var currentHashCode = cachedHashCode
if (currentHashCode != 0) return currentHashCode
currentHashCode = computeHashCode()
cachedHashCode = currentHashCode
return currentHashCode
}
override fun equals(other: Any?): Boolean = when {
other === this -> true
other is CirClassType -> classifierId == other.classifierId
&& isMarkedNullable == other.isMarkedNullable
&& visibility == other.visibility
&& arguments == other.arguments
&& outerType == other.outerType
else -> false
}
}
@@ -27,7 +27,7 @@ object CirAnnotationFactory {
val classId = CirEntityId.create(source.className) val classId = CirEntityId.create(source.className)
val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId) val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId)
val type = CirTypeFactory.createClassType( val type = CirClassType.createInterned(
classId = classId, classId = classId,
outerType = null, // annotation class can't be inner class outerType = null, // annotation class can't be inner class
visibility = clazz.visibility, visibility = clazz.visibility,
@@ -59,7 +59,7 @@ object CirClassFactory {
isInner = false, isInner = false,
isExternal = false isExternal = false
).apply { ).apply {
val enumClassType = CirTypeFactory.createClassType( val enumClassType = CirClassType.createInterned(
classId = enumClassId, classId = enumClassId,
outerType = null, outerType = null,
visibility = decodeVisibility(enumClass.flags), visibility = decodeVisibility(enumClass.flags),
@@ -141,7 +141,7 @@ object CirTypeAliasExpander {
makeNullableTypeIfNecessary(projection, argument) makeNullableTypeIfNecessary(projection, argument)
} }
return CirTypeFactory.createClassType( return CirClassType.createInterned(
classId = type.classId, classId = type.classId,
outerType = type.outerType?.let { expandClassType(expansion, it) }, outerType = type.outerType?.let { expandClassType(expansion, it) },
visibility = clazz.visibility, visibility = clazz.visibility,
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import gnu.trove.TIntObjectHashMap import gnu.trove.TIntObjectHashMap
import kotlinx.metadata.* import kotlinx.metadata.*
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirProvided import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirProvided
@@ -21,7 +19,7 @@ import org.jetbrains.kotlin.types.Variance
object CirTypeFactory { object CirTypeFactory {
object StandardTypes { object StandardTypes {
val ANY: CirClassType = createClassType( val ANY: CirClassType = CirClassType.createInterned(
classId = ANY_CLASS_ID, classId = ANY_CLASS_ID,
outerType = null, outerType = null,
visibility = Visibilities.Public, visibility = Visibilities.Public,
@@ -30,7 +28,6 @@ object CirTypeFactory {
) )
} }
private val classTypeInterner = Interner<CirClassType>()
private val typeAliasTypeInterner = Interner<CirTypeAliasType>() private val typeAliasTypeInterner = Interner<CirTypeAliasType>()
fun create(source: KmType, typeResolver: CirTypeResolver): CirType { fun create(source: KmType, typeResolver: CirTypeResolver): CirType {
@@ -50,7 +47,7 @@ object CirTypeFactory {
val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId) val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId)
createClassType( CirClassType.createInterned(
classId = classId, classId = classId,
outerType = outerType, outerType = outerType,
visibility = clazz.visibility, visibility = clazz.visibility,
@@ -83,24 +80,6 @@ object CirTypeFactory {
} }
} }
fun createClassType(
classId: CirEntityId,
outerType: CirClassType?,
visibility: Visibility,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirClassType {
return classTypeInterner.intern(
CirClassTypeImpl(
classifierId = classId,
outerType = outerType,
visibility = visibility,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
)
}
fun createTypeAliasType( fun createTypeAliasType(
typeAliasId: CirEntityId, typeAliasId: CirEntityId,
underlyingType: CirClassOrTypeAliasType, underlyingType: CirClassOrTypeAliasType,
@@ -122,7 +101,7 @@ object CirTypeFactory {
return type return type
val result = when (type) { val result = when (type) {
is CirClassType -> createClassType( is CirClassType -> CirClassType.createInterned(
classId = type.classifierId, classId = type.classifierId,
outerType = type.outerType, outerType = type.outerType,
visibility = type.visibility, visibility = type.visibility,
@@ -182,7 +161,7 @@ object CirTypeFactory {
if (!hasAbbreviationsInArguments && outerType == unabbreviatedOuterType) if (!hasAbbreviationsInArguments && outerType == unabbreviatedOuterType)
type type
else else
createClassType( CirClassType.createInterned(
classId = type.classifierId, classId = type.classifierId,
outerType = unabbreviatedOuterType, outerType = unabbreviatedOuterType,
visibility = type.visibility, visibility = type.visibility,
@@ -1,51 +0,0 @@
/*
* Copyright 2010-2020 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.commonizer.cir.impl
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
data class CirClassTypeImpl(
override val classifierId: CirEntityId,
override val outerType: CirClassType?,
override val visibility: Visibility, // visibility of the class descriptor
override val arguments: List<CirTypeProjection>,
override val isMarkedNullable: Boolean,
) : CirClassType() {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = hashCode(classifierId)
.appendHashCode(outerType)
.appendHashCode(visibility)
.appendHashCode(arguments)
.appendHashCode(isMarkedNullable)
override fun hashCode(): Int {
var currentHashCode = cachedHashCode
if (currentHashCode != 0) return currentHashCode
currentHashCode = computeHashCode()
cachedHashCode = currentHashCode
return currentHashCode
}
override fun equals(other: Any?): Boolean = when {
other === this -> true
other is CirClassType -> {
classifierId == other.classifierId
&& isMarkedNullable == other.isMarkedNullable
&& visibility == other.visibility
&& arguments == other.arguments
&& outerType == other.outerType
}
else -> false
}
}
@@ -6,12 +6,8 @@
package org.jetbrains.kotlin.descriptors.commonizer.core package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.* import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE import org.jetbrains.kotlin.descriptors.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID import org.jetbrains.kotlin.descriptors.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
@@ -154,7 +150,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
it.name to EnumValue(DEPRECATION_LEVEL_CLASS_ID, CirName.create(it.name)) it.name to EnumValue(DEPRECATION_LEVEL_CLASS_ID, CirName.create(it.name))
} }
private fun buildAnnotationType(classId: CirEntityId) = CirTypeFactory.createClassType( private fun buildAnnotationType(classId: CirEntityId) = CirClassType.createInterned(
classId = classId, classId = classId,
outerType = null, outerType = null,
visibility = Visibilities.Public, visibility = Visibilities.Public,
@@ -43,7 +43,7 @@ private class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers)
private val arguments = TypeArgumentListCommonizer(classifiers) private val arguments = TypeArgumentListCommonizer(classifiers)
private var isMarkedNullable = false private var isMarkedNullable = false
override fun commonizationResult() = CirTypeFactory.createClassType( override fun commonizationResult() = CirClassType.createInterned(
classId = classId, classId = classId,
outerType = outerType.result, outerType = outerType.result,
// N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is // N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is
@@ -127,7 +127,7 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie
// type alias has been commonized to expect class, need to build type for expect class // type alias has been commonized to expect class, need to build type for expect class
fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder { fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder {
override fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) = override fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
CirTypeFactory.createClassType( CirClassType.createInterned(
classId = typeAliasId, classId = typeAliasId,
outerType = null, // there can't be outer type outerType = null, // there can't be outer type
visibility = commonClass.visibility, visibility = commonClass.visibility,
@@ -40,7 +40,7 @@ private fun CirClassType.withCommonizedArguments(classifiers: CirKnownClassifier
val newOuterType = existingOuterType?.let { it.withCommonizedArguments(classifiers) ?: return null } val newOuterType = existingOuterType?.let { it.withCommonizedArguments(classifiers) ?: return null }
return if (newArguments !== existingArguments || newOuterType !== existingOuterType) return if (newArguments !== existingArguments || newOuterType !== existingOuterType)
CirTypeFactory.createClassType( CirClassType.createInterned(
classId = classifierId, classId = classifierId,
outerType = newOuterType, outerType = newOuterType,
visibility = visibility, visibility = visibility,
@@ -38,7 +38,7 @@ internal fun mockTAType(
internal fun mockClassType( internal fun mockClassType(
classId: String, classId: String,
nullable: Boolean = false nullable: Boolean = false
): CirClassType = CirTypeFactory.createClassType( ): CirClassType = CirClassType.createInterned(
classId = createValidClassifierId(classId), classId = createValidClassifierId(classId),
outerType = null, outerType = null,
visibility = Visibilities.Public, visibility = Visibilities.Public,