[Commonizer] Refactor CIR type representation

1. Drop CirClassifierId
2. Specialized classes for each kind of types (classes, TAs, type parameters, flexible types).
3. TypeCommonizer now returns commonized type. In case of TAs this could be a completely new type
   describing expect class or a new TA with the different underlying type.
This commit is contained in:
Dmitriy Dolovov
2020-10-19 20:33:23 +03:00
parent 2764550bbe
commit f5bb60f7cd
40 changed files with 818 additions and 340 deletions

View File

@@ -17,12 +17,12 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.asSimpleType
class CommonizedTypeAliasDescriptor(
override val storageManager: StorageManager,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
visibility: DescriptorVisibility,
private val isActual: Boolean
override val storageManager: StorageManager,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
visibility: DescriptorVisibility,
private val isActual: Boolean
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility) {
private lateinit var underlyingTypeImpl: NotNullLazyValue<SimpleType>

View File

@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -101,31 +100,32 @@ internal fun CirSimpleType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): SimpleType {
val classifier: ClassifierDescriptor = when (val classifierId = classifierId) {
is CirClassifierId.Class -> {
targetComponents.findClassOrTypeAlias(classifierId.classId).checkClassifierType<ClassDescriptor>()
}
is CirClassifierId.TypeAlias -> {
val classId = classifierId.classId
val classOrTypeAlias: ClassifierDescriptorWithTypeParameters = targetComponents.findClassOrTypeAlias(classId)
): SimpleType = when (this) {
is CirClassType -> buildSimpleType(
classifier = targetComponents.findClassOrTypeAlias(classifierId).checkClassifierType<ClassDescriptor>(),
arguments = collectArguments(targetComponents, typeParameterResolver, expandTypeAliases),
isMarkedNullable = isMarkedNullable
)
is CirTypeAliasType -> {
val typeAliasDescriptor = targetComponents.findClassOrTypeAlias(classifierId).checkClassifierType<TypeAliasDescriptor>()
val arguments = this.arguments.map { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
if (classId.packageFqName.isUnderStandardKotlinPackages || !targetComponents.isCommon) {
// classifier type could be only type alias
classOrTypeAlias.checkClassifierType<TypeAliasDescriptor>()
} else {
// classifier could be class or type alias
classOrTypeAlias
}
}
is CirClassifierId.TypeParameter -> {
typeParameterResolver.resolve(classifierId.index)
?: error("Type parameter $classifierId not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}")
}
if (expandTypeAliases)
buildExpandedType(typeAliasDescriptor, arguments, isMarkedNullable)
else
buildSimpleType(typeAliasDescriptor, arguments, isMarkedNullable)
}
is CirTypeParameterType -> buildSimpleType(
classifier = typeParameterResolver.resolve(index)
?: error("Type parameter with index=$index not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}"),
arguments = emptyList(),
isMarkedNullable = isMarkedNullable
)
}
val arguments = arguments.map { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
val simpleType = simpleType(
@Suppress("NOTHING_TO_INLINE")
private inline fun buildSimpleType(classifier: ClassifierDescriptor, arguments: List<TypeProjection>, isMarkedNullable: Boolean) =
simpleType(
annotations = Annotations.EMPTY,
constructor = classifier.typeConstructor,
arguments = arguments,
@@ -133,29 +133,46 @@ internal fun CirSimpleType.buildType(
kotlinTypeRefiner = null
)
return if (expandTypeAliases && classifier is TypeAliasDescriptor) {
val expandedType = TypeAliasExpander.NON_REPORTING.expandWithoutAbbreviation(
TypeAliasExpansion.create(null, classifier, arguments),
Annotations.EMPTY
)
@Suppress("NOTHING_TO_INLINE")
private inline fun buildExpandedType(classifier: TypeAliasDescriptor, arguments: List<TypeProjection>, isMarkedNullable: Boolean) =
TypeAliasExpander.NON_REPORTING.expand(
TypeAliasExpansion.create(null, classifier, arguments),
Annotations.EMPTY
).makeNullableAsSpecified(isMarkedNullable)
expandedType.makeNullableAsSpecified(simpleType.isMarkedNullable).withAbbreviation(simpleType)
} else
simpleType
}
private inline fun <reified T : ClassifierDescriptorWithTypeParameters> ClassifierDescriptorWithTypeParameters.checkClassifierType(): T {
check(this is T) { "Mismatched classifier kinds.\nFound: ${this::class.java}, $this\nShould be: ${T::class.java}" }
return this
}
private fun CirClassType.collectArguments(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): List<TypeProjection> {
return if (outerType == null) {
arguments.map { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
} else {
val allTypes = generateSequence(this) { it.outerType }.toList()
val arguments = mutableListOf<TypeProjection>()
for (index in allTypes.size - 1 downTo 0) {
allTypes[index].arguments.mapTo(arguments) { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
}
arguments.toList()
}
}
private fun CirTypeProjection.buildArgument(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): TypeProjection =
if (isStarProjection) {
StarProjectionForAbsentTypeParameter(targetComponents.builtIns)
} else {
TypeProjectionImpl(projectionKind, type.buildType(targetComponents, typeParameterResolver, expandTypeAliases))
}
): TypeProjection = when (this) {
is CirStarTypeProjection -> StarProjectionForAbsentTypeParameter(targetComponents.builtIns)
is CirTypeProjectionImpl -> TypeProjectionImpl(
projectionKind,
type.buildType(targetComponents, typeParameterResolver, expandTypeAliases)
)
}

View File

@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
interface CirAnnotation {
val type: CirSimpleType
val type: CirClassType
val constantValueArguments: Map<Name, ConstantValue<*>>
val annotationValueArguments: Map<Name, CirAnnotation>
}

View File

@@ -1,18 +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
import org.jetbrains.kotlin.name.ClassId
sealed class CirClassifierId {
interface ClassOrTypeAlias {
val classId: ClassId
}
data class Class(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId()
data class TypeAlias(override val classId: ClassId) : ClassOrTypeAlias, CirClassifierId()
data class TypeParameter(val index: Int) : CirClassifierId()
}

View File

@@ -5,31 +5,107 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.AbbreviatedType
import org.jetbrains.kotlin.types.Variance
typealias CirTypeSignature = String
sealed class CirType
/**
* The hierarchy of [CirType]:
*
* [CirType]
* / \
* [CirFlexibleType] [CirSimpleType]
* / \
* [CirTypeParameterType] [CirClassOrTypeAliasType]
* / \
* [CirClassType] [CirTypeAliasType]
*/
sealed class CirType {
final override fun toString() = buildString { appendDescriptionTo(this) }
internal abstract fun appendDescriptionTo(builder: StringBuilder)
}
data class CirFlexibleType(val lowerBound: CirSimpleType, val upperBound: CirSimpleType) : CirType() {
override fun appendDescriptionTo(builder: StringBuilder) {
builder.append("lower = ")
lowerBound.appendDescriptionTo(builder)
builder.append(", upper = ")
upperBound.appendDescriptionTo(builder)
}
}
/**
* Note: Annotations at simple types are not preserved. After commonization all annotations assigned to types will be lost.
*/
sealed class CirSimpleType : CirType() {
abstract val isMarkedNullable: Boolean
override fun appendDescriptionTo(builder: StringBuilder) {
if (isMarkedNullable) builder.append('?')
}
}
data class CirTypeParameterType(
val index: Int,
override val isMarkedNullable: Boolean
) : CirSimpleType() {
override fun appendDescriptionTo(builder: StringBuilder) {
builder.append('#').append(index)
super.appendDescriptionTo(builder)
}
}
sealed class CirClassOrTypeAliasType : CirSimpleType() {
abstract val classifierId: ClassId
abstract val arguments: List<CirTypeProjection>
override fun appendDescriptionTo(builder: StringBuilder) {
builder.append(classifierId.asString())
if (arguments.isNotEmpty()) arguments.joinTo(builder, prefix = "<", postfix = ">")
super.appendDescriptionTo(builder)
}
}
abstract class CirClassType : CirClassOrTypeAliasType(), CirHasVisibility {
abstract val outerType: CirClassType?
override fun appendDescriptionTo(builder: StringBuilder) {
outerType?.let {
it.appendDescriptionTo(builder)
builder.append('.')
}
super.appendDescriptionTo(builder)
}
}
/**
* All attributes are read from the abbreviation type: [AbbreviatedType.abbreviation].
*
* This is necessary to properly compare types for type aliases, where abbreviation type represents the type alias itself while
* expanded type represents right-hand side declaration that should be processed separately.
*
* There is no difference between "abbreviation" and "expanded" for types representing classes and type parameters.
* For details, see [CirTypeFactory].
*
* Note: Annotations at simple types are not preserved. After commonization all annotations assigned to types will be lost.
*/
abstract class CirSimpleType : CirType(), CirHasVisibility {
abstract val classifierId: CirClassifierId
abstract val arguments: List<CirTypeProjection>
abstract val isMarkedNullable: Boolean
abstract class CirTypeAliasType : CirClassOrTypeAliasType() {
abstract val underlyingType: CirClassOrTypeAliasType
override fun appendDescriptionTo(builder: StringBuilder) {
super.appendDescriptionTo(builder)
builder.append(" -> ")
underlyingType.appendDescriptionTo(builder)
}
}
data class CirFlexibleType(val lowerBound: CirSimpleType, val upperBound: CirSimpleType) : CirType()
sealed class CirTypeProjection
data class CirTypeProjection(val projectionKind: Variance, val isStarProjection: Boolean, val type: CirType)
object CirStarTypeProjection : CirTypeProjection() {
override fun toString() = "*"
}
data class CirTypeProjectionImpl(val projectionKind: Variance, val type: CirType) : CirTypeProjection() {
override fun toString() = buildString {
append(projectionKind)
if (isNotEmpty()) append(' ')
type.appendDescriptionTo(this)
}
}

View File

@@ -6,6 +6,6 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir
interface CirTypeAlias : CirClassifier, CirLiftedUpDeclaration {
val underlyingType: CirSimpleType
val expandedType: CirSimpleType
val underlyingType: CirClassOrTypeAliasType
val expandedType: CirClassType
}

View File

@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import gnu.trove.THashMap
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirSimpleType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirAnnotationImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.checkConstantSupportedInCommonization
@@ -21,7 +21,7 @@ object CirAnnotationFactory {
private val interner = Interner<CirAnnotation>()
fun create(source: AnnotationDescriptor): CirAnnotation {
val type = CirTypeFactory.create(source.type) as CirSimpleType
val type = CirTypeFactory.create(source.type, useAbbreviation = false) as CirClassType
val allValueArguments: Map<Name, ConstantValue<*>> = source.allValueArguments
if (allValueArguments.isEmpty())
@@ -52,7 +52,7 @@ object CirAnnotationFactory {
}
fun create(
type: CirSimpleType,
type: CirClassType,
constantValueArguments: Map<Name, ConstantValue<*>>,
annotationValueArguments: Map<Name, CirAnnotation>
): CirAnnotation {

View File

@@ -1,38 +0,0 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
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.internedClassId
import org.jetbrains.kotlin.name.ClassId
@Suppress("MemberVisibilityCanBePrivate")
object CirClassifierIdFactory {
private val interner = Interner<CirClassifierId>()
fun create(source: ClassifierDescriptor): CirClassifierId {
return when (source) {
is ClassDescriptor -> createForClass(source.internedClassId)
is TypeAliasDescriptor -> createForTypeAlias(source.internedClassId)
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(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
}

View File

@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirSimpleType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.Name
@@ -21,18 +18,18 @@ object CirTypeAliasFactory {
name = source.name.intern(),
typeParameters = source.declaredTypeParameters.map(CirTypeParameterFactory::create),
visibility = source.visibility,
underlyingType = CirTypeFactory.create(source.underlyingType),
expandedType = CirTypeFactory.create(source.expandedType, useAbbreviation = false)
underlyingType = CirTypeFactory.create(source.underlyingType, useAbbreviation = true) as CirClassOrTypeAliasType,
expandedType = CirTypeFactory.create(source.expandedType, useAbbreviation = false) as CirClassType
)
@Suppress("NOTHING_TO_INLINE")
inline fun create(
annotations: List<CirAnnotation>,
name: Name,
typeParameters: List<CirTypeParameter>,
visibility: DescriptorVisibility,
underlyingType: CirSimpleType,
expandedType: CirSimpleType
annotations: List<CirAnnotation>,
name: Name,
typeParameters: List<CirTypeParameter>,
visibility: DescriptorVisibility,
underlyingType: CirClassOrTypeAliasType,
expandedType: CirClassType
): CirTypeAlias {
return CirTypeAliasImpl(
annotations = annotations,

View File

@@ -5,58 +5,168 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.factory
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirSimpleTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner
import org.jetbrains.kotlin.descriptors.commonizer.utils.declarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.extractExpandedType
import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.*
object CirTypeFactory {
private val interner = Interner<CirSimpleType>()
private val classTypeInterner = Interner<CirClassType>()
private val typeAliasTypeInterner = Interner<CirTypeAliasType>()
private val typeParameterTypeInterner = Interner<CirTypeParameterType>()
fun create(source: KotlinType): CirType = source.unwrap().run {
fun create(source: KotlinType, useAbbreviation: Boolean = true): CirType = source.unwrap().run {
when (this) {
is SimpleType -> create(this)
is FlexibleType -> CirFlexibleType(create(lowerBound), create(upperBound))
is SimpleType -> create(this, useAbbreviation)
is FlexibleType -> CirFlexibleType(create(lowerBound, useAbbreviation), create(upperBound, useAbbreviation))
}
}
fun create(source: SimpleType, useAbbreviation: Boolean = true): CirSimpleType {
@Suppress("NAME_SHADOWING")
val source = if (useAbbreviation && source is AbbreviatedType) source.abbreviation else source
val classifierDescriptor: ClassifierDescriptor = source.declarationDescriptor
fun create(source: SimpleType, useAbbreviation: Boolean): CirSimpleType {
if (useAbbreviation && source is AbbreviatedType) {
val abbreviation = source.abbreviation
when (val classifierDescriptor = abbreviation.declarationDescriptor) {
is TypeAliasDescriptor -> {
return createTypeAliasType(
typeAliasId = classifierDescriptor.internedClassId,
underlyingType = create(extractExpandedType(source), useAbbreviation = true) as CirClassOrTypeAliasType,
arguments = createArguments(abbreviation.arguments, useAbbreviation = true),
isMarkedNullable = abbreviation.isMarkedNullable
)
}
else -> error("Unexpected classifier descriptor type for abbreviation type: ${classifierDescriptor::class.java}, $classifierDescriptor, ${source.abbreviation}")
}
}
return create(
classifierId = CirClassifierIdFactory.create(classifierDescriptor),
visibility = (classifierDescriptor as? ClassifierDescriptorWithTypeParameters)?.visibility ?: DescriptorVisibilities.UNKNOWN,
arguments = source.arguments.map { projection ->
CirTypeProjection(
projectionKind = projection.projectionKind,
isStarProjection = projection.isStarProjection,
type = create(projection.type)
return when (val classifierDescriptor = source.declarationDescriptor) {
is ClassDescriptor -> createClassTypeWithAllOuterTypes(
classDescriptor = classifierDescriptor,
arguments = createArguments(source.arguments, useAbbreviation),
isMarkedNullable = source.isMarkedNullable
)
is TypeAliasDescriptor -> {
val abbreviatedType = TypeAliasExpander.NON_REPORTING.expand(
TypeAliasExpansion.create(null, classifierDescriptor, source.arguments),
Annotations.EMPTY
) as AbbreviatedType
createTypeAliasType(
typeAliasId = classifierDescriptor.internedClassId,
underlyingType = create(extractExpandedType(abbreviatedType), useAbbreviation = true) as CirClassOrTypeAliasType,
arguments = createArguments(source.arguments, useAbbreviation = true),
isMarkedNullable = source.isMarkedNullable
)
},
isMarkedNullable = source.isMarkedNullable
)
}
is TypeParameterDescriptor -> createTypeParameterType(classifierDescriptor.typeParameterIndex, source.isMarkedNullable)
else -> error("Unexpected classifier descriptor type: ${classifierDescriptor::class.java}, $classifierDescriptor, $source")
}
}
fun create(
classifierId: CirClassifierId,
visibility: DescriptorVisibility,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirSimpleType {
return interner.intern(
CirSimpleTypeImpl(
classifierId = classifierId,
fun createClassType(
classId: ClassId,
outerType: CirClassType?,
visibility: DescriptorVisibility,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirClassType {
return classTypeInterner.intern(
CirClassTypeImpl(
classifierId = classId,
outerType = outerType,
visibility = visibility,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
)
}
fun createTypeAliasType(
typeAliasId: ClassId,
underlyingType: CirClassOrTypeAliasType,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirTypeAliasType {
return typeAliasTypeInterner.intern(
CirTypeAliasTypeImpl(
classifierId = typeAliasId,
underlyingType = underlyingType,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
)
}
fun createTypeParameterType(
index: Int,
isMarkedNullable: Boolean
): CirTypeParameterType {
return typeParameterTypeInterner.intern(
CirTypeParameterType(
index = index,
isMarkedNullable = isMarkedNullable
)
)
}
private fun createClassTypeWithAllOuterTypes(
classDescriptor: ClassDescriptor,
arguments: List<CirTypeProjection>,
isMarkedNullable: Boolean
): CirClassType {
val outerType: CirClassType?
val remainingArguments: List<CirTypeProjection>
if (classDescriptor.isInner) {
val declaredTypeParametersCount = classDescriptor.declaredTypeParameters.size
outerType = createClassTypeWithAllOuterTypes(
classDescriptor = classDescriptor.containingDeclaration as ClassDescriptor,
arguments = arguments.subList(0, arguments.size - declaredTypeParametersCount),
isMarkedNullable = false // don't pass nullable flag to outer types
)
remainingArguments = arguments.subList(arguments.size - declaredTypeParametersCount, arguments.size)
} else {
outerType = null
remainingArguments = arguments
}
return createClassType(
classId = classDescriptor.internedClassId,
outerType = outerType,
visibility = classDescriptor.visibility,
arguments = remainingArguments,
isMarkedNullable = isMarkedNullable
)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun createArguments(arguments: List<TypeProjection>, useAbbreviation: Boolean): List<CirTypeProjection> =
arguments.map { projection ->
if (projection.isStarProjection)
CirStarTypeProjection
else
CirTypeProjectionImpl(
projectionKind = projection.projectionKind,
type = create(projection.type, useAbbreviation)
)
}
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
}
}

View File

@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.impl
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirSimpleType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
data class CirAnnotationImpl(
override val type: CirSimpleType,
override val type: CirClassType,
override val constantValueArguments: Map<Name, ConstantValue<*>>,
override val annotationValueArguments: Map<Name, CirAnnotation>
) : CirAnnotation {

View File

@@ -6,20 +6,24 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.impl
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.name.ClassId
data class CirSimpleTypeImpl(
override val classifierId: CirClassifierId,
override val visibility: DescriptorVisibility, // visibility of the classifier descriptor
override val arguments: List<CirTypeProjection>,
override val isMarkedNullable: Boolean
) : CirSimpleType() {
data class CirClassTypeImpl(
override val classifierId: ClassId,
override val outerType: CirClassType?,
override val visibility: DescriptorVisibility, // visibility of the class descriptor
override val arguments: List<CirTypeProjection>,
override val isMarkedNullable: Boolean,
) : CirClassType() {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = hashCode(classifierId)
.appendHashCode(outerType)
.appendHashCode(visibility)
.appendHashCode(arguments)
.appendHashCode(isMarkedNullable)
@@ -33,13 +37,14 @@ data class CirSimpleTypeImpl(
return currentHashCode
}
override fun equals(other: Any?) = when {
override fun equals(other: Any?): Boolean = when {
other === this -> true
other is CirSimpleType -> {
isMarkedNullable == other.isMarkedNullable
&& classifierId == other.classifierId
other is CirClassType -> {
classifierId == other.classifierId
&& isMarkedNullable == other.isMarkedNullable
&& visibility == other.visibility
&& arguments == other.arguments
&& outerType == other.outerType
}
else -> false
}

View File

@@ -6,19 +6,16 @@
package org.jetbrains.kotlin.descriptors.commonizer.cir.impl
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirSimpleType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.name.Name
data class CirTypeAliasImpl(
override val annotations: List<CirAnnotation>,
override val name: Name,
override val typeParameters: List<CirTypeParameter>,
override val visibility: DescriptorVisibility,
override val underlyingType: CirSimpleType,
override val expandedType: CirSimpleType // only for commonization algorithm; does not participate in building resulting declarations
override val annotations: List<CirAnnotation>,
override val name: Name,
override val typeParameters: List<CirTypeParameter>,
override val visibility: DescriptorVisibility,
override val underlyingType: CirClassOrTypeAliasType,
override val expandedType: CirClassType // only for commonization algorithm; does not participate in building resulting declarations
) : CirTypeAlias {
// any TA in "common" fragment is already lifted up
override val isLiftedUp get() = true

View File

@@ -0,0 +1,48 @@
/*
* 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.CirClassOrTypeAliasType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAliasType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
import org.jetbrains.kotlin.name.ClassId
data class CirTypeAliasTypeImpl(
override val classifierId: ClassId,
override val underlyingType: CirClassOrTypeAliasType,
override val arguments: List<CirTypeProjection>,
override val isMarkedNullable: Boolean
) : CirTypeAliasType() {
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
private var cachedHashCode = 0
private fun computeHashCode() = 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 equals(other: Any?): Boolean = when {
other === this -> true
other is CirTypeAliasType -> {
classifierId == other.classifierId
&& underlyingType == other.underlyingType
&& isMarkedNullable == other.isMarkedNullable
&& arguments == other.arguments
}
else -> false
}
}

View File

@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassifierIdFactory
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_CID
@@ -38,9 +36,7 @@ class AnnotationsCommonizer : AbstractStandardCommonizer<List<CirAnnotation>, Li
override fun initialize(first: List<CirAnnotation>) = Unit
override fun doCommonizeWith(next: List<CirAnnotation>): Boolean {
val nextDeprecatedAnnotation = next.firstOrNull { annotation ->
(annotation.type.classifierId as? CirClassifierId.Class)?.classId == DEPRECATED_ANNOTATION_CID
} ?: return true
val nextDeprecatedAnnotation = next.firstOrNull { it.type.classifierId == DEPRECATED_ANNOTATION_CID } ?: return true
val deprecatedAnnotationCommonizer = deprecatedAnnotationCommonizer
?: DeprecatedAnnotationCommonizer().also { this.deprecatedAnnotationCommonizer = it }
@@ -160,8 +156,9 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
it.name to EnumValue(DEPRECATION_LEVEL_CID, Name.identifier(it.name).intern())
}
private fun buildAnnotationType(classId: ClassId) = CirTypeFactory.create(
classifierId = CirClassifierIdFactory.createForClass(classId),
private fun buildAnnotationType(classId: ClassId) = CirTypeFactory.createClassType(
classId = classId,
outerType = null,
visibility = DescriptorVisibilities.PUBLIC,
arguments = emptyList(),
isMarkedNullable = false

View File

@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import com.intellij.util.containers.FactoryMap
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirCallableMemberWithParameters
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirHasAnnotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirValueParameterFactory
@@ -229,9 +228,7 @@ class CallableValueParametersCommonizer(
}
private fun CirCallableMemberWithParameters.canNamesBeOverwritten(): Boolean {
return (this as CirHasAnnotations).annotations.none { annotation ->
(annotation.type.classifierId as? CirClassifierId.ClassOrTypeAlias)?.classId?.isObjCInteropCallableAnnotation == true
}
return (this as CirHasAnnotations).annotations.none { it.type.classifierId.isObjCInteropCallableAnnotation }
}
private fun failIllegalState(current: ValueParameterNames?, next: ValueParameterNames): Nothing =

View File

@@ -6,13 +6,11 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifierId
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.utils.addToStdlib.cast
internal class CommonizationVisitor(
private val root: CirRootNode
@@ -128,7 +126,7 @@ internal class CommonizationVisitor(
private fun CirTypeAliasNode.collectCommonSupertypes(): Map<CirType, CommonizedGroup<CirType>>? {
val supertypesMap: MutableMap<CirType, CommonizedGroup<CirType>> = linkedMapOf() // preserve supertype order
for ((index, typeAlias) in targetDeclarations.withIndex()) {
val expandedClassId = typeAlias!!.expandedType.classifierId.cast<CirClassifierId.Class>().classId
val expandedClassId = typeAlias!!.expandedType.classifierId
if (expandedClassId.packageFqName.isUnderStandardKotlinPackages)
return null // this case is not supported

View File

@@ -56,7 +56,7 @@ fun Commonizer<*, *>.failInEmptyState(): Nothing = throw IllegalCommonizerStateE
@Suppress("unused")
fun Commonizer<*, *>.failInErrorState(): Nothing = throw IllegalCommonizerStateException("empty")
fun <T : Any> Commonizer<*, *>.checkState(value: T?, error: Boolean): T = when {
inline fun <reified T : Any> Commonizer<*, *>.checkState(value: T?, error: Boolean): T = when {
value == null -> failInEmptyState()
error -> failInErrorState()
else -> value

View File

@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.name.Name
/**
@@ -32,7 +33,6 @@ class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommoniz
override fun initialize(first: CirTypeAlias) = Unit
@Suppress("ReplaceNegatedIsEmptyWithIsNotEmpty")
override fun doCommonizeWith(next: CirTypeAlias): Boolean {
val primaryResult = primary.commonizeWith(next)
val secondaryResult = secondary.commonizeWith(next)
@@ -46,19 +46,59 @@ class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommoniz
private class TypeAliasShortCircuitingCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
private lateinit var name: Name
private val typeParameters = TypeParameterListCommonizer(cache)
private lateinit var underlyingType: CirClassOrTypeAliasType
private val expandedType = TypeCommonizer(cache)
private val visibility = VisibilityCommonizer.lowering()
override fun commonizationResult() = CirTypeAliasFactory.create(
annotations = emptyList(),
name = name,
typeParameters = typeParameters.result,
visibility = visibility.result,
underlyingType = computeCommonizedUnderlyingType(underlyingType),
expandedType = expandedType.result as CirClassType
)
val resultOrNull: CirTypeAlias?
get() = if (hasResult) commonizationResult() else null
override fun initialize(first: CirTypeAlias) {
name = first.name
underlyingType = first.underlyingType
}
override fun doCommonizeWith(next: CirTypeAlias) =
typeParameters.commonizeWith(next.typeParameters)
&& expandedType.commonizeWith(next.expandedType)
&& visibility.commonizeWith(next)
private tailrec fun computeCommonizedUnderlyingType(underlyingType: CirClassOrTypeAliasType): CirClassOrTypeAliasType {
return when (underlyingType) {
is CirClassType -> underlyingType
is CirTypeAliasType -> if (underlyingType.classifierId.packageFqName.isUnderStandardKotlinPackages)
underlyingType
else
computeCommonizedUnderlyingType(underlyingType.underlyingType)
}
}
}
private class TypeAliasLiftingUpCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
private lateinit var name: Name
private val typeParameters = TypeParameterListCommonizer(cache)
private val underlyingType = TypeCommonizer(cache)
private val visibility = VisibilityCommonizer.lowering()
override fun commonizationResult(): CirTypeAlias {
val expandedType = expandedType.result as CirSimpleType
val underlyingType = underlyingType.result as CirClassOrTypeAliasType
return CirTypeAliasFactory.create(
annotations = emptyList(),
name = name,
typeParameters = typeParameters.result,
visibility = visibility.result,
underlyingType = expandedType, // pass expanded type as underlying type
expandedType = expandedType
underlyingType = underlyingType,
expandedType = computeCommonizedExpandedType(underlyingType)
)
}
@@ -69,40 +109,17 @@ private class TypeAliasShortCircuitingCommonizer(cache: CirClassifiersCache) : A
name = first.name
}
override fun doCommonizeWith(next: CirTypeAlias) =
typeParameters.commonizeWith(next.typeParameters)
&& expandedType.commonizeWith(next.expandedType)
&& visibility.commonizeWith(next)
}
private class TypeAliasLiftingUpCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
private lateinit var name: Name
private val typeParameters = TypeParameterListCommonizer(cache)
private val underlyingType = TypeCommonizer(cache)
private lateinit var expandedType: CirSimpleType
private val visibility = VisibilityCommonizer.lowering()
override fun commonizationResult(): CirTypeAlias = CirTypeAliasFactory.create(
annotations = emptyList(),
name = name,
typeParameters = typeParameters.result,
visibility = visibility.result,
underlyingType = underlyingType.result as CirSimpleType,
expandedType = expandedType
)
val resultOrNull: CirTypeAlias?
get() = if (hasResult) commonizationResult() else null
override fun initialize(first: CirTypeAlias) {
name = first.name
expandedType = first.expandedType
}
override fun doCommonizeWith(next: CirTypeAlias) =
typeParameters.commonizeWith(next.typeParameters)
&& underlyingType.commonizeWith(next.underlyingType)
&& visibility.commonizeWith(next)
private tailrec fun computeCommonizedExpandedType(underlyingType: CirClassOrTypeAliasType): CirClassType {
return when (underlyingType) {
is CirClassType -> underlyingType
is CirTypeAliasType -> computeCommonizedExpandedType(underlyingType.underlyingType)
}
}
}
private class TypeAliasExpectClassCommonizer : AbstractStandardCommonizer<CirTypeAlias, CirClass>() {
@@ -129,9 +146,19 @@ private class TypeAliasExpectClassCommonizer : AbstractStandardCommonizer<CirTyp
name = first.name
}
override fun doCommonizeWith(next: CirTypeAlias) =
next.typeParameters.isEmpty() // TAs with declared type parameters can't be commonized
&& next.underlyingType.arguments.isEmpty() // TAs with functional types or types with parameters at the right-hand side can't be commonized
&& next.underlyingType.classifierId is CirClassifierId.Class // right-hand side could have only class
&& classVisibility.commonizeWith(next.underlyingType) // the visibilities of the right-hand classes should be equal
override fun doCommonizeWith(next: CirTypeAlias): Boolean {
if (next.typeParameters.isNotEmpty())
return false // TAs with declared type parameters can't be commonized
val underlyingType = next.underlyingType as? CirClassType ?: return false // right-hand side could have only class
return hasNoArguments(underlyingType) // TAs with functional types or types with arguments at the right-hand side can't be commonized
&& classVisibility.commonizeWith(underlyingType) // the visibilities of the right-hand classes should be equal
}
private tailrec fun hasNoArguments(type: CirClassType?): Boolean =
when {
type == null -> true
type.arguments.isNotEmpty() -> false
else -> hasNoArguments(type.outerType)
}
}

View File

@@ -5,105 +5,231 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.Variance
class TypeCommonizer(private val cache: CirClassifiersCache) : AbstractStandardCommonizer<CirType, CirType>() {
private lateinit var temp: CirType
private lateinit var wrapped: Commonizer<*, CirType>
override fun commonizationResult() = temp
override fun commonizationResult() = wrapped.result
override fun initialize(first: CirType) {
temp = first
@Suppress("UNCHECKED_CAST")
wrapped = when (first) {
is CirClassType -> ClassTypeCommonizer(cache)
is CirTypeAliasType -> TypeAliasTypeCommonizer(cache)
is CirTypeParameterType -> TypeParameterTypeCommonizer()
is CirFlexibleType -> FlexibleTypeCommonizer(cache)
} as Commonizer<*, CirType>
}
override fun doCommonizeWith(next: CirType) = areTypesEqual(cache, temp, next)
override fun doCommonizeWith(next: CirType) = when (next) {
is CirClassType -> (wrapped as? ClassTypeCommonizer)?.commonizeWith(next) == true
is CirTypeAliasType -> (wrapped as? TypeAliasTypeCommonizer)?.commonizeWith(next) == true
is CirTypeParameterType -> (wrapped as? TypeParameterTypeCommonizer)?.commonizeWith(next) == true
is CirFlexibleType -> (wrapped as? FlexibleTypeCommonizer)?.commonizeWith(next) == true
}
}
/**
* See also [AbstractStrictEqualityTypeChecker].
*/
@Suppress("IntroduceWhenSubject")
internal fun areTypesEqual(cache: CirClassifiersCache, a: CirType, b: CirType): Boolean = when {
a is CirSimpleType -> (b is CirSimpleType) && areSimpleTypesEqual(cache, a, b)
a is CirFlexibleType -> (b is CirFlexibleType)
&& areSimpleTypesEqual(cache, a.lowerBound, b.lowerBound)
&& areSimpleTypesEqual(cache, a.upperBound, b.upperBound)
else -> false
private class ClassTypeCommonizer(private val cache: CirClassifiersCache) : AbstractStandardCommonizer<CirClassType, CirClassType>() {
private lateinit var classId: ClassId
private val outerType = OuterClassTypeCommonizer(cache)
private lateinit var anyVisibility: DescriptorVisibility
private val arguments = TypeArgumentListCommonizer(cache)
private var isMarkedNullable = false
override fun commonizationResult() = CirTypeFactory.createClassType(
classId = classId,
outerType = outerType.result,
// N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is
// intended to be used in "common" target. It could not participate in TA commonization. So, it does not matter which
// exactly visibility will be recorded for commonized class type. Passing the visibility of the first class type
// to reach better interning rate.
visibility = anyVisibility,
arguments = arguments.result,
isMarkedNullable = isMarkedNullable
)
override fun initialize(first: CirClassType) {
classId = first.classifierId
anyVisibility = first.visibility
isMarkedNullable = first.isMarkedNullable
}
override fun doCommonizeWith(next: CirClassType) =
isMarkedNullable == next.isMarkedNullable
&& classId == next.classifierId
&& outerType.commonizeWith(next.outerType)
&& commonizeClassifier(classId, cache.classes).first
&& arguments.commonizeWith(next.arguments)
}
private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: CirSimpleType, b: CirSimpleType): Boolean {
val aId = a.classifierId
val bId = b.classifierId
private class OuterClassTypeCommonizer(cache: CirClassifiersCache) :
AbstractNullableCommonizer<CirClassType, CirClassType, CirClassType, CirClassType>(
wrappedCommonizerFactory = { ClassTypeCommonizer(cache) },
extractor = { it },
builder = { it }
)
if (a !== b) {
if (a.arguments.size != b.arguments.size || a.isMarkedNullable != b.isMarkedNullable) {
private class TypeAliasTypeCommonizer(private val cache: CirClassifiersCache) :
AbstractStandardCommonizer<CirTypeAliasType, CirClassOrTypeAliasType>() {
private lateinit var typeAliasId: ClassId
private val arguments = TypeArgumentListCommonizer(cache)
private var isMarkedNullable = false
private var commonizedTypeBuilder: CommonizedTypeAliasTypeBuilder? = null // null means not selected yet
override fun commonizationResult() =
(commonizedTypeBuilder ?: failInEmptyState()).build(
typeAliasId = typeAliasId,
arguments = arguments.result,
isMarkedNullable = isMarkedNullable
)
override fun initialize(first: CirTypeAliasType) {
typeAliasId = first.classifierId
isMarkedNullable = first.isMarkedNullable
}
override fun doCommonizeWith(next: CirTypeAliasType): Boolean {
if (isMarkedNullable != next.isMarkedNullable || typeAliasId != next.classifierId)
return false
if (commonizedTypeBuilder == null) {
val (commonized, commonClassifier) = commonizeClassifier(typeAliasId, cache.typeAliases)
if (!commonized)
return false
commonizedTypeBuilder = when (commonClassifier) {
is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier)
is CirTypeAlias -> CommonizedTypeAliasTypeBuilder.forTypeAlias(commonClassifier)
null -> CommonizedTypeAliasTypeBuilder.forKnownUnderlyingType(next.underlyingType)
else -> error("Unexpected common classifier type: ${commonClassifier::class.java}, $commonClassifier")
}
}
if (aId is CirClassifierId.ClassOrTypeAlias) {
if (bId !is CirClassifierId.ClassOrTypeAlias || aId.classId != bId.classId) return false
}
if (aId is CirClassifierId.TypeParameter) {
if (bId !is CirClassifierId.TypeParameter || aId.index != bId.index) return false
}
return arguments.commonizeWith(next.arguments)
}
// N.B. only for descriptors that represent classes or type aliases, but not type parameters!
fun isClassOrTypeAliasUnderStandardKotlinPackages(): Boolean {
return (aId as? CirClassifierId.ClassOrTypeAlias)?.classId?.packageFqName?.isUnderStandardKotlinPackages == true
}
// builds a new type for "common" library fragment for the given combination of type alias types in "platform" fragments
private interface CommonizedTypeAliasTypeBuilder {
fun build(typeAliasId: ClassId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean): CirClassOrTypeAliasType
fun descriptorsCanBeCommonizedThemselves(): Boolean {
return when (aId) {
is CirClassifierId.Class -> bId is CirClassifierId.Class && cache.classes[aId.classId].canBeCommonized()
is CirClassifierId.TypeAlias -> bId is CirClassifierId.TypeAlias && cache.typeAliases[aId.classId].canBeCommonized()
is CirClassifierId.TypeParameter -> {
// Real type parameter commonization is performed in TypeParameterCommonizer.
// Here it is enough to check that FQ names are equal (which is already done above).
true
companion object {
// type alias has been commonized to expect class, need to build type for expect class
fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder {
override fun build(typeAliasId: ClassId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
CirTypeFactory.createClassType(
classId = typeAliasId,
outerType = null, // there can't be outer type
visibility = commonClass.visibility,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
}
// type alias has been commonized to another type alias with the different underlying type, need to build type for
// new type alias
fun forTypeAlias(modifiedTypeAlias: CirTypeAlias) = forKnownUnderlyingType(modifiedTypeAlias.underlyingType)
// type alias don't needs to be commonized because it is from the standard library
fun forKnownUnderlyingType(underlyingType: CirClassOrTypeAliasType) = object : CommonizedTypeAliasTypeBuilder {
override fun build(typeAliasId: ClassId, arguments: List<CirTypeProjection>, isMarkedNullable: Boolean) =
CirTypeFactory.createTypeAliasType(
typeAliasId = typeAliasId,
underlyingType = underlyingType, // TODO replace arguments???
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
}
}
}
}
val descriptorsCanBeCommonized =
/* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages()
|| /* or descriptors themselves can be commonized */ descriptorsCanBeCommonizedThemselves()
private class TypeParameterTypeCommonizer : AbstractStandardCommonizer<CirTypeParameterType, CirTypeParameterType>() {
private lateinit var temp: CirTypeParameterType
if (!descriptorsCanBeCommonized)
return false
override fun commonizationResult() = temp
// N.B. both lists of arguments are already known to be of the same size
for (i in a.arguments.indices) {
val aArg = a.arguments[i]
val bArg = b.arguments[i]
override fun initialize(first: CirTypeParameterType) {
temp = first
}
if (aArg.isStarProjection != bArg.isStarProjection)
return false
override fun doCommonizeWith(next: CirTypeParameterType): Boolean {
// Real type parameter commonization is performed in TypeParameterCommonizer.
// Here it is enough to check that type parameter indices and nullability are equal.
return temp == next
}
}
if (!aArg.isStarProjection) {
if (aArg.projectionKind != bArg.projectionKind)
return false
private class FlexibleTypeCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirFlexibleType, CirFlexibleType>() {
private val lowerBound = TypeCommonizer(cache)
private val upperBound = TypeCommonizer(cache)
if (!areTypesEqual(cache, aArg.type, bArg.type))
return false
override fun commonizationResult() = CirFlexibleType(
lowerBound = lowerBound.result as CirSimpleType,
upperBound = upperBound.result as CirSimpleType
)
override fun initialize(first: CirFlexibleType) = Unit
override fun doCommonizeWith(next: CirFlexibleType) =
lowerBound.commonizeWith(next.lowerBound) && upperBound.commonizeWith(next.upperBound)
}
private class TypeArgumentCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeProjection, CirTypeProjection>() {
private var isStar = false
private lateinit var projectionKind: Variance
private val type = TypeCommonizer(cache)
override fun commonizationResult() = if (isStar) CirStarTypeProjection else CirTypeProjectionImpl(
projectionKind = projectionKind,
type = type.result
)
override fun initialize(first: CirTypeProjection) {
when (first) {
is CirStarTypeProjection -> isStar = true
is CirTypeProjectionImpl -> projectionKind = first.projectionKind
}
}
return true
override fun doCommonizeWith(next: CirTypeProjection) = when (next) {
is CirStarTypeProjection -> isStar
is CirTypeProjectionImpl -> !isStar && projectionKind == next.projectionKind && type.commonizeWith(next.type)
}
}
@Suppress("NOTHING_TO_INLINE")
private inline fun CirNode<*, *>?.canBeCommonized() =
if (this == null) {
// No node means that the class or type alias was not subject for commonization at all, probably it lays
// not in commonized module descriptors but somewhere in their dependencies.
true
} else {
// If entry is present, then contents (common declaration) should not be null.
commonDeclaration() != null
private class TypeArgumentListCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer<CirTypeProjection, CirTypeProjection>(
singleElementCommonizerFactory = { TypeArgumentCommonizer(cache) }
)
private inline fun <reified T : CirClassifier> commonizeClassifier(
classifierId: ClassId,
classifierNodes: Map<ClassId, CirNode<*, T>>,
): Pair<Boolean, T?> {
if (classifierId.packageFqName.isUnderStandardKotlinPackages) {
/* either class or type alias from Kotlin stdlib */
return true to null
}
/* or descriptors themselves can be commonized */
return when (val node = classifierNodes[classifierId]) {
null -> {
// No node means that the class or type alias was not subject for commonization at all, probably it lays
// not in commonized module descriptors but somewhere in their dependencies.
true to null
}
else -> {
// If entry is present, then contents (common declaration) should not be null.
val commonClassifier = node.commonDeclaration()
(commonClassifier != null) to commonClassifier
}
}
}

View File

@@ -12,15 +12,24 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeSignature
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.types.AbbreviatedType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor
get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor"))
// eliminate unnecessary repeated abbreviations
internal fun extractExpandedType(abbreviated: AbbreviatedType): SimpleType {
var expanded = abbreviated.expandedType
while (expanded is AbbreviatedType) {
if (expanded.abbreviation.declarationDescriptor !== abbreviated.abbreviation.declarationDescriptor)
break
else
expanded = expanded.expandedType
}
return expanded
}
internal val ClassifierDescriptorWithTypeParameters.internedClassId: ClassId
get() = when (val owner = containingDeclaration) {
is PackageFragmentDescriptor -> internedClassId(owner.fqName.intern(), name.intern())

View File

@@ -40,3 +40,19 @@ expect fun functionWithTypeParametersInReturnType12(): Box<Fox>
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType2(): T
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T>
expect class Outer<A>() {
class Nested<B>() {
class Nested<C>()
inner class Inner<D>()
}
inner class Inner<E>() {
inner class Inner<F>()
}
}
expect fun <T> returnOuter(): Outer<T>
expect fun <T> returnOuterNested(): Outer.Nested<T>
expect fun <T> returnOuterNestedNested(): Outer.Nested.Nested<T>
expect fun <T, R> returnOuterInner(): Outer<T>.Inner<R>
expect fun <T, R, S> returnOuterInnerInner(): Outer<T>.Inner<R>.Inner<S>

View File

@@ -61,3 +61,19 @@ fun <T> functionWithUnsubstitutedTypeParametersInReturnType6(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType7(): T = TODO()
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType9(): Box<T> = TODO()
actual class Outer<A> actual constructor() {
actual class Nested<B> actual constructor() {
actual class Nested<C> actual constructor()
actual inner class Inner<D> actual constructor()
}
actual inner class Inner<E> actual constructor() {
actual inner class Inner<F> actual constructor()
}
}
actual fun <T> returnOuter(): Outer<T> = TODO()
actual fun <T> returnOuterNested(): Outer.Nested<T> = TODO()
actual fun <T> returnOuterNestedNested(): Outer.Nested.Nested<T> = TODO()
actual fun <T, R> returnOuterInner(): Outer<T>.Inner<R> = TODO()
actual fun <T, R, S> returnOuterInnerInner(): Outer<T>.Inner<R>.Inner<S> = TODO()

View File

@@ -61,3 +61,19 @@ fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType6(): Q = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType7(): String = TODO()
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType9(): Box<String> = TODO()
actual class Outer<A> actual constructor() {
actual class Nested<B> actual constructor() {
actual class Nested<C> actual constructor()
actual inner class Inner<D> actual constructor()
}
actual inner class Inner<E> actual constructor() {
actual inner class Inner<F> actual constructor()
}
}
actual fun <T> returnOuter(): Outer<T> = TODO()
actual fun <T> returnOuterNested(): Outer.Nested<T> = TODO()
actual fun <T> returnOuterNestedNested(): Outer.Nested.Nested<T> = TODO()
actual fun <T, R> returnOuterInner(): Outer<T>.Inner<R> = TODO()
actual fun <T, R, S> returnOuterInnerInner(): Outer<T>.Inner<R>.Inner<S> = TODO()

View File

@@ -64,3 +64,19 @@ fun <T> functionWithUnsubstitutedTypeParametersInReturnType6(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType7(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType9(): Box<T> = TODO()
class Outer<A> {
class Nested<B> {
class Nested<C>
inner class Inner<D>
}
inner class Inner<E> {
inner class Inner<F>
}
}
fun <T> returnOuter(): Outer<T> = TODO()
fun <T> returnOuterNested(): Outer.Nested<T> = TODO()
fun <T> returnOuterNestedNested(): Outer.Nested.Nested<T> = TODO()
fun <T, R> returnOuterInner(): Outer<T>.Inner<R> = TODO()
fun <T, R, S> returnOuterInnerInner(): Outer<T>.Inner<R>.Inner<S> = TODO()

View File

@@ -64,3 +64,19 @@ fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType6(): Q = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType7(): String = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType9(): Box<String> = TODO()
class Outer<A> {
class Nested<B> {
class Nested<C>
inner class Inner<D>
}
inner class Inner<E> {
inner class Inner<F>
}
}
fun <T> returnOuter(): Outer<T> = TODO()
fun <T> returnOuterNested(): Outer.Nested<T> = TODO()
fun <T> returnOuterNestedNested(): Outer.Nested.Nested<T> = TODO()
fun <T, R> returnOuterInner(): Outer<T>.Inner<R> = TODO()
fun <T, R, S> returnOuterInnerInner(): Outer<T>.Inner<R>.Inner<S> = TODO()

View File

@@ -1,5 +1,12 @@
// this is to avoid missing Kotlin/Native stdlib
package kotlinx.cinterop
// fake class with the default constructor and no member scope
public abstract class CStructVar()
// fake classes with the default constructor and no member scope
abstract class CStructVar
class CPointer<T>
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
class UByte
// fake typealiases
typealias CArrayPointer<T> = CPointer<T>
typealias UByteVar = UByteVarOf<UByte>

View File

@@ -42,3 +42,9 @@ typealias Y = V // TA at the RHS with the different nullability of own RHS
// Supertypes:
expect class FILE : kotlinx.cinterop.CStructVar
typealias uuid_t = kotlinx.cinterop.CPointer<kotlinx.cinterop.UByteVarOf<kotlinx.cinterop.UByte>>
// ^^^ TODO: ideally, it should be CArrayPointer<UByteVar>
typealias __darwin_uuid_t = kotlinx.cinterop.CArrayPointer<kotlinx.cinterop.UByteVar>
expect val uuid: uuid_t

View File

@@ -1,5 +1,12 @@
// this is to avoid missing Kotlin/Native stdlib
package kotlinx.cinterop
// fake class with the default constructor and no member scope
public abstract class CStructVar()
// fake classes with the default constructor and no member scope
abstract class CStructVar
class CPointer<T>
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
class UByte
// fake typealiases
typealias CArrayPointer<T> = CPointer<T>
typealias UByteVar = UByteVarOf<UByte>

View File

@@ -20,3 +20,5 @@ typealias X = U? // different nullability of the RHS TA
// Supertypes:
actual typealias FILE = _IO_FILE
final class _IO_FILE : kotlinx.cinterop.CStructVar {}
actual val uuid: uuid_t get() = TODO()

View File

@@ -1,5 +1,12 @@
// this is to avoid missing Kotlin/Native stdlib
package kotlinx.cinterop
// fake class with the default constructor and no member scope
public abstract class CStructVar()
// fake classes with the default constructor and no member scope
abstract class CStructVar
class CPointer<T>
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
class UByte
// fake typealiases
typealias CArrayPointer<T> = CPointer<T>
typealias UByteVar = UByteVarOf<UByte>

View File

@@ -21,6 +21,8 @@ typealias X = U // different nullability of the RHS TA
actual typealias FILE = __sFILE
final class __sFILE : kotlinx.cinterop.CStructVar {}
actual val uuid: uuid_t get() = TODO()
// Type alias chain that is present in one target only:
class AA
typealias BB = AA

View File

@@ -1,5 +1,12 @@
// this is to avoid missing Kotlin/Native stdlib
package kotlinx.cinterop
// fake class with the default constructor and no member scope
public abstract class CStructVar()
// fake classes with the default constructor and no member scope
abstract class CStructVar
class CPointer<T>
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
class UByte
// fake typealiases
typealias CArrayPointer<T> = CPointer<T>
typealias UByteVar = UByteVarOf<UByte>

View File

@@ -51,3 +51,8 @@ typealias Y = V // TA at the RHS with the different nullability of own RHS
// Supertypes:
typealias FILE = _IO_FILE
final class _IO_FILE : kotlinx.cinterop.CStructVar {}
typealias uuid_t = __darwin_uuid_t
typealias __darwin_uuid_t = kotlinx.cinterop.CArrayPointer<kotlinx.cinterop.UByteVar>
val uuid: uuid_t get() = TODO()

View File

@@ -1,5 +1,12 @@
// this is to avoid missing Kotlin/Native stdlib
package kotlinx.cinterop
// fake class with the default constructor and no member scope
public abstract class CStructVar()
// fake classes with the default constructor and no member scope
abstract class CStructVar
class CPointer<T>
@Suppress("FINAL_UPPER_BOUND") class UByteVarOf<T : UByte>
class UByte
// fake typealiases
typealias CArrayPointer<T> = CPointer<T>
typealias UByteVar = UByteVarOf<UByte>

View File

@@ -52,6 +52,11 @@ typealias Y = V // TA at the RHS with the different nullability of own RHS
typealias FILE = __sFILE
final class __sFILE : kotlinx.cinterop.CStructVar {}
typealias uuid_t = __darwin_uuid_t
typealias __darwin_uuid_t = kotlinx.cinterop.CArrayPointer<kotlinx.cinterop.UByteVar>
val uuid: uuid_t get() = TODO()
// Type alias chain that is present in one target only:
class AA
typealias BB = AA

View File

@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirSimpleType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
@@ -290,7 +290,7 @@ private fun mockAnnotation(
constantValueArguments: Map<Name, ConstantValue<*>> = emptyMap(),
annotationValueArguments: Map<Name, CirAnnotation> = emptyMap()
): CirAnnotation = CirAnnotationFactory.create(
type = CirTypeFactory.create(mockClassType(fqName)) as CirSimpleType,
type = CirTypeFactory.create(mockClassType(fqName)) as CirClassType,
constantValueArguments = constantValueArguments,
annotationValueArguments = annotationValueArguments
)

View File

@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.CirClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildTypeAliasNode
@@ -274,7 +275,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
@Test
// why success: expect class/actual TAs
fun taTypesInUserPackageWithDifferentClasses() = doTestSuccess(
expected = mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
expected = mockClassType("org.sample.FooAlias"),
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Bar") }
)
@@ -444,7 +445,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
@Test
// why success: nullability of underlying type does not matter if expect class/actual TAs created
fun taTypesInUserPackageWithDifferentNullability3() = doTestSuccess(
expected = mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = false) },
expected = mockClassType("org.sample.FooAlias"),
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = false) },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = true) }
)
@@ -452,7 +453,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
@Test
// why success: nullability of underlying type does not matter if expect class/actual TAs created
fun taTypesInUserPackageWithDifferentNullability4() = doTestSuccess(
expected = mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = true) },
expected = mockClassType("org.sample.FooAlias"),
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = true) },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = false) }
)
@@ -520,5 +521,10 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
override fun createCommonizer() = TypeCommonizer(cache)
override fun isEqual(a: CirType?, b: CirType?) = (a === b) || (a != null && b != null && areTypesEqual(cache, a, b))
override fun isEqual(a: CirType?, b: CirType?) = (a === b) || (a != null && b != null && areEqual(cache, a, b))
companion object {
fun areEqual(cache: CirClassifiersCache, a: CirType, b: CirType): Boolean =
TypeCommonizer(cache).run { commonizeWith(a) && commonizeWith(b) }
}
}

View File

@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.core.CirTestValueParameter.Companion.areEqual
import org.jetbrains.kotlin.descriptors.commonizer.core.TypeCommonizerTest.Companion.areEqual
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.utils.EMPTY_CLASSIFIERS_CACHE
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
@@ -181,7 +182,7 @@ internal data class CirTestValueParameter(
companion object {
fun areEqual(cache: CirClassifiersCache, a: CirValueParameter, b: CirValueParameter): Boolean {
if (a.name != b.name
|| !areTypesEqual(cache, a.returnType, b.returnType)
|| !areEqual(cache, a.returnType, b.returnType)
|| a.declaresDefaultValue != b.declaresDefaultValue
|| a.isCrossinline != b.isCrossinline
|| a.isNoinline != b.isNoinline
@@ -194,7 +195,7 @@ internal data class CirTestValueParameter(
return (aVarargElementType === bVarargElementType)
|| (aVarargElementType != null && bVarargElementType != null
&& areTypesEqual(cache, aVarargElementType, bVarargElementType))
&& areEqual(cache, aVarargElementType, bVarargElementType))
}
}
}

View File

@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.AbbreviatedType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import kotlin.contracts.ExperimentalContracts
import kotlin.reflect.KCallable
import kotlin.test.fail
@@ -479,17 +478,6 @@ internal class ComparingDeclarationsVisitor(
context.assertEquals(!expectedAbbreviated.isNull(), !actualAbbreviated.isNull(), "type is abbreviated")
if (expectedAbbreviated != null && actualAbbreviated != null) {
fun extractExpandedType(abbreviated: AbbreviatedType): SimpleType { // eliminate unnecessary repeated abbreviations
var expanded = abbreviated.expandedType
while (expanded is AbbreviatedType) {
if (expanded.abbreviation.declarationDescriptor !== abbreviated.abbreviation.declarationDescriptor)
break
else
expanded = expanded.expandedType
}
return expanded
}
visitType(
expectedAbbreviated.abbreviation,
actualAbbreviated.abbreviation,