From 2cde0a800a0c54ae863071218f585bde789839c0 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 25 Sep 2019 15:36:44 +0700 Subject: [PATCH] [Commonizer] Fine-grained use of KotlinBuiltIns --- konan/commonizer/build.gradle.kts | 3 +- .../builder/DeclarationsBuilderVisitor.kt | 4 +- .../commonizer/builder/moduleDescriptors.kt | 11 +-- .../commonizer/core/ModuleCommonizer.kt | 45 +++++++++++ .../kotlin/descriptors/commonizer/facade.kt | 3 +- .../commonizer/mergedtree/ir/Module.kt | 5 +- .../commonizer/mergedtree/ir/nodeBuilders.kt | 2 +- .../commonizer/mergedtree/modules.kt | 1 - .../core/DefaultModuleCommonizerTest.kt | 79 +++++++++++++++++++ 9 files changed, 136 insertions(+), 17 deletions(-) create mode 100644 konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt create mode 100644 konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultModuleCommonizerTest.kt diff --git a/konan/commonizer/build.gradle.kts b/konan/commonizer/build.gradle.kts index 3f93a07cf47..d64f18700de 100644 --- a/konan/commonizer/build.gradle.kts +++ b/konan/commonizer/build.gradle.kts @@ -9,7 +9,8 @@ dependencies { compile(kotlinStdlib()) - compile(project(":kotlin-native:kotlin-native-utils")) + compile(project(":kotlin-native:kotlin-native-utils")) { isTransitive = false } + compile(project(":kotlin-native:kotlin-native-library-reader")) { isTransitive = false } testCompile(commonDep("junit:junit")) testCompile(projectTests(":compiler:tests-common")) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt index 4709b8e302e..5e0672753ca 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.Target @@ -20,7 +19,6 @@ import org.jetbrains.kotlin.utils.addIfNotNull /** Builds and initializes the new tree of common descriptors */ internal class DeclarationsBuilderVisitor( private val storageManager: StorageManager, - private val builtIns: KotlinBuiltIns, private val collector: (Target, Collection) -> Unit ) : NodeVisitor, List> { override fun visitRootNode(node: RootNode, data: List): List { @@ -54,7 +52,7 @@ internal class DeclarationsBuilderVisitor( override fun visitModuleNode(node: ModuleNode, data: List): List { // build module descriptors: val moduleDescriptorsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(moduleDescriptorsGroup, storageManager, builtIns) + node.buildDescriptors(moduleDescriptorsGroup, storageManager) val moduleDescriptors = moduleDescriptorsGroup.toList() // build package fragments: diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt index 0ce75fc1a59..4914532209f 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.Module import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.ModuleNode @@ -15,21 +14,19 @@ import org.jetbrains.kotlin.storage.StorageManager internal fun ModuleNode.buildDescriptors( output: CommonizedGroup, - storageManager: StorageManager, - builtIns: KotlinBuiltIns + storageManager: StorageManager ) { target.forEachIndexed { index, module -> - module?.buildDescriptor(output, index, storageManager, builtIns) + module?.buildDescriptor(output, index, storageManager) } - common()?.buildDescriptor(output, indexOfCommon, storageManager, builtIns) + common()?.buildDescriptor(output, indexOfCommon, storageManager) } private fun Module.buildDescriptor( output: CommonizedGroup, index: Int, - storageManager: StorageManager, - builtIns: KotlinBuiltIns + storageManager: StorageManager ) { val moduleDescriptor = ModuleDescriptorImpl( moduleName = name, diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt new file mode 100644 index 00000000000..6626f24fc13 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt @@ -0,0 +1,45 @@ +/* + * 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.core + +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.Module +import org.jetbrains.kotlin.name.Name + +interface ModuleCommonizer : Commonizer { + companion object { + fun default(): ModuleCommonizer = DefaultModuleCommonizer() + } +} + +private class DefaultModuleCommonizer : ModuleCommonizer, AbstractStandardCommonizer() { + private lateinit var name: Name + private var konanBuiltIns: KonanBuiltIns? = null + + override fun commonizationResult() = Module( + name = name, + builtIns = konanBuiltIns ?: DefaultBuiltIns.Instance + ) + + override fun initialize(first: Module) { + name = first.name + konanBuiltIns = first.konanBuiltIns + } + + override fun doCommonizeWith(next: Module): Boolean { + // keep the first met KonanBuiltIns when all targets are Kotlin/Native + // otherwise use DefaultBuiltIns + if (konanBuiltIns != null) { + konanBuiltIns = konanBuiltIns.takeIf { next.konanBuiltIns != null } + } + + return true + } + + private inline val Module.konanBuiltIns + get() = builtIns as? KonanBuiltIns +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt index 6157f88138b..c5a4630ca13 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer -import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor @@ -74,7 +73,7 @@ fun runCommonization(parameters: CommonizationParameters): CommonizationResult { val modulesByTargets = LinkedHashMap>() // use linked hash map to preserve order // build resulting descriptors: - val visitor = DeclarationsBuilderVisitor(storageManager, DefaultBuiltIns.Instance) { target, commonizedModules -> + val visitor = DeclarationsBuilderVisitor(storageManager) { target, commonizedModules -> check(target !in modulesByTargets) modulesByTargets[target] = commonizedModules } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/Module.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/Module.kt index bd991a80aba..15ed4b75b0f 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/Module.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/Module.kt @@ -5,9 +5,10 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.name.Name -data class Module(val name: Name) : Declaration { - constructor(descriptor: ModuleDescriptor) : this(descriptor.name) +data class Module(val name: Name, val builtIns: KotlinBuiltIns) : Declaration { + constructor(descriptor: ModuleDescriptor) : this(descriptor.name, descriptor.builtIns) } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt index ab5a405a2cd..d01c8efd1b2 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt @@ -34,7 +34,7 @@ internal fun buildModuleNode( storageManager = storageManager, descriptors = modules, targetDeclarationProducer = ::Module, - commonValueProducer = { Module(it.firstNonNull().name) }, + commonValueProducer = { commonize(it, ModuleCommonizer.default()) }, recursionMarker = null, nodeProducer = ::ModuleNode ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt index 080fbfd34da..05425cf080a 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/modules.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildModuleNode import org.jetbrains.kotlin.descriptors.commonizer.toList import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultModuleCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultModuleCommonizerTest.kt new file mode 100644 index 00000000000..e6a26724d9a --- /dev/null +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultModuleCommonizerTest.kt @@ -0,0 +1,79 @@ +/* + * 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.core + +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns +import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.Module +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.junit.Test + +class DefaultModuleCommonizerTest : AbstractCommonizerTest() { + + @Test + fun allAreNative() = doTestSuccess( + KONAN_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock() + ) + + @Test + fun jvmAndNative1() = doTestSuccess( + DEFAULT_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock() + ) + + @Test + fun jvmAndNative2() = doTestSuccess( + DEFAULT_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock(), + KONAN_BUILT_INS.toMock() + ) + + @Test + fun noNative1() = doTestSuccess( + DEFAULT_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock() + ) + + @Test + fun noNative2() = doTestSuccess( + DEFAULT_BUILT_INS.toMock(), + DEFAULT_BUILT_INS.toMock(), + DEFAULT_BUILT_INS.toMock(), + DEFAULT_BUILT_INS.toMock() + ) + + @Test + fun noNative3() = doTestSuccess( + DEFAULT_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock(), + DEFAULT_BUILT_INS.toMock(), + JVM_BUILT_INS.toMock() + ) + + override fun createCommonizer() = ModuleCommonizer.default() + + override fun isEqual(a: Module?, b: Module?) = + (a === b) || (a != null && b != null && a.name == b.name && a.builtIns::class.java.name == b.builtIns::class.java.name) + + private companion object { + inline val KONAN_BUILT_INS get() = KonanBuiltIns(LockBasedStorageManager.NO_LOCKS) + inline val JVM_BUILT_INS get() = JvmBuiltIns(LockBasedStorageManager.NO_LOCKS, JvmBuiltIns.Kind.FROM_CLASS_LOADER) + inline val DEFAULT_BUILT_INS get() = DefaultBuiltIns.Instance + + fun KotlinBuiltIns.toMock() = Module(Name.identifier("fakeModule"), this) + } +}