From 250915f37793548b08c89552f494694b889bacb1 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 30 Mar 2021 14:33:19 +0200 Subject: [PATCH] [Commonizer] Implement AbstractInlineSourcesCommonizationTest and hierarchical commonization tests --- .../kotlin/commonizer/CommonizerTarget.kt | 4 + .../AbstractInlineSourcesCommonizationTest.kt | 215 ++++++++++++++++ .../HierarchicalClassCommonizationTest.kt | 145 +++++++++++ .../HierarchicalFunctionCommonizationTest.kt | 181 ++++++++++++++ .../HierarchicalPackageCommonizationTest.kt | 233 ++++++++++++++++++ .../HierarchicalPropertyCommonizationTest.kt | 32 +++ .../HierarchicalTypeAliasCommonizationTest.kt | 30 +++ .../AbstractCirTreeDeserializerTest.kt | 2 - .../CirTreeClassDeserializerTest.kt | 22 +- .../CirTreeDependenciesDeserializerTest.kt | 7 +- .../CirTreeFunctionDeserializerTest.kt | 6 +- .../CirTreePackageDeserializerTest.kt | 16 +- .../CirTreePropertyDeserializerTest.kt | 10 +- .../CirTreeTypeAliasDeserializerTest.kt | 4 +- .../merge/MergeCirTreeClassConstructorTest.kt | 8 +- .../tree/merge/MergeCirTreeClassTest.kt | 12 +- .../tree/merge/MergeCirTreeFunctionTest.kt | 8 +- .../tree/merge/MergeCirTreePackageTest.kt | 8 +- .../tree/merge/MergeCirTreePropertyTest.kt | 12 +- .../tree/merge/MergeCirTreeTypeAliasTest.kt | 8 +- .../commonizer/utils/InlineSourceBuilder.kt | 80 ++++++ .../utils/InlineSourceBuilderDelegate.kt | 21 ++ ...urceTest.kt => InlineSourceBuilderImpl.kt} | 72 +----- .../utils/KtInlineSourceCommonizerTestCase.kt | 4 +- .../kotlin/commonizer/utils/assertions.kt | 7 +- .../kotlin/commonizer/utils/mocks.kt | 4 +- 26 files changed, 1019 insertions(+), 132 deletions(-) create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/AbstractInlineSourcesCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalFunctionCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPackageCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt create mode 100644 native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderDelegate.kt rename native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/{InlineSourceTest.kt => InlineSourceBuilderImpl.kt} (73%) diff --git a/native/commonizer-api/src/org/jetbrains/kotlin/commonizer/CommonizerTarget.kt b/native/commonizer-api/src/org/jetbrains/kotlin/commonizer/CommonizerTarget.kt index 2bcf82aad20..f95f09d869b 100644 --- a/native/commonizer-api/src/org/jetbrains/kotlin/commonizer/CommonizerTarget.kt +++ b/native/commonizer-api/src/org/jetbrains/kotlin/commonizer/CommonizerTarget.kt @@ -122,6 +122,10 @@ public infix fun CommonizerTarget.isAncestorOf(other: CommonizerTarget): Boolean return false } +public infix fun CommonizerTarget.isEqualOrAncestorOf(other: CommonizerTarget): Boolean { + return this == other || this.isAncestorOf(other) +} + public infix fun CommonizerTarget.isDescendentOf(other: CommonizerTarget): Boolean { return other.isAncestorOf(this) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/AbstractInlineSourcesCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/AbstractInlineSourcesCommonizationTest.kt new file mode 100644 index 00000000000..19886973d06 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/AbstractInlineSourcesCommonizationTest.kt @@ -0,0 +1,215 @@ +/* + * Copyright 2010-2021 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.commonizer + +import org.intellij.lang.annotations.Language +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest.DependencyAwareInlineSourceTestFactory +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest.Parameters +import org.jetbrains.kotlin.commonizer.ResultsConsumer.ModuleResult.Commonized +import org.jetbrains.kotlin.commonizer.konan.NativeManifestDataProvider +import org.jetbrains.kotlin.commonizer.utils.* +import kotlin.test.assertIs + +data class HierarchicalCommonizationResult( + val inlineSourceTestFactory: DependencyAwareInlineSourceTestFactory, + val testParameters: Parameters, + val commonizerParameters: CommonizerParameters, + val results: Map> +) + +abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizerTestCase() { + + data class Parameters( + val outputTarget: SharedCommonizerTarget, + val dependencies: TargetDependent>, + val targets: List + ) + + data class Target( + val target: CommonizerTarget, + val modules: List + ) + + + @DslMarker + annotation class InlineSourcesCommonizationTestDsl + + @InlineSourcesCommonizationTestDsl + class ParametersBuilder(private val parentInlineSourceBuilder: InlineSourceBuilder) { + private var outputTarget: SharedCommonizerTarget? = null + + private val dependencies: MutableMap> = LinkedHashMap() + + private var targets: List = emptyList() + + private val inlineSourceBuilderFactory + get() = DependencyAwareInlineSourceTestFactory(parentInlineSourceBuilder, dependencies.toTargetDependent()) + + + @InlineSourcesCommonizationTestDsl + fun outputTarget(target: String) { + outputTarget = parseCommonizerTarget(target) as SharedCommonizerTarget + } + + @InlineSourcesCommonizationTestDsl + fun target(target: CommonizerTarget, builder: TargetBuilder.() -> Unit) { + targets = targets + TargetBuilder(target, inlineSourceBuilderFactory[target]).also(builder).build() + } + + @InlineSourcesCommonizationTestDsl + fun target(target: String, builder: TargetBuilder.() -> Unit) { + return target(parseCommonizerTarget(target), builder) + } + + @InlineSourcesCommonizationTestDsl + fun registerDependency(target: CommonizerTarget, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) { + val dependenciesList = dependencies.getOrPut(target) { mutableListOf() } + val dependency = inlineSourceBuilderFactory[target].createModule { + builder() + name = "${target.prettyName}-dependency-${dependenciesList.size}-$name" + } + dependenciesList.add(dependency) + } + + @InlineSourcesCommonizationTestDsl + fun registerDependency(target: String, builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) { + registerDependency(parseCommonizerTarget(target), builder) + } + + @InlineSourcesCommonizationTestDsl + fun simpleSingleSourceTarget(target: CommonizerTarget, @Language("kotlin") sourceContent: String) { + target(target) { + module { + source(sourceContent) + } + } + } + + @InlineSourcesCommonizationTestDsl + fun simpleSingleSourceTarget(target: String, @Language("kotlin") sourceCode: String) { + simpleSingleSourceTarget(parseCommonizerTarget(target), sourceCode) + } + + fun build(): Parameters = Parameters( + outputTarget = outputTarget ?: SharedCommonizerTarget(targets.map { it.target }.toSet()), + dependencies = dependencies.toTargetDependent(), + targets = targets.toList() + ) + } + + data class DependencyAwareInlineSourceTestFactory( + private val inlineSourceBuilder: InlineSourceBuilder, + private val dependencies: TargetDependent> + ) { + operator fun get(target: CommonizerTarget): InlineSourceBuilder { + return object : InlineSourceBuilder by inlineSourceBuilder { + override fun createModule(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit): InlineSourceBuilder.Module { + return inlineSourceBuilder.createModule { + dependencies.toMap() + .filterKeys { dependencyTarget -> dependencyTarget.isEqualOrAncestorOf(target) }.values.flatten() + .forEach { dependencyModule -> dependency(dependencyModule) } + builder() + } + } + } + } + } + + @InlineSourcesCommonizationTestDsl + class TargetBuilder(private val target: CommonizerTarget, private val inlineSourceBuilder: InlineSourceBuilder) { + private var modules: List = emptyList() + + @InlineSourcesCommonizationTestDsl + fun module(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit) { + modules = modules + inlineSourceBuilder.createModule(builder) + } + + fun build(): Target = Target(target, modules = modules) + } + + fun commonize(builder: ParametersBuilder.() -> Unit): HierarchicalCommonizationResult { + val consumer = MockResultsConsumer() + val testParameters = ParametersBuilder(this).also(builder).build() + val commonizerParameters = testParameters.toCommonizerParameters(consumer) + runCommonization(commonizerParameters) + assertEquals(ResultsConsumer.Status.DONE, consumer.status) + return HierarchicalCommonizationResult( + inlineSourceTestFactory = DependencyAwareInlineSourceTestFactory(inlineSourceBuilder, testParameters.dependencies), + testParameters = testParameters, + commonizerParameters = commonizerParameters, + results = consumer.modulesByTargets.mapValues { (_, collection) -> collection.toList() } + ) + } + + + private fun Parameters.toCommonizerParameters( + resultsConsumer: ResultsConsumer, + manifestDataProvider: NativeManifestDataProvider = MockNativeManifestDataProvider() + ): CommonizerParameters { + return CommonizerParameters( + outputTarget = outputTarget, + manifestProvider = TargetDependent(outputTarget.withAllAncestors()) { manifestDataProvider }, + dependenciesProvider = TargetDependent(outputTarget.withAllAncestors()) { target -> + val explicitDependencies = dependencies.getOrNull(target).orEmpty().map { module -> createModuleDescriptor(module) } + val implicitDependencies = listOfNotNull(if (target == outputTarget) DefaultBuiltIns.Instance.builtInsModule else null) + val dependencies = explicitDependencies + implicitDependencies + if (dependencies.isEmpty()) null + else MockModulesProvider.create(dependencies) + }, + targetProviders = TargetDependent(targets.map { it.target }) { commonizerTarget -> + val target = targets.single { it.target == commonizerTarget } + TargetProvider( + target = commonizerTarget, + modulesProvider = MockModulesProvider.create(target.modules.map { createModuleDescriptor(it) }) + ) + }, + resultsConsumer = resultsConsumer + ) + } +} + + +/* ASSERTIONS */ + +fun HierarchicalCommonizationResult.getTarget(target: CommonizerTarget): List { + return this.results[target] ?: kotlin.test.fail("Missing target $target in results ${this.results.keys}") +} + +fun HierarchicalCommonizationResult.getTarget(target: String): List { + return getTarget(parseCommonizerTarget(target)) +} + +fun HierarchicalCommonizationResult.assertCommonized( + target: CommonizerTarget, + moduleBuilder: InlineSourceBuilder.ModuleBuilder.() -> Unit +) { + val inlineSourceTest = inlineSourceTestFactory[target] + val commonizedModule = getTarget(target).assertSingleCommonizedModule() + val referenceModule = inlineSourceTest.createModule { + moduleBuilder() + } + assertModulesAreEqual( + inlineSourceTest.createMetadata(referenceModule), commonizedModule.metadata, target + ) +} + +fun HierarchicalCommonizationResult.assertCommonized(target: CommonizerTarget, @Language("kotlin") sourceContent: String) { + assertCommonized(target) { + source(sourceContent) + } +} + +fun HierarchicalCommonizationResult.assertCommonized(target: String, @Language("kotlin") sourceContent: String) = + assertCommonized(parseCommonizerTarget(target), sourceContent) + +fun HierarchicalCommonizationResult.assertCommonized(target: String, moduleBuilder: InlineSourceBuilder.ModuleBuilder.() -> Unit) = + assertCommonized(parseCommonizerTarget(target), moduleBuilder) + +fun Collection.assertSingleCommonizedModule(): Commonized { + kotlin.test.assertEquals(1, size, "Expected exactly one module. Found: ${this.map { it.libraryName }}") + return assertIs(single(), "Expected single module to be 'Commonized'") +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassCommonizationTest.kt new file mode 100644 index 00000000000..fe3b1484614 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassCommonizationTest.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2010-2021 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.commonizer.hierarchical + +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest +import org.jetbrains.kotlin.commonizer.assertCommonized + +class HierarchicalClassCommonizationTest : AbstractInlineSourcesCommonizationTest() { + + fun `test simple class`() { + val result = commonize { + outputTarget("((a,b), (c,d), e)") + simpleSingleSourceTarget("a", "class X") + simpleSingleSourceTarget("b", "class X") + simpleSingleSourceTarget("c", "class X") + simpleSingleSourceTarget("d", "class X") + simpleSingleSourceTarget("e", "class X") + } + + result.assertCommonized("a", "actual class X") + result.assertCommonized("b", "actual class X") + result.assertCommonized("c", "actual class X") + result.assertCommonized("d", "actual class X") + result.assertCommonized("e", "actual class X") + + result.assertCommonized("(a,b)", "class X") + result.assertCommonized("(c,d)", "class X") + result.assertCommonized("(a,b)", "class X") + result.assertCommonized("((a,b), (c,d), e)", "expect class X expect constructor()") + } + + fun `test sample class`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + simpleSingleSourceTarget( + "a", """ + class X { + val a: Int = 42 + val ab: Int = 42 + val abcd: Int = 42 + } + """ + ) + + simpleSingleSourceTarget( + "b", """ + class X { + val b: Int = 42 + val ab: Int = 42 + val abcd: Int = 42 + } + """ + ) + + simpleSingleSourceTarget( + "c", """ + class X { + val c: Int = 42 + val cd: Int = 42 + val abcd: Int = 42 + } + """ + ) + + simpleSingleSourceTarget( + "d", """ + class X { + val d: Int = 42 + val cd: Int = 42 + val abcd: Int = 42 + } + """ + ) + } + + result.assertCommonized( + "a", """ + actual class X { + actual val a: Int = 42 + actual val ab: Int = 42 + actual val abcd: Int = 42 + } + """ + ) + + result.assertCommonized( + "b", """ + actual class X { + actual val b: Int = 42 + actual val ab: Int = 42 + actual val abcd: Int = 42 + } + """ + ) + + result.assertCommonized( + "c", """ + actual class X { + actual val c: Int = 42 + actual val cd: Int = 42 + actual val abcd: Int = 42 + } + """ + ) + + result.assertCommonized( + "d", """ + actual class X { + actual val d: Int = 42 + actual val cd: Int = 42 + actual val abcd: Int = 42 + } + """ + ) + + result.assertCommonized( + "(a,b)", """ + class X { + val ab: Int + val abcd: Int + } + """ + ) + + result.assertCommonized( + "(c,d)", """ + class X { + val cd: Int + val abcd: Int + } + """ + ) + + result.assertCommonized( + "((a,b), (c,d))", """ + expect class X expect constructor() { + expect val abcd: Int + } + """ + ) + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalFunctionCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalFunctionCommonizationTest.kt new file mode 100644 index 00000000000..906ff9bf461 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalFunctionCommonizationTest.kt @@ -0,0 +1,181 @@ +/* + * Copyright 2010-2021 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.commonizer.hierarchical + +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest +import org.jetbrains.kotlin.commonizer.assertCommonized + +class HierarchicalFunctionCommonizationTest : AbstractInlineSourcesCommonizationTest() { + + fun `test simple function 1`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + simpleSingleSourceTarget("a", "fun x(): Int = 42") + simpleSingleSourceTarget("b", "fun x(): Int = 42") + simpleSingleSourceTarget("c", "fun x(): Int = 42") + simpleSingleSourceTarget("d", "fun x(): Int = 42") + } + + result.assertCommonized("((a,b), (c,d))", "expect fun x(): Int") + result.assertCommonized("(a,b)", "actual fun x(): Int = 42") + result.assertCommonized("(c,d)", "actual fun x(): Int = 42") + result.assertCommonized("a", "actual fun x(): Int = 42") + result.assertCommonized("b", "actual fun x(): Int = 42") + result.assertCommonized("c", "actual fun x(): Int = 42") + result.assertCommonized("d", "actual fun x(): Int = 42") + } + + fun `test simple function 2`() { + val result = commonize { + outputTarget("((a,b), c)") + simpleSingleSourceTarget("a", "fun x(): Int = 42") + simpleSingleSourceTarget("b", "fun x(): Int = 42") + simpleSingleSourceTarget("c", "fun x(): Int = 42") + } + + result.assertCommonized("((a,b), c)", "expect fun x(): Int") + result.assertCommonized("(a,b)", "actual fun x(): Int = 42") + result.assertCommonized("a", "actual fun x(): Int = 42") + result.assertCommonized("b", "actual fun x(): Int = 42") + result.assertCommonized("c", "actual fun x(): Int = 42") + } + + fun `test function with returnType`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + simpleSingleSourceTarget( + "a", """ + interface ABCD + fun x(): ABCD = TODO() + """ + ) + simpleSingleSourceTarget( + "b", """ + interface ABCD + fun x(): ABCD = TODO() + """ + ) + simpleSingleSourceTarget( + "c", """ + interface ABCD + fun x(): ABCD = TODO() + """ + ) + + simpleSingleSourceTarget( + "d", """ + interface ABCD + fun x(): ABCD = TODO() + """ + ) + } + + result.assertCommonized( + "a", """ + actual interface ABCD + actual fun x(): ABCD = TODO() + """ + ) + + result.assertCommonized( + "b", """ + actual interface ABCD + actual fun x(): ABCD = TODO() + """ + ) + + result.assertCommonized( + "c", """ + actual interface ABCD + actual fun x(): ABCD = TODO() + """ + ) + + result.assertCommonized( + "d", """ + actual interface ABCD + actual fun x(): ABCD = TODO() + """ + ) + + result.assertCommonized( + "(a, b)", """ + actual interface ABCD + actual fun x(): ABCD + """ + ) + + result.assertCommonized( + "(c, d)", """ + actual interface ABCD + actual fun x(): ABCD + """ + ) + + result.assertCommonized( + "((a,b), (c,d))", """ + expect interface ABCD + expect fun x(): ABCD + """ + ) + } + + fun `test function with returnType from dependency 1`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + registerDependency("((a,b), (c,d))") { source("interface ABCD") } + simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("c", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("d", "fun x(): ABCD = TODO()") + } + + result.assertCommonized("a", "actual fun x(): ABCD") + result.assertCommonized("b", "actual fun x(): ABCD") + result.assertCommonized("c", "actual fun x(): ABCD") + result.assertCommonized("d", "actual fun x(): ABCD") + result.assertCommonized("(c, d)", "fun x(): ABCD") + result.assertCommonized("(a, b)", "fun x(): ABCD") + result.assertCommonized("((a,b), (c,d))", "expect fun x(): ABCD") + } + + fun `test function with returnType from dependency 2`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + registerDependency("(a,b)") { source("interface ABCD") } + registerDependency("(c,d)") { source("interface ABCD") } + simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("c", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("d", "fun x(): ABCD = TODO()") + } + + result.assertCommonized("a", "actual fun x(): ABCD") + result.assertCommonized("b", "actual fun x(): ABCD") + result.assertCommonized("c", "actual fun x(): ABCD") + result.assertCommonized("d", "actual fun x(): ABCD") + result.assertCommonized("(c, d)", "fun x(): ABCD") + result.assertCommonized("(a, b)", "fun x(): ABCD") + result.assertCommonized("((a,b), (c,d))", "") + } + + fun `test function with returnType from dependency 3`() { + val result = commonize { + outputTarget("((a,b), c)") + registerDependency("((a,b), c)") { source("interface ABCD") } + registerDependency("(a,b)") { source("interface ABCD") } + simpleSingleSourceTarget("a", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("b", "fun x(): ABCD = TODO()") + simpleSingleSourceTarget("c", "fun x(): ABCD = TODO()") + } + + result.assertCommonized("a", "actual fun x(): ABCD") + result.assertCommonized("b", "actual fun x(): ABCD") + result.assertCommonized("c", "actual fun x(): ABCD") + result.assertCommonized("(a, b)", "fun x(): ABCD") + result.assertCommonized("((a,b), c)", "expect fun x(): ABCD") + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPackageCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPackageCommonizationTest.kt new file mode 100644 index 00000000000..6abe7e7f798 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPackageCommonizationTest.kt @@ -0,0 +1,233 @@ +/* + * Copyright 2010-2021 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.commonizer.hierarchical + +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest +import org.jetbrains.kotlin.commonizer.assertCommonized + +class HierarchicalPackageCommonizationTest : AbstractInlineSourcesCommonizationTest() { + + fun `test package with dummy`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + + target("a") { + module { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.ab + val dummy = "me" + """, "ab.kt" + ) + source( + """ + package pkg.a + val dummy = "me" + """, "a.kt" + ) + } + } + + target("b") { + module { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.ab + val dummy = "me" + """, "ab.kt" + ) + source( + """ + package pkg.b + val dummy = "me" + """, "b.kt" + ) + } + } + + target("c") { + module { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.cd + val dummy = "me" + """, "cd.kt" + ) + source( + """ + package pkg.c + val dummy = "me" + """, "c.kt" + ) + } + } + + target("d") { + module { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.cd + val dummy = "me" + """, "cd.kt" + ) + source( + """ + package pkg.d + val dummy = "me" + """, "d.kt" + ) + } + } + } + + result.assertCommonized("a") { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.ab + val dummy = "me" + """, "ab.kt" + ) + source( + """ + package pkg.a + val dummy = "me" + """, "a.kt" + ) + } + + result.assertCommonized("b") { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.ab + val dummy = "me" + """, "ab.kt" + ) + source( + """ + package pkg.b + val dummy = "me" + """, "b.kt" + ) + } + + result.assertCommonized("c") { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.cd + val dummy = "me" + """, "cd.kt" + ) + source( + """ + package pkg.c + val dummy = "me" + """, "c.kt" + ) + } + + result.assertCommonized("d") { + source( + """ + package pkg.abcd + val dummy = "me" + """, "abcd.kt" + ) + source( + """ + package pkg.cd + val dummy = "me" + """, "cd.kt" + ) + source( + """ + package pkg.d + val dummy = "me" + """, "d.kt" + ) + } + + result.assertCommonized("(a,b)") { + source( + """ + package pkg.abcd + val dummy: String + """, "abcd.kt" + ) + source( + """ + package pkg.ab + val dummy: String + """, "ab.kt" + ) + } + + result.assertCommonized("(c,d)") { + source( + """ + package pkg.abcd + val dummy: String + """, "abcd.kt" + ) + source( + """ + package pkg.cd + val dummy: String + """, "cd.kt" + ) + } + + result.assertCommonized("((a,b), (c,d))") { + source( + """ + package pkg.abcd + expect val dummy: String + """, "abcd.kt" + ) + } + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt new file mode 100644 index 00000000000..eee883a872e --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalPropertyCommonizationTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2021 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.commonizer.hierarchical + +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest +import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget +import org.jetbrains.kotlin.commonizer.assertCommonized +import org.jetbrains.kotlin.commonizer.parseCommonizerTarget + +class HierarchicalPropertyCommonizationTest : AbstractInlineSourcesCommonizationTest() { + + fun `test simple property`() { + val result = commonize { + outputTarget("((a, b), (c, d))") + simpleSingleSourceTarget("a", "val x: Int = 42") + simpleSingleSourceTarget("b", "val x: Int = 42") + simpleSingleSourceTarget("c", "val x: Int = 42") + simpleSingleSourceTarget("d", "val x: Int = 42") + } + + result.assertCommonized("((a,b), (c,d))", "expect val x: Int") + result.assertCommonized("(a, b)", "actual val x: Int") + result.assertCommonized("(c, d)", "actual val x: Int") + result.assertCommonized("a", "actual val x: Int = 42") + result.assertCommonized("b", "actual val x: Int = 42") + result.assertCommonized("c", "actual val x: Int = 42") + result.assertCommonized("d", "actual val x: Int = 42") + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt new file mode 100644 index 00000000000..2375fa9898f --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalTypeAliasCommonizationTest.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2021 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.commonizer.hierarchical + +import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest +import org.jetbrains.kotlin.commonizer.assertCommonized + +class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizationTest() { + + fun `test simple type alias`() { + val result = commonize { + outputTarget("((a,b), (c,d))") + simpleSingleSourceTarget("a", "typealias X = Int") + simpleSingleSourceTarget("b", "typealias X = Int") + simpleSingleSourceTarget("c", "typealias X = Int") + simpleSingleSourceTarget("d", "typealias X = Int") + } + + result.assertCommonized("((a,b), (c,d))", "typealias X = Int") + result.assertCommonized("(a,b)", "") + result.assertCommonized("(c, d)", "") + result.assertCommonized("a", "") + result.assertCommonized("b", "") + result.assertCommonized("c", "") + result.assertCommonized("d", "") + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/AbstractCirTreeDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/AbstractCirTreeDeserializerTest.kt index 599c0431409..e5d48891ad1 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/AbstractCirTreeDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/AbstractCirTreeDeserializerTest.kt @@ -6,8 +6,6 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer import org.jetbrains.kotlin.commonizer.tree.* -import org.jetbrains.kotlin.commonizer.utils.InlineSourceTest -import org.jetbrains.kotlin.commonizer.utils.InlineSourceTestImpl import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase abstract class AbstractCirTreeDeserializerTest : KtInlineSourceCommonizerTestCase() { diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeClassDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeClassDeserializerTest.kt index 82db282edd8..da3cfd84111 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeClassDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeClassDeserializerTest.kt @@ -14,7 +14,7 @@ import kotlin.test.* class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test simple class`() { - val module = deserializeSourceFile("class X") + val module = createCirTreeFromSourceCode("class X") val clazz = module.assertSingleClass().clazz assertEquals(Visibilities.Public, clazz.visibility, "Expected class to be public") assertNull(clazz.companion, "Expected class *not* having a companion") @@ -29,7 +29,7 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test nested class`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ class Outer { class Inner @@ -46,7 +46,7 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test inner class`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ class Outer { inner class Inner @@ -64,7 +64,7 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test data class`() { - val module = deserializeSourceFile("data class X(val x: String)") + val module = createCirTreeFromSourceCode("data class X(val x: String)") val clazz = module.assertSingleClass() assertTrue(clazz.clazz.isData, "Expected is data class") assertEquals(1, clazz.constructors.size, "Expected single constructor") @@ -72,7 +72,7 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test companion`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ class Outer { companion object { @@ -88,19 +88,19 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test object`() { - val module = deserializeSourceFile("object X") + val module = createCirTreeFromSourceCode("object X") val clazz = module.assertSingleClass() assertEquals(ClassKind.OBJECT, clazz.clazz.kind, "Expected object class kind") } fun `test interface`() { - val module = deserializeSourceFile("interface X") + val module = createCirTreeFromSourceCode("interface X") val clazz = module.assertSingleClass() assertEquals(ClassKind.INTERFACE, clazz.clazz.kind) } fun `test supertypes`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ interface A interface B: A @@ -118,19 +118,19 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test abstract class`() { - val module = deserializeSourceFile("abstract class X") + val module = createCirTreeFromSourceCode("abstract class X") val clazz = module.assertSingleClass() assertEquals(Modality.ABSTRACT, clazz.clazz.modality) } fun `test open class`() { - val module = deserializeSourceFile("open class X") + val module = createCirTreeFromSourceCode("open class X") val clazz = module.assertSingleClass() assertEquals(Modality.OPEN, clazz.clazz.modality) } fun `test class with properties functions and nested classes`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ class X { val myInt: Int = 42 diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeDependenciesDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeDependenciesDeserializerTest.kt index 6c3c1745b33..3760f04a4c7 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeDependenciesDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeDependenciesDeserializerTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer import org.jetbrains.kotlin.commonizer.cir.CirClassType +import org.jetbrains.kotlin.commonizer.utils.createCirTree import org.jetbrains.kotlin.descriptors.ClassKind import kotlin.test.assertEquals import kotlin.test.assertIs @@ -13,11 +14,11 @@ import kotlin.test.assertIs class CirTreeDependenciesDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test deserialize with dependencies`() { - val module = deserializeModule { + val module = createCirTree { dependency { - source("dependencies.kt", "interface Dependency") + source("interface Dependency", "dependencies.kt") } - source("source.kt", "object X: Dependency") + source("object X: Dependency", "source.kt") } val xObject = module.assertSingleClass() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeFunctionDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeFunctionDeserializerTest.kt index 9c4a6aabceb..9ca23204417 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeFunctionDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeFunctionDeserializerTest.kt @@ -16,7 +16,7 @@ import kotlin.test.* class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test simple function`() { - val module = deserializeSourceFile("fun x() = Unit") + val module = createCirTreeFromSourceCode("fun x() = Unit") val (_, function) = module.assertSingleFunction() assertNull(function.containingClass, "Expected function to *not* have containing class") @@ -29,7 +29,7 @@ class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test generic function`() { - val module = deserializeSourceFile("""fun T.isHappy(): Boolean = true""") + val module = createCirTreeFromSourceCode("""fun T.isHappy(): Boolean = true""") val (_, function) = module.assertSingleFunction() val extensionReceiver = assertNotNull(function.extensionReceiver, "Expected function being extension receiver") @@ -50,7 +50,7 @@ class CirTreeFunctionDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test function with outer object`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ object Parent { fun x(): String = "Hello, you're reading a test" diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePackageDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePackageDeserializerTest.kt index bf10b9dc388..677732477e8 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePackageDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePackageDeserializerTest.kt @@ -5,37 +5,39 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer +import org.jetbrains.kotlin.commonizer.utils.createCirTree + class CirTreePackageDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test package with multiple classes properties and functions`() { - val module = deserializeModule { + val module = createCirTree { source( - "root.kt", """ + """ typealias rootTypeAlias = Int val rootProperty: String = "hello," fun rootFunction(): String = "it is me" class RootClass - """.trimIndent() + """.trimIndent(), "root.kt" ) source( - "pkg1.kt", """ + """ package test.pkg1 typealias pkg1TypeAlias = Int val pkg1Property: Int = 42 fun pkg1Function(): String = "answer" class Pkg1 - """.trimIndent() + """.trimIndent(), "pkg1.kt" ) source( - "pkg2.kt", """ + """ package test.pkg2 typealias pkg2TypeAlias = Int val pkg2Property: Int = 42 fun pkg2Function(): String = "answer" class Pkg2 - """.trimIndent() + """.trimIndent(), "pkg2.kt" ) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePropertyDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePropertyDeserializerTest.kt index eb3fae2efd2..dfbe50398d7 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePropertyDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreePropertyDeserializerTest.kt @@ -16,7 +16,7 @@ import kotlin.test.* class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test simple val property`() { - val module = deserializeSourceFile("val x: Int = 42") + val module = createCirTreeFromSourceCode("val x: Int = 42") val (key, property) = module.assertSingleProperty() assertEquals(PropertyApproximationKey(CirName.Companion.create("x"), null), key) @@ -32,7 +32,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test simple var property`() { - val module = deserializeSourceFile("var x: Int = 42") + val module = createCirTreeFromSourceCode("var x: Int = 42") val (_, property) = module.assertSingleProperty() assertNotNull(property.getter, "Expected property has getter") assertNotNull(property.setter, "Expected property has setter") @@ -41,7 +41,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test lateinit var property`() { - val module = deserializeSourceFile("lateinit var x: Int") + val module = createCirTreeFromSourceCode("lateinit var x: Int") val (_, property) = module.assertSingleProperty() assertNotNull(property.getter, "Expected property has getter") @@ -51,7 +51,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test generic var property`() { - val module = deserializeSourceFile("var T.x: T get() = this") + val module = createCirTreeFromSourceCode("var T.x: T get() = this") val (_, property) = module.assertSingleProperty() assertNotNull(property.extensionReceiver, "Expected property has extension receiver") @@ -62,7 +62,7 @@ class CirTreePropertyDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test multiple properties`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ val x: Int = 42 val y: Float = 42f diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeTypeAliasDeserializerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeTypeAliasDeserializerTest.kt index 016ffff6f37..1a8be0aa92e 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeTypeAliasDeserializerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/deserializer/CirTreeTypeAliasDeserializerTest.kt @@ -18,7 +18,7 @@ import kotlin.test.assertIs class CirTreeTypeAliasDeserializerTest : AbstractCirTreeDeserializerTest() { fun `test simple type alias`() { - val module = deserializeSourceFile("typealias x = Int") + val module = createCirTreeFromSourceCode("typealias x = Int") val typeAlias = module.assertSingleTypeAlias().typeAlias assertEquals(CirName.create("x"), typeAlias.name, "Expected correct type alias name") assertEquals("kotlin/Int", typeAlias.expandedType.toString()) @@ -26,7 +26,7 @@ class CirTreeTypeAliasDeserializerTest : AbstractCirTreeDeserializerTest() { } fun `test transitive type alias`() { - val module = deserializeSourceFile( + val module = createCirTreeFromSourceCode( """ interface Map typealias IntMap = Map diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassConstructorTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassConstructorTest.kt index 5f440e3e290..b61694b5350 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassConstructorTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassConstructorTest.kt @@ -8,16 +8,16 @@ package org.jetbrains.kotlin.commonizer.tree.merge class MergeCirTreeClassConstructorTest : AbstractMergeCirTreeTest() { fun `test simple constructors`() { - val aTree = deserializeSourceFile("class X(val x: Int)") - val bTree = deserializeSourceFile("class X(val x: Int)") + val aTree = createCirTreeFromSourceCode("class X(val x: Int)") + val bTree = createCirTreeFromSourceCode("class X(val x: Int)") val merged = mergeCirTree("a" to aTree, "b" to bTree) val constructor = merged.assertSingleModule().assertSinglePackage().assertSingleClass().assertSingleConstructor() constructor.assertNoMissingTargetDeclaration() } fun `test missing target declaration`() { - val aTree = deserializeSourceFile("class X(val a: Int)") - val bTree = deserializeSourceFile("class X(val b: Short)") + val aTree = createCirTreeFromSourceCode("class X(val a: Int)") + val bTree = createCirTreeFromSourceCode("class X(val b: Short)") val merged = mergeCirTree("a" to aTree, "b" to bTree) val clazz = merged.assertSingleModule().assertSinglePackage().assertSingleClass() kotlin.test.assertEquals(2, clazz.constructors.size, "Expected two constructors") diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassTest.kt index 0de2bb4d659..85462fe4db0 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeClassTest.kt @@ -10,16 +10,16 @@ import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey class MergeCirTreeClassTest : AbstractMergeCirTreeTest() { fun `test simple class`() { - val aTree = deserializeSourceFile("class X") - val bTree = deserializeSourceFile("class X") + val aTree = createCirTreeFromSourceCode("class X") + val bTree = createCirTreeFromSourceCode("class X") val merged = mergeCirTree("a" to aTree, "b" to bTree) val clazz = merged.assertSingleModule().assertSinglePackage().assertSingleClass() clazz.assertNoMissingTargetDeclaration() } fun `test missing target declarations`() { - val aTree = deserializeSourceFile("class A") - val bTree = deserializeSourceFile("class B") + val aTree = createCirTreeFromSourceCode("class A") + val bTree = createCirTreeFromSourceCode("class B") val merged = mergeCirTree("a" to aTree, "b" to bTree) val pkg = merged.assertSingleModule().assertSinglePackage() kotlin.test.assertEquals(2, pkg.classes.size, "Expected two classes (A, B)") @@ -31,7 +31,7 @@ class MergeCirTreeClassTest : AbstractMergeCirTreeTest() { } fun `test with children`() { - val aTree = deserializeSourceFile( + val aTree = createCirTreeFromSourceCode( """ class X { val x: Int = 42 @@ -40,7 +40,7 @@ class MergeCirTreeClassTest : AbstractMergeCirTreeTest() { """.trimIndent() ) - val bTree = deserializeSourceFile( + val bTree = createCirTreeFromSourceCode( """ class X { val x: Int = 42 diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeFunctionTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeFunctionTest.kt index a2b4a16c96e..6a1f32bb6e2 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeFunctionTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeFunctionTest.kt @@ -8,8 +8,8 @@ package org.jetbrains.kotlin.commonizer.tree.merge class MergeCirTreeFunctionTest : AbstractMergeCirTreeTest() { fun `test simple function`() { - val aTree = deserializeSourceFile("fun x(): Int = 42") - val bTree = deserializeSourceFile("fun x(): Int = 42") + val aTree = createCirTreeFromSourceCode("fun x(): Int = 42") + val bTree = createCirTreeFromSourceCode("fun x(): Int = 42") val merged = mergeCirTree("a" to aTree, "b" to bTree) val function = merged.assertSingleModule().assertSinglePackage().assertSingleFunction() @@ -22,8 +22,8 @@ class MergeCirTreeFunctionTest : AbstractMergeCirTreeTest() { } fun `test missing target declarations`() { - val aTree = deserializeSourceFile("fun a(): Int = 42") - val bTree = deserializeSourceFile("fun b(): Int = 42") + val aTree = createCirTreeFromSourceCode("fun a(): Int = 42") + val bTree = createCirTreeFromSourceCode("fun b(): Int = 42") val merged = mergeCirTree("a" to aTree, "b" to bTree) val pkg = merged.assertSingleModule().assertSinglePackage() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePackageTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePackageTest.kt index 33e359b0762..009ea7f1d3b 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePackageTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePackageTest.kt @@ -11,8 +11,8 @@ import org.jetbrains.kotlin.commonizer.cir.CirPackageName class MergeCirTreePackageTest : AbstractMergeCirTreeTest() { fun `test simple package`() { - val aTree = deserializeSourceFile("package test.pkg") - val bTree = deserializeSourceFile("package test.pkg") + val aTree = createCirTreeFromSourceCode("package test.pkg") + val bTree = createCirTreeFromSourceCode("package test.pkg") val merged = mergeCirTree("a" to aTree, "b" to bTree) val module = merged.assertSingleModule() kotlin.test.assertEquals(3, module.packages.size, "Expected 3 packages (root, test, test.pkg)") @@ -28,8 +28,8 @@ class MergeCirTreePackageTest : AbstractMergeCirTreeTest() { } fun `test missing target declarations`() { - val aTree = deserializeSourceFile("package a") - val bTree = deserializeSourceFile("package b") + val aTree = createCirTreeFromSourceCode("package a") + val bTree = createCirTreeFromSourceCode("package b") val merged = mergeCirTree("a" to aTree, "b" to bTree) val module = merged.assertSingleModule() kotlin.test.assertEquals(3, module.packages.size, "Expected 3 packages (root, a, b)") diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePropertyTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePropertyTest.kt index 75760973b5f..e31bbde1903 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePropertyTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreePropertyTest.kt @@ -14,8 +14,8 @@ import kotlin.test.assertNotNull class MergeCirTreePropertyTest : AbstractMergeCirTreeTest() { fun `test simple property`() { - val aTree = deserializeSourceFile("""val a: Int = 42""") - val bTree = deserializeSourceFile("""val a: Int = 42""") + val aTree = createCirTreeFromSourceCode("""val a: Int = 42""") + val bTree = createCirTreeFromSourceCode("""val a: Int = 42""") val merged = mergeCirTree("a" to aTree, "b" to bTree) val property = merged.assertSingleModule().assertSinglePackage().assertSingleProperty() @@ -27,7 +27,7 @@ class MergeCirTreePropertyTest : AbstractMergeCirTreeTest() { } fun `test multiple properties`() { - val aTree = deserializeSourceFile( + val aTree = createCirTreeFromSourceCode( """ val a: Int = 42 val b: Int = 42 @@ -35,7 +35,7 @@ class MergeCirTreePropertyTest : AbstractMergeCirTreeTest() { """.trimIndent() ) - val bTree = deserializeSourceFile( + val bTree = createCirTreeFromSourceCode( """ val a: Int = 42 val b: Int = 42 @@ -57,8 +57,8 @@ class MergeCirTreePropertyTest : AbstractMergeCirTreeTest() { } fun `test missing target declarations`() { - val aTree = deserializeSourceFile("val a: Int = 42") - val bTree = deserializeSourceFile("val b: Int = 42") + val aTree = createCirTreeFromSourceCode("val a: Int = 42") + val bTree = createCirTreeFromSourceCode("val b: Int = 42") val merged = mergeCirTree("a" to aTree, "b" to bTree) val pkg = merged.assertSingleModule().assertSinglePackage() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeTypeAliasTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeTypeAliasTest.kt index e543f04a4f3..f7237902383 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeTypeAliasTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/tree/merge/MergeCirTreeTypeAliasTest.kt @@ -11,16 +11,16 @@ import kotlin.test.assertEquals class MergeCirTreeTypeAliasTest : AbstractMergeCirTreeTest() { fun `test simple type alias`() { - val aTree = deserializeSourceFile("typealias a = Int") - val bTree = deserializeSourceFile("typealias a = Int") + val aTree = createCirTreeFromSourceCode("typealias a = Int") + val bTree = createCirTreeFromSourceCode("typealias a = Int") val merged = mergeCirTree("a" to aTree, "b" to bTree) val typeAlias = merged.assertSingleModule().assertSinglePackage().assertSingleTypeAlias() typeAlias.assertNoMissingTargetDeclaration() } fun `test missing target declarations`() { - val aTree = deserializeSourceFile("typealias a = Int") - val bTree = deserializeSourceFile("typealias b = Int") + val aTree = createCirTreeFromSourceCode("typealias a = Int") + val bTree = createCirTreeFromSourceCode("typealias b = Int") val merged = mergeCirTree("a" to aTree, "b" to bTree) val pkg = merged.assertSingleModule().assertSinglePackage() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt new file mode 100644 index 00000000000..91e228d7caa --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilder.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2010-2021 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.commonizer.utils + +import org.intellij.lang.annotations.Language +import org.jetbrains.kotlin.commonizer.tree.CirTreeModule +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.library.SerializedMetadata + +interface InlineSourceBuilder { + annotation class ModuleBuilderDsl + + data class SourceFile(val name: String, @Language("kotlin") val content: String) + + data class Module( + val name: String, val sourceFiles: List, val dependencies: List + ) + + @ModuleBuilderDsl + class ModuleBuilder { + var name: String = "test-module" + private var sourceFiles: List = emptyList() + private var dependencies: List = emptyList() + + + @ModuleBuilderDsl + fun source(@Language("kotlin") content: String, name: String = "test.kt") { + sourceFiles = sourceFiles + SourceFile(name, content) + } + + @ModuleBuilderDsl + fun dependency(builder: ModuleBuilder.() -> Unit) { + dependency(ModuleBuilder().also(builder).build()) + } + + @ModuleBuilderDsl + fun dependency(module: Module) { + this.dependencies += module.copy(name = "${this.name}-dependency-${module.name}-${dependencies.size}") + } + + fun build(): Module = Module(name, sourceFiles.toList(), dependencies.toList()) + } + + fun createModule(builder: ModuleBuilder.() -> Unit): Module { + return ModuleBuilder().also(builder).build() + } + + fun createCirTreeFromSourceCode(@Language("kotlin") sourceCode: String): CirTreeModule { + return createCirTree { + source(content = sourceCode, "test.kt") + } + } + + + fun createCirTree(module: Module): CirTreeModule + + fun createModuleDescriptor(module: Module): ModuleDescriptor + + fun createMetadata(module: Module): SerializedMetadata = createModuleDescriptor(module).toMetadata() +} + + +@InlineSourceBuilder.ModuleBuilderDsl +fun InlineSourceBuilder.createCirTree(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit): CirTreeModule { + return createCirTree(createModule(builder)) +} + +@InlineSourceBuilder.ModuleBuilderDsl +fun InlineSourceBuilder.createModuleDescriptor(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit): ModuleDescriptor { + return createModuleDescriptor(createModule(builder)) +} + +@InlineSourceBuilder.ModuleBuilderDsl +fun InlineSourceBuilder.createMetadata(builder: InlineSourceBuilder.ModuleBuilder.() -> Unit): SerializedMetadata { + return createMetadata(createModule(builder)) +} + diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderDelegate.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderDelegate.kt new file mode 100644 index 00000000000..204768d2e3d --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderDelegate.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2021 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.commonizer.utils + +import org.jetbrains.kotlin.commonizer.tree.CirTreeModule +import org.jetbrains.kotlin.descriptors.ModuleDescriptor + +internal interface InlineSourceBuilderDelegate : InlineSourceBuilder { + val inlineSourceBuilder: InlineSourceBuilder + + override fun createCirTree(module: InlineSourceBuilder.Module): CirTreeModule { + return inlineSourceBuilder.createCirTree(module) + } + + override fun createModuleDescriptor(module: InlineSourceBuilder.Module): ModuleDescriptor { + return inlineSourceBuilder.createModuleDescriptor(module) + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt similarity index 73% rename from native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceTest.kt rename to native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt index 6e612988f9a..df5b512a3c5 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.commonizer.utils import com.intellij.openapi.Disposable import com.intellij.openapi.util.io.FileUtil -import org.intellij.lang.annotations.Language import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices @@ -20,7 +19,6 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver import org.jetbrains.kotlin.commonizer.tree.CirTreeModule import org.jetbrains.kotlin.commonizer.tree.defaultCirTreeModuleDeserializer -import org.jetbrains.kotlin.commonizer.utils.InlineSourceTest.Module import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor @@ -37,66 +35,8 @@ import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.util.KtTestUtil import java.io.File -interface InlineSourceTest { - annotation class ModuleBuilderDsl - - data class SourceFile(val name: String, @Language("kotlin") val content: String) - - data class Module( - val name: String, val sourceFiles: List, val dependencies: List - ) - - @ModuleBuilderDsl - class ModuleBuilder { - var name: String = "test-module" - private var sourceFiles: List = emptyList() - private var dependencies: List = emptyList() - - @ModuleBuilderDsl - fun source(name: String = "test.kt", @Language("kotlin") content: String) { - sourceFiles = sourceFiles + SourceFile(name, content) - } - - @ModuleBuilderDsl - fun dependency(builder: ModuleBuilder.() -> Unit) { - val dependency = ModuleBuilder().also(builder).build().run { - copy(name = "$name-dependency-${dependencies.size}") - } - - dependencies = dependencies + dependency - } - - fun build(): Module = Module(name, sourceFiles.toList(), dependencies.toList()) - } - - @ModuleBuilderDsl - fun module(builder: ModuleBuilder.() -> Unit): Module { - return ModuleBuilder().also(builder).build() - } - - fun deserializeSourceFile(@Language("kotlin") sourceFileContent: String): CirTreeModule { - return deserializeModule { - source("test.kt", content = sourceFileContent) - } - } - - fun deserializeModule(builder: ModuleBuilder.() -> Unit): CirTreeModule { - return deserializeModule(module(builder)) - } - - fun deserializeModule(module: Module): CirTreeModule -} - -internal interface InlineSourceTestDelegate : InlineSourceTest { - val inlineSourceTest: InlineSourceTest - override fun deserializeModule(module: Module): CirTreeModule { - return inlineSourceTest.deserializeModule(module) - } -} - -class InlineSourceTestImpl(private val disposable: Disposable) : InlineSourceTest { - - override fun deserializeModule(module: Module): CirTreeModule { +class InlineSourceBuilderImpl(private val disposable: Disposable) : InlineSourceBuilder { + override fun createCirTree(module: InlineSourceBuilder.Module): CirTreeModule { val moduleDescriptor = createModuleDescriptor(module) val metadata = MockModulesProvider.SERIALIZER.serializeModule(moduleDescriptor) @@ -113,7 +53,7 @@ class InlineSourceTestImpl(private val disposable: Disposable) : InlineSourceTes return defaultCirTreeModuleDeserializer(metadata, typeResolver) } - private fun createModuleDescriptor(module: Module): ModuleDescriptor { + override fun createModuleDescriptor(module: InlineSourceBuilder.Module): ModuleDescriptor { val moduleRoot = FileUtil.createTempDirectory(module.name, null) module.sourceFiles.forEach { sourceFile -> moduleRoot.resolve(sourceFile.name).writeText(sourceFile.content) @@ -121,7 +61,7 @@ class InlineSourceTestImpl(private val disposable: Disposable) : InlineSourceTes return createModuleDescriptor(moduleRoot, module) } - private fun createModuleDescriptor(moduleRoot: File, module: Module): ModuleDescriptor { + private fun createModuleDescriptor(moduleRoot: File, module: InlineSourceBuilder.Module): ModuleDescriptor { check(Name.isValidIdentifier(module.name)) val configuration = KotlinTestUtils.newConfiguration() configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name) @@ -153,14 +93,14 @@ class InlineSourceTestImpl(private val disposable: Disposable) : InlineSourceTes } private inner class DependenciesContainerImpl( - dependencies: List + dependencies: List ) : CommonDependenciesContainer { private val dependenciesByModuleInfos = dependencies.associate { module -> ModuleInfoImpl(module) to createModuleDescriptor(module) } - private inner class ModuleInfoImpl(module: Module) : ModuleInfo { + private inner class ModuleInfoImpl(module: InlineSourceBuilder.Module) : ModuleInfo { private val dependencyModules = module.dependencies.associateBy(::ModuleInfoImpl) override val name: Name = Name.special("<${module.name}>") override fun dependencies(): List = listOf(this) + dependencyModules.keys diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/KtInlineSourceCommonizerTestCase.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/KtInlineSourceCommonizerTestCase.kt index 9723f3fb018..1d7f14dfdb2 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/KtInlineSourceCommonizerTestCase.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/KtInlineSourceCommonizerTestCase.kt @@ -7,6 +7,6 @@ package org.jetbrains.kotlin.commonizer.utils import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase -abstract class KtInlineSourceCommonizerTestCase : KtUsefulTestCase(), InlineSourceTestDelegate { - override val inlineSourceTest: InlineSourceTest = InlineSourceTestImpl(testRootDisposable) +abstract class KtInlineSourceCommonizerTestCase : KtUsefulTestCase(), InlineSourceBuilderDelegate { + override val inlineSourceBuilder: InlineSourceBuilder = InlineSourceBuilderImpl(testRootDisposable) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt index 15418b6e1fc..a72eae9720a 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt @@ -22,7 +22,7 @@ fun assertIsDirectory(file: File) { fail("Not a directory: $file") } -@ExperimentalContracts +@OptIn(ExperimentalContracts::class) fun assertModulesAreEqual(reference: SerializedMetadata, generated: SerializedMetadata, target: CommonizerTarget) { val referenceModule = KlibModuleMetadata.read(SerializedMetadataLibraryProvider(reference)) val generatedModule = KlibModuleMetadata.read(SerializedMetadataLibraryProvider(generated)) @@ -39,7 +39,10 @@ fun assertModulesAreEqual(reference: SerializedMetadata, generated: SerializedMe val digitCount = mismatches.size.toString().length val failureMessage = buildString { - appendLine("${mismatches.size} mismatches found while comparing reference module ${referenceModule.name} (A) and generated module ${generatedModule.name} (B) for target ${target.identityString}:") + appendLine( + "${mismatches.size} mismatches found while comparing reference module ${referenceModule.name} (A) " + + "and generated module ${generatedModule.name} (B) for target ${target.identityString}:" + ) mismatches.forEachIndexed { index, mismatch -> appendLine((index + 1).toString().padStart(digitCount, ' ') + ". " + mismatch) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt index ac52745402d..d6e9289c02f 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt @@ -129,6 +129,8 @@ internal class MockModulesProvider private constructor( } } +fun ModuleDescriptor.toMetadata(): SerializedMetadata = MockModulesProvider.SERIALIZER.serializeModule(this) + private typealias ModuleName = String private typealias ModuleResults = HashMap @@ -146,7 +148,7 @@ internal class MockResultsConsumer : ResultsConsumer { override fun consume(target: CommonizerTarget, moduleResult: ModuleResult) { check(!this::status.isInitialized) - check(target !in finishedTargets) + check(target !in finishedTargets) { "$target already finished"} val moduleResults: ModuleResults = _modulesByTargets.getOrPut(target) { ModuleResults() } val oldResult = moduleResults.put(moduleResult.libraryName, moduleResult) check(oldResult == null) // to avoid accidental overwriting