[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 typeParameterResolver = TypeParameterResolverImpl(
storageManager = targetComponents.storageManager,
ownTypeParameters = ownTypeParameters,
parent = parentTypeParameterResolver
)
@@ -120,9 +119,8 @@ internal fun CirSimpleType.buildType(
}
}
is CirClassifierId.TypeParameter -> {
val name = classifierId.name
typeParameterResolver.resolve(name)
?: error("Type parameter $name not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}")
typeParameterResolver.resolve(classifierId.index)
?: error("Type parameter $classifierId not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}")
}
}
@@ -184,27 +184,36 @@ fun CirRootNode.createGlobalBuilderComponents(
}
interface TypeParameterResolver {
fun resolve(name: Name): TypeParameterDescriptor?
val parametersCount: Int
fun resolve(index: Int): TypeParameterDescriptor?
companion object {
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(
storageManager: StorageManager,
ownTypeParameters: List<TypeParameterDescriptor>,
private val ownTypeParameters: List<TypeParameterDescriptor>,
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
) : TypeParameterResolver {
override val parametersCount: Int
get() = ownTypeParameters.size + parent.parametersCount
private val ownTypeParameters = storageManager.createLazyValue {
// memoize the first occurrence of descriptor with the same Name
ownTypeParameters.groupingBy { it.name }.reduce { _, accumulator, _ -> accumulator }
@Suppress("ConvertTwoComparisonsToRangeCheck")
override fun resolve(index: Int): TypeParameterDescriptor? {
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 =
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
sealed class CirClassifierId {
interface ClassOrTypeAlias {
@@ -15,5 +14,5 @@ sealed class CirClassifierId {
data class Class(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
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId
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.name.ClassId
import org.jetbrains.kotlin.name.Name
@Suppress("MemberVisibilityCanBePrivate")
object CirClassifierIdFactory {
@@ -19,12 +14,25 @@ object CirClassifierIdFactory {
return when (source) {
is ClassDescriptor -> createForClass(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")
}
}
fun createForClass(classId: ClassId): CirClassifierId = interner.intern(CirClassifierId.Class(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 (bId !is CirClassifierId.TypeParameter || aId.name != bId.name) return false
if (bId !is CirClassifierId.TypeParameter || aId.index != bId.index) return false
}
}