From 63575582c47a7e92c02081fd5581be28ae89e13b Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 17 Jun 2020 15:49:37 +0700 Subject: [PATCH] [Commonizer] Reduce memory consumption during approximation phase ^KT-39320 --- .../builder/DeclarationsBuilderVisitor1.kt | 14 +- .../builder/DeclarationsBuilderVisitor2.kt | 19 +- .../commonizer/builder/classDescriptors.kt | 10 +- .../descriptors/commonizer/builder/context.kt | 6 +- .../commonizer/builder/functionDescriptors.kt | 6 +- .../commonizer/builder/moduleDescriptors.kt | 6 +- .../commonizer/builder/packageFragments.kt | 6 +- .../commonizer/builder/propertyDescriptors.kt | 6 +- .../builder/typeAliasDescriptors.kt | 6 +- .../commonizer/core/CommonizationVisitor.kt | 46 ++--- .../commonizer/core/PackageCommonizer.kt | 22 +++ .../commonizer/core/TypeCommonizer.kt | 2 +- .../kotlin/descriptors/commonizer/facade.kt | 4 +- .../mergedtree/CirClassConstructorNode.kt | 20 ++ .../commonizer/mergedtree/CirClassNode.kt | 29 +++ .../mergedtree/CirClassifiersCache.kt | 13 ++ .../commonizer/mergedtree/CirFunctionNode.kt | 20 ++ .../commonizer/mergedtree/CirModuleNode.kt | 23 +++ .../commonizer/mergedtree/CirNode.kt | 36 ++++ .../mergedtree/CirNodeWithFqName.kt | 13 ++ .../commonizer/mergedtree/CirPackageNode.kt | 30 +++ .../commonizer/mergedtree/CirPropertyNode.kt | 20 ++ .../commonizer/mergedtree/CirRootNode.kt | 30 +++ .../commonizer/mergedtree/CirTreeMerger.kt | 175 +++++++++++++++++ .../commonizer/mergedtree/CirTypeAliasNode.kt | 24 +++ .../mergedtree/approximationKeys.kt | 47 +++++ .../commonizer/mergedtree/callableMembers.kt | 33 ---- .../commonizer/mergedtree/classifiers.kt | 62 ------ .../{memberScopes.kt => collectors.kt} | 65 ++++--- .../commonizer/mergedtree/modules.kt | 70 ------- .../commonizer/mergedtree/nodeBuilders.kt | 184 +++++++----------- .../commonizer/mergedtree/nodes.kt | 150 -------------- .../commonizer/mergedtree/packages.kt | 59 ------ .../descriptors/commonizer/mergedtree/root.kt | 34 ---- .../commonizer/utils/commonizedGroup.kt | 3 +- .../commonizer/core/TypeCommonizerTest.kt | 45 +++-- 36 files changed, 713 insertions(+), 625 deletions(-) create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassConstructorNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassifiersCache.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFunctionNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPropertyNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt create mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/callableMembers.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifiers.kt rename native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/{memberScopes.kt => collectors.kt} (55%) delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodes.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/root.kt diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt index 0291631cbb0..dff36419dd0 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt @@ -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>() // collect module descriptors: - for (moduleNode in node.modules) { + for (moduleNode in node.modules.values) { val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining() 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() 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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt index 7e131ef62b2..0819cf51e9d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt @@ -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): List { // 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>(node.dimension) { ArrayList() } - for (constructorNode in node.constructors) { + for (constructorNode in node.constructors.values) { val constructorsByTargets = constructorNode.accept(this, classes).asListContaining() 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()) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt index 048c1b7e0a3..248f399cff7 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt @@ -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, containingDeclarations: List ) { - 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, containingDeclarations: List ) { - 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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt index 033cc5db6ce..d4355aee963 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt @@ -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) { diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt index 4bd753bb187..b1334c92102 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt @@ -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, containingDeclarations: List ) { - 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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt index bb0a65e6a51..c5e4de5f859 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt @@ -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 ) { - 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()) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt index 37c769e69ba..b3e19779fc2 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt @@ -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, modules: List ) { - 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( diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt index 60cb766c814..0bb868a826d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt @@ -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, containingDeclarations: List ) { - 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) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt index 4df8fdb7e50..ffd01f37d45 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt @@ -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, containingDeclarations: List ) { - 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) } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt index 5e008dbd6ec..3508a4afb81 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt @@ -14,91 +14,91 @@ internal class CommonizationVisitor( ) : CirNodeVisitor { 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(node.target.size) - node.target.forEachIndexed { index, clazz -> + val supertypesMap = CommonizedGroupMap(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 } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt new file mode 100644 index 00000000000..a6d763d8ded --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt @@ -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() { + 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 +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt index a4274b78870..f660fb17336 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt @@ -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 } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt index e207e80cc68..a3659bc575c 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt @@ -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) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassConstructorNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassConstructorNode.kt new file mode 100644 index 00000000000..e879f769c22 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassConstructorNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue +) : CirNode { + override fun accept(visitor: CirNodeVisitor, data: T): R = + visitor.visitClassConstructorNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt new file mode 100644 index 00000000000..e1a360b8e14 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue, + override val fqName: FqName +) : CirNodeWithFqName { + + val constructors: MutableMap = HashMap() + val properties: MutableMap = HashMap() + val functions: MutableMap = HashMap() + val classes: MutableMap = HashMap() + + override fun accept(visitor: CirNodeVisitor, data: T): R = + visitor.visitClassNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassifiersCache.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassifiersCache.kt new file mode 100644 index 00000000000..b378b202a90 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassifiersCache.kt @@ -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 + val typeAliases: Map +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFunctionNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFunctionNode.kt new file mode 100644 index 00000000000..4f2ed3f62bf --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirFunctionNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue +) : CirNode { + override fun accept(visitor: CirNodeVisitor, data: T) = + visitor.visitFunctionNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt new file mode 100644 index 00000000000..f5e254dea3b --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue +) : CirNode { + val packages: MutableMap = HashMap() + + override fun accept(visitor: CirNodeVisitor, data: T) = + visitor.visitModuleNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt new file mode 100644 index 00000000000..d7559337fe2 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt @@ -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 { + val targetDeclarations: CommonizedGroup + val commonDeclaration: NullableLazyValue + + fun accept(visitor: CirNodeVisitor, 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 "") + } + } +} + diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt new file mode 100644 index 00000000000..2f4757cfba8 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt @@ -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 : CirNode { + val fqName: FqName +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt new file mode 100644 index 00000000000..4a661212ba0 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue, + override val fqName: FqName, + val moduleName: Name +) : CirNodeWithFqName { + + val properties: MutableMap = HashMap() + val functions: MutableMap = HashMap() + val classes: MutableMap = HashMap() + val typeAliases: MutableMap = HashMap() + + override fun accept(visitor: CirNodeVisitor, data: T) = + visitor.visitPackageNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPropertyNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPropertyNode.kt new file mode 100644 index 00000000000..7add0c5760a --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPropertyNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue +) : CirNode { + override fun accept(visitor: CirNodeVisitor, data: T) = + visitor.visitPropertyNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt new file mode 100644 index 00000000000..f409a687993 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue +) : CirNode { + class CirClassifiersCacheImpl : CirClassifiersCache { + override val classes = HashMap() + override val typeAliases = HashMap() + } + + val modules: MutableMap = HashMap() + val cache = CirClassifiersCacheImpl() + + override fun accept(visitor: CirNodeVisitor, data: T): R = + visitor.visitRootNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt new file mode 100644 index 00000000000..ed2e847c01c --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt @@ -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 +) { + 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 = targetProvider.modulesProvider.loadModules() + val modules: MutableMap = rootNode.modules + + moduleDescriptors.forEach { moduleDescriptor -> + processModule(modules, targetIndex, moduleDescriptor) + } + } + + private fun processModule( + modules: MutableMap, + 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 = moduleNode.packages + + moduleDescriptor.collectNonEmptyPackageMemberScopes { packageFqName, packageMemberScope -> + processPackage(packages, targetIndex, packageFqName.intern(), packageMemberScope, moduleName) + } + } + + private fun processPackage( + packages: MutableMap, + 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 = packageNode.properties + val functions: MutableMap = packageNode.functions + val classes: MutableMap = packageNode.classes + val typeAliases: MutableMap = 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, + 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, + 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, + 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 = classNode.commonDeclaration + + val constructors: MutableMap = classNode.constructors + val properties: MutableMap = classNode.properties + val functions: MutableMap = classNode.functions + val nestedClasses: MutableMap = 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, + 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, + 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) + } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt new file mode 100644 index 00000000000..7dfd566055c --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt @@ -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, + override val commonDeclaration: NullableLazyValue, + override val fqName: FqName +) : CirNodeWithFqName { + + override fun accept(visitor: CirNodeVisitor, data: T): R = + visitor.visitTypeAliasNode(this, data) + + override fun toString() = CirNode.toString(this) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt new file mode 100644 index 00000000000..466805da0a7 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt @@ -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>, + 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> +) { + constructor(constructor: ConstructorDescriptor) : this( + constructor.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters } + ) +} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/callableMembers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/callableMembers.kt deleted file mode 100644 index 31e6362aae9..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/callableMembers.kt +++ /dev/null @@ -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 -) = buildPropertyNode(storageManager, cache, containingDeclarationCommon, properties) - -internal fun mergeFunctions( - storageManager: StorageManager, - cache: CirClassifiersCache, - containingDeclarationCommon: NullableLazyValue<*>?, - properties: List -) = buildFunctionNode(storageManager, cache, containingDeclarationCommon, properties) - -internal fun mergeClassConstructors( - storageManager: StorageManager, - cache: CirClassifiersCache, - containingDeclarationCommon: NullableLazyValue<*>?, - constructors: List -) = buildClassConstructorNode(storageManager, cache, containingDeclarationCommon, constructors) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifiers.kt deleted file mode 100644 index 3e5d71d5241..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifiers.kt +++ /dev/null @@ -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 -): CirClassNode { - val node = buildClassNode(storageManager, cacheRW, containingDeclarationCommon, classes) - - val constructorsMap = CommonizedGroupMap(classes.size) - val propertiesMap = CommonizedGroupMap(classes.size) - val functionsMap = CommonizedGroupMap(classes.size) - val classesMap = CommonizedGroupMap(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 -) = buildTypeAliasNode(storageManager, cacheRW, typeAliases) - diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt similarity index 55% rename from native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt rename to native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt index 1dd5245abc5..d7c08358d12 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt @@ -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>, - 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> -) { - constructor(constructor: ConstructorDescriptor) : this( - constructor.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters } - ) -} \ No newline at end of file + 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) +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt deleted file mode 100644 index 97800266a47..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt +++ /dev/null @@ -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 -): CirModuleNode { - val node = buildModuleNode(storageManager, modules) - - val packageMemberScopesMap = CommonizedGroupMap(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) -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt index fa4655117ff..6d8873feb3a 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt @@ -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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 > buildNode( +private fun > buildNode( storageManager: StorageManager, - descriptors: List, - targetDeclarationProducer: (D) -> T, - commonValueProducer: (List) -> R?, - recursionMarker: R?, - nodeProducer: (List, NullableLazyValue) -> N + size: Int, + parentCommonDeclaration: NullableLazyValue<*>? = null, + commonizerProducer: () -> Commonizer, + recursionMarker: R? = null, + nodeProducer: (CommonizedGroup, NullableLazyValue) -> N ): N { - val declarationsGroup = CommonizedGroup(descriptors.size) - var canHaveCommon = descriptors.size > 1 + val targetDeclarations = CommonizedGroup(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 MutableMap.putSafe(key: K, value: V) = put(key, value)?.let { oldValue -> - error("${oldValue::class.java} with key=$key has been overwritten: $oldValue") -} - -internal fun commonize(declarations: List, commonizer: Commonizer): R? { - for (declaration in declarations) { - if (declaration == null || !commonizer.commonizeWith(declaration)) +internal fun commonize( + targetDeclarations: CommonizedGroup, + commonizer: Commonizer +): R? { + for (targetDeclaration in targetDeclarations.toList()) { + if (targetDeclaration == null || !commonizer.commonizeWith(targetDeclaration)) return null } @@ -192,15 +158,15 @@ internal fun commonize(declarations: List, commonizer: Commonizer commonize( - containingDeclarationCommon: NullableLazyValue<*>?, - declarations: List, +private inline fun commonize( + parentCommonDeclaration: NullableLazyValue<*>?, + targetDeclarations: CommonizedGroup, commonizer: Commonizer ): 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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodes.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodes.kt deleted file mode 100644 index cd6cd5bb858..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodes.kt +++ /dev/null @@ -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 { - val target: List - val common: NullableLazyValue - - fun accept(visitor: CirNodeVisitor, data: T): R -} - -interface CirNodeWithFqName : CirNode { - val fqName: FqName -} - -class CirRootNode( - override val target: List, - override val common: NullableLazyValue -) : CirNode { - class ClassifiersCacheImpl : CirClassifiersCache { - override val classes = HashMap() - override val typeAliases = HashMap() - } - - val modules: MutableList = ArrayList() - val cache = ClassifiersCacheImpl() - - override fun accept(visitor: CirNodeVisitor, data: T): R = - visitor.visitRootNode(this, data) - - override fun toString() = toString(this) -} - -class CirModuleNode( - override val target: List, - override val common: NullableLazyValue -) : CirNode { - val packages: MutableList = ArrayList() - - override fun accept(visitor: CirNodeVisitor, data: T) = - visitor.visitModuleNode(this, data) - - override fun toString() = toString(this) -} - -class CirPackageNode( - override val target: List, - override val common: NullableLazyValue -) : CirNodeWithFqName { - lateinit var moduleName: Name - override lateinit var fqName: FqName - - val properties: MutableList = ArrayList() - val functions: MutableList = ArrayList() - val classes: MutableList = ArrayList() - val typeAliases: MutableList = ArrayList() - - override fun accept(visitor: CirNodeVisitor, data: T) = - visitor.visitPackageNode(this, data) - - override fun toString() = toString(this) -} - -class CirPropertyNode( - override val target: List, - override val common: NullableLazyValue -) : CirNode { - override fun accept(visitor: CirNodeVisitor, data: T) = - visitor.visitPropertyNode(this, data) - - override fun toString() = toString(this) -} - -class CirFunctionNode( - override val target: List, - override val common: NullableLazyValue -) : CirNode { - override fun accept(visitor: CirNodeVisitor, data: T) = - visitor.visitFunctionNode(this, data) - - override fun toString() = toString(this) -} - -class CirClassNode( - override val target: List, - override val common: NullableLazyValue -) : CirNodeWithFqName { - override lateinit var fqName: FqName - - val constructors: MutableList = ArrayList() - val properties: MutableList = ArrayList() - val functions: MutableList = ArrayList() - val classes: MutableList = ArrayList() - - override fun accept(visitor: CirNodeVisitor, data: T): R = - visitor.visitClassNode(this, data) - - override fun toString() = toString(this) -} - -class CirClassConstructorNode( - override val target: List, - override val common: NullableLazyValue -) : CirNode { - override fun accept(visitor: CirNodeVisitor, data: T): R = - visitor.visitClassConstructorNode(this, data) - - override fun toString() = toString(this) -} - -class CirTypeAliasNode( - override val target: List, - override val common: NullableLazyValue -) : CirNodeWithFqName { - override lateinit var fqName: FqName - - override fun accept(visitor: CirNodeVisitor, data: T): R = - visitor.visitTypeAliasNode(this, data) - - override fun toString() = toString(this) -} - -interface CirClassifiersCache { - val classes: Map - val typeAliases: Map -} - -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 "") -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt deleted file mode 100644 index 44bbddf8c67..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/packages.kt +++ /dev/null @@ -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 -): CirPackageNode { - val node = buildPackageNode(storageManager, moduleName, packageFqName, packageMemberScopes) - - val propertiesMap = CommonizedGroupMap(packageMemberScopes.size) - val functionsMap = CommonizedGroupMap(packageMemberScopes.size) - val classesMap = CommonizedGroupMap(packageMemberScopes.size) - val typeAliasesMap = CommonizedGroupMap(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 -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/root.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/root.kt deleted file mode 100644 index 54e697e1ace..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/root.kt +++ /dev/null @@ -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 -): CirRootNode { - val node = buildRootNode(storageManager, targetProviders) - - val modulesMap = CommonizedGroupMap(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 -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/commonizedGroup.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/commonizedGroup.kt index 2ca4881d390..cff88ca67fe 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/commonizedGroup.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/commonizedGroup.kt @@ -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( +class CommonizedGroup( val size: Int, initialize: (Int) -> T? ) { @@ -30,6 +30,7 @@ internal class CommonizedGroup( elements[index] = value } + // TODO: consider removing this method fun toList(): List = object : AbstractList() { override val size get() = this@CommonizedGroup.size diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt index 43e84be5572..d7640d64254 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt @@ -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() { - 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() { private fun prepareCache(variants: Array) { check(variants.isNotEmpty()) - val classesMap = - CommonizedGroupMap(variants.size) - val typeAliasesMap = - CommonizedGroupMap(variants.size) + val classesMap = CommonizedGroupMap(variants.size) + val typeAliasesMap = CommonizedGroupMap(variants.size) fun recurse(type: KotlinType, index: Int) { @Suppress("MoveVariableDeclarationIntoWhen") @@ -476,12 +476,35 @@ class TypeCommonizerTest : AbstractCommonizerTest() { 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) + } + } + } } }