[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.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedPackageFragmentProvider.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.*
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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
@@ -29,12 +31,12 @@ internal class DeclarationsBuilderVisitor1(
check(data.isEmpty()) // root node may not have containing declarations check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension) 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>>() val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
// collect module descriptors: // collect module descriptors:
for (moduleNode in node.modules) { for (moduleNode in node.modules.values) {
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>() val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
modules.forEachIndexed { index, module -> modules.forEachIndexed { index, module ->
val target = allTargets[index] val target = allTargets[index]
@@ -58,7 +60,7 @@ internal class DeclarationsBuilderVisitor1(
// build package fragments: // build package fragments:
val packageFragmentProviders = CommonizedPackageFragmentProvider.createArray(node.dimension) 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>() val packageFragments = packageNode.accept(this, moduleDescriptors).asListContaining<PackageFragmentDescriptor>()
packageFragmentProviders += packageFragments packageFragmentProviders += packageFragments
} }
@@ -81,10 +83,10 @@ internal class DeclarationsBuilderVisitor1(
// build package members: // build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension) val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) { for (classNode in node.classes.values) {
packageMemberScopes += classNode.accept(this, packageFragments) packageMemberScopes += classNode.accept(this, packageFragments)
} }
for (typeAliasNode in node.typeAliases) { for (typeAliasNode in node.typeAliases.values) {
packageMemberScopes += typeAliasNode.accept(this, packageFragments) packageMemberScopes += typeAliasNode.accept(this, packageFragments)
} }
@@ -109,7 +111,7 @@ internal class DeclarationsBuilderVisitor1(
// build class members: // build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension) val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) { for (classNode in node.classes.values) {
classMemberScopes += classNode.accept(this, classes) 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.noContainingDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noReturningDeclarations import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noReturningDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* 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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
@@ -29,7 +30,7 @@ internal class DeclarationsBuilderVisitor2(
check(components.targetComponents.size == node.dimension) check(components.targetComponents.size == node.dimension)
// visit module descriptors: // visit module descriptors:
for (moduleNode in node.modules) { for (moduleNode in node.modules.values) {
moduleNode.accept(this, noContainingDeclarations()) moduleNode.accept(this, noContainingDeclarations())
} }
@@ -38,7 +39,7 @@ internal class DeclarationsBuilderVisitor2(
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> { override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// visit package fragment descriptors: // visit package fragment descriptors:
for (packageNode in node.packages) { for (packageNode in node.packages.values) {
packageNode.accept(this, noContainingDeclarations()) packageNode.accept(this, noContainingDeclarations())
} }
@@ -50,14 +51,14 @@ internal class DeclarationsBuilderVisitor2(
// build non-classifier package members: // build non-classifier package members:
val packageMemberScopes = packageFragments.map { it?.getMemberScope() } val packageMemberScopes = packageFragments.map { it?.getMemberScope() }
for (propertyNode in node.properties) { for (propertyNode in node.properties.values) {
packageMemberScopes += propertyNode.accept(this, packageFragments) packageMemberScopes += propertyNode.accept(this, packageFragments)
} }
for (functionNode in node.functions) { for (functionNode in node.functions.values) {
packageMemberScopes += functionNode.accept(this, packageFragments) packageMemberScopes += functionNode.accept(this, packageFragments)
} }
for (classNode in node.classes) { for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations()) classNode.accept(this, noContainingDeclarations())
} }
@@ -83,7 +84,7 @@ internal class DeclarationsBuilderVisitor2(
// build class constructors: // build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() } 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>() val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor -> constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor) if (constructor != null) allConstructorsByTargets[index].add(constructor)
@@ -97,14 +98,14 @@ internal class DeclarationsBuilderVisitor2(
// build class members: // build class members:
val classMemberScopes = classes.map { it?.unsubstitutedMemberScope } val classMemberScopes = classes.map { it?.unsubstitutedMemberScope }
for (propertyNode in node.properties) { for (propertyNode in node.properties.values) {
classMemberScopes += propertyNode.accept(this, classes) classMemberScopes += propertyNode.accept(this, classes)
} }
for (functionNode in node.functions) { for (functionNode in node.functions.values) {
classMemberScopes += functionNode.accept(this, classes) classMemberScopes += functionNode.accept(this, classes)
} }
for (classNode in node.classes) { for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations()) 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.cir.CirClassConstructor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassConstructorNode import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassConstructorNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassNode 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.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -22,10 +22,10 @@ internal fun CirClassNode.buildDescriptors(
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>, output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?> containingDeclarations: List<DeclarationDescriptor?>
) { ) {
val commonClass = common() val commonClass = commonDeclaration()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY 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) clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
} }
@@ -78,10 +78,10 @@ internal fun CirClassConstructorNode.buildDescriptors(
output: CommonizedGroup<ClassConstructorDescriptor>, output: CommonizedGroup<ClassConstructorDescriptor>,
containingDeclarations: List<CommonizedClassDescriptor?> containingDeclarations: List<CommonizedClassDescriptor?>
) { ) {
val commonConstructor = common() val commonConstructor = commonDeclaration()
val markAsActual = commonConstructor != null val markAsActual = commonConstructor != null
target.forEachIndexed { index, constructor -> targetDeclarations.toList().forEachIndexed { index, constructor ->
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual) 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.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.Target 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.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.stats.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
@@ -172,7 +172,7 @@ fun CirRootNode.createGlobalBuilderComponents(
val targetContexts = (0 until dimension).map { index -> val targetContexts = (0 until dimension).map { index ->
val isCommon = index == indexOfCommon 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() val builtIns = root.builtInsProvider.loadBuiltIns()
check(builtIns::class.java.name == root.builtInsClass) { 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.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunction import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirFunctionNode 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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -20,10 +20,10 @@ internal fun CirFunctionNode.buildDescriptors(
output: CommonizedGroup<SimpleFunctionDescriptor>, output: CommonizedGroup<SimpleFunctionDescriptor>,
containingDeclarations: List<DeclarationDescriptor?> containingDeclarations: List<DeclarationDescriptor?>
) { ) {
val commonFunction = common() val commonFunction = commonDeclaration()
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED 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) 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.cir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirModuleNode 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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
@@ -15,11 +15,11 @@ internal fun CirModuleNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents, components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl> output: CommonizedGroup<ModuleDescriptorImpl>
) { ) {
target.forEachIndexed { index, module -> targetDeclarations.toList().forEachIndexed { index, module ->
module?.buildDescriptor(components, output, index) module?.buildDescriptor(components, output, index)
} }
common()?.buildDescriptor(components, output, indexOfCommon) commonDeclaration()?.buildDescriptor(components, output, indexOfCommon)
// log stats // log stats
components.statsCollector?.logStats(output.toList()) 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.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPackageNode 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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
@@ -19,11 +19,11 @@ internal fun CirPackageNode.buildDescriptors(
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>, output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?> modules: List<ModuleDescriptorImpl?>
) { ) {
target.forEachIndexed { index, pkg -> targetDeclarations.toList().forEachIndexed { index, pkg ->
pkg?.buildDescriptor(components, output, index, modules) pkg?.buildDescriptor(components, output, index, modules)
} }
common()?.buildDescriptor(components, output, indexOfCommon, modules) commonDeclaration()?.buildDescriptor(components, output, indexOfCommon, modules)
} }
private fun CirPackage.buildDescriptor( 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.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPropertyNode 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.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
@@ -23,7 +23,7 @@ internal fun CirPropertyNode.buildDescriptors(
output: CommonizedGroup<PropertyDescriptor>, output: CommonizedGroup<PropertyDescriptor>,
containingDeclarations: List<DeclarationDescriptor?> containingDeclarations: List<DeclarationDescriptor?>
) { ) {
val commonProperty = common() val commonProperty = commonDeclaration()
val isLiftedUp = commonProperty?.isLiftedUp == true val isLiftedUp = commonProperty?.isLiftedUp == true
val markAsExpectAndActual = commonProperty != null val markAsExpectAndActual = commonProperty != null
@@ -31,7 +31,7 @@ internal fun CirPropertyNode.buildDescriptors(
&& !isLiftedUp && !isLiftedUp
if (!isLiftedUp) { if (!isLiftedUp) {
target.forEachIndexed { index, property -> targetDeclarations.toList().forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual) 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.CirClassifier
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirTypeAliasNode 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.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -20,7 +20,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>, output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?> containingDeclarations: List<DeclarationDescriptor?>
) { ) {
val commonClassifier: CirClassifier? = common() val commonClassifier: CirClassifier? = commonDeclaration()
// Note: 'expect class' and lifted up 'typealias' both can't be non-null // Note: 'expect class' and lifted up 'typealias' both can't be non-null
val commonTypeAlias: CirTypeAlias? = commonClassifier as? CirTypeAlias? val commonTypeAlias: CirTypeAlias? = commonClassifier as? CirTypeAlias?
@@ -28,7 +28,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
val markAsActual = commonClassifier != null val markAsActual = commonClassifier != null
if (!isLiftedUp) { if (!isLiftedUp) {
target.forEachIndexed { index, typeAlias -> targetDeclarations.toList().forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual) typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
} }
} }
@@ -14,91 +14,91 @@ internal class CommonizationVisitor(
) : CirNodeVisitor<Unit, Unit> { ) : CirNodeVisitor<Unit, Unit> {
override fun visitRootNode(node: CirRootNode, data: Unit) { override fun visitRootNode(node: CirRootNode, data: Unit) {
check(node === root) 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) module.accept(this, Unit)
} }
} }
override fun visitModuleNode(node: CirModuleNode, data: 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) pkg.accept(this, Unit)
} }
} }
override fun visitPackageNode(node: CirPackageNode, data: 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) property.accept(this, Unit)
} }
node.functions.forEach { function -> node.functions.values.forEach { function ->
function.accept(this, Unit) function.accept(this, Unit)
} }
node.classes.forEach { clazz -> node.classes.values.forEach { clazz ->
clazz.accept(this, Unit) clazz.accept(this, Unit)
} }
node.typeAliases.forEach { typeAlias -> node.typeAliases.values.forEach { typeAlias ->
typeAlias.accept(this, Unit) typeAlias.accept(this, Unit)
} }
} }
override fun visitPropertyNode(node: CirPropertyNode, data: Unit) { override fun visitPropertyNode(node: CirPropertyNode, data: Unit) {
node.common() // commonize property node.commonDeclaration() // commonize property
} }
override fun visitFunctionNode(node: CirFunctionNode, data: Unit) { override fun visitFunctionNode(node: CirFunctionNode, data: Unit) {
node.common() // commonize function node.commonDeclaration() // commonize function
} }
override fun visitClassNode(node: CirClassNode, data: Unit) { 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) constructor.accept(this, Unit)
} }
node.properties.forEach { property -> node.properties.values.forEach { property ->
property.accept(this, Unit) property.accept(this, Unit)
} }
node.functions.forEach { function -> node.functions.values.forEach { function ->
function.accept(this, Unit) function.accept(this, Unit)
} }
node.classes.forEach { clazz -> node.classes.values.forEach { clazz ->
clazz.accept(this, Unit) clazz.accept(this, Unit)
} }
if (commonClass != null) { if (commonClass != null) {
// companion object should have the same FQ name for each target class, then it could be set to common class // 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) { if (companionObjectFqName != null) {
val companionObjectNode = root.cache.classes[companionObjectFqName] val companionObjectNode = root.cache.classes[companionObjectFqName]
?: error("Can't find companion object with FQ name $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 // companion object has been successfully commonized
commonClass.companion = companionObjectFqName commonClass.companion = companionObjectFqName
} }
} }
// find out common (and commonized) supertypes // find out common (and commonized) supertypes
val supertypesMap = CommonizedGroupMap<String, CirType>(node.target.size) val supertypesMap = CommonizedGroupMap<String, CirType>(node.targetDeclarations.size)
node.target.forEachIndexed { index, clazz -> node.targetDeclarations.toList().forEachIndexed { index, clazz ->
for (supertype in clazz!!.supertypes) { for (supertype in clazz!!.supertypes) {
supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype
} }
} }
for ((_, supertypesGroup) in supertypesMap) { for ((_, supertypesGroup) in supertypesMap) {
val commonSupertype = commonize(supertypesGroup.toList(), TypeCommonizer(root.cache)) val commonSupertype = commonize(supertypesGroup, TypeCommonizer(root.cache))
if (commonSupertype != null) if (commonSupertype != null)
commonClass.supertypes.add(commonSupertype) commonClass.supertypes.add(commonSupertype)
} }
@@ -106,10 +106,10 @@ internal class CommonizationVisitor(
} }
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: Unit) { override fun visitClassConstructorNode(node: CirClassConstructorNode, data: Unit) {
node.common() // commonize constructor node.commonDeclaration() // commonize constructor
} }
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: Unit) { 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 true
} else { } else {
// If entry is present, then contents (common declaration) should not be null. // 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.DeclarationsBuilderVisitor2
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor 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 import org.jetbrains.kotlin.storage.LockBasedStorageManager
fun runCommonization(parameters: Parameters): Result { fun runCommonization(parameters: Parameters): Result {
@@ -20,7 +20,7 @@ fun runCommonization(parameters: Parameters): Result {
val storageManager = LockBasedStorageManager("Declaration descriptors commonization") val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
// build merged tree: // build merged tree:
val mergedTree = mergeRoots(storageManager, parameters.targetProviders) val mergedTree = CirTreeMerger(storageManager, parameters.targetProviders).merge()
// commonize: // commonize:
mergedTree.accept(CommonizationVisitor(mergedTree), Unit) 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 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.*
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.utils.* 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.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.alwaysTrue
internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescriptor) -> Boolean) = internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescriptor) -> Boolean) =
getContributedDescriptors().forEach { member -> getContributedDescriptors().forEach { member ->
@@ -60,35 +62,34 @@ internal inline fun FunctionCollector(
} }
} }
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */ // collects member scopes for every non-empty package provided by this module
internal data class PropertyApproximationKey( internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqName, MemberScope) -> Unit) {
val name: Name, // we don's need to process fragments from other modules which are the dependencies of this module, so
val extensionReceiverParameter: String? // let's use the appropriate package fragment provider
) { val packageFragmentProvider = this.packageFragmentProvider
constructor(property: PropertyDescriptor) : this(
property.name.intern(),
property.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
/** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */ fun recurse(packageFqName: FqName) {
internal data class FunctionApproximationKey( if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
val name: Name, return
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 */ val ownPackageFragments = packageFragmentProvider.getPackageFragments(packageFqName)
internal data class ConstructorApproximationKey( val ownPackageMemberScopes = ownPackageFragments.asSequence()
val valueParameters: List<Pair<Name, String>> .filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
) { .map { it.getMemberScope() }
constructor(constructor: ConstructorDescriptor) : this( .filter { it != MemberScope.Empty }
constructor.valueParameters.map { it.name.intern() to it.type.fqNameWithTypeParameters } .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 package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.cir.*
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.impl.CirClassRecursionMarker import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassRecursionMarker
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassifierRecursionMarker import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassifierRecursionMarker
import org.jetbrains.kotlin.descriptors.commonizer.core.* 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.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.FqName
import org.jetbrains.kotlin.name.Name 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.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
internal fun buildRootNode( internal fun buildRootNode(
storageManager: StorageManager, storageManager: StorageManager,
targetProviders: List<TargetProvider> size: Int
): CirRootNode = buildNode( ): CirRootNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = targetProviders, size = size,
targetDeclarationProducer = { CirRootFactory.create(it.target, it.builtInsClass.name, it.builtInsProvider) }, commonizerProducer = ::RootCommonizer,
commonValueProducer = { commonize(it, RootCommonizer()) },
recursionMarker = null,
nodeProducer = ::CirRootNode nodeProducer = ::CirRootNode
) )
internal fun buildModuleNode( internal fun buildModuleNode(
storageManager: StorageManager, storageManager: StorageManager,
modules: List<ModuleDescriptor?> size: Int
): CirModuleNode = buildNode( ): CirModuleNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = modules, size = size,
targetDeclarationProducer = CirModuleFactory::create, commonizerProducer = ::ModuleCommonizer,
commonValueProducer = { commonize(it, ModuleCommonizer()) },
recursionMarker = null,
nodeProducer = ::CirModuleNode nodeProducer = ::CirModuleNode
) )
internal fun buildPackageNode( internal fun buildPackageNode(
storageManager: StorageManager, storageManager: StorageManager,
moduleName: Name, size: Int,
packageFqName: FqName, fqName: FqName,
packageMemberScopes: List<MemberScope?> moduleName: Name
): CirPackageNode = buildNode( ): CirPackageNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = packageMemberScopes, size = size,
targetDeclarationProducer = { CirPackageFactory.create(packageFqName) }, commonizerProducer = ::PackageCommonizer,
commonValueProducer = { CirPackageFactory.create(packageFqName) }, nodeProducer = { targetDeclarations, commonDeclaration ->
recursionMarker = null, CirPackageNode(targetDeclarations, commonDeclaration, fqName, moduleName)
nodeProducer = ::CirPackageNode }
).also { node -> )
node.moduleName = moduleName
node.fqName = packageFqName
}
internal fun buildPropertyNode( internal fun buildPropertyNode(
storageManager: StorageManager, storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache, cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?, parentCommonDeclaration: NullableLazyValue<*>?
properties: List<PropertyDescriptor?>
): CirPropertyNode = buildNode( ): CirPropertyNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = properties, size = size,
targetDeclarationProducer = CirPropertyFactory::create, parentCommonDeclaration = parentCommonDeclaration,
commonValueProducer = { commonize(containingDeclarationCommon, it, PropertyCommonizer(cache)) }, commonizerProducer = { PropertyCommonizer(cache) },
recursionMarker = null,
nodeProducer = ::CirPropertyNode nodeProducer = ::CirPropertyNode
) )
internal fun buildFunctionNode( internal fun buildFunctionNode(
storageManager: StorageManager, storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache, cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?, parentCommonDeclaration: NullableLazyValue<*>?
functions: List<SimpleFunctionDescriptor?>
): CirFunctionNode = buildNode( ): CirFunctionNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = functions, size = size,
targetDeclarationProducer = CirFunctionFactory::create, parentCommonDeclaration = parentCommonDeclaration,
commonValueProducer = { commonize(containingDeclarationCommon, it, FunctionCommonizer(cache)) }, commonizerProducer = { FunctionCommonizer(cache) },
recursionMarker = null,
nodeProducer = ::CirFunctionNode nodeProducer = ::CirFunctionNode
) )
internal fun buildClassNode( internal fun buildClassNode(
storageManager: StorageManager, storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl, size: Int,
containingDeclarationCommon: NullableLazyValue<*>?, cacheRW: CirClassifiersCacheImpl,
classes: List<ClassDescriptor?> parentCommonDeclaration: NullableLazyValue<*>?,
fqName: FqName
): CirClassNode = buildNode( ): CirClassNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = classes, size = size,
targetDeclarationProducer = CirClassFactory::create, parentCommonDeclaration = parentCommonDeclaration,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) }, commonizerProducer = { ClassCommonizer(cacheRW) },
recursionMarker = CirClassRecursionMarker, recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode nodeProducer = { targetDeclarations, commonDeclaration ->
).also { node -> CirClassNode(targetDeclarations, commonDeclaration, fqName).also {
classes.firstNonNull().fqNameSafe.intern().let { fqName -> cacheRW.classes[fqName] = it
node.fqName = fqName }
cacheRW.classes.putSafe(fqName, node)
} }
} )
internal fun buildClassConstructorNode( internal fun buildClassConstructorNode(
storageManager: StorageManager, storageManager: StorageManager,
size: Int,
cache: CirClassifiersCache, cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?, parentCommonDeclaration: NullableLazyValue<*>?
constructors: List<ClassConstructorDescriptor?>
): CirClassConstructorNode = buildNode( ): CirClassConstructorNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = constructors, size = size,
targetDeclarationProducer = CirClassConstructorFactory::create, parentCommonDeclaration = parentCommonDeclaration,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassConstructorCommonizer(cache)) }, commonizerProducer = { ClassConstructorCommonizer(cache) },
recursionMarker = null,
nodeProducer = ::CirClassConstructorNode nodeProducer = ::CirClassConstructorNode
) )
internal fun buildTypeAliasNode( internal fun buildTypeAliasNode(
storageManager: StorageManager, storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl, size: Int,
typeAliases: List<TypeAliasDescriptor?> cacheRW: CirClassifiersCacheImpl,
fqName: FqName
): CirTypeAliasNode = buildNode( ): CirTypeAliasNode = buildNode(
storageManager = storageManager, storageManager = storageManager,
descriptors = typeAliases, size = size,
targetDeclarationProducer = CirTypeAliasFactory::create, commonizerProducer = { TypeAliasCommonizer(cacheRW) },
commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) },
recursionMarker = CirClassifierRecursionMarker, recursionMarker = CirClassifierRecursionMarker,
nodeProducer = ::CirTypeAliasNode nodeProducer = { targetDeclarations, commonDeclaration ->
).also { node -> CirTypeAliasNode(targetDeclarations, commonDeclaration, fqName).also {
typeAliases.firstNonNull().fqNameSafe.intern().let { fqName -> cacheRW.typeAliases[fqName] = it
node.fqName = fqName }
cacheRW.typeAliases.putSafe(fqName, node)
} }
} )
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, storageManager: StorageManager,
descriptors: List<D?>, size: Int,
targetDeclarationProducer: (D) -> T, parentCommonDeclaration: NullableLazyValue<*>? = null,
commonValueProducer: (List<T?>) -> R?, commonizerProducer: () -> Commonizer<T, R>,
recursionMarker: R?, recursionMarker: R? = null,
nodeProducer: (List<T?>, NullableLazyValue<R>) -> N nodeProducer: (CommonizedGroup<T>, NullableLazyValue<R>) -> N
): N { ): N {
val declarationsGroup = CommonizedGroup<T>(descriptors.size) val targetDeclarations = CommonizedGroup<T>(size)
var canHaveCommon = descriptors.size > 1
descriptors.forEachIndexed { index, descriptor -> val commonComputable = { commonize(parentCommonDeclaration, targetDeclarations, commonizerProducer()) }
if (descriptor != null)
declarationsGroup[index] = targetDeclarationProducer(descriptor)
else
canHaveCommon = false
}
val declarations = declarationsGroup.toList()
val commonComputable: () -> R? = if (canHaveCommon) {
{ commonValueProducer(declarations) }
} else {
{ null }
}
val commonLazyValue = if (recursionMarker != null) val commonLazyValue = if (recursionMarker != null)
storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker) storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker)
else else
storageManager.createNullableLazyValue(commonComputable) storageManager.createNullableLazyValue(commonComputable)
return nodeProducer(declarations, commonLazyValue) return nodeProducer(targetDeclarations, commonLazyValue)
} }
@Suppress("NOTHING_TO_INLINE") internal fun <T : Any, R> commonize(
private inline fun <K, V : Any> MutableMap<K, V>.putSafe(key: K, value: V) = put(key, value)?.let { oldValue -> targetDeclarations: CommonizedGroup<T>,
error("${oldValue::class.java} with key=$key has been overwritten: $oldValue") commonizer: Commonizer<T, R>
} ): R? {
for (targetDeclaration in targetDeclarations.toList()) {
internal fun <T, R> commonize(declarations: List<T?>, commonizer: Commonizer<T, R>): R? { if (targetDeclaration == null || !commonizer.commonizeWith(targetDeclaration))
for (declaration in declarations) {
if (declaration == null || !commonizer.commonizeWith(declaration))
return null return null
} }
@@ -192,15 +158,15 @@ internal fun <T, R> commonize(declarations: List<T?>, commonizer: Commonizer<T,
} }
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
private inline fun <T, R> commonize( private inline fun <T : Any, R> commonize(
containingDeclarationCommon: NullableLazyValue<*>?, parentCommonDeclaration: NullableLazyValue<*>?,
declarations: List<T?>, targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R> commonizer: Commonizer<T, R>
): R? { ): R? {
if (containingDeclarationCommon != null && containingDeclarationCommon.invoke() == null) { if (parentCommonDeclaration != null && parentCommonDeclaration.invoke() == null) {
// don't commonize declaration if it has commonizable containing declaration that has not been successfully commonized // don't commonize declaration if it's parent failed to commonize
return null 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 package org.jetbrains.kotlin.descriptors.commonizer.utils
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */ /** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
internal class CommonizedGroup<T : Any>( class CommonizedGroup<T : Any>(
val size: Int, val size: Int,
initialize: (Int) -> T? initialize: (Int) -> T?
) { ) {
@@ -30,6 +30,7 @@ internal class CommonizedGroup<T : Any>(
elements[index] = value elements[index] = value
} }
// TODO: consider removing this method
fun toList(): List<T?> = object : AbstractList<T?>() { fun toList(): List<T?> = object : AbstractList<T?>() {
override val size override val size
get() = this@CommonizedGroup.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.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType 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.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.buildClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildTypeAliasNode import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.buildTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
@@ -25,11 +27,11 @@ import org.junit.Test
class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() { class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
private lateinit var cache: ClassifiersCacheImpl private lateinit var cache: CirClassifiersCacheImpl
@Before @Before
fun initialize() { fun initialize() {
cache = ClassifiersCacheImpl() // reset cache cache = CirClassifiersCacheImpl() // reset cache
} }
@Test @Test
@@ -454,10 +456,8 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
private fun prepareCache(variants: Array<out KotlinType>) { private fun prepareCache(variants: Array<out KotlinType>) {
check(variants.isNotEmpty()) check(variants.isNotEmpty())
val classesMap = val classesMap = CommonizedGroupMap<FqName, ClassDescriptor>(variants.size)
CommonizedGroupMap<FqName, ClassDescriptor>(variants.size) val typeAliasesMap = CommonizedGroupMap<FqName, TypeAliasDescriptor>(variants.size)
val typeAliasesMap =
CommonizedGroupMap<FqName, TypeAliasDescriptor>(variants.size)
fun recurse(type: KotlinType, index: Int) { fun recurse(type: KotlinType, index: Int) {
@Suppress("MoveVariableDeclarationIntoWhen") @Suppress("MoveVariableDeclarationIntoWhen")
@@ -476,12 +476,35 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
recurse(type, index) recurse(type, index)
} }
for ((_, classesGroup) in classesMap) { for ((fqName, classesGroup) in classesMap) {
buildClassNode(LockBasedStorageManager.NO_LOCKS, cache, null, classesGroup.toList()) 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) { for ((fqName, typeAliasesGroup) in typeAliasesMap) {
buildTypeAliasNode(LockBasedStorageManager.NO_LOCKS, cache, typeAliasesGroup.toList()) buildTypeAliasNode(
LockBasedStorageManager.NO_LOCKS,
typeAliasesGroup.size,
cache,
fqName
).also {
typeAliasesGroup.toList().forEachIndexed { index, typeAlias ->
if (typeAlias != null) {
it.targetDeclarations[index] = CirTypeAliasFactory.create(typeAlias)
}
}
}
} }
} }