[Commonizer] Kotlin types

This commit is contained in:
Dmitriy Dolovov
2019-09-26 19:09:54 +07:00
parent 310166443a
commit 72869e848d
48 changed files with 1121 additions and 432 deletions
@@ -7,6 +7,8 @@ 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.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
@@ -15,14 +17,12 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory.*
import org.jetbrains.kotlin.resolve.descriptorUtil.computeSealedSubclasses
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
class CommonizedClassDescriptor(
storageManager: StorageManager,
targetComponents: TargetDeclarationsBuilderComponents,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
@@ -36,18 +36,33 @@ class CommonizedClassDescriptor(
isExternal: Boolean,
private val isExpect: Boolean,
private val isActual: Boolean,
cirDeclaredTypeParameters: List<CirTypeParameter>,
companionObjectName: Name?,
supertypes: Collection<KotlinType>
) : ClassDescriptorBase(storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) {
private lateinit var _unsubstitutedMemberScope: MemberScope
cirSupertypes: Collection<CirType>
) : ClassDescriptorBase(targetComponents.storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) {
private lateinit var _unsubstitutedMemberScope: CommonizedMemberScope
private lateinit var constructors: Collection<ClassConstructorDescriptor>
private var primaryConstructor: ClassConstructorDescriptor? = null
private val staticScope = if (kind == ClassKind.ENUM_CLASS) StaticScopeForKotlinEnum(storageManager, this) else MemberScope.Empty
private lateinit var declaredTypeParameters: List<TypeParameterDescriptor>
private val typeConstructor = CommonizedClassTypeConstructor(storageManager, supertypes)
private val sealedSubclasses = storageManager.createLazyValue { computeSealedSubclasses(this) }
private val companionObjectDescriptor = storageManager.createNullableLazyValue {
private val staticScope = if (kind == ClassKind.ENUM_CLASS)
StaticScopeForKotlinEnum(targetComponents.storageManager, this)
else
MemberScope.Empty
private val typeConstructor = CommonizedClassTypeConstructor(targetComponents, cirSupertypes)
private val sealedSubclasses = targetComponents.storageManager.createLazyValue { computeSealedSubclasses(this) }
private val declaredTypeParametersAndTypeParameterResolver = targetComponents.storageManager.createLazyValue {
val parent = if (isInner) (containingDeclaration as? ClassDescriptor)?.getTypeParameterResolver() else null
cirDeclaredTypeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
parent ?: TypeParameterResolver.EMPTY,
this
)
}
private val companionObjectDescriptor = targetComponents.storageManager.createNullableLazyValue {
if (companionObjectName != null)
unsubstitutedMemberScope.getContributedClassifier(companionObjectName, NoLookupLocation.FOR_ALREADY_TRACKED) as? ClassDescriptor
else
@@ -64,18 +79,21 @@ class CommonizedClassDescriptor(
override fun isExpect() = isExpect
override fun isActual() = isActual
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope {
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): CommonizedMemberScope {
check(kotlinTypeRefiner == KotlinTypeRefiner.Default) {
"${kotlinTypeRefiner::class.java} is not supported in ${this::class.java}"
}
return _unsubstitutedMemberScope
}
override fun getDeclaredTypeParameters() = declaredTypeParameters
fun setDeclaredTypeParameters(declaredTypeParameters: List<TypeParameterDescriptor>) {
this.declaredTypeParameters = declaredTypeParameters
override fun getUnsubstitutedMemberScope(): CommonizedMemberScope = super.getUnsubstitutedMemberScope() as CommonizedMemberScope
fun setUnsubstitutedMemberScope(unsubstitutedMemberScope: CommonizedMemberScope) {
_unsubstitutedMemberScope = unsubstitutedMemberScope
}
override fun getDeclaredTypeParameters() = declaredTypeParametersAndTypeParameterResolver().first
val typeParameterResolver: TypeParameterResolver get() = declaredTypeParametersAndTypeParameterResolver().second
override fun getConstructors() = constructors
override fun getUnsubstitutedPrimaryConstructor() = primaryConstructor
override fun getStaticScope(): MemberScope = staticScope
@@ -83,12 +101,7 @@ class CommonizedClassDescriptor(
override fun getCompanionObjectDescriptor() = companionObjectDescriptor()
override fun getSealedSubclasses() = sealedSubclasses()
fun initialize(
unsubstitutedMemberScope: MemberScope,
constructors: Collection<CommonizedClassConstructorDescriptor>
) {
_unsubstitutedMemberScope = unsubstitutedMemberScope
fun initialize(constructors: Collection<CommonizedClassConstructorDescriptor>) {
if (isExpect && kind.isSingleton) {
check(constructors.isEmpty())
@@ -109,15 +122,19 @@ class CommonizedClassDescriptor(
override fun toString() = (if (isExpect) "expect " else if (isActual) "actual " else "") + "class " + name.toString()
private inner class CommonizedClassTypeConstructor(
storageManager: StorageManager,
private val computedSupertypes: Collection<KotlinType>
) : AbstractClassTypeConstructor(storageManager) {
private val parameters = storageManager.createLazyValue {
targetComponents: TargetDeclarationsBuilderComponents,
cirSupertypes: Collection<CirType>
) : AbstractClassTypeConstructor(targetComponents.storageManager) {
private val parameters = targetComponents.storageManager.createLazyValue {
this@CommonizedClassDescriptor.computeConstructorTypeParameters()
}
private val supertypes = targetComponents.storageManager.createLazyValue {
cirSupertypes.map { it.buildType(targetComponents, this@CommonizedClassDescriptor.typeParameterResolver) }
}
override fun getParameters() = parameters()
override fun computeSupertypes() = computedSupertypes
override fun computeSupertypes() = supertypes()
override fun isDenotable() = true
override fun getDeclarationDescriptor() = this@CommonizedClassDescriptor
override val supertypeLoopChecker get() = SupertypeLoopChecker.EMPTY
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.utils.Printer
internal class CommonizedMemberScope : MemberScopeImpl() {
class CommonizedMemberScope : MemberScopeImpl() {
private val members = ArrayList<DeclarationDescriptor>()
operator fun plusAssign(member: DeclarationDescriptor) {
@@ -51,7 +51,17 @@ internal class CommonizedMemberScope : MemberScopeImpl() {
operator fun Array<CommonizedMemberScope>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
this[index] += member ?: return@forEachIndexed
if (member != null) {
this[index] += member
}
}
}
operator fun List<CommonizedMemberScope?>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
if (member != null) {
this[index]?.run { this += member }
}
}
}
}
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -25,28 +25,33 @@ class CommonizedTypeAliasDescriptor(
private val isActual: Boolean
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility) {
override lateinit var underlyingType: SimpleType
override lateinit var expandedType: SimpleType
private lateinit var underlyingTypeImpl: NotNullLazyValue<SimpleType>
override val underlyingType get() = underlyingTypeImpl()
private lateinit var defaultType: SimpleType
override fun getDefaultType() = defaultType
private lateinit var expandedTypeImpl: NotNullLazyValue<SimpleType>
override val expandedType: SimpleType get() = expandedTypeImpl()
private val defaultTypeImpl = storageManager.createLazyValue { computeDefaultType() }
override fun getDefaultType() = defaultTypeImpl()
override val classDescriptor get() = expandedType.constructor.declarationDescriptor as? ClassDescriptor
private lateinit var typeConstructorParameters: List<TypeParameterDescriptor>
override fun getTypeConstructorTypeParameters() = typeConstructorParameters
private val typeConstructorParametersImpl = storageManager.createLazyValue { computeConstructorTypeParameters() }
override fun getTypeConstructorTypeParameters() = typeConstructorParametersImpl()
override lateinit var constructors: Collection<TypeAliasConstructorDescriptor>
private val constructorsImpl = storageManager.createLazyValue { getTypeAliasConstructors() }
override val constructors get() = constructorsImpl()
override fun isActual() = isActual
fun initialize(declaredTypeParameters: List<TypeParameterDescriptor>, underlyingType: SimpleType, expandedType: SimpleType) {
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
underlyingType: NotNullLazyValue<SimpleType>,
expandedType: NotNullLazyValue<SimpleType>
) {
super.initialize(declaredTypeParameters)
this.underlyingType = underlyingType
this.expandedType = expandedType
typeConstructorParameters = computeConstructorTypeParameters()
defaultType = computeDefaultType()
constructors = getTypeAliasConstructors()
underlyingTypeImpl = underlyingType
expandedTypeImpl = expandedType
}
override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters {
@@ -61,8 +66,8 @@ class CommonizedTypeAliasDescriptor(
)
substituted.initialize(
declaredTypeParameters,
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(),
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType()
storageManager.createLazyValue { substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType() },
storageManager.createLazyValue { substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() }
)
return substituted
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2019 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.builder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
class CommonizedTypeParameterDescriptor(
private val targetComponents: TargetDeclarationsBuilderComponents,
private val typeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
variance: Variance,
isReified: Boolean,
index: Int,
private val cirUpperBounds: List<CirType>
) : AbstractLazyTypeParameterDescriptor(
targetComponents.storageManager,
containingDeclaration,
name,
variance,
isReified,
index,
SourceElement.NO_SOURCE,
SupertypeLoopChecker.EMPTY
) {
override fun resolveUpperBounds(): List<UnwrappedType> {
return if (cirUpperBounds.isEmpty())
listOf(targetComponents.builtIns.defaultBound)
else
cirUpperBounds.map { it.buildType(targetComponents, typeParameterResolver) }
}
override fun reportSupertypeLoopError(type: KotlinType) =
error("There should be no cycles for commonized type parameters, but found for: $type in $this")
}
@@ -11,17 +11,23 @@ import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedPackageFragmentProvider.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.addIfNotNull
/** Builds and initializes the new tree of common descriptors */
internal class DeclarationsBuilderVisitor(
private val storageManager: StorageManager,
private val collector: (Target, Collection<ModuleDescriptor>) -> Unit
/**
* Serves two goals:
* 1. Builds and initializes descriptors that do not depend on Kotlin types, such as [ModuleDescriptor], [PackageFragmentDescriptor], etc.
* 2. Builds BUT not initializes classifier descriptors, so that they can be used during the next phase for construction of Kotlin types.
*/
internal class DeclarationsBuilderVisitor1(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
val allTargets = (node.target + node.common()!!).map { it.target }
val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
@@ -41,9 +47,9 @@ internal class DeclarationsBuilderVisitor(
module.setDependencies(modulesSameTarget)
}
// return result (preserve platforms order):
for (target in allTargets) {
collector(target, modulesByTargets.getValue(target))
// return result (preserving order of targets):
allTargets.forEachIndexed { index, target ->
components.cache.cache(index, modulesByTargets.getValue(target))
}
return noReturningDeclarations()
@@ -52,7 +58,7 @@ internal class DeclarationsBuilderVisitor(
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// build module descriptors:
val moduleDescriptorsGroup = CommonizedGroup<ModuleDescriptorImpl>(node.dimension)
node.buildDescriptors(moduleDescriptorsGroup, storageManager)
node.buildDescriptors(components, moduleDescriptorsGroup)
val moduleDescriptors = moduleDescriptorsGroup.toList()
// build package fragments:
@@ -75,17 +81,11 @@ internal class DeclarationsBuilderVisitor(
// build package fragments:
val packageFragmentsGroup = CommonizedGroup<CommonizedPackageFragmentDescriptor>(node.dimension)
node.buildDescriptors(packageFragmentsGroup, containingDeclarations)
node.buildDescriptors(components, packageFragmentsGroup, containingDeclarations)
val packageFragments = packageFragmentsGroup.toList()
// build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (propertyNode in node.properties) {
packageMemberScopes += propertyNode.accept(this, packageFragments)
}
for (functionNode in node.functions) {
packageMemberScopes += functionNode.accept(this, packageFragments)
}
for (classNode in node.classes) {
packageMemberScopes += classNode.accept(this, packageFragments)
}
@@ -101,80 +101,52 @@ internal class DeclarationsBuilderVisitor(
return packageFragments
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>): List<PropertyDescriptor?> {
val propertyDescriptorsGroup = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(propertyDescriptorsGroup, data, storageManager)
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
return propertyDescriptorsGroup.toList()
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val functionDescriptorsGroup = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(functionDescriptorsGroup, data)
return functionDescriptorsGroup.toList()
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(classesGroup, data, storageManager)
node.buildDescriptors(components, classesGroup, data)
val classes = classesGroup.toList().asListContaining<CommonizedClassDescriptor>()
// build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() }
for (constructorNode in node.constructors) {
val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor)
}
}
// build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (propertyNode in node.properties) {
classMemberScopes += propertyNode.accept(this, classes)
}
for (functionNode in node.functions) {
classMemberScopes += functionNode.accept(this, classes)
}
for (classNode in node.classes) {
classMemberScopes += classNode.accept(this, classes)
}
// initialize classes
// save member scope
classes.forEachIndexed { index, clazz ->
clazz?.initialize(classMemberScopes[index], allConstructorsByTargets[index])
clazz?.unsubstitutedMemberScope = classMemberScopes[index]
}
return classes
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val containingDeclarations = data.asListContaining<ClassDescriptor>()
val constructorsGroup = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(constructorsGroup, containingDeclarations)
return constructorsGroup.toList()
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val typeAliasesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(typeAliasesGroup, data, storageManager)
node.buildDescriptors(components, typeAliasesGroup, data)
val typeAliases = typeAliasesGroup.toList()
val commonClass = typeAliases[node.indexOfCommon] as CommonizedClassDescriptor?
commonClass?.initialize(MemberScope.Empty, emptyList())
commonClass?.unsubstitutedMemberScope = CommonizedMemberScope() // empty member scope
commonClass?.initialize(emptyList()) // no constructors
return typeAliases
}
companion object {
inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
internal inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
internal inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : DeclarationDescriptor> List<DeclarationDescriptor?>.asListContaining(): List<T?> =
this as List<T?>
}
}
@Suppress("UNCHECKED_CAST")
private inline fun <reified T : DeclarationDescriptor> List<DeclarationDescriptor?>.asListContaining(): List<T?> =
this as List<T?>
@@ -0,0 +1,125 @@
/*
* Copyright 2010-2019 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.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noContainingDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noReturningDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.asListContaining
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
/** Builds and initializes the new tree of common descriptors */
/**
* This visitor should be applied right after [DeclarationsBuilderVisitor1]. It does the following:
* 1. Builds and initializes descriptors that depend on Kotlin types, such as [PropertyDescriptor], [SimpleFunctionDescriptor], etc.
* 2. Initializes classifier descriptors.
*/
internal class DeclarationsBuilderVisitor2(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
// visit module descriptors:
for (moduleNode in node.modules) {
moduleNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// visit package fragment descriptors:
for (packageNode in node.packages) {
packageNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val packageFragments = components.cache.getCachedPackageFragments(node.fqName)
// build non-classifier package members:
val packageMemberScopes = packageFragments.map { it?.getMemberScope() }
for (propertyNode in node.properties) {
packageMemberScopes += propertyNode.accept(this, packageFragments)
}
for (functionNode in node.functions) {
packageMemberScopes += functionNode.accept(this, packageFragments)
}
for (classNode in node.classes) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>): List<PropertyDescriptor?> {
val propertyDescriptorsGroup = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(components, propertyDescriptorsGroup, data)
return propertyDescriptorsGroup.toList()
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val functionDescriptorsGroup = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(components, functionDescriptorsGroup, data)
return functionDescriptorsGroup.toList()
}
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classes = components.cache.getCachedClasses(node.fqName)
// build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() }
for (constructorNode in node.constructors) {
val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor)
}
}
// initialize classes
classes.forEachIndexed { index, clazz ->
clazz?.initialize(allConstructorsByTargets[index])
}
// build class members:
val classMemberScopes = classes.map { it?.unsubstitutedMemberScope }
for (propertyNode in node.properties) {
classMemberScopes += propertyNode.accept(this, classes)
}
for (functionNode in node.functions) {
classMemberScopes += functionNode.accept(this, classes)
}
for (classNode in node.classes) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val containingDeclarations = data.asListContaining<CommonizedClassDescriptor>()
val constructorsGroup = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(components, constructorsGroup, containingDeclarations)
return constructorsGroup.toList()
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
}
@@ -9,35 +9,37 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.name.FqName
internal fun CirClassNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass = common()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY
target.forEachIndexed { index, clazz ->
clazz?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsActual)
clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
commonClass?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = true)
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true)
}
internal fun CirClass.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<in ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager,
fqName: FqName,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for class $this")
val classDescriptor = CommonizedClassDescriptor(
storageManager = storageManager,
targetComponents = targetComponents,
containingDeclaration = containingDeclaration,
annotations = annotations,
name = name,
@@ -51,36 +53,41 @@ internal fun CirClass.buildDescriptor(
isExternal = isExternal,
isExpect = isExpect,
isActual = isActual,
cirDeclaredTypeParameters = typeParameters,
companionObjectName = companion?.shortName(),
supertypes = supertypes
cirSupertypes = supertypes
)
classDescriptor.declaredTypeParameters = typeParameters.buildDescriptors(classDescriptor)
// cache created class descriptor:
components.cache.cache(fqName, index, classDescriptor)
output[index] = classDescriptor
}
internal fun CirClassConstructorNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
containingDeclarations: List<ClassDescriptor?>
containingDeclarations: List<CommonizedClassDescriptor?>
) {
val commonConstructor = common()
val markAsActual = commonConstructor != null
target.forEachIndexed { index, constructor ->
constructor?.buildDescriptor(output, index, containingDeclarations, isActual = markAsActual)
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual)
}
commonConstructor?.buildDescriptor(output, indexOfCommon, containingDeclarations, isExpect = true)
commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true)
}
private fun CirClassConstructor.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
index: Int,
containingDeclarations: List<ClassDescriptor?>,
containingDeclarations: List<CommonizedClassDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for constructor $this")
val constructorDescriptor = CommonizedClassConstructorDescriptor(
@@ -96,10 +103,18 @@ private fun CirClassConstructor.buildDescriptor(
constructorDescriptor.setHasStableParameterNames(hasStableParameterNames)
constructorDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames)
val classTypeParameters = containingDeclaration.declaredTypeParameters
val (constructorTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents = targetComponents,
parentTypeParameterResolver = containingDeclaration.typeParameterResolver,
containingDeclaration = constructorDescriptor,
typeParametersIndexOffset = classTypeParameters.size
)
constructorDescriptor.initialize(
valueParameters.buildDescriptors(constructorDescriptor),
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, constructorDescriptor),
visibility,
typeParameters.buildDescriptors(constructorDescriptor)
classTypeParameters + constructorTypeParameters
)
output[index] = constructorDescriptor
@@ -0,0 +1,141 @@
/*
* Copyright 2010-2019 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.builder
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.StorageManager
/**
* Temporary caches for constructed descriptors.
*/
class DeclarationsBuilderCache(dimension: Int) {
init {
check(dimension > 0)
}
private val packageFragments = CommonizedGroupMap<FqName, CommonizedPackageFragmentDescriptor>(dimension)
private val classes = CommonizedGroupMap<FqName, CommonizedClassDescriptor>(dimension)
private val typeAliases = CommonizedGroupMap<FqName, CommonizedTypeAliasDescriptor>(dimension)
private val modules = CommonizedGroup<Collection<ModuleDescriptor>>(dimension)
fun getCachedPackageFragments(fqName: FqName): List<CommonizedPackageFragmentDescriptor?> = packageFragments.getOrFail(fqName)
fun getCachedClasses(fqName: FqName): List<CommonizedClassDescriptor?> = classes.getOrFail(fqName)
private inline fun <reified T : DeclarationDescriptor> CommonizedGroupMap<FqName, T>.getOrFail(fqName: FqName): List<T?> =
getOrNull(fqName)?.toList() ?: error("No cached ${T::class.java} with FQ name $fqName found")
fun cache(fqName: FqName, index: Int, descriptor: CommonizedPackageFragmentDescriptor) {
packageFragments[fqName][index] = descriptor
}
fun cache(fqName: FqName, index: Int, descriptor: CommonizedClassDescriptor) {
classes[fqName][index] = descriptor
}
fun cache(fqName: FqName, index: Int, descriptor: CommonizedTypeAliasDescriptor) {
typeAliases[fqName][index] = descriptor
}
fun cache(index: Int, modules: Collection<ModuleDescriptor>) {
this.modules[index] = modules
}
fun getCachedClassifier(fqName: FqName, index: Int): ClassifierDescriptorWithTypeParameters? =
classes.getOrNull(fqName)?.get(index) ?: typeAliases.getOrNull(fqName)?.get(index)
fun getCachedModules(index: Int): Collection<ModuleDescriptor> = modules[index] ?: error("No module descriptors found for index $index")
}
class GlobalDeclarationsBuilderComponents(
val storageManager: StorageManager,
val targetComponents: List<TargetDeclarationsBuilderComponents>,
val cache: DeclarationsBuilderCache
) {
init {
check(targetComponents.size > 1)
targetComponents.forEachIndexed { index, targetComponent -> check(index == targetComponent.index) }
}
}
class TargetDeclarationsBuilderComponents(
val storageManager: StorageManager,
val target: Target,
val builtIns: KotlinBuiltIns,
val isCommon: Boolean,
val index: Int,
private val cache: DeclarationsBuilderCache
) {
// only for classes and type aliases
fun getCachedClassifier(fqName: FqName): ClassifierDescriptorWithTypeParameters? = cache.getCachedClassifier(fqName, index)
}
fun CirRootNode.createGlobalBuilderComponents(storageManager: StorageManager): GlobalDeclarationsBuilderComponents {
val cache = DeclarationsBuilderCache(dimension)
val targetContexts = (0 until dimension).map { index ->
val isCommon = index == indexOfCommon
val target = (if (isCommon) common()!! else target[index]).target
val builtIns = modules.asSequence()
.mapNotNull { if (isCommon) it.common() else it.target[index] }
.first()
.builtIns
TargetDeclarationsBuilderComponents(
storageManager = storageManager,
target = target,
builtIns = builtIns,
isCommon = isCommon,
index = index,
cache = cache
)
}
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache)
}
interface TypeParameterResolver {
fun resolve(name: Name): TypeParameterDescriptor?
companion object {
val EMPTY = object : TypeParameterResolver {
override fun resolve(name: Name): TypeParameterDescriptor? = null
}
}
}
class TypeParameterResolverImpl(
storageManager: StorageManager,
ownTypeParameters: List<TypeParameterDescriptor>,
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
) : TypeParameterResolver {
private val ownTypeParameters = storageManager.createLazyValue {
// memoize the first occurrence of descriptor with the same Name
ownTypeParameters.groupingBy { it.name }.reduce { _, accumulator, _ -> accumulator }
}
override fun resolve(name: Name) = ownTypeParameters()[name] ?: parent.resolve(name)
}
fun DeclarationDescriptor.getTypeParameterResolver(): TypeParameterResolver =
when (this) {
is CommonizedClassDescriptor -> typeParameterResolver
is ClassDescriptor -> {
// all class descriptors must be instances of CommonizedClassDescriptor, and therefore must implement ContainerWithTypeParameterResolver
error("Class descriptor that is not instance of ${CommonizedClassDescriptor::class.java}: ${this::class.java}, $this")
}
else -> TypeParameterResolver.EMPTY
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
internal fun CirFunctionNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
@@ -23,19 +24,21 @@ internal fun CirFunctionNode.buildDescriptors(
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, function ->
function?.buildDescriptor(output, index, containingDeclarations, isActual = markAsExpectAndActual)
function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonFunction?.buildDescriptor(output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
}
private fun CirFunction.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for function $this")
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
@@ -59,12 +62,18 @@ private fun CirFunction.buildDescriptor(
functionDescriptor.setHasStableParameterNames(hasStableParameterNames)
functionDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
functionDescriptor
)
functionDescriptor.initialize(
extensionReceiver?.buildExtensionReceiver(functionDescriptor),
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, functionDescriptor),
buildDispatchReceiver(functionDescriptor),
typeParameters.buildDescriptors(functionDescriptor),
valueParameters.buildDescriptors(functionDescriptor),
returnType,
typeParameters,
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, functionDescriptor),
returnType.buildType(targetComponents, typeParameterResolver),
modality,
visibility
)
@@ -10,27 +10,26 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.storage.StorageManager
internal fun CirModuleNode.buildDescriptors(
output: CommonizedGroup<ModuleDescriptorImpl>,
storageManager: StorageManager
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>
) {
target.forEachIndexed { index, module ->
module?.buildDescriptor(output, index, storageManager)
module?.buildDescriptor(components, output, index)
}
common()?.buildDescriptor(output, indexOfCommon, storageManager)
common()?.buildDescriptor(components, output, indexOfCommon)
}
private fun CirModule.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>,
index: Int,
storageManager: StorageManager
index: Int
) {
val moduleDescriptor = ModuleDescriptorImpl(
moduleName = name,
storageManager = storageManager,
storageManager = components.storageManager,
builtIns = builtIns,
capabilities = emptyMap() // TODO: preserve capabilities from the original module descriptors, KT-33998
)
@@ -13,38 +13,44 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.MemberScope
internal fun CirPackageNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?>
) {
target.forEachIndexed { index, pkg ->
pkg?.buildDescriptor(output, index, modules)
pkg?.buildDescriptor(components, output, index, modules)
}
common()?.buildDescriptor(output, indexOfCommon, modules)
common()?.buildDescriptor(components, output, indexOfCommon, modules)
}
private fun CirPackage.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
index: Int,
modules: List<ModuleDescriptorImpl?>
) {
val module = modules[index] ?: error("No containing declaration for package $this")
val packageFragment = CommonizedPackageFragmentDescriptor(module, fqName)
// cache created package fragment descriptor:
components.cache.cache(fqName, index, packageFragment)
output[index] = packageFragment
}
internal class CommonizedPackageFragmentDescriptor(
class CommonizedPackageFragmentDescriptor(
module: ModuleDescriptor,
fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private lateinit var memberScope: MemberScope
private lateinit var memberScope: CommonizedMemberScope
fun initialize(memberScope: MemberScope) {
fun initialize(memberScope: CommonizedMemberScope) {
this.memberScope = memberScope
}
override fun getMemberScope() = memberScope
override fun getMemberScope(): CommonizedMemberScope = memberScope
}
@@ -16,31 +16,31 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.storage.StorageManager
internal fun CirPropertyNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonProperty = common()
val markAsExpectAndActual = commonProperty != null && commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, property ->
property?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsExpectAndActual)
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonProperty?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = markAsExpectAndActual)
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
}
private fun CirProperty.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for property $this")
val propertyDescriptor = PropertyDescriptorImpl.create(
@@ -60,11 +60,17 @@ private fun CirProperty.buildDescriptor(
isDelegate
)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
propertyDescriptor
)
propertyDescriptor.setType(
returnType,
typeParameters.buildDescriptors(propertyDescriptor),
returnType.buildType(targetComponents, typeParameterResolver),
typeParameters,
buildDispatchReceiver(propertyDescriptor),
extensionReceiver?.buildExtensionReceiver(propertyDescriptor)
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, propertyDescriptor)
)
val getterDescriptor = getter?.let { getter ->
@@ -103,7 +109,7 @@ private fun CirProperty.buildDescriptor(
)
compileTimeInitializer?.let { constantValue ->
propertyDescriptor.setCompileTimeInitializer(storageManager.createNullableLazyValue { constantValue })
propertyDescriptor.setCompileTimeInitializer(targetComponents.storageManager.createNullableLazyValue { constantValue })
}
output[index] = propertyDescriptor
@@ -12,30 +12,33 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.name.FqName
internal fun CirTypeAliasNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass: CirClass? = common()
val markAsActual = commonClass != null
target.forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsActual)
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
commonClass?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = true)
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true)
}
private fun CirTypeAlias.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
storageManager: StorageManager,
fqName: FqName,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val storageManager = targetComponents.storageManager
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for type alias $this")
val typeAliasDescriptor = CommonizedTypeAliasDescriptor(
@@ -47,11 +50,20 @@ private fun CirTypeAlias.buildDescriptor(
isActual = isActual
)
typeAliasDescriptor.initialize(
declaredTypeParameters = typeParameters.buildDescriptors(typeAliasDescriptor),
underlyingType = underlyingType,
expandedType = expandedType
val (declaredTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
TypeParameterResolver.EMPTY,
typeAliasDescriptor
)
typeAliasDescriptor.initialize(
declaredTypeParameters = declaredTypeParameters,
underlyingType = storageManager.createLazyValue { underlyingType.buildType(targetComponents, typeParameterResolver) },
expandedType = storageManager.createLazyValue { expandedType.buildType(targetComponents, typeParameterResolver) }
)
// cache created type alias descriptor:
components.cache.cache(fqName, index, typeAliasDescriptor)
output[index] = typeAliasDescriptor
}
@@ -6,60 +6,157 @@
package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.Companion.areCompatible
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.KotlinTypeFactory.flexibleType
import org.jetbrains.kotlin.types.KotlinTypeFactory.simpleType
import org.jetbrains.kotlin.utils.addToStdlib.cast
internal fun List<CirTypeParameter>.buildDescriptors(
containingDeclaration: DeclarationDescriptor
): List<TypeParameterDescriptor> {
return mapIndexed { index, param ->
val descriptor = TypeParameterDescriptorImpl.createForFurtherModification(
containingDeclaration,
param.annotations,
param.isReified,
param.variance,
param.name,
index,
SourceElement.NO_SOURCE
internal fun List<CirTypeParameter>.buildDescriptorsAndTypeParameterResolver(
targetComponents: TargetDeclarationsBuilderComponents,
parentTypeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
typeParametersIndexOffset: Int = 0
): Pair<List<TypeParameterDescriptor>, TypeParameterResolver> {
val ownTypeParameters = mutableListOf<TypeParameterDescriptor>()
val typeParameterResolver = TypeParameterResolverImpl(
storageManager = targetComponents.storageManager,
ownTypeParameters = ownTypeParameters,
parent = parentTypeParameterResolver
)
forEachIndexed { index, param ->
ownTypeParameters += CommonizedTypeParameterDescriptor(
targetComponents = targetComponents,
typeParameterResolver = typeParameterResolver,
containingDeclaration = containingDeclaration,
annotations = param.annotations,
name = param.name,
variance = param.variance,
isReified = param.isReified,
index = typeParametersIndexOffset + index,
cirUpperBounds = param.upperBounds
)
param.upperBounds.forEach(descriptor::addUpperBound)
descriptor.setInitialized()
descriptor
}
return ownTypeParameters to typeParameterResolver
}
internal fun List<CirValueParameter>.buildDescriptors(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
) = mapIndexed { index, param ->
): List<ValueParameterDescriptor> = mapIndexed { index, param ->
ValueParameterDescriptorImpl(
containingDeclaration,
null,
index,
param.annotations,
param.name,
param.returnType,
param.returnType.buildType(targetComponents, typeParameterResolver),
param.declaresDefaultValue,
param.isCrossinline,
param.isNoinline,
param.varargElementType,
param.varargElementType?.buildType(targetComponents, typeParameterResolver),
SourceElement.NO_SOURCE
)
}
internal fun CirExtensionReceiver.buildExtensionReceiver(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
) = DescriptorFactory.createExtensionReceiverParameterForCallable(
containingDeclaration,
type,
type.buildType(targetComponents, typeParameterResolver),
annotations
)
internal fun buildDispatchReceiver(callableDescriptor: CallableDescriptor) =
DescriptorUtils.getDispatchReceiverParameterIfNeeded(callableDescriptor.containingDeclaration)
internal fun CirType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): UnwrappedType = when (this) {
is CirSimpleType -> buildType(targetComponents, typeParameterResolver)
is CirFlexibleType -> flexibleType(
lowerBound = lowerBound.buildType(targetComponents, typeParameterResolver),
upperBound = upperBound.buildType(targetComponents, typeParameterResolver)
)
}
internal fun CirSimpleType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): SimpleType {
val classifier: ClassifierDescriptor = when (kind) {
CirSimpleTypeKind.TYPE_PARAMETER -> {
typeParameterResolver.resolve(fqName.shortName())
?: error("Type parameter $fqName not found in ${typeParameterResolver::class.java}, $typeParameterResolver")
}
CirSimpleTypeKind.CLASS, CirSimpleTypeKind.TYPE_ALIAS -> {
if (fqName.isUnderStandardKotlinPackages) {
// look up for classifier in built-ins module:
val builtInsModule = targetComponents.builtIns.builtInsModule
// TODO: this works fine for Native as far as built-ins module contains full Native stdlib, but this is not enough for JVM and JS
builtInsModule.getPackage(fqName.parent())
.memberScope
.getContributedClassifier(fqName.shortName(), NoLookupLocation.FOR_ALREADY_TRACKED)
?.cast<ClassifierDescriptorWithTypeParameters>()
?.also { checkClassifier(it, kind, true) }
?: error("Classifier $fqName not found in built-ins module $builtInsModule")
} else {
// otherwise, look up in created descriptors cache:
targetComponents.getCachedClassifier(fqName)
?.also { checkClassifier(it, kind, !targetComponents.isCommon) }
?: error("Classifier $fqName not found in created descriptors cache")
}
}
}
val rawType = simpleType(
annotations = Annotations.EMPTY, // TODO: support annotations
constructor = classifier.typeConstructor,
arguments = arguments.map { it.buildArgument(targetComponents, typeParameterResolver) },
nullable = isMarkedNullable,
kotlinTypeRefiner = null
)
return if (isDefinitelyNotNullType) rawType.makeSimpleTypeDefinitelyNotNullOrNotNull() else rawType
}
private fun checkClassifier(classifier: ClassifierDescriptor, kindInCir: CirSimpleTypeKind, strict: Boolean) {
val classifierKind = CirSimpleTypeKind.determineKind(classifier)
if (strict) {
check(kindInCir == classifierKind) {
"Mismatched classifier kinds.\nFound: $classifierKind, ${classifier::class.java}, $classifier\nShould be: $kindInCir"
}
} else {
check(areCompatible(classifierKind, kindInCir)) {
"Incompatible classifier kinds.\nExpect: $classifierKind, ${classifier::class.java}, $classifier\nActual: $kindInCir"
}
}
}
private fun CirTypeProjection.buildArgument(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): TypeProjection =
if (isStarProjection) {
StarProjectionForAbsentTypeParameter(targetComponents.builtIns)
} else {
TypeProjectionImpl(projectionKind, type.buildType(targetComponents, typeParameterResolver))
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.descriptors.commonizer
/** Fixed-size ordered collection that represents a commonized group of same-rank elements */
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
internal class CommonizedGroup<T : Any>(
val size: Int,
initialize: (Int) -> T?
@@ -42,6 +42,7 @@ internal class CommonizedGroupMap<K, V : Any>(val size: Int) : Iterable<Map.Entr
private val wrapped: MutableMap<K, CommonizedGroup<V>> = HashMap()
operator fun get(key: K): CommonizedGroup<V> = wrapped.getOrPut(key) { CommonizedGroup(size) }
fun getOrNull(key: K): CommonizedGroup<V>? = wrapped[key]
override fun iterator(): Iterator<Map.Entry<K, CommonizedGroup<V>>> = wrapped.iterator()
}
@@ -5,16 +5,15 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
/**
* Unlike [Commonizer] which commonizes only single elements, this [AbstractListCommonizer] commonizes lists of elements using
* [Commonizer]s produced by [singleElementCommonizerFactory].
*
* Example:
* Input: N lists of [KotlinType]
* Output: list of [UnwrappedType]
* Input: N lists of [CirType]
* Output: list of [CirType]
*/
abstract class AbstractListCommonizer<T, R>(
private val singleElementCommonizerFactory: () -> Commonizer<T, R>
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.types.KotlinType
import java.lang.IllegalStateException
internal class CommonizationVisitor(
private val root: CirRootNode
@@ -83,7 +80,7 @@ internal class CommonizationVisitor(
val companionObjectFqName = node.target.mapTo(HashSet()) { it!!.companion }.singleOrNull()
if (companionObjectFqName != null) {
val companionObjectNode = root.cache.classes[companionObjectFqName]
?: throw IllegalStateException("Can't find companion object with FQ name $companionObjectFqName")
?: error("Can't find companion object with FQ name $companionObjectFqName")
if (companionObjectNode.common() != null) {
// companion object has been successfully commonized
@@ -92,7 +89,7 @@ internal class CommonizationVisitor(
}
// find out common (and commonized) supertypes
val supertypesMap = CommonizedGroupMap<String, KotlinType>(node.target.size)
val supertypesMap = CommonizedGroupMap<String, CirType>(node.target.size)
node.target.forEachIndexed { index, clazz ->
for (supertype in clazz!!.supertypes) {
supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations
interface ExtensionReceiverCommonizer : Commonizer<CirExtensionReceiver?, UnwrappedType?> {
interface ExtensionReceiverCommonizer : Commonizer<CirExtensionReceiver?, CirExtensionReceiver?> {
companion object {
fun default(cache: CirClassifiersCache): ExtensionReceiverCommonizer = DefaultExtensionReceiverCommonizer(cache)
}
@@ -18,8 +18,8 @@ interface ExtensionReceiverCommonizer : Commonizer<CirExtensionReceiver?, Unwrap
private class DefaultExtensionReceiverCommonizer(cache: CirClassifiersCache) :
ExtensionReceiverCommonizer,
AbstractNullableCommonizer<CirExtensionReceiver, UnwrappedType, KotlinType, UnwrappedType>(
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
wrappedCommonizerFactory = { TypeCommonizer.default(cache) },
extractor = { it.type },
builder = { it }
builder = { it.toReceiverNoAnnotations() }
)
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunction
class FunctionCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirFunction>(cache) {
@@ -20,7 +19,7 @@ class FunctionCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
name = name,
modality = modality.result,
visibility = visibility.result,
extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(),
extensionReceiver = extensionReceiver.result,
returnType = returnType.result,
kind = kind,
modifiers = modifiers.result,
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirProperty
class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirProperty>(cache) {
@@ -19,7 +18,7 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert
modality = modality.result,
visibility = visibility.result,
isExternal = isExternal,
extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(),
extensionReceiver = extensionReceiver.result,
returnType = returnType.result,
kind = kind,
setter = setter.result,
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.checker.isClassType
class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeAlias, CirClass>() {
private lateinit var name: Name
@@ -34,7 +33,7 @@ class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommoniz
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.isClassType // right-hand side could have only class
&& next.underlyingType.kind == CirSimpleTypeKind.CLASS // right-hand side could have only class
&& underlyingType.commonizeWith(next.underlyingType)
&& visibility.commonizeWith(next)
}
@@ -5,14 +5,11 @@
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirNode
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
interface TypeCommonizer : Commonizer<KotlinType, UnwrappedType> {
interface TypeCommonizer : Commonizer<CirType, CirType> {
companion object {
fun default(cache: CirClassifiersCache): TypeCommonizer = DefaultTypeCommonizer(cache)
}
@@ -20,45 +17,32 @@ interface TypeCommonizer : Commonizer<KotlinType, UnwrappedType> {
private class DefaultTypeCommonizer(private val cache: CirClassifiersCache) :
TypeCommonizer,
AbstractStandardCommonizer<KotlinType, UnwrappedType>() {
AbstractStandardCommonizer<CirType, CirType>() {
private lateinit var temp: UnwrappedType
private lateinit var temp: CirType
override fun commonizationResult() = temp
override fun initialize(first: KotlinType) {
temp = first.unwrap()
override fun initialize(first: CirType) {
temp = first
}
override fun doCommonizeWith(next: KotlinType) = areTypesEqual(cache, temp, next.unwrap())
override fun doCommonizeWith(next: CirType) = areTypesEqual(cache, temp, next)
}
/**
* See also [AbstractStrictEqualityTypeChecker].
*/
internal fun areTypesEqual(cache: CirClassifiersCache, a: UnwrappedType, b: UnwrappedType): Boolean = when {
internal fun areTypesEqual(cache: CirClassifiersCache, a: CirType, b: CirType): Boolean = when {
a === b -> true
a is SimpleType -> (b is SimpleType) && areSimpleTypesEqual(cache, a, b)
a is FlexibleType -> (b is FlexibleType)
&& areSimpleTypesEqual(cache, a.lowerBound, b.lowerBound) && areSimpleTypesEqual(cache, a.upperBound, b.upperBound)
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 fun areSimpleTypesEqual(cache: CirClassifiersCache, a: SimpleType, b: SimpleType): Boolean = areAbbreviatedTypesEqual(
cache,
a = a.getAbbreviation() ?: a,
aExpanded = a,
b = b.getAbbreviation() ?: b,
bExpandedType = b
)
private fun areAbbreviatedTypesEqual(
cache: CirClassifiersCache,
a: SimpleType,
aExpanded: SimpleType,
b: SimpleType,
bExpandedType: SimpleType
): Boolean {
private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: CirSimpleType, b: CirSimpleType): Boolean {
if (a.arguments.size != b.arguments.size
|| a.isMarkedNullable != b.isMarkedNullable
|| a.isDefinitelyNotNullType != b.isDefinitelyNotNullType
@@ -66,41 +50,32 @@ private fun areAbbreviatedTypesEqual(
return false
}
val aDescriptor = requireNotNull(a.constructor.declarationDescriptor, a::nonNullDescriptorExpectedErrorMessage)
val bDescriptor = requireNotNull(b.constructor.declarationDescriptor, b::nonNullDescriptorExpectedErrorMessage)
val aFqName = aDescriptor.fqNameSafe
val bFqName = bDescriptor.fqNameSafe
if (aFqName != bFqName)
if (a.fqName != b.fqName)
return false
val isClassOrTypeAliasUnderStandardKotlinPackages =
fun isClassOrTypeAliasUnderStandardKotlinPackages() =
// N.B. only for descriptors that represent classes or type aliases, but not type parameters!
aDescriptor is ClassifierDescriptorWithTypeParameters
&& bDescriptor is ClassifierDescriptorWithTypeParameters
&& aFqName.isUnderStandardKotlinPackages
a.isClassOrTypeAlias && b.isClassOrTypeAlias
&& a.fqName.isUnderStandardKotlinPackages
// If classes are from the standard Kotlin packages, compare them only by type constructors.
// Effectively, this includes 1) comparison of FQ names and 2) number of type constructor parameters.
// Effectively, this includes comparison of 1) FQ names of underlying descriptors and 2) number of type constructor parameters.
// See org.jetbrains.kotlin.types.AbstractClassTypeConstructor.equals() for details.
&& aExpanded.constructor == bExpandedType.constructor
&& a.expandedTypeConstructorId == b.expandedTypeConstructorId
fun descriptorsCanBeCommonizedThemselves() =
a.kind == b.kind && when (a.kind) {
CirSimpleTypeKind.CLASS -> cache.classes[a.fqName].canBeCommonized()
CirSimpleTypeKind.TYPE_ALIAS -> cache.typeAliases[a.fqName].canBeCommonized()
CirSimpleTypeKind.TYPE_PARAMETER -> {
// 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
}
}
val descriptorsCanBeCommonized =
/* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages
|| /* or descriptors themselves can be commonized */ when (aDescriptor) {
is TypeParameterDescriptor -> {
// Real type parameter commonization is performed in TypeParameterCommonizer.
// Here it is enough to check that FQ names are equal (already done above).
bDescriptor is TypeParameterDescriptor
}
is ClassDescriptor -> {
(bDescriptor is ClassDescriptor) && cache.classes[aFqName].canBeCommonized()
}
is TypeAliasDescriptor -> {
(bDescriptor is TypeAliasDescriptor) && cache.typeAliases[aFqName].canBeCommonized()
}
else -> false
}
/* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages()
|| /* or descriptors themselves can be commonized */ descriptorsCanBeCommonizedThemselves()
if (!descriptorsCanBeCommonized)
return false
@@ -117,7 +92,7 @@ private fun areAbbreviatedTypesEqual(
if (aArg.projectionKind != bArg.projectionKind)
return false
if (!areTypesEqual(cache, aArg.type.unwrap(), bArg.type.unwrap()))
if (!areTypesEqual(cache, aArg.type, bArg.type))
return false
}
}
@@ -125,10 +100,6 @@ private fun areAbbreviatedTypesEqual(
return true
}
@Suppress("NOTHING_TO_INLINE")
private inline fun SimpleType.nonNullDescriptorExpectedErrorMessage() =
"${TypeCommonizer::class} couldn't obtain non-null descriptor from: $this, ${this::class}"
@Suppress("NOTHING_TO_INLINE")
private inline fun CirNode<*, *>?.canBeCommonized() =
if (this == null) {
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
interface TypeParameterCommonizer : Commonizer<CirTypeParameter, CirTypeParameter> {
@@ -48,7 +47,7 @@ private class DefaultTypeParameterCommonizer(cache: CirClassifiersCache) :
&& upperBounds.commonizeWith(next.upperBounds)
}
private class TypeParameterUpperBoundsCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer<KotlinType, UnwrappedType>(
private class TypeParameterUpperBoundsCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer<CirType, CirType>(
singleElementCommonizerFactory = { TypeCommonizer.default(cache) }
)
@@ -9,8 +9,8 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonValueP
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.isNull
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
interface ValueParameterCommonizer : Commonizer<CirValueParameter, CirValueParameter> {
companion object {
@@ -24,7 +24,7 @@ private class DefaultValueParameterCommonizer(cache: CirClassifiersCache) :
private lateinit var name: Name
private val returnType = TypeCommonizer.default(cache)
private var varargElementType: UnwrappedType? = null
private var varargElementType: CirType? = null
private var isCrossinline = true
private var isNoinline = true
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor
import org.jetbrains.kotlin.descriptors.commonizer.builder.*
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.mergeRoots
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -63,21 +65,26 @@ fun runCommonization(parameters: CommonizationParameters): CommonizationResult {
if (!parameters.hasIntersection())
return NothingToCommonize
// build merged tree:
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
// build merged tree:
val mergedTree = mergeRoots(storageManager, parameters.getModulesByTargets())
// commonize:
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
val modulesByTargets = LinkedHashMap<Target, Collection<ModuleDescriptor>>() // use linked hash map to preserve order
// build resulting descriptors:
val visitor = DeclarationsBuilderVisitor(storageManager) { target, commonizedModules ->
val components = mergedTree.createGlobalBuilderComponents(storageManager)
mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList())
mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList())
val modulesByTargets = LinkedHashMap<Target, Collection<ModuleDescriptor>>() // use linked hash map to preserve order
components.targetComponents.forEach {
val target = it.target
check(target !in modulesByTargets)
modulesByTargets[target] = commonizedModules
modulesByTargets[target] = components.cache.getCachedModules(it.index)
}
mergedTree.accept(visitor, DeclarationsBuilderVisitor.noContainingDeclarations())
return CommonizationPerformed(modulesByTargets)
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirClass : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality {
@@ -21,7 +20,7 @@ interface CirClass : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclaratio
val isInline: Boolean
val isInner: Boolean
val isExternal: Boolean
val supertypes: Collection<KotlinType>
val supertypes: Collection<CirType>
}
interface CirClassConstructor : CirAnnotatedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirMaybeCallableMemberOfClass, CirCallableMemberWithParameters {
@@ -46,7 +45,7 @@ data class CirCommonClass(
override val isData get() = false
override val isExternal get() = false
override var companion: FqName? = null
override val supertypes: MutableCollection<KotlinType> = ArrayList()
override val supertypes: MutableCollection<CirType> = ArrayList()
}
data class CirCommonClassConstructor(
@@ -58,10 +57,10 @@ data class CirCommonClassConstructor(
override val hasStableParameterNames: Boolean,
override val hasSynthesizedParameterNames: Boolean
) : CirClassConstructor {
override val annotations: Annotations get() = Annotations.EMPTY
override val containingClassKind: ClassKind get() = unsupported()
override val containingClassModality: Modality get() = unsupported()
override val containingClassIsData: Boolean get() = unsupported()
override val annotations get() = Annotations.EMPTY
override val containingClassKind get() = unsupported()
override val containingClassModality get() = unsupported()
override val containingClassIsData get() = unsupported()
}
class CirWrappedClass(private val wrapped: ClassDescriptor) : CirClass {
@@ -77,35 +76,40 @@ class CirWrappedClass(private val wrapped: ClassDescriptor) : CirClass {
override val isInline get() = wrapped.isInline
override val isInner get() = wrapped.isInner
override val isExternal get() = wrapped.isExternal
override val supertypes: Collection<KotlinType> get() = wrapped.typeConstructor.supertypes
override val supertypes by lazy(PUBLICATION) { wrapped.typeConstructor.supertypes.map(CirType.Companion::create) }
}
class CirWrappedClassConstructor(private val wrapped: ClassConstructorDescriptor) : CirClassConstructor {
override val isPrimary: Boolean get() = wrapped.isPrimary
override val kind: CallableMemberDescriptor.Kind get() = wrapped.kind
override val containingClassKind: ClassKind get() = wrapped.containingDeclaration.kind
override val containingClassModality: Modality get() = wrapped.containingDeclaration.modality
override val containingClassIsData: Boolean get() = wrapped.containingDeclaration.isData
override val annotations: Annotations get() = wrapped.annotations
override val visibility: Visibility get() = wrapped.visibility
override val typeParameters: List<CirTypeParameter> by lazy(PUBLICATION) { wrapped.typeParameters.map(::CirWrappedTypeParameter) }
override val valueParameters: List<CirValueParameter> by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) }
override val hasStableParameterNames: Boolean get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames: Boolean get() = wrapped.hasSynthesizedParameterNames()
override val isPrimary get() = wrapped.isPrimary
override val kind get() = wrapped.kind
override val containingClassKind get() = wrapped.containingDeclaration.kind
override val containingClassModality get() = wrapped.containingDeclaration.modality
override val containingClassIsData get() = wrapped.containingDeclaration.isData
override val annotations get() = wrapped.annotations
override val visibility get() = wrapped.visibility
override val typeParameters by lazy(PUBLICATION) {
wrapped.typeParameters.mapNotNull { typeParameter ->
// save only type parameters that are contributed by the constructor itself
typeParameter.takeIf { it.containingDeclaration == wrapped }?.let(::CirWrappedTypeParameter)
}
}
override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) }
override val hasStableParameterNames get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames()
}
object CirClassRecursionMarker : CirClass, CirRecursionMarker {
override val companion: FqName? get() = unsupported()
override val kind: ClassKind get() = unsupported()
override val modality: Modality get() = unsupported()
override val isCompanion: Boolean get() = unsupported()
override val isData: Boolean get() = unsupported()
override val isInline: Boolean get() = unsupported()
override val isInner: Boolean get() = unsupported()
override val isExternal: Boolean get() = unsupported()
override val supertypes: Collection<KotlinType> get() = unsupported()
override val annotations: Annotations get() = unsupported()
override val name: Name get() = unsupported()
override val visibility: Visibility get() = unsupported()
override val typeParameters: List<CirTypeParameter> get() = unsupported()
override val companion get() = unsupported()
override val kind get() = unsupported()
override val modality get() = unsupported()
override val isCompanion get() = unsupported()
override val isData get() = unsupported()
override val isInline get() = unsupported()
override val isInner get() = unsupported()
override val isExternal get() = unsupported()
override val supertypes get() = unsupported()
override val annotations get() = unsupported()
override val name get() = unsupported()
override val visibility get() = unsupported()
override val typeParameters get() = unsupported()
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirFunctionModifiers {
@@ -33,7 +32,7 @@ data class CirCommonFunction(
override val modality: Modality,
override val visibility: Visibility,
override val extensionReceiver: CirExtensionReceiver?,
override val returnType: UnwrappedType,
override val returnType: CirType,
override val kind: CallableMemberDescriptor.Kind,
private val modifiers: CirFunctionModifiers,
override val valueParameters: List<CirValueParameter>,
@@ -49,15 +48,15 @@ class CirWrappedFunction(wrapped: SimpleFunctionDescriptor) : CirWrappedFunction
override val isTailrec get() = wrapped.isTailrec
override val isSuspend get() = wrapped.isSuspend
override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) }
override val hasStableParameterNames: Boolean get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames: Boolean get() = wrapped.hasSynthesizedParameterNames()
override val hasStableParameterNames get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames()
}
interface CirValueParameter {
val name: Name
val annotations: Annotations
val returnType: UnwrappedType
val varargElementType: UnwrappedType?
val returnType: CirType
val varargElementType: CirType?
val declaresDefaultValue: Boolean
val isCrossinline: Boolean
val isNoinline: Boolean
@@ -65,8 +64,8 @@ interface CirValueParameter {
data class CirCommonValueParameter(
override val name: Name,
override val returnType: UnwrappedType,
override val varargElementType: UnwrappedType?,
override val returnType: CirType,
override val varargElementType: CirType?,
override val isCrossinline: Boolean,
override val isNoinline: Boolean
) : CirValueParameter {
@@ -77,8 +76,8 @@ data class CirCommonValueParameter(
data class CirWrappedValueParameter(private val wrapped: ValueParameterDescriptor) : CirValueParameter {
override val name get() = wrapped.name
override val annotations get() = wrapped.annotations
override val returnType by lazy(PUBLICATION) { wrapped.returnType!!.unwrap() }
override val varargElementType by lazy(PUBLICATION) { wrapped.varargElementType?.unwrap() }
override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) }
override val varargElementType by lazy(PUBLICATION) { wrapped.varargElementType?.let(CirType.Companion::create) }
override val declaresDefaultValue get() = wrapped.declaresDefaultValue()
override val isCrossinline get() = wrapped.isCrossinline
override val isNoinline get() = wrapped.isNoinline
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiver
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.KotlinType
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirFunctionOrProperty : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality, CirMaybeCallableMemberOfClass {
val isExternal: Boolean
val extensionReceiver: CirExtensionReceiver?
val returnType: UnwrappedType
val returnType: CirType
val kind: CallableMemberDescriptor.Kind
}
@@ -32,7 +32,7 @@ abstract class CirWrappedFunctionOrProperty<T : CallableMemberDescriptor>(protec
final override val visibility get() = wrapped.visibility
final override val isExternal get() = wrapped.isExternal
final override val extensionReceiver by lazy(PUBLICATION) { wrapped.extensionReceiverParameter?.toReceiver() }
final override val returnType by lazy(PUBLICATION) { wrapped.returnType!!.unwrap() }
final override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) }
final override val kind get() = wrapped.kind
final override val containingClassKind: ClassKind? get() = containingClass?.kind
final override val containingClassModality: Modality? get() = containingClass?.modality
@@ -43,11 +43,11 @@ abstract class CirWrappedFunctionOrProperty<T : CallableMemberDescriptor>(protec
data class CirExtensionReceiver(
val annotations: Annotations,
val type: UnwrappedType
val type: CirType
) {
companion object {
fun UnwrappedType.toReceiverNoAnnotations() = CirExtensionReceiver(Annotations.EMPTY, this)
fun ReceiverParameterDescriptor.toReceiver() = CirExtensionReceiver(annotations, type.unwrap())
fun CirType.toReceiverNoAnnotations() = CirExtensionReceiver(Annotations.EMPTY, this)
fun ReceiverParameterDescriptor.toReceiver() = CirExtensionReceiver(annotations, CirType.create(type))
}
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirGetter.Companion.toGetter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSetter.Companion.toSetter
import org.jetbrains.kotlin.resolve.constants.ConstantValue
@@ -32,7 +31,7 @@ data class CirCommonProperty(
override val visibility: Visibility,
override val isExternal: Boolean,
override val extensionReceiver: CirExtensionReceiver?,
override val returnType: UnwrappedType,
override val returnType: CirType,
override val kind: CallableMemberDescriptor.Kind,
override val setter: CirSetter?,
override val typeParameters: List<CirTypeParameter>
@@ -0,0 +1,93 @@
/*
* Copyright 2010-2019 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.mergedtree.ir
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.declarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.fqName
import org.jetbrains.kotlin.descriptors.commonizer.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.CLASS
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.TYPE_ALIAS
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.*
import kotlin.LazyThreadSafetyMode.PUBLICATION
sealed class CirType {
companion object {
fun create(type: KotlinType): CirType = type.unwrap().run {
when (this) {
is SimpleType -> CirSimpleType(this)
is FlexibleType -> CirFlexibleType(CirSimpleType(lowerBound), CirSimpleType(upperBound))
}
}
}
}
/**
* All attributes except for [expandedTypeConstructorId] are read from the abbreviation type: [AbbreviatedType.abbreviation].
* And [expandedTypeConstructorId] is read from the expanded type: [AbbreviatedType.expandedType].
*
* 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.
*/
class CirSimpleType(private val wrapped: SimpleType) : CirType() {
val kind = CirSimpleTypeKind.determineKind(abbreviation.declarationDescriptor)
val fqName by lazy(PUBLICATION) { abbreviation.fqName }
val arguments by lazy(PUBLICATION) { abbreviation.arguments.map(::CirTypeProjection) }
val isMarkedNullable get() = abbreviation.isMarkedNullable
val isDefinitelyNotNullType get() = abbreviation.isDefinitelyNotNullType
val expandedTypeConstructorId by lazy(PUBLICATION) { CirTypeConstructorId(expanded) }
inline val isClassOrTypeAlias: Boolean get() = (kind == CLASS || kind == TYPE_ALIAS)
val fqNameWithTypeParameters: String get() = wrapped.fqNameWithTypeParameters
override fun equals(other: Any?) = wrapped == (other as? CirSimpleType)?.wrapped
override fun hashCode() = wrapped.hashCode()
private inline val abbreviation: SimpleType get() = (wrapped as? AbbreviatedType)?.abbreviation ?: wrapped
private inline val expanded: SimpleType get() = (wrapped as? AbbreviatedType)?.expandedType ?: wrapped
}
enum class CirSimpleTypeKind {
CLASS,
TYPE_ALIAS,
TYPE_PARAMETER;
companion object {
fun determineKind(classifier: ClassifierDescriptor) = when (classifier) {
is ClassDescriptor -> CLASS
is TypeAliasDescriptor -> TYPE_ALIAS
is TypeParameterDescriptor -> TYPE_PARAMETER
else -> error("Unexpected classifier descriptor type: ${classifier::class.java}, $classifier")
}
fun areCompatible(expect: CirSimpleTypeKind, actual: CirSimpleTypeKind) =
expect == actual || (expect == CLASS && actual == TYPE_ALIAS)
}
}
data class CirTypeConstructorId(val fqName: FqName, val numberOfTypeParameters: Int) {
constructor(type: SimpleType) : this(type.fqName, type.constructor.parameters.size)
}
class CirTypeProjection(private val wrapped: TypeProjection) {
val projectionKind get() = wrapped.projectionKind
val isStarProjection get() = wrapped.isStarProjection
val type by lazy(PUBLICATION) { CirType.create(wrapped.type) }
}
data class CirFlexibleType(val lowerBound: CirSimpleType, val upperBound: CirSimpleType) : CirType()
val CirType.fqNameWithTypeParameters: String
get() = when (this) {
is CirSimpleType -> fqNameWithTypeParameters
is CirFlexibleType -> lowerBound.fqNameWithTypeParameters
}
@@ -6,12 +6,11 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.types.SimpleType
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirTypeAlias : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility {
val underlyingType: SimpleType
val expandedType: SimpleType
val underlyingType: CirSimpleType
val expandedType: CirSimpleType
}
class CirWrappedTypeAlias(private val wrapped: TypeAliasDescriptor) : CirTypeAlias {
@@ -19,6 +18,6 @@ class CirWrappedTypeAlias(private val wrapped: TypeAliasDescriptor) : CirTypeAli
override val name get() = wrapped.name
override val typeParameters by lazy(PUBLICATION) { wrapped.declaredTypeParameters.map(::CirWrappedTypeParameter) }
override val visibility get() = wrapped.visibility
override val underlyingType get() = wrapped.underlyingType
override val expandedType get() = wrapped.expandedType
override val underlyingType by lazy(PUBLICATION) { CirSimpleType(wrapped.underlyingType) }
override val expandedType by lazy(PUBLICATION) { CirSimpleType(wrapped.expandedType) }
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
import kotlin.LazyThreadSafetyMode.PUBLICATION
@@ -17,14 +16,14 @@ interface CirTypeParameter {
val name: Name
val isReified: Boolean
val variance: Variance
val upperBounds: List<UnwrappedType>
val upperBounds: List<CirType>
}
data class CirCommonTypeParameter(
override val name: Name,
override val isReified: Boolean,
override val variance: Variance,
override val upperBounds: List<UnwrappedType>
override val upperBounds: List<CirType>
) : CirTypeParameter {
override val annotations get() = Annotations.EMPTY
}
@@ -34,5 +33,5 @@ data class CirWrappedTypeParameter(private val wrapped: TypeParameterDescriptor)
override val name get() = wrapped.name
override val isReified get() = wrapped.isReified
override val variance get() = wrapped.variance
override val upperBounds by lazy(PUBLICATION) { wrapped.upperBounds.map { it.unwrap() } }
override val upperBounds by lazy(PUBLICATION) { wrapped.upperBounds.map(CirType.Companion::create) }
}
@@ -50,7 +50,9 @@ internal fun buildPackageNode(
commonValueProducer = { CirPackage(packageFqName) },
recursionMarker = null,
nodeProducer = ::CirPackageNode
)
).also { node ->
node.fqName = packageFqName
}
internal fun buildPropertyNode(
storageManager: StorageManager,
@@ -85,21 +87,17 @@ internal fun buildClassNode(
cacheRW: ClassifiersCacheImpl,
containingDeclarationCommon: NullableLazyValue<*>?,
classes: List<ClassDescriptor?>
): CirClassNode {
val fqName = classes.firstNonNull().fqNameSafe
return buildNode(
storageManager = storageManager,
descriptors = classes,
targetDeclarationProducer = ::CirWrappedClass,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode
).also { node ->
): CirClassNode = buildNode(
storageManager = storageManager,
descriptors = classes,
targetDeclarationProducer = ::CirWrappedClass,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode
).also { node ->
classes.firstNonNull().fqNameSafe.let { fqName ->
node.fqName = fqName
cacheRW.classes.put(fqName, node)?.let { oldNode ->
throw IllegalStateException("Class node with FQ name $fqName has been overwritten: $oldNode")
}
cacheRW.classes.putSafe(fqName, node)
}
}
@@ -121,21 +119,17 @@ internal fun buildTypeAliasNode(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
typeAliases: List<TypeAliasDescriptor?>
): CirTypeAliasNode {
val fqName = typeAliases.firstNonNull().fqNameSafe
return buildNode(
storageManager = storageManager,
descriptors = typeAliases,
targetDeclarationProducer = ::CirWrappedTypeAlias,
commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirTypeAliasNode
).also { node ->
): CirTypeAliasNode = buildNode(
storageManager = storageManager,
descriptors = typeAliases,
targetDeclarationProducer = ::CirWrappedTypeAlias,
commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirTypeAliasNode
).also { node ->
typeAliases.firstNonNull().fqNameSafe.let { fqName ->
node.fqName = fqName
cacheRW.typeAliases.put(fqName, node)?.let { oldNode ->
throw IllegalStateException("Type alias node with FQ name $fqName has been overwritten: $oldNode")
}
cacheRW.typeAliases.putSafe(fqName, node)
}
}
@@ -173,6 +167,11 @@ private fun <D : Any, T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>>
return nodeProducer(declarations, commonLazyValue)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun <K, V : Any> MutableMap<K, V>.putSafe(key: K, value: V) = put(key, value)?.let { oldValue ->
error("${oldValue::class.java} with key=$key has been overwritten: $oldValue")
}
internal fun <T, R> commonize(declarations: List<T?>, commonizer: Commonizer<T, R>): R? {
for (declaration in declarations) {
if (declaration == null || !commonizer.commonizeWith(declaration))
@@ -15,6 +15,10 @@ interface CirNode<T : CirDeclaration, R : CirDeclaration> {
fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R
}
interface CirNodeWithFqName<T : CirDeclaration, R : CirDeclaration> : CirNode<T, R> {
val fqName: FqName
}
class CirRootNode(
override val target: List<CirRoot>,
override val common: NullableLazyValue<CirRoot>
@@ -29,6 +33,8 @@ class CirRootNode(
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitRootNode(this, data)
override fun toString() = toString(this)
}
class CirModuleNode(
@@ -39,12 +45,16 @@ class CirModuleNode(
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitModuleNode(this, data)
override fun toString() = toString(this)
}
class CirPackageNode(
override val target: List<CirPackage?>,
override val common: NullableLazyValue<CirPackage>
) : CirNode<CirPackage, CirPackage> {
) : CirNodeWithFqName<CirPackage, CirPackage> {
override lateinit var fqName: FqName
val properties: MutableList<CirPropertyNode> = ArrayList()
val functions: MutableList<CirFunctionNode> = ArrayList()
val classes: MutableList<CirClassNode> = ArrayList()
@@ -52,6 +62,8 @@ class CirPackageNode(
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPackageNode(this, data)
override fun toString() = toString(this)
}
class CirPropertyNode(
@@ -60,6 +72,8 @@ class CirPropertyNode(
) : CirNode<CirProperty, CirProperty> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPropertyNode(this, data)
override fun toString() = toString(this)
}
class CirFunctionNode(
@@ -68,13 +82,15 @@ class CirFunctionNode(
) : CirNode<CirFunction, CirFunction> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitFunctionNode(this, data)
override fun toString() = toString(this)
}
class CirClassNode(
override val target: List<CirClass?>,
override val common: NullableLazyValue<CirClass>
) : CirNode<CirClass, CirClass> {
lateinit var fqName: FqName
) : CirNodeWithFqName<CirClass, CirClass> {
override lateinit var fqName: FqName
val constructors: MutableList<CirClassConstructorNode> = ArrayList()
val properties: MutableList<CirPropertyNode> = ArrayList()
@@ -83,6 +99,8 @@ class CirClassNode(
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassNode(this, data)
override fun toString() = toString(this)
}
class CirClassConstructorNode(
@@ -91,16 +109,20 @@ class CirClassConstructorNode(
) : CirNode<CirClassConstructor, CirClassConstructor> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassConstructorNode(this, data)
override fun toString() = toString(this)
}
class CirTypeAliasNode(
override val target: List<CirTypeAlias?>,
override val common: NullableLazyValue<CirClass>
) : CirNode<CirTypeAlias, CirClass> {
lateinit var fqName: FqName
) : CirNodeWithFqName<CirTypeAlias, CirClass> {
override lateinit var fqName: FqName
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitTypeAliasNode(this, data)
override fun toString() = toString(this)
}
interface CirClassifiersCache {
@@ -113,3 +135,13 @@ internal inline val CirNode<*, *>.indexOfCommon: Int
internal inline val CirNode<*, *>.dimension: Int
get() = target.size + 1
private fun toString(node: CirNode<*, *>) = buildString {
if (node is CirNodeWithFqName) {
append("fqName=").append(node.fqName).append(", ")
}
append("target=")
node.target.joinTo(this)
append(", common=")
append(if (node.common.isComputed()) node.common() else "<NOT COMPUTED>")
}
@@ -15,7 +15,7 @@ internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescripto
getContributedDescriptors().forEach { member ->
collectors.any { it(member) }
// each member must be consumed, otherwise - error
|| throw IllegalStateException("Unhandled member declaration: $member")
|| error("Unhandled member declaration: $member")
}
@Suppress("FunctionName")
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -21,8 +22,11 @@ internal fun <T> Sequence<T>.toList(expectedCapacity: Int): List<T> {
internal inline fun <reified T> Iterable<T?>.firstNonNull() = firstIsInstance<T>()
internal val KotlinType.fqName: FqName
get() = (constructor.declarationDescriptor ?: throw IllegalStateException("No declaration descriptor found for $constructor")).fqNameSafe
internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor
get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor"))
internal inline val KotlinType.fqName: FqName
get() = declarationDescriptor.fqNameSafe
internal val KotlinType.fqNameWithTypeParameters: String
get() = buildString { buildFqNameWithTypeParameters(this@fqNameWithTypeParameters) }
@@ -124,3 +124,26 @@ expect class I<T : I<T>>() {
val property: T
fun function(value: T): T
}
expect interface J1<A> {
fun a(): A
}
expect interface J2<A, B> {
fun a(b: B): A
fun b(a: A): B
}
expect interface J3<A, B, C> {
fun a(b: B, c: C): A
fun b(a: A, c: C): B
fun c(a: A, b: B): C
}
expect class K<A, B : A, C : J1<B>, D : J2<C, A>>() : J3<D, C, B> {
override fun a(b: C, c: B): D
override fun b(a: D, c: B): C
override fun c(a: D, b: C): B
inner class Inner<C, D : C, E : J2<C, D>>() {
fun dependentFunction(value: A): E
fun <A : CharSequence, E : Number> independentFunction(value: A): E
}
}
@@ -634,3 +634,26 @@ actual class I<T : I<T>> actual constructor() {
actual val property: T get() = TODO()
actual fun function(value: T): T = value
}
actual interface J1<A> {
actual fun a(): A
}
actual interface J2<A, B> {
actual fun a(b: B): A
actual fun b(a: A): B
}
actual interface J3<A, B, C> {
actual fun a(b: B, c: C): A
actual fun b(a: A, c: C): B
actual fun c(a: A, b: B): C
}
actual class K<A, B : A, C : J1<B>, D : J2<C, A>> actual constructor() : J3<D, C, B> {
actual override fun a(b: C, c: B): D = TODO()
actual override fun b(a: D, c: B): C = TODO()
actual override fun c(a: D, b: C): B = TODO()
actual inner class Inner<C, D : C, E : J2<C, D>> actual constructor() {
actual fun dependentFunction(value: A): E = TODO()
actual fun <A : CharSequence, E : Number> independentFunction(value: A): E = TODO()
}
}
@@ -634,3 +634,26 @@ actual class I<T : I<T>> actual constructor() {
actual val property: T get() = TODO()
actual fun function(value: T): T = value
}
actual interface J1<A> {
actual fun a(): A
}
actual interface J2<A, B> {
actual fun a(b: B): A
actual fun b(a: A): B
}
actual interface J3<A, B, C> {
actual fun a(b: B, c: C): A
actual fun b(a: A, c: C): B
actual fun c(a: A, b: B): C
}
actual class K<A, B : A, C : J1<B>, D : J2<C, A>> actual constructor() : J3<D, C, B> {
actual override fun a(b: C, c: B): D = TODO()
actual override fun b(a: D, c: B): C = TODO()
actual override fun c(a: D, b: C): B = TODO()
actual inner class Inner<C, D : C, E : J2<C, D>> actual constructor() {
actual fun dependentFunction(value: A): E = TODO()
actual fun <A : CharSequence, E : Number> independentFunction(value: A): E = TODO()
}
}
@@ -634,3 +634,26 @@ class I<T : I<T>> {
val property: T get() = TODO()
fun function(value: T): T = value
}
interface J1<A> {
actual fun a(): A
}
interface J2<A, B> {
actual fun a(b: B): A
actual fun b(a: A): B
}
interface J3<A, B, C> {
actual fun a(b: B, c: C): A
actual fun b(a: A, c: C): B
actual fun c(a: A, b: B): C
}
class K<A, B : A, C : J1<B>, D : J2<C, A>> : J3<D, C, B> {
override fun a(b: C, c: B): D = TODO()
override fun b(a: D, c: B): C = TODO()
override fun c(a: D, b: C): B = TODO()
inner class Inner<C, D : C, E : J2<C, D>> {
fun dependentFunction(value: A): E = TODO()
fun <A : CharSequence, E : Number> independentFunction(value: A): E = TODO()
}
}
@@ -634,3 +634,26 @@ class I<T : I<T>> {
val property: T get() = TODO()
fun function(value: T): T = value
}
interface J1<A> {
actual fun a(): A
}
interface J2<A, B> {
actual fun a(b: B): A
actual fun b(a: A): B
}
interface J3<A, B, C> {
actual fun a(b: B, c: C): A
actual fun b(a: A, c: C): B
actual fun c(a: A, b: B): C
}
class K<A, B : A, C : J1<B>, D : J2<C, A>> : J3<D, C, B> {
override fun a(b: C, c: B): D = TODO()
override fun b(a: D, c: B): C = TODO()
override fun c(a: D, b: C): B = TODO()
inner class Inner<C, D : C, E : J2<C, D>> {
fun dependentFunction(value: A): E = TODO()
fun <A : CharSequence, E : Number> independentFunction(value: A): E = TODO()
}
}
@@ -20,7 +20,7 @@ abstract class AbstractCommonizerTest<T, R> {
protected open fun isEqual(a: R?, b: R?): Boolean = a == b
protected open fun doTestSuccess(expected: R, vararg variants: T) {
protected fun doTestSuccess(expected: R, vararg variants: T) {
check(variants.isNotEmpty())
val commonized = createCommonizer().apply {
@@ -34,7 +34,7 @@ abstract class AbstractCommonizerTest<T, R> {
}
// should fail on the last variant
protected open fun doTestFailure(vararg variants: T) {
protected fun doTestFailure(vararg variants: T) {
check(variants.isNotEmpty())
val commonized = createCommonizer().apply {
@@ -8,11 +8,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.utils.EMPTY_CLASSIFIERS_CACHE
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
import org.jetbrains.kotlin.types.UnwrappedType
import org.junit.Test
class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionReceiver?, UnwrappedType?>() {
class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensionReceiver?, CirExtensionReceiver?>() {
@Test
fun nullReceiver() = doTestSuccess(
@@ -24,7 +24,7 @@ class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensi
@Test
fun sameReceiver() = doTestSuccess(
mockClassType("kotlin.String").unwrap(),
mockExtensionReceiver("kotlin.String"),
mockExtensionReceiver("kotlin.String"),
mockExtensionReceiver("kotlin.String"),
mockExtensionReceiver("kotlin.String")
@@ -56,5 +56,5 @@ class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest<CirExtensi
private fun mockExtensionReceiver(typeFqName: String) = CirExtensionReceiver(
annotations = Annotations.EMPTY,
type = mockClassType(typeFqName).unwrap()
type = CirType.create(mockClassType(typeFqName))
)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
@@ -17,12 +18,11 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.getAbbreviation
import org.junit.Before
import org.junit.Test
class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedType>() {
class DefaultTypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
private lateinit var cache: ClassifiersCacheImpl
@@ -33,7 +33,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInKotlinPackageWithSameName() = doTestSuccess(
mockClassType("kotlin.collections.List").unwrap(),
mockClassType("kotlin.collections.List"),
mockClassType("kotlin.collections.List"),
mockClassType("kotlin.collections.List"),
mockClassType("kotlin.collections.List")
@@ -62,7 +62,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInKotlinxPackageWithSameName() = doTestSuccess(
mockClassType("kotlinx.cinterop.CPointer").unwrap(),
mockClassType("kotlinx.cinterop.CPointer"),
mockClassType("kotlinx.cinterop.CPointer"),
mockClassType("kotlinx.cinterop.CPointer"),
mockClassType("kotlinx.cinterop.CPointer")
@@ -91,7 +91,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInUserPackageWithSameName() = doTestSuccess(
mockClassType("org.sample.Foo").unwrap(),
mockClassType("org.sample.Foo"),
mockClassType("org.sample.Foo"),
mockClassType("org.sample.Foo"),
mockClassType("org.sample.Foo")
@@ -117,7 +117,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInKotlinPackageWithSameNullability1() = doTestSuccess(
mockClassType("kotlin.collections.List").unwrap(),
mockClassType("kotlin.collections.List"),
mockClassType("kotlin.collections.List", nullable = false),
mockClassType("kotlin.collections.List", nullable = false),
mockClassType("kotlin.collections.List", nullable = false)
@@ -125,7 +125,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInKotlinPackageWithSameNullability2() = doTestSuccess(
mockClassType("kotlin.collections.List", nullable = true).unwrap(),
mockClassType("kotlin.collections.List", nullable = true),
mockClassType("kotlin.collections.List", nullable = true),
mockClassType("kotlin.collections.List", nullable = true),
mockClassType("kotlin.collections.List", nullable = true)
@@ -147,7 +147,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInUserPackageWithSameNullability1() = doTestSuccess(
mockClassType("org.sample.Foo").unwrap(),
mockClassType("org.sample.Foo"),
mockClassType("org.sample.Foo", nullable = false),
mockClassType("org.sample.Foo", nullable = false),
mockClassType("org.sample.Foo", nullable = false)
@@ -155,7 +155,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun classTypesInUserPackageWithSameNullability2() = doTestSuccess(
mockClassType("org.sample.Foo", nullable = true).unwrap(),
mockClassType("org.sample.Foo", nullable = true),
mockClassType("org.sample.Foo", nullable = true),
mockClassType("org.sample.Foo", nullable = true),
mockClassType("org.sample.Foo", nullable = true)
@@ -177,7 +177,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinPackageWithSameNameAndClass() = doTestSuccess(
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") }.unwrap(),
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") }
@@ -199,7 +199,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinxPackageWithSameNameAndClass() = doTestSuccess(
mockTAType("kotlinx.cinterop.CArrayPointer") { mockClassType("kotlinx.cinterop.CPointer") }.unwrap(),
mockTAType("kotlinx.cinterop.CArrayPointer") { mockClassType("kotlinx.cinterop.CPointer") },
mockTAType("kotlinx.cinterop.CArrayPointer") { mockClassType("kotlinx.cinterop.CPointer") },
mockTAType("kotlinx.cinterop.CArrayPointer") { mockClassType("kotlinx.cinterop.CPointer") },
mockTAType("kotlinx.cinterop.CArrayPointer") { mockClassType("kotlinx.cinterop.CPointer") }
@@ -224,7 +224,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
// that's OK as long as the fully expanded right-hand side is the same class
mockTAType("kotlin.FictitiousTypeAlias") {
mockClassType("kotlin.FictitiousClass")
}.unwrap(),
},
mockTAType("kotlin.FictitiousTypeAlias") {
mockClassType("kotlin.FictitiousClass")
@@ -247,7 +247,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInUserPackageWithSameNameAndClass() = doTestSuccess(
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") }.unwrap(),
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") }
@@ -280,7 +280,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinPackageWithSameNullability1() = doTestSuccess(
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") }.unwrap(),
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = false) { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = false) { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = false) { mockClassType("kotlin.sequences.SequenceScope") }
@@ -288,7 +288,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinPackageWithSameNullability2() = doTestSuccess(
mockTAType("kotlin.sequences.SequenceBuilder", nullable = true) { mockClassType("kotlin.sequences.SequenceScope") }.unwrap(),
mockTAType("kotlin.sequences.SequenceBuilder", nullable = true) { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = true) { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = true) { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder", nullable = true) { mockClassType("kotlin.sequences.SequenceScope") }
@@ -310,7 +310,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinPackageWithDifferentNullability3() = doTestSuccess(
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") }.unwrap(),
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = false) },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = false) },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = true) }
@@ -318,7 +318,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInKotlinPackageWithDifferentNullability4() = doTestSuccess(
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") }.unwrap(),
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope") },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = true) },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = true) },
mockTAType("kotlin.sequences.SequenceBuilder") { mockClassType("kotlin.sequences.SequenceScope", nullable = false) }
@@ -326,7 +326,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInUserPackageWithSameNullability1() = doTestSuccess(
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") }.unwrap(),
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = false) { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = false) { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = false) { mockClassType("org.sample.Foo") }
@@ -334,7 +334,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
@Test
fun taTypesInUserPackageWithSameNullability2() = doTestSuccess(
mockTAType("org.sample.FooAlias", nullable = true) { mockClassType("org.sample.Foo") }.unwrap(),
mockTAType("org.sample.FooAlias", nullable = true) { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = true) { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = true) { mockClassType("org.sample.Foo") },
mockTAType("org.sample.FooAlias", nullable = true) { mockClassType("org.sample.Foo") }
@@ -366,7 +366,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
mockTAType("org.sample.FooAlias") { mockClassType("org.sample.Foo", nullable = false) }
)
private fun prepareCache(vararg variants: KotlinType) {
private fun prepareCache(variants: Array<out KotlinType>) {
check(variants.isNotEmpty())
val classesMap = CommonizedGroupMap<FqName, ClassDescriptor>(variants.size)
@@ -381,7 +381,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
typeAliasesMap[descriptor.fqNameSafe][index] = descriptor
recurse(descriptor.underlyingType, index) // expand underlying types recursively
}
else -> IllegalStateException("Unexpected descriptor of KotlinType: $descriptor, $type")
else -> error("Unexpected descriptor of KotlinType: $descriptor, $type")
}
}
@@ -398,17 +398,22 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest<KotlinType, UnwrappedTy
}
}
override fun doTestSuccess(expected: UnwrappedType, vararg variants: KotlinType) {
prepareCache(*variants)
super.doTestSuccess(expected, *variants)
fun doTestSuccess(expected: KotlinType, vararg variants: KotlinType) {
prepareCache(variants)
doTestSuccess(
expected = CirType.create(expected),
variants = *variants.map(CirType.Companion::create).toTypedArray()
)
}
override fun doTestFailure(vararg variants: KotlinType) {
prepareCache(*variants)
super.doTestFailure(*variants)
fun doTestFailure(vararg variants: KotlinType) {
prepareCache(variants)
doTestFailure(variants = *variants.map(CirType.Companion::create).toTypedArray())
}
override fun createCommonizer() = TypeCommonizer.default(cache)
override fun isEqual(a: UnwrappedType?, b: UnwrappedType?) = (a === b) || (a != null && b != null && areTypesEqual(cache, a, b))
override fun isEqual(a: CirType?, b: CirType?) = (a === b) || (a != null && b != null && areTypesEqual(cache, a, b))
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.utils.EMPTY_CLASSIFIERS_CACHE
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
import org.jetbrains.kotlin.name.Name
@@ -91,7 +92,7 @@ class DefaultTypeParameterCommonizerTest : AbstractCommonizerTest<CirTypeParamet
name = Name.identifier(name),
isReified = isReified,
variance = variance,
upperBounds = upperBounds.map { mockClassType(it).unwrap() }
upperBounds = upperBounds.map { CirType.create(mockClassType(it)) }
)
}
}
@@ -9,10 +9,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.utils.EMPTY_CLASSIFIERS_CACHE
import org.jetbrains.kotlin.descriptors.commonizer.core.CirTestValueParameter.Companion.areEqual
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
import org.junit.Test
class DefaultValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParameter, CirValueParameter>() {
@@ -153,7 +153,7 @@ class DefaultValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParam
isNoinline: Boolean = false,
declaresDefaultValue: Boolean = false
): CirValueParameter {
val returnType = mockClassType(returnTypeFqName).unwrap()
val returnType = CirType.create(mockClassType(returnTypeFqName))
return CirTestValueParameter(
name = Name.identifier(name),
@@ -171,8 +171,8 @@ class DefaultValueParameterCommonizerTest : AbstractCommonizerTest<CirValueParam
internal data class CirTestValueParameter(
override val name: Name,
override val annotations: Annotations,
override val returnType: UnwrappedType,
override val varargElementType: UnwrappedType?,
override val returnType: CirType,
override val varargElementType: CirType?,
override val declaresDefaultValue: Boolean,
override val isCrossinline: Boolean,
override val isNoinline: Boolean
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.Visibilities.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.UnwrappedType
import org.junit.Test
abstract class LoweringVisibilityCommonizerTest(
@@ -39,7 +38,7 @@ abstract class LoweringVisibilityCommonizerTest(
override val containingClassKind: ClassKind? get() = if (areMembersVirtual) ClassKind.CLASS else null
override val isExternal: Boolean get() = unsupported()
override val extensionReceiver: CirExtensionReceiver? get() = unsupported()
override val returnType: UnwrappedType get() = unsupported()
override val returnType: CirType get() = unsupported()
override val kind: CallableMemberDescriptor.Kind get() = unsupported()
override val annotations: Annotations get() = unsupported()
override val name: Name get() = unsupported()
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedClassDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedTypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
import org.jetbrains.kotlin.descriptors.commonizer.builder.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.parentOrNull
@@ -31,8 +32,17 @@ internal fun mockClassType(
): KotlinType = LazyWrappedType(LockBasedStorageManager.NO_LOCKS) {
val classFqName = FqName(fqName)
val classDescriptor = CommonizedClassDescriptor(
val targetComponents = TargetDeclarationsBuilderComponents(
storageManager = LockBasedStorageManager.NO_LOCKS,
target = InputTarget("Arbitrary target"),
builtIns = DefaultBuiltIns.Instance,
isCommon = false,
index = 0,
cache = DeclarationsBuilderCache(1)
)
val classDescriptor = CommonizedClassDescriptor(
targetComponents = targetComponents,
containingDeclaration = createPackageFragmentForClassifier(classFqName),
annotations = Annotations.EMPTY,
name = classFqName.shortName(),
@@ -46,16 +56,14 @@ internal fun mockClassType(
isExternal = false,
isExpect = false,
isActual = false,
cirDeclaredTypeParameters = emptyList(),
companionObjectName = null,
supertypes = emptyList()
cirSupertypes = emptyList()
)
classDescriptor.declaredTypeParameters = emptyList()
classDescriptor.unsubstitutedMemberScope = CommonizedMemberScope()
classDescriptor.initialize(
unsubstitutedMemberScope = MemberScope.Empty,
constructors = emptyList()
)
classDescriptor.initialize(constructors = emptyList())
classDescriptor.defaultType.makeNullableAsSpecified(nullable)
}
@@ -80,8 +88,8 @@ internal fun mockTAType(
typeAliasDescriptor.initialize(
declaredTypeParameters = emptyList(),
underlyingType = rightHandSideType.getAbbreviation() ?: rightHandSideType,
expandedType = rightHandSideType
underlyingType = LockBasedStorageManager.NO_LOCKS.createLazyValue { rightHandSideType.getAbbreviation() ?: rightHandSideType },
expandedType = LockBasedStorageManager.NO_LOCKS.createLazyValue { rightHandSideType }
)
(rightHandSideType.getAbbreviatedType()?.expandedType ?: rightHandSideType)