[Commonizer] Reduce memory consumption during approximation phase

^KT-39320
This commit is contained in:
Dmitriy Dolovov
2020-06-17 15:49:37 +07:00
parent d5ffc7416d
commit 63575582c4
36 changed files with 713 additions and 625 deletions
@@ -13,6 +13,8 @@ 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.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -29,12 +31,12 @@ internal class DeclarationsBuilderVisitor1(
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 allTargets = (node.targetDeclarations.toList() + node.commonDeclaration()!!).map { it!!.target }
val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
// collect module descriptors:
for (moduleNode in node.modules) {
for (moduleNode in node.modules.values) {
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
modules.forEachIndexed { index, module ->
val target = allTargets[index]
@@ -58,7 +60,7 @@ internal class DeclarationsBuilderVisitor1(
// build package fragments:
val packageFragmentProviders = CommonizedPackageFragmentProvider.createArray(node.dimension)
for (packageNode in node.packages) {
for (packageNode in node.packages.values) {
val packageFragments = packageNode.accept(this, moduleDescriptors).asListContaining<PackageFragmentDescriptor>()
packageFragmentProviders += packageFragments
}
@@ -81,10 +83,10 @@ internal class DeclarationsBuilderVisitor1(
// build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) {
for (classNode in node.classes.values) {
packageMemberScopes += classNode.accept(this, packageFragments)
}
for (typeAliasNode in node.typeAliases) {
for (typeAliasNode in node.typeAliases.values) {
packageMemberScopes += typeAliasNode.accept(this, packageFragments)
}
@@ -109,7 +111,7 @@ internal class DeclarationsBuilderVisitor1(
// build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) {
for (classNode in node.classes.values) {
classMemberScopes += classNode.accept(this, classes)
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVi
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.mergedtree.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
@@ -29,7 +30,7 @@ internal class DeclarationsBuilderVisitor2(
check(components.targetComponents.size == node.dimension)
// visit module descriptors:
for (moduleNode in node.modules) {
for (moduleNode in node.modules.values) {
moduleNode.accept(this, noContainingDeclarations())
}
@@ -38,7 +39,7 @@ internal class DeclarationsBuilderVisitor2(
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// visit package fragment descriptors:
for (packageNode in node.packages) {
for (packageNode in node.packages.values) {
packageNode.accept(this, noContainingDeclarations())
}
@@ -50,14 +51,14 @@ internal class DeclarationsBuilderVisitor2(
// build non-classifier package members:
val packageMemberScopes = packageFragments.map { it?.getMemberScope() }
for (propertyNode in node.properties) {
for (propertyNode in node.properties.values) {
packageMemberScopes += propertyNode.accept(this, packageFragments)
}
for (functionNode in node.functions) {
for (functionNode in node.functions.values) {
packageMemberScopes += functionNode.accept(this, packageFragments)
}
for (classNode in node.classes) {
for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations())
}
@@ -83,7 +84,7 @@ internal class DeclarationsBuilderVisitor2(
// build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() }
for (constructorNode in node.constructors) {
for (constructorNode in node.constructors.values) {
val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor)
@@ -97,14 +98,14 @@ internal class DeclarationsBuilderVisitor2(
// build class members:
val classMemberScopes = classes.map { it?.unsubstitutedMemberScope }
for (propertyNode in node.properties) {
for (propertyNode in node.properties.values) {
classMemberScopes += propertyNode.accept(this, classes)
}
for (functionNode in node.functions) {
for (functionNode in node.functions.values) {
classMemberScopes += functionNode.accept(this, classes)
}
for (classNode in node.classes) {
for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations())
}
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassConstructor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassConstructorNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
@@ -22,10 +22,10 @@ internal fun CirClassNode.buildDescriptors(
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass = common()
val commonClass = commonDeclaration()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY
target.forEachIndexed { index, clazz ->
targetDeclarations.toList().forEachIndexed { index, clazz ->
clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
@@ -78,10 +78,10 @@ internal fun CirClassConstructorNode.buildDescriptors(
output: CommonizedGroup<ClassConstructorDescriptor>,
containingDeclarations: List<CommonizedClassDescriptor?>
) {
val commonConstructor = common()
val commonConstructor = commonDeclaration()
val markAsActual = commonConstructor != null
target.forEachIndexed { index, constructor ->
targetDeclarations.toList().forEachIndexed { index, constructor ->
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual)
}
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
@@ -172,7 +172,7 @@ fun CirRootNode.createGlobalBuilderComponents(
val targetContexts = (0 until dimension).map { index ->
val isCommon = index == indexOfCommon
val root = if (isCommon) common()!! else target[index]!!
val root = if (isCommon) commonDeclaration()!! else targetDeclarations[index]!!
val builtIns = root.builtInsProvider.loadBuiltIns()
check(builtIns::class.java.name == root.builtInsClass) {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirFunctionNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -20,10 +20,10 @@ internal fun CirFunctionNode.buildDescriptors(
output: CommonizedGroup<SimpleFunctionDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonFunction = common()
val commonFunction = commonDeclaration()
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, function ->
targetDeclarations.toList().forEachIndexed { index, function ->
function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
@@ -15,11 +15,11 @@ internal fun CirModuleNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>
) {
target.forEachIndexed { index, module ->
targetDeclarations.toList().forEachIndexed { index, module ->
module?.buildDescriptor(components, output, index)
}
common()?.buildDescriptor(components, output, indexOfCommon)
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon)
// log stats
components.statsCollector?.logStats(output.toList())
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPackageNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
@@ -19,11 +19,11 @@ internal fun CirPackageNode.buildDescriptors(
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?>
) {
target.forEachIndexed { index, pkg ->
targetDeclarations.toList().forEachIndexed { index, pkg ->
pkg?.buildDescriptor(components, output, index, modules)
}
common()?.buildDescriptor(components, output, indexOfCommon, modules)
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon, modules)
}
private fun CirPackage.buildDescriptor(
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPropertyNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
@@ -23,7 +23,7 @@ internal fun CirPropertyNode.buildDescriptors(
output: CommonizedGroup<PropertyDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonProperty = common()
val commonProperty = commonDeclaration()
val isLiftedUp = commonProperty?.isLiftedUp == true
val markAsExpectAndActual = commonProperty != null
@@ -31,7 +31,7 @@ internal fun CirPropertyNode.buildDescriptors(
&& !isLiftedUp
if (!isLiftedUp) {
target.forEachIndexed { index, property ->
targetDeclarations.toList().forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
@@ -20,7 +20,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClassifier: CirClassifier? = common()
val commonClassifier: CirClassifier? = commonDeclaration()
// Note: 'expect class' and lifted up 'typealias' both can't be non-null
val commonTypeAlias: CirTypeAlias? = commonClassifier as? CirTypeAlias?
@@ -28,7 +28,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
val markAsActual = commonClassifier != null
if (!isLiftedUp) {
target.forEachIndexed { index, typeAlias ->
targetDeclarations.toList().forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
}
@@ -14,91 +14,91 @@ internal class CommonizationVisitor(
) : CirNodeVisitor<Unit, Unit> {
override fun visitRootNode(node: CirRootNode, data: Unit) {
check(node === root)
check(node.common() != null) // root should already be commonized
check(node.commonDeclaration() != null) // root should already be commonized
node.modules.forEach { module ->
node.modules.values.forEach { module ->
module.accept(this, Unit)
}
}
override fun visitModuleNode(node: CirModuleNode, data: Unit) {
node.common() // commonize module
node.commonDeclaration() // commonize module
node.packages.forEach { pkg ->
node.packages.values.forEach { pkg ->
pkg.accept(this, Unit)
}
}
override fun visitPackageNode(node: CirPackageNode, data: Unit) {
node.common() // commonize package
node.commonDeclaration() // commonize package
node.properties.forEach { property ->
node.properties.values.forEach { property ->
property.accept(this, Unit)
}
node.functions.forEach { function ->
node.functions.values.forEach { function ->
function.accept(this, Unit)
}
node.classes.forEach { clazz ->
node.classes.values.forEach { clazz ->
clazz.accept(this, Unit)
}
node.typeAliases.forEach { typeAlias ->
node.typeAliases.values.forEach { typeAlias ->
typeAlias.accept(this, Unit)
}
}
override fun visitPropertyNode(node: CirPropertyNode, data: Unit) {
node.common() // commonize property
node.commonDeclaration() // commonize property
}
override fun visitFunctionNode(node: CirFunctionNode, data: Unit) {
node.common() // commonize function
node.commonDeclaration() // commonize function
}
override fun visitClassNode(node: CirClassNode, data: Unit) {
val commonClass = node.common() // commonized class
val commonClass = node.commonDeclaration() // commonized class
node.constructors.forEach { constructor ->
node.constructors.values.forEach { constructor ->
constructor.accept(this, Unit)
}
node.properties.forEach { property ->
node.properties.values.forEach { property ->
property.accept(this, Unit)
}
node.functions.forEach { function ->
node.functions.values.forEach { function ->
function.accept(this, Unit)
}
node.classes.forEach { clazz ->
node.classes.values.forEach { clazz ->
clazz.accept(this, Unit)
}
if (commonClass != null) {
// companion object should have the same FQ name for each target class, then it could be set to common class
val companionObjectFqName = node.target.mapTo(HashSet()) { it!!.companion }.singleOrNull()
val companionObjectFqName = node.targetDeclarations.toList().mapTo(HashSet()) { it!!.companion }.singleOrNull()
if (companionObjectFqName != null) {
val companionObjectNode = root.cache.classes[companionObjectFqName]
?: error("Can't find companion object with FQ name $companionObjectFqName")
if (companionObjectNode.common() != null) {
if (companionObjectNode.commonDeclaration() != null) {
// companion object has been successfully commonized
commonClass.companion = companionObjectFqName
}
}
// find out common (and commonized) supertypes
val supertypesMap = CommonizedGroupMap<String, CirType>(node.target.size)
node.target.forEachIndexed { index, clazz ->
val supertypesMap = CommonizedGroupMap<String, CirType>(node.targetDeclarations.size)
node.targetDeclarations.toList().forEachIndexed { index, clazz ->
for (supertype in clazz!!.supertypes) {
supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype
}
}
for ((_, supertypesGroup) in supertypesMap) {
val commonSupertype = commonize(supertypesGroup.toList(), TypeCommonizer(root.cache))
val commonSupertype = commonize(supertypesGroup, TypeCommonizer(root.cache))
if (commonSupertype != null)
commonClass.supertypes.add(commonSupertype)
}
@@ -106,10 +106,10 @@ internal class CommonizationVisitor(
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: Unit) {
node.common() // commonize constructor
node.commonDeclaration() // commonize constructor
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: Unit) {
node.common() // commonize type alias
node.commonDeclaration() // commonize type alias
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPackageFactory
import org.jetbrains.kotlin.name.FqName
class PackageCommonizer : AbstractStandardCommonizer<CirPackage, CirPackage>() {
private lateinit var fqName: FqName
override fun commonizationResult() = CirPackageFactory.create(fqName = fqName)
override fun initialize(first: CirPackage) {
fqName = first.fqName
}
override fun doCommonizeWith(next: CirPackage) = true
}
@@ -98,5 +98,5 @@ private inline fun CirNode<*, *>?.canBeCommonized() =
true
} else {
// If entry is present, then contents (common declaration) should not be null.
common() != null
commonDeclaration() != null
}
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVi
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.mergeRoots
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirTreeMerger
import org.jetbrains.kotlin.storage.LockBasedStorageManager
fun runCommonization(parameters: Parameters): Result {
@@ -20,7 +20,7 @@ fun runCommonization(parameters: Parameters): Result {
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
// build merged tree:
val mergedTree = mergeRoots(storageManager, parameters.targetProviders)
val mergedTree = CirTreeMerger(storageManager, parameters.targetProviders).merge()
// commonize:
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassConstructor
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirClassConstructorNode(
override val targetDeclarations: CommonizedGroup<CirClassConstructor>,
override val commonDeclaration: NullableLazyValue<CirClassConstructor>
) : CirNode<CirClassConstructor, CirClassConstructor> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassConstructorNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirClassNode(
override val targetDeclarations: CommonizedGroup<CirClass>,
override val commonDeclaration: NullableLazyValue<CirClass>,
override val fqName: FqName
) : CirNodeWithFqName<CirClass, CirClass> {
val constructors: MutableMap<ConstructorApproximationKey, CirClassConstructorNode> = HashMap()
val properties: MutableMap<PropertyApproximationKey, CirPropertyNode> = HashMap()
val functions: MutableMap<FunctionApproximationKey, CirFunctionNode> = HashMap()
val classes: MutableMap<Name, CirClassNode> = HashMap()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.name.FqName
interface CirClassifiersCache {
val classes: Map<FqName, CirClassNode>
val typeAliases: Map<FqName, CirTypeAliasNode>
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunction
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirFunctionNode(
override val targetDeclarations: CommonizedGroup<CirFunction>,
override val commonDeclaration: NullableLazyValue<CirFunction>
) : CirNode<CirFunction, CirFunction> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitFunctionNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirModuleNode(
override val targetDeclarations: CommonizedGroup<CirModule>,
override val commonDeclaration: NullableLazyValue<CirModule>
) : CirNode<CirModule, CirModule> {
val packages: MutableMap<FqName, CirPackageNode> = HashMap()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitModuleNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.storage.NullableLazyValue
interface CirNode<T : CirDeclaration, R : CirDeclaration> {
val targetDeclarations: CommonizedGroup<T>
val commonDeclaration: NullableLazyValue<R>
fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R
companion object {
inline val CirNode<*, *>.indexOfCommon: Int
get() = targetDeclarations.size
internal inline val CirNode<*, *>.dimension: Int
get() = targetDeclarations.size + 1
fun toString(node: CirNode<*, *>) = buildString {
if (node is CirNodeWithFqName) {
append("fqName=").append(node.fqName).append(", ")
}
append("target=")
node.targetDeclarations.toList().joinTo(this)
append(", common=")
append(if (node.commonDeclaration.isComputed()) node.commonDeclaration() else "<NOT COMPUTED>")
}
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration
import org.jetbrains.kotlin.name.FqName
interface CirNodeWithFqName<T : CirDeclaration, R : CirDeclaration> : CirNode<T, R> {
val fqName: FqName
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirPackageNode(
override val targetDeclarations: CommonizedGroup<CirPackage>,
override val commonDeclaration: NullableLazyValue<CirPackage>,
override val fqName: FqName,
val moduleName: Name
) : CirNodeWithFqName<CirPackage, CirPackage> {
val properties: MutableMap<PropertyApproximationKey, CirPropertyNode> = HashMap()
val functions: MutableMap<FunctionApproximationKey, CirFunctionNode> = HashMap()
val classes: MutableMap<Name, CirClassNode> = HashMap()
val typeAliases: MutableMap<Name, CirTypeAliasNode> = HashMap()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPackageNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirPropertyNode(
override val targetDeclarations: CommonizedGroup<CirProperty>,
override val commonDeclaration: NullableLazyValue<CirProperty>
) : CirNode<CirProperty, CirProperty> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPropertyNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirRoot
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirRootNode(
override val targetDeclarations: CommonizedGroup<CirRoot>,
override val commonDeclaration: NullableLazyValue<CirRoot>
) : CirNode<CirRoot, CirRoot> {
class CirClassifiersCacheImpl : CirClassifiersCache {
override val classes = HashMap<FqName, CirClassNode>()
override val typeAliases = HashMap<FqName, CirTypeAliasNode>()
}
val modules: MutableMap<Name, CirModuleNode> = HashMap()
val cache = CirClassifiersCacheImpl()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitRootNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,175 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.CirClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
class CirTreeMerger(
private val storageManager: StorageManager,
private val targetProviders: List<TargetProvider>
) {
private val size = targetProviders.size
private lateinit var cacheRW: CirClassifiersCacheImpl
fun merge(): CirRootNode {
val rootNode: CirRootNode = buildRootNode(storageManager, size)
cacheRW = rootNode.cache
targetProviders.forEachIndexed { targetIndex, targetProvider ->
processTarget(rootNode, targetIndex, targetProvider)
System.gc()
}
return rootNode
}
private fun processTarget(
rootNode: CirRootNode,
targetIndex: Int,
targetProvider: TargetProvider
) {
rootNode.targetDeclarations[targetIndex] = CirRootFactory.create(
targetProvider.target,
targetProvider.builtInsClass.name,
targetProvider.builtInsProvider
)
val moduleDescriptors: Collection<ModuleDescriptor> = targetProvider.modulesProvider.loadModules()
val modules: MutableMap<Name, CirModuleNode> = rootNode.modules
moduleDescriptors.forEach { moduleDescriptor ->
processModule(modules, targetIndex, moduleDescriptor)
}
}
private fun processModule(
modules: MutableMap<Name, CirModuleNode>,
targetIndex: Int,
moduleDescriptor: ModuleDescriptor
) {
val moduleName: Name = moduleDescriptor.name.intern()
val moduleNode: CirModuleNode = modules.computeIfAbsent(moduleName) {
buildModuleNode(storageManager, size)
}
moduleNode.targetDeclarations[targetIndex] = CirModuleFactory.create(moduleDescriptor)
val packages: MutableMap<FqName, CirPackageNode> = moduleNode.packages
moduleDescriptor.collectNonEmptyPackageMemberScopes { packageFqName, packageMemberScope ->
processPackage(packages, targetIndex, packageFqName.intern(), packageMemberScope, moduleName)
}
}
private fun processPackage(
packages: MutableMap<FqName, CirPackageNode>,
targetIndex: Int,
packageFqName: FqName,
packageMemberScope: MemberScope,
moduleName: Name
) {
val packageNode: CirPackageNode = packages.computeIfAbsent(packageFqName) {
buildPackageNode(storageManager, size, packageFqName, moduleName)
}
packageNode.targetDeclarations[targetIndex] = CirPackageFactory.create(packageFqName)
val properties: MutableMap<PropertyApproximationKey, CirPropertyNode> = packageNode.properties
val functions: MutableMap<FunctionApproximationKey, CirFunctionNode> = packageNode.functions
val classes: MutableMap<Name, CirClassNode> = packageNode.classes
val typeAliases: MutableMap<Name, CirTypeAliasNode> = packageNode.typeAliases
packageMemberScope.collectMembers(
PropertyCollector { processProperty(properties, targetIndex, it, null) },
FunctionCollector { processFunction(functions, targetIndex, it, null) },
ClassCollector { processClass(classes, targetIndex, it, null) },
TypeAliasCollector { processTypeAlias(typeAliases, targetIndex, it) }
)
}
private fun processProperty(
properties: MutableMap<PropertyApproximationKey, CirPropertyNode>,
targetIndex: Int,
propertyDescriptor: PropertyDescriptor,
parentCommonDeclaration: NullableLazyValue<*>?
) {
val propertyNode: CirPropertyNode = properties.computeIfAbsent(PropertyApproximationKey(propertyDescriptor)) {
buildPropertyNode(storageManager, size, cacheRW, parentCommonDeclaration)
}
propertyNode.targetDeclarations[targetIndex] = CirPropertyFactory.create(propertyDescriptor)
}
private fun processFunction(
functions: MutableMap<FunctionApproximationKey, CirFunctionNode>,
targetIndex: Int,
functionDescriptor: SimpleFunctionDescriptor,
parentCommonDeclaration: NullableLazyValue<*>?
) {
val functionNode: CirFunctionNode = functions.computeIfAbsent(FunctionApproximationKey(functionDescriptor)) {
buildFunctionNode(storageManager, size, cacheRW, parentCommonDeclaration)
}
functionNode.targetDeclarations[targetIndex] = CirFunctionFactory.create(functionDescriptor)
}
private fun processClass(
classes: MutableMap<Name, CirClassNode>,
targetIndex: Int,
classDescriptor: ClassDescriptor,
parentCommonDeclaration: NullableLazyValue<*>?
) {
val classNode: CirClassNode = classes.computeIfAbsent(classDescriptor.name.intern()) {
buildClassNode(storageManager, size, cacheRW, parentCommonDeclaration, classDescriptor.fqNameSafe.intern())
}
classNode.targetDeclarations[targetIndex] = CirClassFactory.create(classDescriptor)
val parentCommonDeclarationForMembers: NullableLazyValue<CirClass> = classNode.commonDeclaration
val constructors: MutableMap<ConstructorApproximationKey, CirClassConstructorNode> = classNode.constructors
val properties: MutableMap<PropertyApproximationKey, CirPropertyNode> = classNode.properties
val functions: MutableMap<FunctionApproximationKey, CirFunctionNode> = classNode.functions
val nestedClasses: MutableMap<Name, CirClassNode> = classNode.classes
classDescriptor.constructors.forEach { processClassConstructor(constructors, targetIndex, it, parentCommonDeclarationForMembers) }
classDescriptor.unsubstitutedMemberScope.collectMembers(
PropertyCollector { processProperty(properties, targetIndex, it, parentCommonDeclarationForMembers) },
FunctionCollector { processFunction(functions, targetIndex, it, parentCommonDeclarationForMembers) },
ClassCollector { processClass(nestedClasses, targetIndex, it, parentCommonDeclarationForMembers) }
)
}
private fun processClassConstructor(
constructors: MutableMap<ConstructorApproximationKey, CirClassConstructorNode>,
targetIndex: Int,
constructorDescriptor: ClassConstructorDescriptor,
parentCommonDeclaration: NullableLazyValue<*>?
) {
val constructorNode: CirClassConstructorNode = constructors.computeIfAbsent(ConstructorApproximationKey(constructorDescriptor)) {
buildClassConstructorNode(storageManager, size, cacheRW, parentCommonDeclaration)
}
constructorNode.targetDeclarations[targetIndex] = CirClassConstructorFactory.create(constructorDescriptor)
}
private fun processTypeAlias(
typeAliases: MutableMap<Name, CirTypeAliasNode>,
targetIndex: Int,
typeAliasDescriptor: TypeAliasDescriptor
) {
val typeAliasNode: CirTypeAliasNode = typeAliases.computeIfAbsent(typeAliasDescriptor.name.intern()) {
buildTypeAliasNode(storageManager, size, cacheRW, typeAliasDescriptor.fqNameSafe.intern())
}
typeAliasNode.targetDeclarations[targetIndex] = CirTypeAliasFactory.create(typeAliasDescriptor)
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.storage.NullableLazyValue
class CirTypeAliasNode(
override val targetDeclarations: CommonizedGroup<CirTypeAlias>,
override val commonDeclaration: NullableLazyValue<CirClassifier>,
override val fqName: FqName
) : CirNodeWithFqName<CirTypeAlias, CirClassifier> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitTypeAliasNode(this, data)
override fun toString() = CirNode.toString(this)
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.Name
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */
data class PropertyApproximationKey(
val name: Name,
val extensionReceiverParameter: String?
) {
constructor(property: PropertyDescriptor) : this(
property.name.intern(),
property.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
/** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */
data class FunctionApproximationKey(
val name: Name,
val valueParameters: List<Pair<Name, String>>,
val extensionReceiverParameter: String?
) {
constructor(function: SimpleFunctionDescriptor) : this(
function.name.intern(),
function.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters },
function.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
/** Used for approximation of [ConstructorDescriptor]s before running concrete [Commonizer]s */
data class ConstructorApproximationKey(
val valueParameters: List<Pair<Name, String>>
) {
constructor(constructor: ConstructorDescriptor) : this(
constructor.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters }
)
}
@@ -1,33 +0,0 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeProperties(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<PropertyDescriptor?>
) = buildPropertyNode(storageManager, cache, containingDeclarationCommon, properties)
internal fun mergeFunctions(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<SimpleFunctionDescriptor?>
) = buildFunctionNode(storageManager, cache, containingDeclarationCommon, properties)
internal fun mergeClassConstructors(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
constructors: List<ClassConstructorDescriptor?>
) = buildClassConstructorNode(storageManager, cache, containingDeclarationCommon, constructors)
@@ -1,62 +0,0 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeClasses(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
containingDeclarationCommon: NullableLazyValue<*>?,
classes: List<ClassDescriptor?>
): CirClassNode {
val node = buildClassNode(storageManager, cacheRW, containingDeclarationCommon, classes)
val constructorsMap = CommonizedGroupMap<ConstructorApproximationKey, ClassConstructorDescriptor>(classes.size)
val propertiesMap = CommonizedGroupMap<PropertyApproximationKey, PropertyDescriptor>(classes.size)
val functionsMap = CommonizedGroupMap<FunctionApproximationKey, SimpleFunctionDescriptor>(classes.size)
val classesMap = CommonizedGroupMap<Name, ClassDescriptor>(classes.size)
classes.forEachIndexed { index, clazz ->
clazz?.constructors?.forEach { constructorsMap[ConstructorApproximationKey(it)][index] = it }
clazz?.unsubstitutedMemberScope?.collectMembers(
PropertyCollector { propertiesMap[PropertyApproximationKey(it)][index] = it },
FunctionCollector { functionsMap[FunctionApproximationKey(it)][index] = it },
ClassCollector { classesMap[it.name.intern()][index] = it }
)
}
for ((_, constructorsGroup) in constructorsMap) {
node.constructors += mergeClassConstructors(storageManager, cacheRW, node.common, constructorsGroup.toList())
}
for ((_, propertiesGroup) in propertiesMap) {
node.properties += mergeProperties(storageManager, cacheRW, node.common, propertiesGroup.toList())
}
for ((_, functionsGroup) in functionsMap) {
node.functions += mergeFunctions(storageManager, cacheRW, node.common, functionsGroup.toList())
}
for ((_, classesGroup) in classesMap) {
node.classes += mergeClasses(storageManager, cacheRW, node.common, classesGroup.toList())
}
return node
}
internal fun mergeTypeAliases(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
typeAliases: List<TypeAliasDescriptor?>
) = buildTypeAliasNode(storageManager, cacheRW, typeAliases)
@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.alwaysTrue
internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescriptor) -> Boolean) =
getContributedDescriptors().forEach { member ->
@@ -60,35 +62,34 @@ internal inline fun FunctionCollector(
}
}
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */
internal data class PropertyApproximationKey(
val name: Name,
val extensionReceiverParameter: String?
) {
constructor(property: PropertyDescriptor) : this(
property.name.intern(),
property.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
// collects member scopes for every non-empty package provided by this module
internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqName, MemberScope) -> Unit) {
// we don's need to process fragments from other modules which are the dependencies of this module, so
// let's use the appropriate package fragment provider
val packageFragmentProvider = this.packageFragmentProvider
/** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */
internal data class FunctionApproximationKey(
val name: Name,
val valueParameters: List<Pair<Name, String>>,
val extensionReceiverParameter: String?
) {
constructor(function: SimpleFunctionDescriptor) : this(
function.name.intern(),
function.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters },
function.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
fun recurse(packageFqName: FqName) {
if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
return
/** Used for approximation of [ConstructorDescriptor]s before running concrete [Commonizer]s */
internal data class ConstructorApproximationKey(
val valueParameters: List<Pair<Name, String>>
) {
constructor(constructor: ConstructorDescriptor) : this(
constructor.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters }
)
}
val ownPackageFragments = packageFragmentProvider.getPackageFragments(packageFqName)
val ownPackageMemberScopes = ownPackageFragments.asSequence()
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
.map { it.getMemberScope() }
.filter { it != MemberScope.Empty }
.toList(ownPackageFragments.size)
if (ownPackageMemberScopes.isNotEmpty()) {
// don't include subpackages into chained member scope
val memberScope = ChainedMemberScope.create(
"package member scope for $packageFqName in $name",
ownPackageMemberScopes
)
collector(packageFqName, memberScope)
}
packageFragmentProvider.getSubPackagesOf(packageFqName, alwaysTrue()).toSet().map { recurse(it) }
}
recurse(FqName.ROOT)
}
@@ -1,70 +0,0 @@
/*
* 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
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.alwaysTrue
internal fun mergeModules(
storageManager: StorageManager,
cacheRW: CirRootNode.ClassifiersCacheImpl,
modules: List<ModuleDescriptor?>
): CirModuleNode {
val node = buildModuleNode(storageManager, modules)
val packageMemberScopesMap = CommonizedGroupMap<FqName, MemberScope>(modules.size)
modules.forEachIndexed { index, module ->
module?.collectNonEmptyPackageMemberScopes { packageFqName, memberScope ->
packageMemberScopesMap[packageFqName.intern()][index] = memberScope
}
}
val moduleName = modules.firstNonNull().name.intern()
for ((packageFqName, packageMemberScopesGroup) in packageMemberScopesMap) {
node.packages += mergePackages(storageManager, cacheRW, moduleName, packageFqName, packageMemberScopesGroup.toList())
}
return node
}
// collects member scopes for every non-empty package provided by this module
internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqName, MemberScope) -> Unit) {
// we don's need to process fragments from other modules which are the dependencies of this module, so
// let's use the appropriate package fragment provider
val packageFragmentProvider = this.packageFragmentProvider
fun recurse(packageFqName: FqName) {
if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
return
val ownPackageFragments = packageFragmentProvider.getPackageFragments(packageFqName)
val ownPackageMemberScopes = ownPackageFragments.asSequence()
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
.map { it.getMemberScope() }
.filter { it != MemberScope.Empty }
.toList(ownPackageFragments.size)
if (ownPackageMemberScopes.isNotEmpty()) {
// don't include subpackages into chained member scope
val memberScope = ChainedMemberScope.create(
"package member scope for $packageFqName in $name",
ownPackageMemberScopes
)
collector(packageFqName, memberScope)
}
packageFragmentProvider.getSubPackagesOf(packageFqName, alwaysTrue()).toSet().map { recurse(it) }
}
recurse(FqName.ROOT)
}
@@ -5,186 +5,152 @@
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassRecursionMarker
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassifierRecursionMarker
import org.jetbrains.kotlin.descriptors.commonizer.core.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.CirClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun buildRootNode(
storageManager: StorageManager,
targetProviders: List<TargetProvider>
size: Int
): CirRootNode = buildNode(
storageManager = storageManager,
descriptors = targetProviders,
targetDeclarationProducer = { CirRootFactory.create(it.target, it.builtInsClass.name, it.builtInsProvider) },
commonValueProducer = { commonize(it, RootCommonizer()) },
recursionMarker = null,
size = size,
commonizerProducer = ::RootCommonizer,
nodeProducer = ::CirRootNode
)
internal fun buildModuleNode(
storageManager: StorageManager,
modules: List<ModuleDescriptor?>
size: Int
): CirModuleNode = buildNode(
storageManager = storageManager,
descriptors = modules,
targetDeclarationProducer = CirModuleFactory::create,
commonValueProducer = { commonize(it, ModuleCommonizer()) },
recursionMarker = null,
size = size,
commonizerProducer = ::ModuleCommonizer,
nodeProducer = ::CirModuleNode
)
internal fun buildPackageNode(
storageManager: StorageManager,
moduleName: Name,
packageFqName: FqName,
packageMemberScopes: List<MemberScope?>
size: Int,
fqName: FqName,
moduleName: Name
): CirPackageNode = buildNode(
storageManager = storageManager,
descriptors = packageMemberScopes,
targetDeclarationProducer = { CirPackageFactory.create(packageFqName) },
commonValueProducer = { CirPackageFactory.create(packageFqName) },
recursionMarker = null,
nodeProducer = ::CirPackageNode
).also { node ->
node.moduleName = moduleName
node.fqName = packageFqName
}
size = size,
commonizerProducer = ::PackageCommonizer,
nodeProducer = { targetDeclarations, commonDeclaration ->
CirPackageNode(targetDeclarations, commonDeclaration, fqName, moduleName)
}
)
internal fun buildPropertyNode(
storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<PropertyDescriptor?>
parentCommonDeclaration: NullableLazyValue<*>?
): CirPropertyNode = buildNode(
storageManager = storageManager,
descriptors = properties,
targetDeclarationProducer = CirPropertyFactory::create,
commonValueProducer = { commonize(containingDeclarationCommon, it, PropertyCommonizer(cache)) },
recursionMarker = null,
size = size,
parentCommonDeclaration = parentCommonDeclaration,
commonizerProducer = { PropertyCommonizer(cache) },
nodeProducer = ::CirPropertyNode
)
internal fun buildFunctionNode(
storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
functions: List<SimpleFunctionDescriptor?>
parentCommonDeclaration: NullableLazyValue<*>?
): CirFunctionNode = buildNode(
storageManager = storageManager,
descriptors = functions,
targetDeclarationProducer = CirFunctionFactory::create,
commonValueProducer = { commonize(containingDeclarationCommon, it, FunctionCommonizer(cache)) },
recursionMarker = null,
size = size,
parentCommonDeclaration = parentCommonDeclaration,
commonizerProducer = { FunctionCommonizer(cache) },
nodeProducer = ::CirFunctionNode
)
internal fun buildClassNode(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
containingDeclarationCommon: NullableLazyValue<*>?,
classes: List<ClassDescriptor?>
size: Int,
cacheRW: CirClassifiersCacheImpl,
parentCommonDeclaration: NullableLazyValue<*>?,
fqName: FqName
): CirClassNode = buildNode(
storageManager = storageManager,
descriptors = classes,
targetDeclarationProducer = CirClassFactory::create,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) },
size = size,
parentCommonDeclaration = parentCommonDeclaration,
commonizerProducer = { ClassCommonizer(cacheRW) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode
).also { node ->
classes.firstNonNull().fqNameSafe.intern().let { fqName ->
node.fqName = fqName
cacheRW.classes.putSafe(fqName, node)
nodeProducer = { targetDeclarations, commonDeclaration ->
CirClassNode(targetDeclarations, commonDeclaration, fqName).also {
cacheRW.classes[fqName] = it
}
}
}
)
internal fun buildClassConstructorNode(
storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
constructors: List<ClassConstructorDescriptor?>
parentCommonDeclaration: NullableLazyValue<*>?
): CirClassConstructorNode = buildNode(
storageManager = storageManager,
descriptors = constructors,
targetDeclarationProducer = CirClassConstructorFactory::create,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassConstructorCommonizer(cache)) },
recursionMarker = null,
size = size,
parentCommonDeclaration = parentCommonDeclaration,
commonizerProducer = { ClassConstructorCommonizer(cache) },
nodeProducer = ::CirClassConstructorNode
)
internal fun buildTypeAliasNode(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
typeAliases: List<TypeAliasDescriptor?>
size: Int,
cacheRW: CirClassifiersCacheImpl,
fqName: FqName
): CirTypeAliasNode = buildNode(
storageManager = storageManager,
descriptors = typeAliases,
targetDeclarationProducer = CirTypeAliasFactory::create,
commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) },
size = size,
commonizerProducer = { TypeAliasCommonizer(cacheRW) },
recursionMarker = CirClassifierRecursionMarker,
nodeProducer = ::CirTypeAliasNode
).also { node ->
typeAliases.firstNonNull().fqNameSafe.intern().let { fqName ->
node.fqName = fqName
cacheRW.typeAliases.putSafe(fqName, node)
nodeProducer = { targetDeclarations, commonDeclaration ->
CirTypeAliasNode(targetDeclarations, commonDeclaration, fqName).also {
cacheRW.typeAliases[fqName] = it
}
}
}
)
private fun <D : Any, T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
private fun <T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
storageManager: StorageManager,
descriptors: List<D?>,
targetDeclarationProducer: (D) -> T,
commonValueProducer: (List<T?>) -> R?,
recursionMarker: R?,
nodeProducer: (List<T?>, NullableLazyValue<R>) -> N
size: Int,
parentCommonDeclaration: NullableLazyValue<*>? = null,
commonizerProducer: () -> Commonizer<T, R>,
recursionMarker: R? = null,
nodeProducer: (CommonizedGroup<T>, NullableLazyValue<R>) -> N
): N {
val declarationsGroup = CommonizedGroup<T>(descriptors.size)
var canHaveCommon = descriptors.size > 1
val targetDeclarations = CommonizedGroup<T>(size)
descriptors.forEachIndexed { index, descriptor ->
if (descriptor != null)
declarationsGroup[index] = targetDeclarationProducer(descriptor)
else
canHaveCommon = false
}
val declarations = declarationsGroup.toList()
val commonComputable: () -> R? = if (canHaveCommon) {
{ commonValueProducer(declarations) }
} else {
{ null }
}
val commonComputable = { commonize(parentCommonDeclaration, targetDeclarations, commonizerProducer()) }
val commonLazyValue = if (recursionMarker != null)
storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker)
else
storageManager.createNullableLazyValue(commonComputable)
return nodeProducer(declarations, commonLazyValue)
return nodeProducer(targetDeclarations, 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))
internal fun <T : Any, R> commonize(
targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R>
): R? {
for (targetDeclaration in targetDeclarations.toList()) {
if (targetDeclaration == null || !commonizer.commonizeWith(targetDeclaration))
return null
}
@@ -192,15 +158,15 @@ internal fun <T, R> commonize(declarations: List<T?>, commonizer: Commonizer<T,
}
@Suppress("NOTHING_TO_INLINE")
private inline fun <T, R> commonize(
containingDeclarationCommon: NullableLazyValue<*>?,
declarations: List<T?>,
private inline fun <T : Any, R> commonize(
parentCommonDeclaration: NullableLazyValue<*>?,
targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R>
): R? {
if (containingDeclarationCommon != null && containingDeclarationCommon.invoke() == null) {
// don't commonize declaration if it has commonizable containing declaration that has not been successfully commonized
if (parentCommonDeclaration != null && parentCommonDeclaration.invoke() == null) {
// don't commonize declaration if it's parent failed to commonize
return null
}
return commonize(declarations, commonizer)
return commonize(targetDeclarations, commonizer)
}
@@ -1,150 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
interface CirNode<T : CirDeclaration, R : CirDeclaration> {
val target: List<T?>
val common: NullableLazyValue<R>
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>
) : CirNode<CirRoot, CirRoot> {
class ClassifiersCacheImpl : CirClassifiersCache {
override val classes = HashMap<FqName, CirClassNode>()
override val typeAliases = HashMap<FqName, CirTypeAliasNode>()
}
val modules: MutableList<CirModuleNode> = ArrayList()
val cache = ClassifiersCacheImpl()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitRootNode(this, data)
override fun toString() = toString(this)
}
class CirModuleNode(
override val target: List<CirModule?>,
override val common: NullableLazyValue<CirModule>
) : CirNode<CirModule, CirModule> {
val packages: MutableList<CirPackageNode> = ArrayList()
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>
) : CirNodeWithFqName<CirPackage, CirPackage> {
lateinit var moduleName: Name
override lateinit var fqName: FqName
val properties: MutableList<CirPropertyNode> = ArrayList()
val functions: MutableList<CirFunctionNode> = ArrayList()
val classes: MutableList<CirClassNode> = ArrayList()
val typeAliases: MutableList<CirTypeAliasNode> = ArrayList()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPackageNode(this, data)
override fun toString() = toString(this)
}
class CirPropertyNode(
override val target: List<CirProperty?>,
override val common: NullableLazyValue<CirProperty>
) : 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(
override val target: List<CirFunction?>,
override val common: NullableLazyValue<CirFunction>
) : 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>
) : CirNodeWithFqName<CirClass, CirClass> {
override lateinit var fqName: FqName
val constructors: MutableList<CirClassConstructorNode> = ArrayList()
val properties: MutableList<CirPropertyNode> = ArrayList()
val functions: MutableList<CirFunctionNode> = ArrayList()
val classes: MutableList<CirClassNode> = ArrayList()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassNode(this, data)
override fun toString() = toString(this)
}
class CirClassConstructorNode(
override val target: List<CirClassConstructor?>,
override val common: NullableLazyValue<CirClassConstructor>
) : 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<CirClassifier>
) : CirNodeWithFqName<CirTypeAlias, CirClassifier> {
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 {
val classes: Map<FqName, CirClassNode>
val typeAliases: Map<FqName, CirTypeAliasNode>
}
internal inline val CirNode<*, *>.indexOfCommon: Int
get() = target.size
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>")
}
@@ -1,59 +0,0 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergePackages(
storageManager: StorageManager,
cacheRW: CirRootNode.ClassifiersCacheImpl,
moduleName: Name,
packageFqName: FqName,
packageMemberScopes: List<MemberScope?>
): CirPackageNode {
val node = buildPackageNode(storageManager, moduleName, packageFqName, packageMemberScopes)
val propertiesMap = CommonizedGroupMap<PropertyApproximationKey, PropertyDescriptor>(packageMemberScopes.size)
val functionsMap = CommonizedGroupMap<FunctionApproximationKey, SimpleFunctionDescriptor>(packageMemberScopes.size)
val classesMap = CommonizedGroupMap<Name, ClassDescriptor>(packageMemberScopes.size)
val typeAliasesMap = CommonizedGroupMap<Name, TypeAliasDescriptor>(packageMemberScopes.size)
packageMemberScopes.forEachIndexed { index, memberScope ->
memberScope?.collectMembers(
PropertyCollector { propertiesMap[PropertyApproximationKey(it)][index] = it },
FunctionCollector { functionsMap[FunctionApproximationKey(it)][index] = it },
ClassCollector { classesMap[it.name.intern()][index] = it },
TypeAliasCollector { typeAliasesMap[it.name.intern()][index] = it }
)
}
for ((_, propertiesGroup) in propertiesMap) {
node.properties += mergeProperties(storageManager, cacheRW, null, propertiesGroup.toList())
}
for ((_, functionsGroup) in functionsMap) {
node.functions += mergeFunctions(storageManager, cacheRW, null, functionsGroup.toList())
}
for ((_, classesGroup) in classesMap) {
node.classes += mergeClasses(storageManager, cacheRW, null, classesGroup.toList())
}
for ((_, typeAliasesGroup) in typeAliasesMap) {
node.typeAliases += mergeTypeAliases(storageManager, cacheRW, typeAliasesGroup.toList())
}
return node
}
@@ -1,34 +0,0 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeRoots(
storageManager: StorageManager,
targetProviders: List<TargetProvider>
): CirRootNode {
val node = buildRootNode(storageManager, targetProviders)
val modulesMap = CommonizedGroupMap<Name, ModuleDescriptor>(targetProviders.size)
targetProviders.forEachIndexed { index, targetProvider ->
for (module in targetProvider.modulesProvider.loadModules()) {
modulesMap[module.name.intern()][index] = module
}
}
for ((_, modulesGroup) in modulesMap) {
node.modules += mergeModules(storageManager, node.cache, modulesGroup.toList())
}
return node
}
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
internal class CommonizedGroup<T : Any>(
class CommonizedGroup<T : Any>(
val size: Int,
initialize: (Int) -> T?
) {
@@ -30,6 +30,7 @@ internal class CommonizedGroup<T : Any>(
elements[index] = value
}
// TODO: consider removing this method
fun toList(): List<T?> = object : AbstractList<T?>() {
override val size
get() = this@CommonizedGroup.size
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode.CirClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
@@ -25,11 +27,11 @@ import org.junit.Test
class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
private lateinit var cache: ClassifiersCacheImpl
private lateinit var cache: CirClassifiersCacheImpl
@Before
fun initialize() {
cache = ClassifiersCacheImpl() // reset cache
cache = CirClassifiersCacheImpl() // reset cache
}
@Test
@@ -454,10 +456,8 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
private fun prepareCache(variants: Array<out KotlinType>) {
check(variants.isNotEmpty())
val classesMap =
CommonizedGroupMap<FqName, ClassDescriptor>(variants.size)
val typeAliasesMap =
CommonizedGroupMap<FqName, TypeAliasDescriptor>(variants.size)
val classesMap = CommonizedGroupMap<FqName, ClassDescriptor>(variants.size)
val typeAliasesMap = CommonizedGroupMap<FqName, TypeAliasDescriptor>(variants.size)
fun recurse(type: KotlinType, index: Int) {
@Suppress("MoveVariableDeclarationIntoWhen")
@@ -476,12 +476,35 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
recurse(type, index)
}
for ((_, classesGroup) in classesMap) {
buildClassNode(LockBasedStorageManager.NO_LOCKS, cache, null, classesGroup.toList())
for ((fqName, classesGroup) in classesMap) {
buildClassNode(
LockBasedStorageManager.NO_LOCKS,
classesGroup.size,
cache,
null,
fqName
).also {
classesGroup.toList().forEachIndexed { index, clazz ->
if (clazz != null) {
it.targetDeclarations[index] = CirClassFactory.create(clazz)
}
}
}
}
for ((_, typeAliasesGroup) in typeAliasesMap) {
buildTypeAliasNode(LockBasedStorageManager.NO_LOCKS, cache, typeAliasesGroup.toList())
for ((fqName, typeAliasesGroup) in typeAliasesMap) {
buildTypeAliasNode(
LockBasedStorageManager.NO_LOCKS,
typeAliasesGroup.size,
cache,
fqName
).also {
typeAliasesGroup.toList().forEachIndexed { index, typeAlias ->
if (typeAlias != null) {
it.targetDeclarations[index] = CirTypeAliasFactory.create(typeAlias)
}
}
}
}
}