[Commonizer] Implement AbstractInlineSourcesCommonizationTest and hierarchical commonization tests
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
+215
@@ -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<CommonizerTarget, List<ResultsConsumer.ModuleResult>>
|
||||
)
|
||||
|
||||
abstract class AbstractInlineSourcesCommonizationTest : KtInlineSourceCommonizerTestCase() {
|
||||
|
||||
data class Parameters(
|
||||
val outputTarget: SharedCommonizerTarget,
|
||||
val dependencies: TargetDependent<List<InlineSourceBuilder.Module>>,
|
||||
val targets: List<Target>
|
||||
)
|
||||
|
||||
data class Target(
|
||||
val target: CommonizerTarget,
|
||||
val modules: List<InlineSourceBuilder.Module>
|
||||
)
|
||||
|
||||
|
||||
@DslMarker
|
||||
annotation class InlineSourcesCommonizationTestDsl
|
||||
|
||||
@InlineSourcesCommonizationTestDsl
|
||||
class ParametersBuilder(private val parentInlineSourceBuilder: InlineSourceBuilder) {
|
||||
private var outputTarget: SharedCommonizerTarget? = null
|
||||
|
||||
private val dependencies: MutableMap<CommonizerTarget, MutableList<InlineSourceBuilder.Module>> = LinkedHashMap()
|
||||
|
||||
private var targets: List<Target> = 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<List<InlineSourceBuilder.Module>>
|
||||
) {
|
||||
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<InlineSourceBuilder.Module> = 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<ResultsConsumer.ModuleResult> {
|
||||
return this.results[target] ?: kotlin.test.fail("Missing target $target in results ${this.results.keys}")
|
||||
}
|
||||
|
||||
fun HierarchicalCommonizationResult.getTarget(target: String): List<ResultsConsumer.ModuleResult> {
|
||||
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<ResultsConsumer.ModuleResult>.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'")
|
||||
}
|
||||
+145
@@ -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
|
||||
}
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
+181
@@ -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")
|
||||
}
|
||||
}
|
||||
+233
@@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -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")
|
||||
}
|
||||
}
|
||||
+30
@@ -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", "")
|
||||
}
|
||||
}
|
||||
-2
@@ -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() {
|
||||
|
||||
+11
-11
@@ -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
|
||||
|
||||
+4
-3
@@ -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()
|
||||
|
||||
+3
-3
@@ -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: Any> T.isHappy(): Boolean = true""")
|
||||
val module = createCirTreeFromSourceCode("""fun <T: Any> 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"
|
||||
|
||||
+9
-7
@@ -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"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -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> T.x: T get() = this")
|
||||
val module = createCirTreeFromSourceCode("var <T> 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
|
||||
|
||||
+2
-2
@@ -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<K, V>
|
||||
typealias IntMap<V> = Map<Int, V>
|
||||
|
||||
+4
-4
@@ -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")
|
||||
|
||||
+6
-6
@@ -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
|
||||
|
||||
+4
-4
@@ -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()
|
||||
|
||||
|
||||
+4
-4
@@ -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)")
|
||||
|
||||
+6
-6
@@ -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()
|
||||
|
||||
|
||||
+4
-4
@@ -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()
|
||||
|
||||
|
||||
@@ -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<SourceFile>, val dependencies: List<Module>
|
||||
)
|
||||
|
||||
@ModuleBuilderDsl
|
||||
class ModuleBuilder {
|
||||
var name: String = "test-module"
|
||||
private var sourceFiles: List<SourceFile> = emptyList()
|
||||
private var dependencies: List<Module> = 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))
|
||||
}
|
||||
|
||||
+21
@@ -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)
|
||||
}
|
||||
}
|
||||
+6
-66
@@ -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<SourceFile>, val dependencies: List<Module>
|
||||
)
|
||||
|
||||
@ModuleBuilderDsl
|
||||
class ModuleBuilder {
|
||||
var name: String = "test-module"
|
||||
private var sourceFiles: List<SourceFile> = emptyList()
|
||||
private var dependencies: List<Module> = 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<Module>
|
||||
dependencies: List<InlineSourceBuilder.Module>
|
||||
) : 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<ModuleInfo> = listOf(this) + dependencyModules.keys
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<ModuleName, ModuleResult>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user