[Commonizer] Include dependencies in CirCommonClassifierId

^KT-48288
This commit is contained in:
sebastian.sellmair
2021-09-10 10:25:53 +02:00
committed by Space
parent ef6f84b151
commit c1f118e502
18 changed files with 221 additions and 107 deletions
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2021 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.commonizer.cir
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvided
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
import org.jetbrains.kotlin.descriptors.Visibilities
internal fun CirProvidedClassifiers.toCirClassOrTypeAliasTypeOrNull(type: CirProvided.ClassOrTypeAliasType): CirClassOrTypeAliasType? {
return when (type) {
is CirProvided.ClassType -> type.toCirClassTypeOrNull()
is CirProvided.TypeAliasType -> toCirTypeAliasTypeOrNull(type)
}
}
internal fun CirProvidedClassifiers.toCirTypeAliasTypeOrNull(type: CirProvided.TypeAliasType): CirTypeAliasType? {
val typeAlias = this.classifier(type.classifierId) as? CirProvided.TypeAlias ?: return null
return CirTypeAliasType.createInterned(
typeAliasId = type.classifierId,
isMarkedNullable = type.isMarkedNullable,
arguments = type.arguments.map { it.toCirTypeProjection() ?: return null },
underlyingType = toCirClassOrTypeAliasTypeOrNull(typeAlias.underlyingType) ?: return null
)
}
internal fun CirProvided.ClassType.toCirClassTypeOrNull(): CirClassType? {
return CirClassType.createInterned(
classId = this.classifierId,
outerType = this.outerType?.let { it.toCirClassTypeOrNull() ?: return null },
isMarkedNullable = this.isMarkedNullable,
arguments = this.arguments.map { it.toCirTypeProjection() ?: return null },
visibility = Visibilities.Public,
)
}
internal fun CirProvided.TypeProjection.toCirTypeProjection(): CirTypeProjection? {
return when (this) {
is CirProvided.StarTypeProjection -> CirStarTypeProjection
is CirProvided.RegularTypeProjection -> CirRegularTypeProjection(
projectionKind = variance,
type = (type as? CirProvided.ClassType)?.toCirClassTypeOrNull() ?: return null
)
}
}
@@ -94,15 +94,16 @@ class CirEntityId private constructor(val packageName: CirPackageName, val relat
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (other !is CirEntityId) return false if (other !is CirEntityId) return false
if (other._hashCode != this._hashCode) return false
if (other.packageName != this.packageName) return false if (other.packageName != this.packageName) return false
if (!other.relativeNameSegments.contentEquals(relativeNameSegments)) return false if (!other.relativeNameSegments.contentEquals(relativeNameSegments)) return false
return true return true
} }
private var _hashCode: Int = 0 private var _hashCode: Int = hashCode(packageName)
.appendHashCode(relativeNameSegments).also { hashCode -> _hashCode = hashCode }
override fun hashCode(): Int = if (_hashCode != 0) _hashCode else override fun hashCode(): Int = _hashCode
hashCode(packageName).appendHashCode(relativeNameSegments).also { hashCode -> _hashCode = hashCode }
override fun toString(): String = buildString { override fun toString(): String = buildString {
packageName.segments.joinTo(this, "/") packageName.segments.joinTo(this, "/")
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvided import org.jetbrains.kotlin.commonizer.mergedtree.CirProvided
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
import org.jetbrains.kotlin.commonizer.mergedtree.findClass import org.jetbrains.kotlin.commonizer.mergedtree.findClass
import org.jetbrains.kotlin.descriptors.Visibilities
internal interface CirSupertypesResolver { internal interface CirSupertypesResolver {
/** /**
@@ -63,42 +62,3 @@ internal class SimpleCirSupertypesResolver(
return null return null
} }
} }
internal fun CirProvidedClassifiers.toCirClassOrTypeAliasTypeOrNull(type: CirProvided.Type): CirClassOrTypeAliasType? {
return when (type) {
is CirProvided.ClassType -> type.toCirClassTypeOrNull()
is CirProvided.TypeParameterType -> null
is CirProvided.TypeAliasType -> TODO()
}
}
internal fun CirProvidedClassifiers.toCirTypeAliasTypeOrNull(type: CirProvided.TypeAliasType): CirTypeAliasType? {
val typeAlias = this.classifier(type.typeAliasId) as? CirProvided.TypeAlias ?: return null
return CirTypeAliasType.createInterned(
typeAliasId = type.typeAliasId,
isMarkedNullable = type.isMarkedNullable,
arguments = type.arguments.map { it.toCirTypeProjection() ?: return null },
underlyingType = toCirClassOrTypeAliasTypeOrNull(typeAlias.underlyingType) ?: return null
)
}
// TODO NOW move
internal fun CirProvided.ClassType.toCirClassTypeOrNull(): CirClassType? {
return CirClassType.createInterned(
classId = this.classId,
outerType = this.outerType?.let { it.toCirClassTypeOrNull() ?: return null },
isMarkedNullable = this.isMarkedNullable,
arguments = this.arguments.map { it.toCirTypeProjection() ?: return null },
visibility = Visibilities.Public,
)
}
internal fun CirProvided.TypeProjection.toCirTypeProjection(): CirTypeProjection? {
return when (this) {
is CirProvided.StarTypeProjection -> CirStarTypeProjection
is CirProvided.RegularTypeProjection -> CirRegularTypeProjection(
projectionKind = variance,
type = (type as? CirProvided.ClassType)?.toCirClassTypeOrNull() ?: return null
)
}
}
@@ -265,28 +265,22 @@ private class CirTypeAliasTypeInternedImpl(
override val isMarkedNullable: Boolean override val isMarkedNullable: Boolean
) : CirTypeAliasType() { ) : CirTypeAliasType() {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode // See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0 private val hashCode = hashCode(classifierId)
private fun computeHashCode() = hashCode(classifierId)
.appendHashCode(underlyingType) .appendHashCode(underlyingType)
.appendHashCode(arguments) .appendHashCode(arguments)
.appendHashCode(isMarkedNullable) .appendHashCode(isMarkedNullable)
override fun hashCode(): Int {
var currentHashCode = cachedHashCode
if (currentHashCode != 0) return currentHashCode
currentHashCode = computeHashCode() override fun hashCode(): Int = hashCode
cachedHashCode = currentHashCode
return currentHashCode
}
override fun equals(other: Any?): Boolean = when { override fun equals(other: Any?): Boolean = when {
other === this -> true other === this -> true
other is CirTypeAliasType -> classifierId == other.classifierId other is CirTypeAliasType ->
&& underlyingType == other.underlyingType hashCode == other.hashCode() &&
&& isMarkedNullable == other.isMarkedNullable classifierId == other.classifierId
&& arguments == other.arguments && underlyingType == other.underlyingType
&& isMarkedNullable == other.isMarkedNullable
&& arguments == other.arguments
else -> false else -> false
} }
} }
@@ -68,7 +68,6 @@ internal class ClassOrTypeAliasTypeCommonizer(
val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke() val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke()
?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke() ?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke()
when (commonizedClassifier) { when (commonizedClassifier) {
is CirClass -> return CirClassType.createInterned( is CirClass -> return CirClassType.createInterned(
classId = classifierId, classId = classifierId,
@@ -7,8 +7,20 @@ package org.jetbrains.kotlin.commonizer.mergedtree
import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirEntityId
@JvmInline class CirCommonClassifierId(val aliases: List<CirEntityId>) {
value class CirCommonClassifierId(val aliases: LinkedHashSet<CirEntityId>) {
private val _hashCode = aliases.hashCode()
override fun hashCode(): Int = _hashCode
override fun equals(other: Any?): Boolean {
if (other === this) return true
if (other !is CirCommonClassifierId) return false
if (other._hashCode != this._hashCode) return false
if (other.aliases != this.aliases) return false
return true
}
override fun toString(): String { override fun toString(): String {
return aliases.joinToString(prefix = "(", postfix = ")") return aliases.joinToString(prefix = "(", postfix = ")")
} }
@@ -7,6 +7,8 @@
package org.jetbrains.kotlin.commonizer.mergedtree package org.jetbrains.kotlin.commonizer.mergedtree
import gnu.trove.THashMap
import gnu.trove.THashSet
import org.jetbrains.kotlin.commonizer.TargetDependent import org.jetbrains.kotlin.commonizer.TargetDependent
import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.commonizer.cir.CirTypeAlias import org.jetbrains.kotlin.commonizer.cir.CirTypeAlias
@@ -27,8 +29,8 @@ private class CirCommonClassifierIdResolverImpl(
private val dependencies: CirProvidedClassifiers private val dependencies: CirProvidedClassifiers
) : CirCommonClassifierIdResolver { ) : CirCommonClassifierIdResolver {
private val cachedResults = HashMap<CirEntityId, CirCommonClassifierId>() private val cachedResults = THashMap<CirEntityId, CirCommonClassifierId>()
private val cachedNullResults = HashSet<CirEntityId>() private val cachedNullResults = THashSet<CirEntityId>()
override fun findCommonId(id: CirEntityId): CirCommonClassifierId? { override fun findCommonId(id: CirEntityId): CirCommonClassifierId? {
cachedResults[id]?.let { return it } cachedResults[id]?.let { return it }
@@ -37,10 +39,10 @@ private class CirCommonClassifierIdResolverImpl(
} }
private fun doFindCommonId(id: CirEntityId): CirCommonClassifierId? { private fun doFindCommonId(id: CirEntityId): CirCommonClassifierId? {
val results = LinkedHashSet<CirEntityId>() val results = ArrayList<CirEntityId>()
/* Set of every classifier id that once was enqueued already */ /* Set of every classifier id that once was enqueued already */
val visited = mutableSetOf<CirEntityId>() val visited = THashSet<CirEntityId>()
/* Actual, current queue of classifiers to resolve */ /* Actual, current queue of classifiers to resolve */
val queue = ArrayDeque<CirEntityId>() val queue = ArrayDeque<CirEntityId>()
@@ -50,6 +52,8 @@ private class CirCommonClassifierIdResolverImpl(
while (queue.isNotEmpty()) { while (queue.isNotEmpty()) {
val nextClassifierId = queue.removeFirst() val nextClassifierId = queue.removeFirst()
/* Either CirClassifier or CirProvided.Classifier or null */
val foundClassifiers = classifierIndices.associateWith { index -> val foundClassifiers = classifierIndices.associateWith { index ->
index.findClassifier(nextClassifierId) ?: dependencies.classifier(nextClassifierId) index.findClassifier(nextClassifierId) ?: dependencies.classifier(nextClassifierId)
} }
@@ -69,6 +73,12 @@ private class CirCommonClassifierIdResolverImpl(
} }
} }
dependencies.findTypeAliasesWithUnderlyingType(nextClassifierId).forEach { aliasId ->
if (visited.add(aliasId)) {
queue.add(aliasId)
}
}
// Propagate to the right (towards expansion) // Propagate to the right (towards expansion)
if (classifier is CirTypeAlias) { if (classifier is CirTypeAlias) {
if (visited.add(classifier.underlyingType.classifierId)) { if (visited.add(classifier.underlyingType.classifierId)) {
@@ -77,13 +87,8 @@ private class CirCommonClassifierIdResolverImpl(
} }
if (classifier is CirProvided.TypeAlias) { if (classifier is CirProvided.TypeAlias) {
val underlyingTypeId = when (val underlyingType = classifier.underlyingType) { if (visited.add(classifier.underlyingType.classifierId)) {
is CirProvided.ClassType -> underlyingType.classId queue.add(classifier.underlyingType.classifierId)
is CirProvided.TypeAliasType -> underlyingType.typeAliasId
is CirProvided.TypeParameterType -> null
}
if (underlyingTypeId != null && visited.add(underlyingTypeId)) {
queue.add(underlyingTypeId)
} }
} }
} }
@@ -30,6 +30,7 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers {
override fun hasClassifier(classifierId: CirEntityId) = classifierId in classifiers override fun hasClassifier(classifierId: CirEntityId) = classifierId in classifiers
override fun classifier(classifierId: CirEntityId): CirProvided.RegularClass? = classifiers[classifierId] override fun classifier(classifierId: CirEntityId): CirProvided.RegularClass? = classifiers[classifierId]
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> = emptyList()
private inline fun buildFictitiousFunctionClass(prefix: String, arity: Int, consumer: (CirEntityId, CirProvided.RegularClass) -> Unit) { private inline fun buildFictitiousFunctionClass(prefix: String, arity: Int, consumer: (CirEntityId, CirProvided.RegularClass) -> Unit) {
val typeParameters = List(arity + 1) { index -> val typeParameters = List(arity + 1) { index ->
@@ -14,7 +14,7 @@ class CirKnownClassifiers(
val targetDependencies: TargetDependent<CirProvidedClassifiers>, val targetDependencies: TargetDependent<CirProvidedClassifiers>,
val commonizedNodes: CirCommonizedClassifierNodes, val commonizedNodes: CirCommonizedClassifierNodes,
val commonDependencies: CirProvidedClassifiers, val commonDependencies: CirProvidedClassifiers,
val commonClassifierIdResolver: CirCommonClassifierIdResolver = CirCommonClassifierIdResolver(classifierIndices), val commonClassifierIdResolver: CirCommonClassifierIdResolver = CirCommonClassifierIdResolver(classifierIndices, commonDependencies),
) )
/** A set of all CIR nodes built for commonized classes and type aliases. */ /** A set of all CIR nodes built for commonized classes and type aliases. */
@@ -22,9 +22,13 @@ interface CirProvidedClassifiers {
fun hasClassifier(classifierId: CirEntityId): Boolean fun hasClassifier(classifierId: CirEntityId): Boolean
fun classifier(classifierId: CirEntityId): CirProvided.Classifier? fun classifier(classifierId: CirEntityId): CirProvided.Classifier?
// TODO NOW: Test
fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId>
object EMPTY : CirProvidedClassifiers { object EMPTY : CirProvidedClassifiers {
override fun hasClassifier(classifierId: CirEntityId) = false override fun hasClassifier(classifierId: CirEntityId) = false
override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? = null override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? = null
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId) = emptyList<CirEntityId>()
} }
private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : CirProvidedClassifiers { private class CompositeClassifiers(val delegates: List<CirProvidedClassifiers>) : CirProvidedClassifiers {
@@ -39,6 +43,10 @@ interface CirProvidedClassifiers {
} }
return fallbackReturn return fallbackReturn
} }
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> {
return delegates.flatMap { it.findTypeAliasesWithUnderlyingType(underlyingClassifier) }
}
} }
companion object { companion object {
@@ -97,7 +105,7 @@ object CirProvided {
data class TypeAlias( data class TypeAlias(
override val typeParameters: List<TypeParameter>, override val typeParameters: List<TypeParameter>,
val underlyingType: Type val underlyingType: ClassOrTypeAliasType
) : Classifier ) : Classifier
/* Type parameter */ /* Type parameter */
@@ -108,23 +116,28 @@ object CirProvided {
val isMarkedNullable: Boolean val isMarkedNullable: Boolean
} }
sealed interface ClassOrTypeAliasType : Type {
val classifierId: CirEntityId
val arguments: List<TypeProjection>
}
data class TypeParameterType( data class TypeParameterType(
val index: Int, val index: Int,
override val isMarkedNullable: Boolean override val isMarkedNullable: Boolean
) : Type ) : Type
data class ClassType( data class ClassType(
val classId: CirEntityId, override val classifierId: CirEntityId,
val outerType: ClassType?, override val arguments: List<TypeProjection>,
val arguments: List<TypeProjection>, override val isMarkedNullable: Boolean,
override val isMarkedNullable: Boolean val outerType: ClassType?
) : Type ) : ClassOrTypeAliasType
data class TypeAliasType( data class TypeAliasType(
val typeAliasId: CirEntityId, override val classifierId: CirEntityId,
val arguments: List<TypeProjection>, override val arguments: List<TypeProjection>,
override val isMarkedNullable: Boolean override val isMarkedNullable: Boolean
) : Type ) : ClassOrTypeAliasType
/* Type projections */ /* Type projections */
sealed interface TypeProjection sealed interface TypeProjection
@@ -139,7 +152,7 @@ object CirProvided {
private object ArtificialSupertypes { private object ArtificialSupertypes {
private fun createType(classId: String): CirProvided.ClassType { private fun createType(classId: String): CirProvided.ClassType {
return CirProvided.ClassType( return CirProvided.ClassType(
classId = CirEntityId.create(classId), classifierId = CirEntityId.create(classId),
outerType = null, arguments = emptyList(), isMarkedNullable = false outerType = null, arguments = emptyList(), isMarkedNullable = false
) )
} }
@@ -25,6 +25,18 @@ internal class CirProvidedClassifiersByModules internal constructor(
private val hasForwardDeclarations: Boolean, private val hasForwardDeclarations: Boolean,
private val classifiers: Map<CirEntityId, CirProvided.Classifier>, private val classifiers: Map<CirEntityId, CirProvided.Classifier>,
) : CirProvidedClassifiers { ) : CirProvidedClassifiers {
private val typeAliasesByUnderlyingTypes = run {
THashMap<CirEntityId, MutableList<CirEntityId>>().also { map ->
classifiers.forEach { (id, classifier) ->
if (classifier is CirProvided.TypeAlias) {
val set = map.computeIfAbsent(classifier.underlyingType.classifierId) { ArrayList() }
set.add(id)
}
}
}
}
override fun hasClassifier(classifierId: CirEntityId) = override fun hasClassifier(classifierId: CirEntityId) =
if (classifierId.packageName.isUnderKotlinNativeSyntheticPackages) { if (classifierId.packageName.isUnderKotlinNativeSyntheticPackages) {
hasForwardDeclarations hasForwardDeclarations
@@ -32,6 +44,10 @@ internal class CirProvidedClassifiersByModules internal constructor(
classifierId in classifiers classifierId in classifiers
} }
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> {
return typeAliasesByUnderlyingTypes[underlyingClassifier].orEmpty()
}
override fun classifier(classifierId: CirEntityId) = override fun classifier(classifierId: CirEntityId) =
classifiers[classifierId] ?: if (hasForwardDeclarations && classifierId.packageName.isUnderKotlinNativeSyntheticPackages) classifiers[classifierId] ?: if (hasForwardDeclarations && classifierId.packageName.isUnderKotlinNativeSyntheticPackages)
FALLBACK_FORWARD_DECLARATION_CLASS else null FALLBACK_FORWARD_DECLARATION_CLASS else null
@@ -167,7 +183,7 @@ private fun readClass(
val supertypes = (classProto.supertypeList.map { readType(it, typeReadContext) } + val supertypes = (classProto.supertypeList.map { readType(it, typeReadContext) } +
classProto.supertypeIdList.map { readType(classProto.typeTable.getType(it), typeReadContext) }) classProto.supertypeIdList.map { readType(classProto.typeTable.getType(it), typeReadContext) })
.filterNot { type -> type is CirProvided.ClassType && type.classId == ANY_CLASS_ID } .filterNot { type -> type is CirProvided.ClassType && type.classifierId == ANY_CLASS_ID }
val visibility = ProtoEnumFlags.visibility(Flags.VISIBILITY.get(classProto.flags)) val visibility = ProtoEnumFlags.visibility(Flags.VISIBILITY.get(classProto.flags))
@@ -198,7 +214,7 @@ private inline fun readTypeAlias(
) )
val underlyingType = readType(typeAliasProto.underlyingType(types), TypeReadContext(strings, types, typeParameterNameToIndex)) val underlyingType = readType(typeAliasProto.underlyingType(types), TypeReadContext(strings, types, typeParameterNameToIndex))
val typeAlias = CirProvided.TypeAlias(typeParameters, underlyingType) val typeAlias = CirProvided.TypeAlias(typeParameters, underlyingType as CirProvided.ClassOrTypeAliasType)
consumer(typeAliasId, typeAlias) consumer(typeAliasId, typeAlias)
} }
@@ -243,14 +259,14 @@ private fun readType(typeProto: ProtoBuf.Type, context: TypeReadContext): CirPro
} }
CirProvided.ClassType( CirProvided.ClassType(
classId = classId, classifierId = classId,
outerType = outerType, outerType = outerType,
arguments = readTypeArguments(argumentList, context), arguments = readTypeArguments(argumentList, context),
isMarkedNullable = nullable isMarkedNullable = nullable
) )
} }
hasTypeAliasName() -> CirProvided.TypeAliasType( hasTypeAliasName() -> CirProvided.TypeAliasType(
typeAliasId = CirEntityId.create(context.strings.getQualifiedClassName(typeAliasName)), classifierId = CirEntityId.create(context.strings.getQualifiedClassName(typeAliasName)),
arguments = readTypeArguments(argumentList, context), arguments = readTypeArguments(argumentList, context),
isMarkedNullable = nullable isMarkedNullable = nullable
) )
@@ -40,7 +40,6 @@ class CirTypeSignature {
} }
} }
typealias ObjCFunctionApproximation = Int typealias ObjCFunctionApproximation = Int
data class PropertyApproximationKey( data class PropertyApproximationKey(
@@ -188,8 +187,7 @@ internal fun CirTypeSignature.appendTypeApproximationSignature(context: Signatur
internal fun CirTypeSignature.appendClassOrTypeAliasTypeApproximationSignature( internal fun CirTypeSignature.appendClassOrTypeAliasTypeApproximationSignature(
context: SignatureBuildingContext, type: CirClassOrTypeAliasType context: SignatureBuildingContext, type: CirClassOrTypeAliasType
) { ) {
val classifierId = context.commonClassifierIdResolver.findCommonId(type.classifierId)?.aliases ?: type.classifierId add(context.commonClassifierIdResolver.findCommonId(type.classifierId) ?: type.classifierId)
add(classifierId)
if (type.arguments.isNotEmpty()) { if (type.arguments.isNotEmpty()) {
add(TypeSignatureElements.ArgumentsStartToken) add(TypeSignatureElements.ArgumentsStartToken)
type.arguments.forEachIndexed { index, argument -> type.arguments.forEachIndexed { index, argument ->
@@ -110,8 +110,8 @@ object CirTypeAliasExpander {
expansion: CirTypeAliasExpansion, expansion: CirTypeAliasExpansion,
type: CirProvided.TypeAliasType type: CirProvided.TypeAliasType
): CirTypeAliasType { ): CirTypeAliasType {
val typeAlias: CirProvided.TypeAlias = expansion.typeResolver.resolveClassifier(type.typeAliasId) val typeAlias: CirProvided.TypeAlias = expansion.typeResolver.resolveClassifier(type.classifierId)
checkArgumentsCount(typeAlias, type.typeAliasId, type.arguments) checkArgumentsCount(typeAlias, type.classifierId, type.arguments)
val expandedArguments = type.arguments.compactMapIndexed { index, argument -> val expandedArguments = type.arguments.compactMapIndexed { index, argument ->
val projection = expandTypeProjection(expansion, argument, typeAlias.typeParameters[index].variance) val projection = expandTypeProjection(expansion, argument, typeAlias.typeParameters[index].variance)
@@ -122,7 +122,7 @@ object CirTypeAliasExpander {
val nestedExpandedType = expand(nestedExpansion) val nestedExpandedType = expand(nestedExpansion)
return CirTypeAliasType.createInterned( return CirTypeAliasType.createInterned(
typeAliasId = type.typeAliasId, typeAliasId = type.classifierId,
underlyingType = nestedExpandedType, underlyingType = nestedExpandedType,
arguments = expandedArguments, arguments = expandedArguments,
isMarkedNullable = type.isMarkedNullable isMarkedNullable = type.isMarkedNullable
@@ -133,8 +133,8 @@ object CirTypeAliasExpander {
expansion: CirTypeAliasExpansion, expansion: CirTypeAliasExpansion,
type: CirProvided.ClassType type: CirProvided.ClassType
): CirClassType { ): CirClassType {
val clazz: CirProvided.Class = expansion.typeResolver.resolveClassifier(type.classId) val clazz: CirProvided.Class = expansion.typeResolver.resolveClassifier(type.classifierId)
checkArgumentsCount(clazz, type.classId, type.arguments) checkArgumentsCount(clazz, type.classifierId, type.arguments)
val expandedArguments = type.arguments.compactMapIndexed { index, argument -> val expandedArguments = type.arguments.compactMapIndexed { index, argument ->
val projection = expandTypeProjection(expansion, argument, clazz.typeParameters[index].variance) val projection = expandTypeProjection(expansion, argument, clazz.typeParameters[index].variance)
@@ -142,7 +142,7 @@ object CirTypeAliasExpander {
} }
return CirClassType.createInterned( return CirClassType.createInterned(
classId = type.classId, classId = type.classifierId,
outerType = type.outerType?.let { expandClassType(expansion, it) }, outerType = type.outerType?.let { expandClassType(expansion, it) },
visibility = clazz.visibility, visibility = clazz.visibility,
arguments = expandedArguments, arguments = expandedArguments,
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex
import org.jetbrains.kotlin.commonizer.mergedtree.CirCommonClassifierIdResolver import org.jetbrains.kotlin.commonizer.mergedtree.CirCommonClassifierIdResolver
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
import org.jetbrains.kotlin.commonizer.utils.createCirProvidedClassifiers
import org.jetbrains.kotlin.commonizer.utils.createCirTreeRoot
import org.jetbrains.kotlin.commonizer.utils.createCirTreeRootFromSourceCode import org.jetbrains.kotlin.commonizer.utils.createCirTreeRootFromSourceCode
class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest() { class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest() {
@@ -64,11 +67,11 @@ class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest
) )
) )
//assertEquals(setOf("C"), resolver.findCommonId("A")) assertEquals(setOf("C"), resolver.findCommonId("A"))
//assertEquals(setOf("C"), resolver.findCommonId("B")) assertEquals(setOf("C"), resolver.findCommonId("B"))
//assertEquals(setOf("C"), resolver.findCommonId("C")) assertEquals(setOf("C"), resolver.findCommonId("C"))
assertEquals(setOf("C"), resolver.findCommonId("D")) assertEquals(setOf("C"), resolver.findCommonId("D"))
//assertEquals(setOf("C"), resolver.findCommonId("E")) assertEquals(setOf("C"), resolver.findCommonId("E"))
} }
/* /*
@@ -223,12 +226,58 @@ class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest
assertEquals(setOf("A", "B", "C", "X", "Y", "Z"), resolver.findCommonId("Y")) assertEquals(setOf("A", "B", "C", "X", "Y", "Z"), resolver.findCommonId("Y"))
assertEquals(setOf("A", "B", "C", "X", "Y", "Z"), resolver.findCommonId("Z")) assertEquals(setOf("A", "B", "C", "X", "Y", "Z"), resolver.findCommonId("Z"))
} }
fun `test sample 7 - with dependencies`() {
val dependenciesModule = createModule {
source(
"""
class D_X
class D_TA = D_X
""".trimIndent()
)
}
val rootA = createCirTreeRoot {
dependency(dependenciesModule)
source(
"""
typealias A = D_TA
typealias B = D_X
typealias C = B
""".trimIndent()
)
}
val rootB = createCirTreeRoot {
dependency(dependenciesModule)
source(
"""
typealias A = D_TA
typealias C = D_TA
""".trimIndent()
)
}
val resolver = createCommonClassifierIdResolver(
rootA, rootB, dependencies = createCirProvidedClassifiers(dependenciesModule)
)
assertEquals(setOf("D_X", "D_TA", "A", "C"), resolver.findCommonId("D_X"))
assertEquals(setOf("D_X", "D_TA", "A", "C"), resolver.findCommonId("D_TA"))
assertEquals(setOf("D_X", "D_TA", "A", "C"), resolver.findCommonId("A"))
assertEquals(setOf("D_X", "D_TA", "A", "C"), resolver.findCommonId("B"))
assertEquals(setOf("D_X", "D_TA", "A", "C"), resolver.findCommonId("C"))
}
} }
private fun createCommonClassifierIdResolver(vararg root: CirTreeRoot): CirCommonClassifierIdResolver { private fun createCommonClassifierIdResolver(
vararg root: CirTreeRoot,
dependencies: CirProvidedClassifiers = CirProvidedClassifiers.EMPTY
): CirCommonClassifierIdResolver {
return CirCommonClassifierIdResolver( return CirCommonClassifierIdResolver(
TargetDependent(root.withIndex().associate { (index, root) -> LeafCommonizerTarget(index.toString()) to root }) TargetDependent(root.withIndex().associate { (index, root) -> LeafCommonizerTarget(index.toString()) to root })
.mapValue(::CirClassifierIndex) .mapValue(::CirClassifierIndex),
dependencies = dependencies
) )
} }
@@ -32,6 +32,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType?>() {
commonDependencies = object : CirProvidedClassifiers { commonDependencies = object : CirProvidedClassifiers {
override fun hasClassifier(classifierId: CirEntityId) = classifierId.packageName.isUnderStandardKotlinPackages override fun hasClassifier(classifierId: CirEntityId) = classifierId.packageName.isUnderStandardKotlinPackages
override fun classifier(classifierId: CirEntityId) = error("This method should not be called") override fun classifier(classifierId: CirEntityId) = error("This method should not be called")
override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List<CirEntityId> = emptyList()
} }
) )
} }
@@ -183,8 +183,7 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization
"(a, b)", """ "(a, b)", """
expect class AB expect constructor() expect class AB expect constructor()
typealias TA_AB = AB typealias TA_AB = AB
// https://youtrack.jetbrains.com/issue/KT-47100 expect val x: TA_AB
expect val x: AB
""".trimIndent() """.trimIndent()
) )
} }
@@ -214,8 +213,7 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization
"(a, b)", """ "(a, b)", """
expect class AB expect constructor() expect class AB expect constructor()
typealias TA_AB = AB typealias TA_AB = AB
// https://youtrack.jetbrains.com/issue/KT-47100 expect val x: TA_AB
expect val x: AB
""".trimIndent() """.trimIndent()
) )
} }
@@ -84,7 +84,7 @@ class InlineTypeAliasCirNodeTransformerTest : KtInlineSourceCommonizerTestCase()
visibility = Visibilities.Public, visibility = Visibilities.Public,
supertypes = listOf( supertypes = listOf(
CirProvided.ClassType( CirProvided.ClassType(
classId = CirEntityId.create("dep/ClassA"), classifierId = CirEntityId.create("dep/ClassA"),
outerType = null, outerType = null,
arguments = emptyList(), arguments = emptyList(),
isMarkedNullable = false isMarkedNullable = false
@@ -151,7 +151,7 @@ class InlineTypeAliasCirNodeTransformerTest : KtInlineSourceCommonizerTestCase()
visibility = Visibilities.Public, visibility = Visibilities.Public,
supertypes = listOf( supertypes = listOf(
CirProvided.ClassType( CirProvided.ClassType(
classId = CirEntityId.create("dep/ClassA"), classifierId = CirEntityId.create("dep/ClassA"),
outerType = null, outerType = null,
arguments = emptyList(), arguments = emptyList(),
isMarkedNullable = false isMarkedNullable = false
@@ -7,10 +7,14 @@ package org.jetbrains.kotlin.commonizer.utils
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest.InlineSourcesCommonizationTestDsl import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest.InlineSourcesCommonizationTestDsl
import org.jetbrains.kotlin.commonizer.ModulesProvider
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiersByModules
import org.jetbrains.kotlin.commonizer.tree.CirTreeModule import org.jetbrains.kotlin.commonizer.tree.CirTreeModule
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.library.SerializedMetadata
import java.io.File
interface InlineSourceBuilder { interface InlineSourceBuilder {
annotation class ModuleBuilderDsl annotation class ModuleBuilderDsl
@@ -94,3 +98,19 @@ fun InlineSourceBuilder.createCirTreeRoot(builder: InlineSourceBuilder.ModuleBui
fun InlineSourceBuilder.createCirTreeRootFromSourceCode(@Language("kotlin") sourceCode: String): CirTreeRoot { fun InlineSourceBuilder.createCirTreeRootFromSourceCode(@Language("kotlin") sourceCode: String): CirTreeRoot {
return CirTreeRoot(listOf(createCirTreeFromSourceCode(sourceCode))) return CirTreeRoot(listOf(createCirTreeFromSourceCode(sourceCode)))
} }
@InlineSourceBuilder.ModuleBuilderDsl
fun InlineSourceBuilder.createCirProvidedClassifiers(module: InlineSourceBuilder.Module): CirProvidedClassifiers {
val modulesProvider = object : ModulesProvider {
override val moduleInfos: Collection<ModulesProvider.ModuleInfo> = listOf(
ModulesProvider.ModuleInfo(name = "CirProvidedForTest", originalLocation = File("."), cInteropAttributes = null)
)
override fun loadModuleMetadata(name: String): SerializedMetadata {
if (name == moduleInfos.single().name) return createMetadata(module)
else error("Unknown Module $name")
}
}
return CirProvidedClassifiersByModules.load(modulesProvider)
}