diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirConversions.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirConversions.kt new file mode 100644 index 00000000000..fee77c15594 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirConversions.kt @@ -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 + ) + } +} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirName.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirName.kt index 9e2708f4552..cd80fc89110 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirName.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirName.kt @@ -94,15 +94,16 @@ class CirEntityId private constructor(val packageName: CirPackageName, val relat override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is CirEntityId) return false + if (other._hashCode != this._hashCode) return false if (other.packageName != this.packageName) return false if (!other.relativeNameSegments.contentEquals(relativeNameSegments)) return false 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 - hashCode(packageName).appendHashCode(relativeNameSegments).also { hashCode -> _hashCode = hashCode } + override fun hashCode(): Int = _hashCode override fun toString(): String = buildString { packageName.segments.joinTo(this, "/") diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirSupertypesResolver.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirSupertypesResolver.kt index 11db8fe2a63..3bf1c332fd2 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirSupertypesResolver.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirSupertypesResolver.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex import org.jetbrains.kotlin.commonizer.mergedtree.CirProvided import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers import org.jetbrains.kotlin.commonizer.mergedtree.findClass -import org.jetbrains.kotlin.descriptors.Visibilities internal interface CirSupertypesResolver { /** @@ -63,42 +62,3 @@ internal class SimpleCirSupertypesResolver( 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 - ) - } -} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt index ed86cab0ef9..447f76100a7 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirType.kt @@ -265,28 +265,22 @@ private class CirTypeAliasTypeInternedImpl( override val isMarkedNullable: Boolean ) : CirTypeAliasType() { // See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode - private var cachedHashCode = 0 - - private fun computeHashCode() = hashCode(classifierId) + private val hashCode = hashCode(classifierId) .appendHashCode(underlyingType) .appendHashCode(arguments) .appendHashCode(isMarkedNullable) - override fun hashCode(): Int { - var currentHashCode = cachedHashCode - if (currentHashCode != 0) return currentHashCode - currentHashCode = computeHashCode() - cachedHashCode = currentHashCode - return currentHashCode - } + override fun hashCode(): Int = hashCode override fun equals(other: Any?): Boolean = when { other === this -> true - other is CirTypeAliasType -> classifierId == other.classifierId - && underlyingType == other.underlyingType - && isMarkedNullable == other.isMarkedNullable - && arguments == other.arguments + other is CirTypeAliasType -> + hashCode == other.hashCode() && + classifierId == other.classifierId + && underlyingType == other.underlyingType + && isMarkedNullable == other.isMarkedNullable + && arguments == other.arguments else -> false } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt index b0397ac4579..f6db63af985 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt @@ -68,7 +68,6 @@ internal class ClassOrTypeAliasTypeCommonizer( val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke() ?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke() - when (commonizedClassifier) { is CirClass -> return CirClassType.createInterned( classId = classifierId, diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierId.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierId.kt index 23228155228..ca0007fc75b 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierId.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierId.kt @@ -7,8 +7,20 @@ package org.jetbrains.kotlin.commonizer.mergedtree import org.jetbrains.kotlin.commonizer.cir.CirEntityId -@JvmInline -value class CirCommonClassifierId(val aliases: LinkedHashSet) { +class CirCommonClassifierId(val aliases: List) { + + 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 { return aliases.joinToString(prefix = "(", postfix = ")") } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierIdResolver.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierIdResolver.kt index eda75bfbab5..a2a32559838 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierIdResolver.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirCommonClassifierIdResolver.kt @@ -7,6 +7,8 @@ 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.cir.CirEntityId import org.jetbrains.kotlin.commonizer.cir.CirTypeAlias @@ -27,8 +29,8 @@ private class CirCommonClassifierIdResolverImpl( private val dependencies: CirProvidedClassifiers ) : CirCommonClassifierIdResolver { - private val cachedResults = HashMap() - private val cachedNullResults = HashSet() + private val cachedResults = THashMap() + private val cachedNullResults = THashSet() override fun findCommonId(id: CirEntityId): CirCommonClassifierId? { cachedResults[id]?.let { return it } @@ -37,10 +39,10 @@ private class CirCommonClassifierIdResolverImpl( } private fun doFindCommonId(id: CirEntityId): CirCommonClassifierId? { - val results = LinkedHashSet() + val results = ArrayList() /* Set of every classifier id that once was enqueued already */ - val visited = mutableSetOf() + val visited = THashSet() /* Actual, current queue of classifiers to resolve */ val queue = ArrayDeque() @@ -50,6 +52,8 @@ private class CirCommonClassifierIdResolverImpl( while (queue.isNotEmpty()) { val nextClassifierId = queue.removeFirst() + + /* Either CirClassifier or CirProvided.Classifier or null */ val foundClassifiers = classifierIndices.associateWith { index -> 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) if (classifier is CirTypeAlias) { if (visited.add(classifier.underlyingType.classifierId)) { @@ -77,13 +87,8 @@ private class CirCommonClassifierIdResolverImpl( } if (classifier is CirProvided.TypeAlias) { - val underlyingTypeId = when (val underlyingType = classifier.underlyingType) { - is CirProvided.ClassType -> underlyingType.classId - is CirProvided.TypeAliasType -> underlyingType.typeAliasId - is CirProvided.TypeParameterType -> null - } - if (underlyingTypeId != null && visited.add(underlyingTypeId)) { - queue.add(underlyingTypeId) + if (visited.add(classifier.underlyingType.classifierId)) { + queue.add(classifier.underlyingType.classifierId) } } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt index 4daedc522c6..ae98cd7fb66 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt @@ -30,6 +30,7 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers { override fun hasClassifier(classifierId: CirEntityId) = classifierId in classifiers override fun classifier(classifierId: CirEntityId): CirProvided.RegularClass? = classifiers[classifierId] + override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List = emptyList() private inline fun buildFictitiousFunctionClass(prefix: String, arity: Int, consumer: (CirEntityId, CirProvided.RegularClass) -> Unit) { val typeParameters = List(arity + 1) { index -> diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirKnownClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirKnownClassifiers.kt index 8c38409f90a..30f8148b523 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirKnownClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirKnownClassifiers.kt @@ -14,7 +14,7 @@ class CirKnownClassifiers( val targetDependencies: TargetDependent, val commonizedNodes: CirCommonizedClassifierNodes, 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. */ diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt index 6684d549f85..da457a551de 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt @@ -22,9 +22,13 @@ interface CirProvidedClassifiers { fun hasClassifier(classifierId: CirEntityId): Boolean fun classifier(classifierId: CirEntityId): CirProvided.Classifier? + // TODO NOW: Test + fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List + object EMPTY : CirProvidedClassifiers { override fun hasClassifier(classifierId: CirEntityId) = false override fun classifier(classifierId: CirEntityId): CirProvided.Classifier? = null + override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId) = emptyList() } private class CompositeClassifiers(val delegates: List) : CirProvidedClassifiers { @@ -39,6 +43,10 @@ interface CirProvidedClassifiers { } return fallbackReturn } + + override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List { + return delegates.flatMap { it.findTypeAliasesWithUnderlyingType(underlyingClassifier) } + } } companion object { @@ -97,7 +105,7 @@ object CirProvided { data class TypeAlias( override val typeParameters: List, - val underlyingType: Type + val underlyingType: ClassOrTypeAliasType ) : Classifier /* Type parameter */ @@ -108,23 +116,28 @@ object CirProvided { val isMarkedNullable: Boolean } + sealed interface ClassOrTypeAliasType : Type { + val classifierId: CirEntityId + val arguments: List + } + data class TypeParameterType( val index: Int, override val isMarkedNullable: Boolean ) : Type data class ClassType( - val classId: CirEntityId, - val outerType: ClassType?, - val arguments: List, - override val isMarkedNullable: Boolean - ) : Type + override val classifierId: CirEntityId, + override val arguments: List, + override val isMarkedNullable: Boolean, + val outerType: ClassType? + ) : ClassOrTypeAliasType data class TypeAliasType( - val typeAliasId: CirEntityId, - val arguments: List, + override val classifierId: CirEntityId, + override val arguments: List, override val isMarkedNullable: Boolean - ) : Type + ) : ClassOrTypeAliasType /* Type projections */ sealed interface TypeProjection @@ -139,7 +152,7 @@ object CirProvided { private object ArtificialSupertypes { private fun createType(classId: String): CirProvided.ClassType { return CirProvided.ClassType( - classId = CirEntityId.create(classId), + classifierId = CirEntityId.create(classId), outerType = null, arguments = emptyList(), isMarkedNullable = false ) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt index 12e70f1c2aa..9f8bda972dc 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt @@ -25,6 +25,18 @@ internal class CirProvidedClassifiersByModules internal constructor( private val hasForwardDeclarations: Boolean, private val classifiers: Map, ) : CirProvidedClassifiers { + + private val typeAliasesByUnderlyingTypes = run { + THashMap>().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) = if (classifierId.packageName.isUnderKotlinNativeSyntheticPackages) { hasForwardDeclarations @@ -32,6 +44,10 @@ internal class CirProvidedClassifiersByModules internal constructor( classifierId in classifiers } + override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List { + return typeAliasesByUnderlyingTypes[underlyingClassifier].orEmpty() + } + override fun classifier(classifierId: CirEntityId) = classifiers[classifierId] ?: if (hasForwardDeclarations && classifierId.packageName.isUnderKotlinNativeSyntheticPackages) FALLBACK_FORWARD_DECLARATION_CLASS else null @@ -167,7 +183,7 @@ private fun readClass( val supertypes = (classProto.supertypeList.map { readType(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)) @@ -198,7 +214,7 @@ private inline fun readTypeAlias( ) 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) } @@ -243,14 +259,14 @@ private fun readType(typeProto: ProtoBuf.Type, context: TypeReadContext): CirPro } CirProvided.ClassType( - classId = classId, + classifierId = classId, outerType = outerType, arguments = readTypeArguments(argumentList, context), isMarkedNullable = nullable ) } hasTypeAliasName() -> CirProvided.TypeAliasType( - typeAliasId = CirEntityId.create(context.strings.getQualifiedClassName(typeAliasName)), + classifierId = CirEntityId.create(context.strings.getQualifiedClassName(typeAliasName)), arguments = readTypeArguments(argumentList, context), isMarkedNullable = nullable ) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/approximationKeys.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/approximationKeys.kt index 4971be6fd13..40a1f6e0127 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/approximationKeys.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/approximationKeys.kt @@ -40,7 +40,6 @@ class CirTypeSignature { } } - typealias ObjCFunctionApproximation = Int data class PropertyApproximationKey( @@ -188,8 +187,7 @@ internal fun CirTypeSignature.appendTypeApproximationSignature(context: Signatur internal fun CirTypeSignature.appendClassOrTypeAliasTypeApproximationSignature( context: SignatureBuildingContext, type: CirClassOrTypeAliasType ) { - val classifierId = context.commonClassifierIdResolver.findCommonId(type.classifierId)?.aliases ?: type.classifierId - add(classifierId) + add(context.commonClassifierIdResolver.findCommonId(type.classifierId) ?: type.classifierId) if (type.arguments.isNotEmpty()) { add(TypeSignatureElements.ArgumentsStartToken) type.arguments.forEachIndexed { index, argument -> diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirTypeAliasExpander.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirTypeAliasExpander.kt index ac1e2ae0387..4d377d1323e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirTypeAliasExpander.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirTypeAliasExpander.kt @@ -110,8 +110,8 @@ object CirTypeAliasExpander { expansion: CirTypeAliasExpansion, type: CirProvided.TypeAliasType ): CirTypeAliasType { - val typeAlias: CirProvided.TypeAlias = expansion.typeResolver.resolveClassifier(type.typeAliasId) - checkArgumentsCount(typeAlias, type.typeAliasId, type.arguments) + val typeAlias: CirProvided.TypeAlias = expansion.typeResolver.resolveClassifier(type.classifierId) + checkArgumentsCount(typeAlias, type.classifierId, type.arguments) val expandedArguments = type.arguments.compactMapIndexed { index, argument -> val projection = expandTypeProjection(expansion, argument, typeAlias.typeParameters[index].variance) @@ -122,7 +122,7 @@ object CirTypeAliasExpander { val nestedExpandedType = expand(nestedExpansion) return CirTypeAliasType.createInterned( - typeAliasId = type.typeAliasId, + typeAliasId = type.classifierId, underlyingType = nestedExpandedType, arguments = expandedArguments, isMarkedNullable = type.isMarkedNullable @@ -133,8 +133,8 @@ object CirTypeAliasExpander { expansion: CirTypeAliasExpansion, type: CirProvided.ClassType ): CirClassType { - val clazz: CirProvided.Class = expansion.typeResolver.resolveClassifier(type.classId) - checkArgumentsCount(clazz, type.classId, type.arguments) + val clazz: CirProvided.Class = expansion.typeResolver.resolveClassifier(type.classifierId) + checkArgumentsCount(clazz, type.classifierId, type.arguments) val expandedArguments = type.arguments.compactMapIndexed { index, argument -> val projection = expandTypeProjection(expansion, argument, clazz.typeParameters[index].variance) @@ -142,7 +142,7 @@ object CirTypeAliasExpander { } return CirClassType.createInterned( - classId = type.classId, + classId = type.classifierId, outerType = type.outerType?.let { expandClassType(expansion, it) }, visibility = clazz.visibility, arguments = expandedArguments, diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CirCommonClassifierIdResolverTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CirCommonClassifierIdResolverTest.kt index 741ec525667..c95696c8fc1 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CirCommonClassifierIdResolverTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/CirCommonClassifierIdResolverTest.kt @@ -8,7 +8,10 @@ package org.jetbrains.kotlin.commonizer import org.jetbrains.kotlin.commonizer.cir.CirEntityId import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex 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.utils.createCirProvidedClassifiers +import org.jetbrains.kotlin.commonizer.utils.createCirTreeRoot import org.jetbrains.kotlin.commonizer.utils.createCirTreeRootFromSourceCode class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest() { @@ -64,11 +67,11 @@ class CirCommonClassifierIdResolverTest : AbstractInlineSourcesCommonizationTest ) ) - //assertEquals(setOf("C"), resolver.findCommonId("A")) - //assertEquals(setOf("C"), resolver.findCommonId("B")) - //assertEquals(setOf("C"), resolver.findCommonId("C")) + assertEquals(setOf("C"), resolver.findCommonId("A")) + assertEquals(setOf("C"), resolver.findCommonId("B")) + assertEquals(setOf("C"), resolver.findCommonId("C")) 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("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( TargetDependent(root.withIndex().associate { (index, root) -> LeafCommonizerTarget(index.toString()) to root }) - .mapValue(::CirClassifierIndex) + .mapValue(::CirClassifierIndex), + dependencies = dependencies ) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt index 0ceb160ca9d..c1d17cabae7 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt @@ -32,6 +32,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { commonDependencies = object : CirProvidedClassifiers { override fun hasClassifier(classifierId: CirEntityId) = classifierId.packageName.isUnderStandardKotlinPackages override fun classifier(classifierId: CirEntityId) = error("This method should not be called") + override fun findTypeAliasesWithUnderlyingType(underlyingClassifier: CirEntityId): List = emptyList() } ) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt index d369552cea8..ef230f186b3 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt @@ -183,8 +183,7 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization "(a, b)", """ expect class AB expect constructor() typealias TA_AB = AB - // https://youtrack.jetbrains.com/issue/KT-47100 - expect val x: AB + expect val x: TA_AB """.trimIndent() ) } @@ -214,8 +213,7 @@ class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonization "(a, b)", """ expect class AB expect constructor() typealias TA_AB = AB - // https://youtrack.jetbrains.com/issue/KT-47100 - expect val x: AB + expect val x: TA_AB """.trimIndent() ) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt index 8dc0a7fece7..2af62b5bca8 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt @@ -84,7 +84,7 @@ class InlineTypeAliasCirNodeTransformerTest : KtInlineSourceCommonizerTestCase() visibility = Visibilities.Public, supertypes = listOf( CirProvided.ClassType( - classId = CirEntityId.create("dep/ClassA"), + classifierId = CirEntityId.create("dep/ClassA"), outerType = null, arguments = emptyList(), isMarkedNullable = false @@ -151,7 +151,7 @@ class InlineTypeAliasCirNodeTransformerTest : KtInlineSourceCommonizerTestCase() visibility = Visibilities.Public, supertypes = listOf( CirProvided.ClassType( - classId = CirEntityId.create("dep/ClassA"), + classifierId = CirEntityId.create("dep/ClassA"), outerType = null, arguments = emptyList(), isMarkedNullable = false diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt index aff691ea0f9..a23cb950cfe 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt @@ -7,10 +7,14 @@ package org.jetbrains.kotlin.commonizer.utils import org.intellij.lang.annotations.Language 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.CirTreeRoot import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.library.SerializedMetadata +import java.io.File interface InlineSourceBuilder { annotation class ModuleBuilderDsl @@ -94,3 +98,19 @@ fun InlineSourceBuilder.createCirTreeRoot(builder: InlineSourceBuilder.ModuleBui fun InlineSourceBuilder.createCirTreeRootFromSourceCode(@Language("kotlin") sourceCode: String): CirTreeRoot { return CirTreeRoot(listOf(createCirTreeFromSourceCode(sourceCode))) } + +@InlineSourceBuilder.ModuleBuilderDsl +fun InlineSourceBuilder.createCirProvidedClassifiers(module: InlineSourceBuilder.Module): CirProvidedClassifiers { + val modulesProvider = object : ModulesProvider { + override val moduleInfos: Collection = 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) +} +