mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-17 08:31:31 +00:00
[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:
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user