[Commonizer] Encapsulate interning inside of CIR entities: CirAnnotation

This commit is contained in:
Dmitriy Dolovov
2021-03-04 13:33:58 +03:00
parent f7d977d7c4
commit 3012839f49
5 changed files with 56 additions and 69 deletions
@@ -5,8 +5,59 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
interface CirAnnotation {
val type: CirClassType
val constantValueArguments: Map<CirName, CirConstantValue<*>>
val annotationValueArguments: Map<CirName, CirAnnotation>
companion object {
fun createInterned(
type: CirClassType,
constantValueArguments: Map<CirName, CirConstantValue<*>>,
annotationValueArguments: Map<CirName, CirAnnotation>
): CirAnnotation = interner.intern(
CirAnnotationInternedImpl(
type = type,
constantValueArguments = constantValueArguments,
annotationValueArguments = annotationValueArguments
)
)
private val interner = Interner<CirAnnotationInternedImpl>()
}
}
private data class CirAnnotationInternedImpl(
override val type: CirClassType,
override val constantValueArguments: Map<CirName, CirConstantValue<*>>,
override val annotationValueArguments: Map<CirName, CirAnnotation>
) : CirAnnotation {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = hashCode(type)
.appendHashCode(constantValueArguments)
.appendHashCode(annotationValueArguments)
override fun hashCode(): Int {
var currentHashCode = cachedHashCode
if (currentHashCode != 0) return currentHashCode
currentHashCode = computeHashCode()
cachedHashCode = currentHashCode
return currentHashCode
}
override fun equals(other: Any?): Boolean {
if (other === this) return true
return other is CirAnnotation
&& type == other.type
&& constantValueArguments == other.constantValueArguments
&& annotationValueArguments == other.annotationValueArguments
}
}
@@ -11,15 +11,11 @@ import kotlinx.metadata.Flags
import kotlinx.metadata.KmAnnotation
import kotlinx.metadata.KmAnnotationArgument
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirAnnotationImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirProvided
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.compact
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
object CirAnnotationFactory {
private val interner = Interner<CirAnnotation>()
fun createAnnotations(flags: Flags, typeResolver: CirTypeResolver, annotations: () -> List<KmAnnotation>): List<CirAnnotation> {
return if (!Flag.Common.HAS_ANNOTATIONS(flags))
emptyList()
@@ -49,7 +45,7 @@ object CirAnnotationFactory {
val allValueArguments: Map<String, KmAnnotationArgument<*>> = source.arguments
if (allValueArguments.isEmpty())
return create(type = type, constantValueArguments = emptyMap(), annotationValueArguments = emptyMap())
return CirAnnotation.createInterned(type = type, constantValueArguments = emptyMap(), annotationValueArguments = emptyMap())
val constantValueArguments: MutableMap<CirName, CirConstantValue<*>> = THashMap(allValueArguments.size)
val annotationValueArguments: MutableMap<CirName, CirAnnotation> = THashMap(allValueArguments.size)
@@ -66,24 +62,10 @@ object CirAnnotationFactory {
)
}
return create(
return CirAnnotation.createInterned(
type = type,
constantValueArguments = constantValueArguments.compact(),
annotationValueArguments = annotationValueArguments.compact()
)
}
fun create(
type: CirClassType,
constantValueArguments: Map<CirName, CirConstantValue<*>>,
annotationValueArguments: Map<CirName, CirAnnotation>
): CirAnnotation {
return interner.intern(
CirAnnotationImpl(
type = type,
constantValueArguments = constantValueArguments,
annotationValueArguments = annotationValueArguments
)
)
}
}
@@ -1,44 +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.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
data class CirAnnotationImpl(
override val type: CirClassType,
override val constantValueArguments: Map<CirName, CirConstantValue<*>>,
override val annotationValueArguments: Map<CirName, CirAnnotation>
) : CirAnnotation {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = hashCode(type)
.appendHashCode(constantValueArguments)
.appendHashCode(annotationValueArguments)
override fun hashCode(): Int {
var currentHashCode = cachedHashCode
if (currentHashCode != 0) return currentHashCode
currentHashCode = computeHashCode()
cachedHashCode = currentHashCode
return currentHashCode
}
override fun equals(other: Any?): Boolean {
if (other === this) return true
return other is CirAnnotation
&& type == other.type
&& constantValueArguments == other.constantValueArguments
&& annotationValueArguments == other.annotationValueArguments
}
}
@@ -11,7 +11,6 @@ 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.CirAnnotationFactory
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
@@ -74,7 +73,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
} else
compactMapOf(PROPERTY_NAME_REPLACE_WITH, replaceWithExpression.toReplaceWithValue(replaceWithImports))
return CirAnnotationFactory.create(
return CirAnnotation.createInterned(
type = DEPRECATED_ANNOTATION_TYPE,
constantValueArguments = constantValueArguments,
annotationValueArguments = annotationValueArguments
@@ -216,7 +215,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
}
private inline fun createReplaceWithAnnotation(expression: String, imports: List<String>): CirAnnotation =
CirAnnotationFactory.create(
CirAnnotation.createInterned(
type = REPLACE_WITH_ANNOTATION_TYPE,
constantValueArguments = compactMapOf(
PROPERTY_NAME_EXPRESSION, StringValue(expression),
@@ -10,7 +10,6 @@ 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.CirAnnotationFactory
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
import org.junit.Test
import kotlin.DeprecationLevel.*
@@ -284,7 +283,7 @@ private fun mockAnnotation(
classId: String,
constantValueArguments: Map<CirName, CirConstantValue<*>> = emptyMap(),
annotationValueArguments: Map<CirName, CirAnnotation> = emptyMap()
): CirAnnotation = CirAnnotationFactory.create(
): CirAnnotation = CirAnnotation.createInterned(
type = mockClassType(classId),
constantValueArguments = constantValueArguments,
annotationValueArguments = annotationValueArguments