[Commonizer] Use 'index:Int' instead of Name for addressing type parameters

This commit is contained in:
Dmitriy Dolovov
2020-07-03 16:41:28 +07:00
parent 0ee7306d9c
commit d63728afe5
5 changed files with 38 additions and 24 deletions
@@ -27,7 +27,6 @@ internal fun List<CirTypeParameter>.buildDescriptorsAndTypeParameterResolver(
val ownTypeParameters = mutableListOf<TypeParameterDescriptor>() val ownTypeParameters = mutableListOf<TypeParameterDescriptor>()
val typeParameterResolver = TypeParameterResolverImpl( val typeParameterResolver = TypeParameterResolverImpl(
storageManager = targetComponents.storageManager,
ownTypeParameters = ownTypeParameters, ownTypeParameters = ownTypeParameters,
parent = parentTypeParameterResolver parent = parentTypeParameterResolver
) )
@@ -120,9 +119,8 @@ internal fun CirSimpleType.buildType(
} }
} }
is CirClassifierId.TypeParameter -> { is CirClassifierId.TypeParameter -> {
val name = classifierId.name typeParameterResolver.resolve(classifierId.index)
typeParameterResolver.resolve(name) ?: error("Type parameter $classifierId not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}")
?: error("Type parameter $name not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}")
} }
} }
@@ -184,27 +184,36 @@ fun CirRootNode.createGlobalBuilderComponents(
} }
interface TypeParameterResolver { interface TypeParameterResolver {
fun resolve(name: Name): TypeParameterDescriptor? val parametersCount: Int
fun resolve(index: Int): TypeParameterDescriptor?
companion object { companion object {
val EMPTY = object : TypeParameterResolver { val EMPTY = object : TypeParameterResolver {
override fun resolve(name: Name): TypeParameterDescriptor? = null override val parametersCount get() = 0
override fun resolve(index: Int): TypeParameterDescriptor? = null
} }
} }
} }
class TypeParameterResolverImpl( class TypeParameterResolverImpl(
storageManager: StorageManager, private val ownTypeParameters: List<TypeParameterDescriptor>,
ownTypeParameters: List<TypeParameterDescriptor>,
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
) : TypeParameterResolver { ) : TypeParameterResolver {
override val parametersCount: Int
get() = ownTypeParameters.size + parent.parametersCount
private val ownTypeParameters = storageManager.createLazyValue { @Suppress("ConvertTwoComparisonsToRangeCheck")
// memoize the first occurrence of descriptor with the same Name override fun resolve(index: Int): TypeParameterDescriptor? {
ownTypeParameters.groupingBy { it.name }.reduce { _, accumulator, _ -> accumulator } val parentParametersCount = parent.parametersCount
if (index >= 0 && index < parentParametersCount)
return parent.resolve(index)
val localIndex = index - parentParametersCount
if (localIndex < ownTypeParameters.size)
return ownTypeParameters[localIndex]
error("Illegal type parameter index: $index. Should be between 0 and ${parametersCount - 1}")
} }
override fun resolve(name: Name) = ownTypeParameters()[name] ?: parent.resolve(name)
} }
fun DeclarationDescriptor.getTypeParameterResolver(): TypeParameterResolver = fun DeclarationDescriptor.getTypeParameterResolver(): TypeParameterResolver =
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
sealed class CirClassifierId { sealed class CirClassifierId {
interface ClassOrTypeAlias { interface ClassOrTypeAlias {
@@ -15,5 +14,5 @@ sealed class CirClassifierId {
data class Class(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId() data class Class(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId()
data class TypeAlias(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId() data class TypeAlias(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId()
data class TypeParameter(val name: Name) : CirClassifierId() data class TypeParameter(val index: Int) : CirClassifierId()
} }
@@ -1,15 +1,10 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.factory package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
object CirClassifierIdFactory { object CirClassifierIdFactory {
@@ -19,12 +14,25 @@ object CirClassifierIdFactory {
return when (source) { return when (source) {
is ClassDescriptor -> createForClass(source.internedClassId) is ClassDescriptor -> createForClass(source.internedClassId)
is TypeAliasDescriptor -> createForTypeAlias(source.internedClassId) is TypeAliasDescriptor -> createForTypeAlias(source.internedClassId)
is TypeParameterDescriptor -> createForTypeParameter(source.name.intern()) is TypeParameterDescriptor -> createForTypeParameter(source.typeParameterIndex)
else -> error("Unexpected classifier descriptor type: ${source::class.java}, $this") else -> error("Unexpected classifier descriptor type: ${source::class.java}, $this")
} }
} }
fun createForClass(classId: ClassId): CirClassifierId = interner.intern(CirClassifierId.Class(classId)) fun createForClass(classId: ClassId): CirClassifierId = interner.intern(CirClassifierId.Class(classId))
fun createForTypeAlias(classId: ClassId): CirClassifierId = interner.intern(CirClassifierId.TypeAlias(classId)) fun createForTypeAlias(classId: ClassId): CirClassifierId = interner.intern(CirClassifierId.TypeAlias(classId))
fun createForTypeParameter(name: Name): CirClassifierId = interner.intern(CirClassifierId.TypeParameter(name)) fun createForTypeParameter(index: Int): CirClassifierId = interner.intern(CirClassifierId.TypeParameter(index))
} }
private inline val TypeParameterDescriptor.typeParameterIndex: Int
get() {
var index = index
var parent = containingDeclaration
while ((parent as? ClassifierDescriptorWithTypeParameters)?.isInner != false) {
parent = parent.containingDeclaration as? ClassifierDescriptorWithTypeParameters ?: break
index += parent.declaredTypeParameters.size
}
return index
}
@@ -52,7 +52,7 @@ private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: CirSimpleType, b:
} }
if (aId is CirClassifierId.TypeParameter) { if (aId is CirClassifierId.TypeParameter) {
if (bId !is CirClassifierId.TypeParameter || aId.name != bId.name) return false if (bId !is CirClassifierId.TypeParameter || aId.index != bId.index) return false
} }
} }