[Commonizer] Implement basic tests for CirTree merging
This commit is contained in:
@@ -11,20 +11,20 @@ import org.jetbrains.kotlin.commonizer.mergedtree.FunctionApproximationKey
|
|||||||
import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey
|
import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey
|
||||||
|
|
||||||
data class CirTreeRoot(
|
data class CirTreeRoot(
|
||||||
val modules: List<CirTreeModule>
|
val modules: List<CirTreeModule> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CirTreeModule(
|
data class CirTreeModule(
|
||||||
val module: CirModule,
|
val module: CirModule,
|
||||||
val packages: List<CirTreePackage>
|
val packages: List<CirTreePackage> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CirTreePackage(
|
data class CirTreePackage(
|
||||||
val pkg: CirPackage,
|
val pkg: CirPackage,
|
||||||
val properties: List<CirTreeProperty>,
|
val properties: List<CirTreeProperty> = emptyList(),
|
||||||
val functions: List<CirTreeFunction>,
|
val functions: List<CirTreeFunction> = emptyList(),
|
||||||
val classes: List<CirTreeClass>,
|
val classes: List<CirTreeClass> = emptyList(),
|
||||||
val typeAliases: List<CirTreeTypeAlias>
|
val typeAliases: List<CirTreeTypeAlias> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
data class CirTreeProperty(
|
data class CirTreeProperty(
|
||||||
@@ -49,10 +49,10 @@ data class CirTreeTypeAlias(
|
|||||||
data class CirTreeClass(
|
data class CirTreeClass(
|
||||||
override val id: CirEntityId,
|
override val id: CirEntityId,
|
||||||
val clazz: CirClass,
|
val clazz: CirClass,
|
||||||
val properties: List<CirTreeProperty>,
|
val properties: List<CirTreeProperty> = emptyList(),
|
||||||
val functions: List<CirTreeFunction>,
|
val functions: List<CirTreeFunction> = emptyList(),
|
||||||
val constructors: List<CirTreeClassConstructor>,
|
val constructors: List<CirTreeClassConstructor> = emptyList(),
|
||||||
val classes: List<CirTreeClass>,
|
val classes: List<CirTreeClass> = emptyList(),
|
||||||
) : CirTreeClassifier
|
) : CirTreeClassifier
|
||||||
|
|
||||||
class CirTreeClassConstructor(
|
class CirTreeClassConstructor(
|
||||||
|
|||||||
+4
-166
@@ -5,174 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
package org.jetbrains.kotlin.commonizer.tree.deserializer
|
||||||
|
|
||||||
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
|
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
|
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirFictitiousFunctionClassifiers
|
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers
|
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
|
|
||||||
import org.jetbrains.kotlin.commonizer.tree.*
|
import org.jetbrains.kotlin.commonizer.tree.*
|
||||||
import org.jetbrains.kotlin.commonizer.utils.MockModulesProvider
|
import org.jetbrains.kotlin.commonizer.utils.InlineSourceTest
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.commonizer.utils.InlineSourceTestImpl
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
|
||||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
|
||||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
abstract class AbstractCirTreeDeserializerTest : KtUsefulTestCase() {
|
|
||||||
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"
|
|
||||||
var sourceFiles: List<SourceFile> = emptyList()
|
|
||||||
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(name, sourceFiles.toList(), dependencies.toList())
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModuleBuilderDsl
|
|
||||||
fun module(builder: ModuleBuilder.() -> Unit): Module {
|
|
||||||
return ModuleBuilder().also(builder).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deserializeModule(builder: ModuleBuilder.() -> Unit): CirTreeModule {
|
|
||||||
val module = module(builder)
|
|
||||||
val moduleDescriptor = createModuleDescriptor(module)
|
|
||||||
val metadata = MockModulesProvider.SERIALIZER.serializeModule(moduleDescriptor)
|
|
||||||
|
|
||||||
val classifiers = listOf(
|
|
||||||
CirFictitiousFunctionClassifiers,
|
|
||||||
CirProvidedClassifiers.by(MockModulesProvider.create(moduleDescriptor)),
|
|
||||||
CirProvidedClassifiers.by(MockModulesProvider.create(DefaultBuiltIns.Instance.builtInsModule))
|
|
||||||
) + module.dependencies.map { CirProvidedClassifiers.by(MockModulesProvider.create(createModuleDescriptor(it))) }
|
|
||||||
|
|
||||||
val typeResolver = CirTypeResolver.create(
|
|
||||||
CirProvidedClassifiers.of(*classifiers.toTypedArray())
|
|
||||||
)
|
|
||||||
|
|
||||||
return defaultCirTreeModuleDeserializer(metadata, typeResolver)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deserializeSourceFile(@Language("kotlin") sourceFileContent: String): CirTreeModule {
|
|
||||||
return deserializeModule {
|
|
||||||
source("test.kt", content = sourceFileContent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createModuleDescriptor(module: Module): ModuleDescriptor {
|
|
||||||
val moduleRoot = FileUtil.createTempDirectory(module.name, null)
|
|
||||||
module.sourceFiles.forEach { sourceFile ->
|
|
||||||
moduleRoot.resolve(sourceFile.name).writeText(sourceFile.content)
|
|
||||||
}
|
|
||||||
return createModuleDescriptor(moduleRoot, module)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createModuleDescriptor(moduleRoot: File, module: Module): ModuleDescriptor {
|
|
||||||
check(Name.isValidIdentifier(module.name))
|
|
||||||
val configuration = KotlinTestUtils.newConfiguration()
|
|
||||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name)
|
|
||||||
|
|
||||||
val environment: KotlinCoreEnvironment = KotlinCoreEnvironment.createForTests(
|
|
||||||
parentDisposable = testRootDisposable,
|
|
||||||
initialConfiguration = configuration,
|
|
||||||
extensionConfigs = EnvironmentConfigFiles.METADATA_CONFIG_FILES
|
|
||||||
)
|
|
||||||
|
|
||||||
val psiFactory = KtPsiFactory(environment.project)
|
|
||||||
|
|
||||||
val psiFiles: List<KtFile> = moduleRoot.walkTopDown()
|
|
||||||
.filter { it.isFile }
|
|
||||||
.map { psiFactory.createFile(it.name, KtTestUtil.doLoadFile(it)) }
|
|
||||||
.toList()
|
|
||||||
|
|
||||||
return CommonResolverForModuleFactory.analyzeFiles(
|
|
||||||
files = psiFiles,
|
|
||||||
moduleName = Name.special("<${module.name}>"),
|
|
||||||
dependOnBuiltIns = true,
|
|
||||||
languageVersionSettings = environment.configuration.languageVersionSettings,
|
|
||||||
targetPlatform = CommonPlatforms.defaultCommonPlatform,
|
|
||||||
targetEnvironment = CompilerEnvironment,
|
|
||||||
dependenciesContainer = DependenciesContainerImpl(module.dependencies),
|
|
||||||
) { content ->
|
|
||||||
environment.createPackagePartProvider(content.moduleContentScope)
|
|
||||||
}.moduleDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class DependenciesContainerImpl(
|
|
||||||
dependencies: List<Module>
|
|
||||||
) : CommonDependenciesContainer {
|
|
||||||
|
|
||||||
private val dependenciesByModuleInfos = dependencies.associate { module ->
|
|
||||||
ModuleInfoImpl(module) to createModuleDescriptor(module)
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class ModuleInfoImpl(module: 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
|
|
||||||
override val platform: TargetPlatform get() = CommonPlatforms.defaultCommonPlatform
|
|
||||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = CommonPlatformAnalyzerServices
|
|
||||||
}
|
|
||||||
|
|
||||||
override val moduleInfos: List<ModuleInfo> get() = listOf(DefaultBuiltInsModuleInfo) + dependenciesByModuleInfos.keys
|
|
||||||
override val friendModuleInfos: List<ModuleInfo> get() = emptyList()
|
|
||||||
override val refinesModuleInfos: List<ModuleInfo> get() = emptyList()
|
|
||||||
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
|
|
||||||
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
|
|
||||||
|
|
||||||
override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor {
|
|
||||||
dependenciesByModuleInfos[moduleInfo]?.let { return it }
|
|
||||||
check(moduleInfo == DefaultBuiltInsModuleInfo) { "Unknown module info $moduleInfo" }
|
|
||||||
return DefaultBuiltIns.Instance.builtInsModule
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object DefaultBuiltInsModuleInfo : ModuleInfo {
|
|
||||||
override val name get() = DefaultBuiltIns.Instance.builtInsModule.name
|
|
||||||
override fun dependencies() = listOf(this)
|
|
||||||
override fun dependencyOnBuiltIns() = ModuleInfo.DependencyOnBuiltIns.LAST
|
|
||||||
override val platform get() = CommonPlatforms.defaultCommonPlatform
|
|
||||||
override val analyzerServices get() = CommonPlatformAnalyzerServices
|
|
||||||
}
|
|
||||||
|
|
||||||
|
abstract class AbstractCirTreeDeserializerTest : KtInlineSourceCommonizerTestCase() {
|
||||||
protected fun CirTreeModule.assertSinglePackage(): CirTreePackage {
|
protected fun CirTreeModule.assertSinglePackage(): CirTreePackage {
|
||||||
return packages.singleOrNull()
|
return packages.singleOrNull()
|
||||||
?: kotlin.test.fail("Expected single package. Found ${packages.map { it.pkg.packageName }}")
|
?: kotlin.test.fail("Expected single package. Found ${packages.map { it.pkg.packageName }}")
|
||||||
|
|||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("TestFunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.commonizer.tree.merge
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
|
||||||
|
import org.jetbrains.kotlin.commonizer.TargetDependent
|
||||||
|
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
||||||
|
import org.jetbrains.kotlin.commonizer.toTargetDependent
|
||||||
|
import org.jetbrains.kotlin.commonizer.tree.CirTreeModule
|
||||||
|
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||||
|
import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase
|
||||||
|
import org.jetbrains.kotlin.commonizer.utils.MockModulesProvider
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
|
||||||
|
abstract class AbstractMergeCirTreeTest : KtInlineSourceCommonizerTestCase() {
|
||||||
|
private val storageManager = LockBasedStorageManager(this::class.simpleName)
|
||||||
|
|
||||||
|
fun mergeCirTree(vararg modules: Pair<String, CirTreeModule>): CirRootNode {
|
||||||
|
return org.jetbrains.kotlin.commonizer.tree.mergeCirTree(storageManager, createDefaultKnownClassifiers(), TargetDependent(*modules))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirRootNode.assertSingleModule(): CirModuleNode {
|
||||||
|
kotlin.test.assertEquals(1, modules.size, "Expected exactly one merged module. Found ${modules.map { it.key }}")
|
||||||
|
return modules.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirModuleNode.assertSinglePackage(): CirPackageNode {
|
||||||
|
kotlin.test.assertEquals(1, packages.size, "Expected exactly one package. Found ${packages.map { it.key }}")
|
||||||
|
return packages.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirPackageNode.assertSingleProperty(): CirPropertyNode {
|
||||||
|
kotlin.test.assertEquals(1, properties.size, "Expected exactly one property. Found ${properties.map { it.key }}")
|
||||||
|
return properties.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirPackageNode.assertSingleFunction(): CirFunctionNode {
|
||||||
|
kotlin.test.assertEquals(1, functions.size, "Expected exactly one function. Found ${functions.map { it.key }}")
|
||||||
|
return functions.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirPackageNode.assertSingleTypeAlias(): CirTypeAliasNode {
|
||||||
|
kotlin.test.assertEquals(1, typeAliases.size, "Expected exactly one type alias. Found ${typeAliases.map { it.key }}")
|
||||||
|
return typeAliases.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirPackageNode.assertSingleClass(): CirClassNode {
|
||||||
|
kotlin.test.assertEquals(1, classes.size, "Expected exactly one class. Found ${classes.map { it.key }}")
|
||||||
|
return classes.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirClassNode.assertSingleConstructor(): CirClassConstructorNode {
|
||||||
|
kotlin.test.assertEquals(1, constructors.size, "Expected exactly one function. Found ${constructors.map { it.key }}")
|
||||||
|
return constructors.values.single()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirNode<*, *>.assertNoMissingTargetDeclaration() {
|
||||||
|
this.targetDeclarations.forEachIndexed { index, target ->
|
||||||
|
kotlin.test.assertNotNull(target, "Missing target declaration at index $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CirNode<*, *>.assertOnlyTargetDeclarationAtIndex(vararg indices: Int) {
|
||||||
|
this.targetDeclarations.forEachIndexed { index, target ->
|
||||||
|
if (index in indices) {
|
||||||
|
kotlin.test.assertNotNull(target, "Expected target declaration at index $index")
|
||||||
|
} else {
|
||||||
|
kotlin.test.assertNull(target, "Expected *no* target declaration at index $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TargetDependent(vararg modules: Pair<String, CirTreeModule>): TargetDependent<CirTreeRoot> {
|
||||||
|
return TargetDependent(modules.toList())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TargetDependent(modules: Iterable<Pair<String, CirTreeModule>>): TargetDependent<CirTreeRoot> {
|
||||||
|
return modules.toMap().mapKeys { (targetName, _) -> LeafCommonizerTarget(targetName) }
|
||||||
|
.mapValues { (_, module) -> CirTreeRoot(listOf(module)) }
|
||||||
|
.toTargetDependent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDefaultKnownClassifiers(): CirKnownClassifiers {
|
||||||
|
return CirKnownClassifiers(
|
||||||
|
CirCommonizedClassifierNodes.default(),
|
||||||
|
CirProvidedClassifiers.of(
|
||||||
|
CirFictitiousFunctionClassifiers,
|
||||||
|
CirProvidedClassifiers.by(MockModulesProvider.create(DefaultBuiltIns.Instance.builtInsModule))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 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 merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val clazz = merged.assertSingleModule().assertSinglePackage().assertSingleClass()
|
||||||
|
kotlin.test.assertEquals(2, clazz.constructors.size, "Expected two constructors")
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.tree.merge
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
|
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 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 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)")
|
||||||
|
val a = pkg.classes[CirName.create("A")] ?: kotlin.test.fail("Missing class 'A'")
|
||||||
|
val b = pkg.classes[CirName.create("B")] ?: kotlin.test.fail("Missing class 'B'")
|
||||||
|
|
||||||
|
a.assertOnlyTargetDeclarationAtIndex(0)
|
||||||
|
b.assertOnlyTargetDeclarationAtIndex(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test with children`() {
|
||||||
|
val aTree = deserializeSourceFile(
|
||||||
|
"""
|
||||||
|
class X {
|
||||||
|
val x: Int = 42
|
||||||
|
val a: Int = 42
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val bTree = deserializeSourceFile(
|
||||||
|
"""
|
||||||
|
class X {
|
||||||
|
val x: Int = 42
|
||||||
|
val b: Int = 42
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val clazz = merged.assertSingleModule().assertSinglePackage().assertSingleClass()
|
||||||
|
kotlin.test.assertEquals(3, clazz.properties.size, "Expected three properties (x, a, b)")
|
||||||
|
val x = clazz.properties[PropertyApproximationKey(CirName.create("x"), null)] ?: kotlin.test.fail("Missing property 'x'")
|
||||||
|
val a = clazz.properties[PropertyApproximationKey(CirName.create("a"), null)] ?: kotlin.test.fail("Missing property 'a'")
|
||||||
|
val b = clazz.properties[PropertyApproximationKey(CirName.create("b"), null)] ?: kotlin.test.fail("Missing property 'b'")
|
||||||
|
|
||||||
|
x.assertNoMissingTargetDeclaration()
|
||||||
|
a.assertOnlyTargetDeclarationAtIndex(0)
|
||||||
|
b.assertOnlyTargetDeclarationAtIndex(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.tree.merge
|
||||||
|
|
||||||
|
class MergeCirTreeFunctionTest : AbstractMergeCirTreeTest() {
|
||||||
|
|
||||||
|
fun `test simple function`() {
|
||||||
|
val aTree = deserializeSourceFile("fun x(): Int = 42")
|
||||||
|
val bTree = deserializeSourceFile("fun x(): Int = 42")
|
||||||
|
val merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val function = merged.assertSingleModule().assertSinglePackage().assertSingleFunction()
|
||||||
|
|
||||||
|
function.assertNoMissingTargetDeclaration()
|
||||||
|
function.targetDeclarations.forEachIndexed { index, cirFunction ->
|
||||||
|
kotlin.test.assertNotNull(cirFunction)
|
||||||
|
kotlin.test.assertEquals("x", cirFunction.name.toStrippedString(), "Expected function name 'x' at index $index")
|
||||||
|
kotlin.test.assertEquals("kotlin/Int", cirFunction.returnType.toString(), "Expected return type 'kotlin/Int' at index $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test missing target declarations`() {
|
||||||
|
val aTree = deserializeSourceFile("fun a(): Int = 42")
|
||||||
|
val bTree = deserializeSourceFile("fun b(): Int = 42")
|
||||||
|
val merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val pkg = merged.assertSingleModule().assertSinglePackage()
|
||||||
|
|
||||||
|
val aKey = pkg.functions.keys.singleOrNull { it.name.toStrippedString() == "a" } ?: kotlin.test.fail("Missing function key 'a'")
|
||||||
|
val bKey = pkg.functions.keys.singleOrNull { it.name.toStrippedString() == "b" } ?: kotlin.test.fail("Missing function key 'b'")
|
||||||
|
|
||||||
|
val aFunction = pkg.functions.getValue(aKey)
|
||||||
|
val bFunction = pkg.functions.getValue(bKey)
|
||||||
|
|
||||||
|
kotlin.test.assertNotNull(aFunction.targetDeclarations[0], "Expected target declaration for 'a' at index 0")
|
||||||
|
kotlin.test.assertNotNull(bFunction.targetDeclarations[1], "Expected target for declaration 'b' at index 1")
|
||||||
|
kotlin.test.assertNull(aFunction.targetDeclarations[1], "Expected *no* target declaration for 'a' at index 1")
|
||||||
|
kotlin.test.assertNull(bFunction.targetDeclarations[0], "Expected *no* target declaration for 'b' at index 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.tree.merge
|
||||||
|
|
||||||
|
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 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)")
|
||||||
|
module.packages[CirPackageName.ROOT] ?: kotlin.test.fail("Missing root package")
|
||||||
|
module.packages[CirPackageName.create("test")] ?: kotlin.test.fail("Missing test package")
|
||||||
|
val pkg = module.packages[CirPackageName.create("test.pkg")] ?: kotlin.test.fail("Missing test.pkg package")
|
||||||
|
|
||||||
|
pkg.assertNoMissingTargetDeclaration()
|
||||||
|
pkg.targetDeclarations.forEachIndexed { index, cirPackage ->
|
||||||
|
kotlin.test.assertNotNull(cirPackage)
|
||||||
|
kotlin.test.assertEquals("test/pkg", cirPackage.packageName.toMetadataString(), "Expected correct packageName at index $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test missing target declarations`() {
|
||||||
|
val aTree = deserializeSourceFile("package a")
|
||||||
|
val bTree = deserializeSourceFile("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)")
|
||||||
|
|
||||||
|
val a = module.packages[CirPackageName.create("a")] ?: kotlin.test.fail("Missing a package")
|
||||||
|
val b = module.packages[CirPackageName.create("b")] ?: kotlin.test.fail("Missing b package")
|
||||||
|
|
||||||
|
kotlin.test.assertNotNull(a.targetDeclarations[0], "Expected target declaration for 'a' at index 0")
|
||||||
|
kotlin.test.assertNotNull(b.targetDeclarations[1], "Expected target declaration for 'b' at index 1")
|
||||||
|
kotlin.test.assertNull(a.targetDeclarations[1], "Expected *no* target declaration for 'a' at index 1")
|
||||||
|
kotlin.test.assertNull(b.targetDeclarations[0], "Expected *no* target declaration for 'b' at index 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("RemoveRedundantQualifierName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.commonizer.tree.merge
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirName.Companion.create
|
||||||
|
import org.jetbrains.kotlin.commonizer.mergedtree.PropertyApproximationKey
|
||||||
|
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 merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
|
||||||
|
val property = merged.assertSingleModule().assertSinglePackage().assertSingleProperty()
|
||||||
|
property.targetDeclarations.forEachIndexed { index, cirProperty ->
|
||||||
|
assertNotNull(cirProperty, "Expected not-null property at index $index")
|
||||||
|
kotlin.test.assertEquals("a", cirProperty.name.toStrippedString(), "Expected correct property name at index $index")
|
||||||
|
kotlin.test.assertEquals("kotlin/Int", cirProperty.returnType.toString(), "Expected correct return type at index $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test multiple properties`() {
|
||||||
|
val aTree = deserializeSourceFile(
|
||||||
|
"""
|
||||||
|
val a: Int = 42
|
||||||
|
val b: Int = 42
|
||||||
|
val c: String = "hello"
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val bTree = deserializeSourceFile(
|
||||||
|
"""
|
||||||
|
val a: Int = 42
|
||||||
|
val b: Int = 42
|
||||||
|
val c: String = "hello"
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val pkg = merged.assertSingleModule().assertSinglePackage()
|
||||||
|
kotlin.test.assertEquals(3, pkg.properties.size, "Expected exactly three properties")
|
||||||
|
|
||||||
|
val a = pkg.properties[PropertyApproximationKey(create("a"), null)] ?: kotlin.test.fail("Missing a property")
|
||||||
|
val b = pkg.properties[PropertyApproximationKey(create("b"), null)] ?: kotlin.test.fail("Missing a property")
|
||||||
|
val c = pkg.properties[PropertyApproximationKey(create("c"), null)] ?: kotlin.test.fail("Missing a property")
|
||||||
|
|
||||||
|
a.assertNoMissingTargetDeclaration()
|
||||||
|
b.assertNoMissingTargetDeclaration()
|
||||||
|
c.assertNoMissingTargetDeclaration()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test missing target declarations`() {
|
||||||
|
val aTree = deserializeSourceFile("val a: Int = 42")
|
||||||
|
val bTree = deserializeSourceFile("val b: Int = 42")
|
||||||
|
val merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val pkg = merged.assertSingleModule().assertSinglePackage()
|
||||||
|
|
||||||
|
val a = pkg.properties[PropertyApproximationKey(create("a"), null)] ?: kotlin.test.fail("Missing a property")
|
||||||
|
val b = pkg.properties[PropertyApproximationKey(create("b"), null)] ?: kotlin.test.fail("Missing a property")
|
||||||
|
|
||||||
|
kotlin.test.assertNotNull(a.targetDeclarations[0], "Expected *non* missing target declaration at index 0")
|
||||||
|
kotlin.test.assertNull(a.targetDeclarations[1], "Expected missing target declaration for a at index 1")
|
||||||
|
|
||||||
|
kotlin.test.assertNull(b.targetDeclarations[0], "Expected missing target declaration at index 0")
|
||||||
|
kotlin.test.assertNotNull(b.targetDeclarations[1], "Expected *non* missing target declaration for a at index 1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.tree.merge
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
|
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 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 merged = mergeCirTree("a" to aTree, "b" to bTree)
|
||||||
|
val pkg = merged.assertSingleModule().assertSinglePackage()
|
||||||
|
|
||||||
|
assertEquals(2, pkg.typeAliases.size, "Expected 2 type aliases (a, b)")
|
||||||
|
val a = pkg.typeAliases[CirName.create("a")] ?: kotlin.test.fail("Missing type alias 'a'")
|
||||||
|
val b = pkg.typeAliases[CirName.create("b")] ?: kotlin.test.fail("Missing type alias 'b'")
|
||||||
|
|
||||||
|
kotlin.test.assertNotNull(a.targetDeclarations[0], "Expected target declaration for 'a' at index 0")
|
||||||
|
kotlin.test.assertNotNull(b.targetDeclarations[1], "Expected target declaration for 'b' at index 1")
|
||||||
|
kotlin.test.assertNull(a.targetDeclarations[1], "Expected *no* target declaration for 'a' at index 1")
|
||||||
|
kotlin.test.assertNull(b.targetDeclarations[0], "Expected *no* target declaration for 'b' at index 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* 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 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
|
||||||
|
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirFictitiousFunctionClassifiers
|
||||||
|
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
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||||
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
|
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 {
|
||||||
|
val moduleDescriptor = createModuleDescriptor(module)
|
||||||
|
val metadata = MockModulesProvider.SERIALIZER.serializeModule(moduleDescriptor)
|
||||||
|
|
||||||
|
val classifiers = listOf(
|
||||||
|
CirFictitiousFunctionClassifiers,
|
||||||
|
CirProvidedClassifiers.by(MockModulesProvider.create(moduleDescriptor)),
|
||||||
|
CirProvidedClassifiers.by(MockModulesProvider.create(DefaultBuiltIns.Instance.builtInsModule))
|
||||||
|
) + module.dependencies.map { CirProvidedClassifiers.by(MockModulesProvider.create(createModuleDescriptor(it))) }
|
||||||
|
|
||||||
|
val typeResolver = CirTypeResolver.create(
|
||||||
|
CirProvidedClassifiers.of(*classifiers.toTypedArray())
|
||||||
|
)
|
||||||
|
|
||||||
|
return defaultCirTreeModuleDeserializer(metadata, typeResolver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModuleDescriptor(module: Module): ModuleDescriptor {
|
||||||
|
val moduleRoot = FileUtil.createTempDirectory(module.name, null)
|
||||||
|
module.sourceFiles.forEach { sourceFile ->
|
||||||
|
moduleRoot.resolve(sourceFile.name).writeText(sourceFile.content)
|
||||||
|
}
|
||||||
|
return createModuleDescriptor(moduleRoot, module)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModuleDescriptor(moduleRoot: File, module: Module): ModuleDescriptor {
|
||||||
|
check(Name.isValidIdentifier(module.name))
|
||||||
|
val configuration = KotlinTestUtils.newConfiguration()
|
||||||
|
configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name)
|
||||||
|
|
||||||
|
val environment: KotlinCoreEnvironment = KotlinCoreEnvironment.createForTests(
|
||||||
|
parentDisposable = disposable,
|
||||||
|
initialConfiguration = configuration,
|
||||||
|
extensionConfigs = EnvironmentConfigFiles.METADATA_CONFIG_FILES
|
||||||
|
)
|
||||||
|
|
||||||
|
val psiFactory = KtPsiFactory(environment.project)
|
||||||
|
|
||||||
|
val psiFiles: List<KtFile> = moduleRoot.walkTopDown()
|
||||||
|
.filter { it.isFile }
|
||||||
|
.map { psiFactory.createFile(it.name, KtTestUtil.doLoadFile(it)) }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
return CommonResolverForModuleFactory.analyzeFiles(
|
||||||
|
files = psiFiles,
|
||||||
|
moduleName = Name.special("<${module.name}>"),
|
||||||
|
dependOnBuiltIns = true,
|
||||||
|
languageVersionSettings = environment.configuration.languageVersionSettings,
|
||||||
|
targetPlatform = CommonPlatforms.defaultCommonPlatform,
|
||||||
|
targetEnvironment = CompilerEnvironment,
|
||||||
|
dependenciesContainer = DependenciesContainerImpl(module.dependencies),
|
||||||
|
) { content ->
|
||||||
|
environment.createPackagePartProvider(content.moduleContentScope)
|
||||||
|
}.moduleDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class DependenciesContainerImpl(
|
||||||
|
dependencies: List<Module>
|
||||||
|
) : CommonDependenciesContainer {
|
||||||
|
|
||||||
|
private val dependenciesByModuleInfos = dependencies.associate { module ->
|
||||||
|
ModuleInfoImpl(module) to createModuleDescriptor(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class ModuleInfoImpl(module: 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
|
||||||
|
override val platform: TargetPlatform get() = CommonPlatforms.defaultCommonPlatform
|
||||||
|
override val analyzerServices: PlatformDependentAnalyzerServices get() = CommonPlatformAnalyzerServices
|
||||||
|
}
|
||||||
|
|
||||||
|
override val moduleInfos: List<ModuleInfo> get() = listOf(DefaultBuiltInsModuleInfo) + dependenciesByModuleInfos.keys
|
||||||
|
override val friendModuleInfos: List<ModuleInfo> get() = emptyList()
|
||||||
|
override val refinesModuleInfos: List<ModuleInfo> get() = emptyList()
|
||||||
|
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
|
||||||
|
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
|
||||||
|
|
||||||
|
override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor {
|
||||||
|
dependenciesByModuleInfos[moduleInfo]?.let { return it }
|
||||||
|
check(moduleInfo == DefaultBuiltInsModuleInfo) { "Unknown module info $moduleInfo" }
|
||||||
|
return DefaultBuiltIns.Instance.builtInsModule
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object DefaultBuiltInsModuleInfo : ModuleInfo {
|
||||||
|
override val name get() = DefaultBuiltIns.Instance.builtInsModule.name
|
||||||
|
override fun dependencies() = listOf(this)
|
||||||
|
override fun dependencyOnBuiltIns() = ModuleInfo.DependencyOnBuiltIns.LAST
|
||||||
|
override val platform get() = CommonPlatforms.defaultCommonPlatform
|
||||||
|
override val analyzerServices get() = CommonPlatformAnalyzerServices
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.testFramework.KtUsefulTestCase
|
||||||
|
|
||||||
|
abstract class KtInlineSourceCommonizerTestCase : KtUsefulTestCase(), InlineSourceTestDelegate {
|
||||||
|
override val inlineSourceTest: InlineSourceTest = InlineSourceTestImpl(testRootDisposable)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user