[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
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.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.types.Variance
typealias CirTypeSignature = String
@@ -94,6 +97,26 @@ abstract class CirClassType : CirClassOrTypeAliasType(), CirHasVisibility {
}
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 isMarkedNullable: Boolean
) : 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 clazz: CirProvided.Class = typeResolver.resolveClassifier(classId)
val type = CirTypeFactory.createClassType(
val type = CirClassType.createInterned(
classId = classId,
outerType = null, // annotation class can't be inner class
visibility = clazz.visibility,
@@ -59,7 +59,7 @@ object CirClassFactory {
isInner = false,
isExternal = false
).apply {
val enumClassType = CirTypeFactory.createClassType(
val enumClassType = CirClassType.createInterned(
classId = enumClassId,
outerType = null,
visibility = decodeVisibility(enumClass.flags),
@@ -141,7 +141,7 @@ object CirTypeAliasExpander {
makeNullableTypeIfNecessary(projection, argument)
}
return CirTypeFactory.createClassType(
return CirClassType.createInterned(
classId = type.classId,
outerType = type.outerType?.let { expandClassType(expansion, it) },
visibility = clazz.visibility,
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import gnu.trove.TIntObjectHashMap
import kotlinx.metadata.*
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.impl.CirClassTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirProvided
@@ -21,7 +19,7 @@ import org.jetbrains.kotlin.types.Variance
object CirTypeFactory {
object StandardTypes {
val ANY: CirClassType = createClassType(
val ANY: CirClassType = CirClassType.createInterned(
classId = ANY_CLASS_ID,
outerType = null,
visibility = Visibilities.Public,
@@ -30,7 +28,6 @@ object CirTypeFactory {
)
}
private val classTypeInterner = Interner<CirClassType>()
private val typeAliasTypeInterner = Interner<CirTypeAliasType>()
fun create(source: KmType, typeResolver: CirTypeResolver): CirType {
@@ -50,7 +47,7 @@ object CirTypeFactory {
val clazz: CirProvided.Class = typeResolver.resolveClassifier(classId)
createClassType(
CirClassType.createInterned(
classId = classId,
outerType = outerType,
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(
typeAliasId: CirEntityId,
underlyingType: CirClassOrTypeAliasType,
@@ -122,7 +101,7 @@ object CirTypeFactory {
return type
val result = when (type) {
is CirClassType -> createClassType(
is CirClassType -> CirClassType.createInterned(
classId = type.classifierId,
outerType = type.outerType,
visibility = type.visibility,
@@ -182,7 +161,7 @@ object CirTypeFactory {
if (!hasAbbreviationsInArguments && outerType == unabbreviatedOuterType)
type
else
createClassType(
CirClassType.createInterned(
classId = type.classifierId,
outerType = unabbreviatedOuterType,
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
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
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.utils.DEPRECATED_ANNOTATION_CLASS_ID
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))
}
private fun buildAnnotationType(classId: CirEntityId) = CirTypeFactory.createClassType(
private fun buildAnnotationType(classId: CirEntityId) = CirClassType.createInterned(
classId = classId,
outerType = null,
visibility = Visibilities.Public,
@@ -43,7 +43,7 @@ private class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers)
private val arguments = TypeArgumentListCommonizer(classifiers)
private var isMarkedNullable = false
override fun commonizationResult() = CirTypeFactory.createClassType(
override fun commonizationResult() = CirClassType.createInterned(
classId = classId,
outerType = outerType.result,
// 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
fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder {
override fun build(typeAliasId: CirEntityId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
CirTypeFactory.createClassType(
CirClassType.createInterned(
classId = typeAliasId,
outerType = null, // there can't be outer type
visibility = commonClass.visibility,
@@ -40,7 +40,7 @@ private fun CirClassType.withCommonizedArguments(classifiers: CirKnownClassifier
val newOuterType = existingOuterType?.let { it.withCommonizedArguments(classifiers) ?: return null }
return if (newArguments !== existingArguments || newOuterType !== existingOuterType)
CirTypeFactory.createClassType(
CirClassType.createInterned(
classId = classifierId,
outerType = newOuterType,
visibility = visibility,
@@ -38,7 +38,7 @@ internal fun mockTAType(
internal fun mockClassType(
classId: String,
nullable: Boolean = false
): CirClassType = CirTypeFactory.createClassType(
): CirClassType = CirClassType.createInterned(
classId = createValidClassifierId(classId),
outerType = null,
visibility = Visibilities.Public,