From e37a485aaa3c5e51927d54ec99e40a807192f2b6 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 3 Jun 2020 18:43:54 +0700 Subject: [PATCH] [Commonizer] Process expect/actual cross-module dependencies in source-based tests --- .../AbstractCommonizationFromSourcesTest.kt | 80 ++++++++++++++++++- .../commonizer/utils/assertions.kt | 4 + 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt index b5ea258b6f9..9ef88dc60e1 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt @@ -7,6 +7,9 @@ package org.jetbrains.kotlin.descriptors.commonizer import com.intellij.openapi.Disposable import com.intellij.testFramework.PlatformTestUtil.lowercaseFirstLetter +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.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment @@ -14,14 +17,19 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentProvider +import org.jetbrains.kotlin.descriptors.commonizer.SourceModuleRoot.Companion.COMMON_TARGET_NAME import org.jetbrains.kotlin.descriptors.commonizer.utils.assertCommonizationPerformed import org.jetbrains.kotlin.descriptors.commonizer.utils.assertIsDirectory import org.jetbrains.kotlin.descriptors.commonizer.utils.assertModulesAreEqual import org.jetbrains.kotlin.descriptors.commonizer.utils.assertValidModule +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.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.test.KotlinTestUtils.* import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import java.io.File @@ -85,8 +93,6 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() { } } -private const val COMMON_TARGET_NAME = "common" - private data class SourceModuleRoot( val targetName: String, val root: File @@ -100,6 +106,8 @@ private data class SourceModuleRoot( targetName = directory.name, root = directory ) + + const val COMMON_TARGET_NAME = "common" } } @@ -145,6 +153,7 @@ private class AnalyzedModule( fun create( target: T, sourceModuleRoot: SourceModuleRoot, + commonSourceModuleRoot: SourceModuleRoot? = null, parentDisposable: Disposable ): AnalyzedModule { val moduleName: String = sourceModuleRoot.root.parentFile.parentFile.name @@ -155,6 +164,7 @@ private class AnalyzedModule( module = analyze( moduleName = moduleName, moduleRoot = sourceModuleRoot.root, + commonModuleRoot = commonSourceModuleRoot?.root, parentDisposable = parentDisposable ) ) @@ -163,6 +173,37 @@ private class AnalyzedModule( private fun analyze( moduleName: String, moduleRoot: File, + commonModuleRoot: File?, + parentDisposable: Disposable + ): ModuleDescriptor { + val commonModule: ModuleDescriptor? = if (commonModuleRoot != null) { + analyzeModule( + moduleName = "common" + moduleName.capitalize(), + moduleRoot = commonModuleRoot, + dependencyContainer = null, // common module does not have any specific dependencies + parentDisposable = parentDisposable + ) + } else null + + val module: ModuleDescriptor = analyzeModule( + moduleName = moduleName, + moduleRoot = moduleRoot, + dependencyContainer = commonModule?.let(::CommonizedCommonDependenciesContainer), // platform module has dependencies to common module + parentDisposable = parentDisposable + ) + + if (commonModule != null) { + check(commonModule in module.expectedByModules) + check(commonModule in module.allDependencyModules) + } + + return module + } + + private fun analyzeModule( + moduleName: String, + moduleRoot: File, + dependencyContainer: CommonDependenciesContainer?, parentDisposable: Disposable ): ModuleDescriptor { val configuration: CompilerConfiguration = newConfiguration() @@ -186,7 +227,8 @@ private class AnalyzedModule( moduleName = Name.special("<$moduleName>"), dependOnBuiltIns = true, languageVersionSettings = environment.configuration.languageVersionSettings, - targetPlatform = CommonPlatforms.defaultCommonPlatform + targetPlatform = CommonPlatforms.defaultCommonPlatform, + dependenciesContainer = dependencyContainer ) { content -> environment.createPackagePartProvider(content.moduleContentScope) }.moduleDescriptor @@ -224,6 +266,7 @@ private class AnalyzedModules( val commonizedPlatformModules: Map> = createInputTargetModules( sourceModuleRoots = sourceModuleRoots.commonizedPlatformRoots, + commonSourceModuleRoot = sourceModuleRoots.commonizedCommonRoot, parentDisposable = parentDisposable ) @@ -236,17 +279,48 @@ private class AnalyzedModules( private fun createInputTargetModules( sourceModuleRoots: Map, + commonSourceModuleRoot: SourceModuleRoot? = null, parentDisposable: Disposable ): Map> = sourceModuleRoots.map { (targetName, sourceModuleRoot) -> AnalyzedModule.create( target = InputTarget(targetName), sourceModuleRoot = sourceModuleRoot, + commonSourceModuleRoot = commonSourceModuleRoot, parentDisposable = parentDisposable ) }.associateBy { it.target } } } +private class CommonizedCommonDependenciesContainer( + private val commonModule: ModuleDescriptor +) : CommonDependenciesContainer { + private val commonModuleInfo = object : ModuleInfo { + override val name: Name get() = commonModule.name + + override fun dependencies(): List = listOf(this) + override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns = ModuleInfo.DependencyOnBuiltIns.LAST + + override val platform: TargetPlatform get() = CommonPlatforms.defaultCommonPlatform + override val analyzerServices: PlatformDependentAnalyzerServices get() = CommonPlatformAnalyzerServices + } + + override val moduleInfos: List get() = listOf(commonModuleInfo) + + override fun moduleDescriptorForModuleInfo(moduleInfo: ModuleInfo): ModuleDescriptor { + if (moduleInfo !== commonModuleInfo) + error("Unknown module info $moduleInfo") + + return commonModule + } + + override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit + override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null + + override val friendModuleInfos: List get() = emptyList() + override val refinesModuleInfos: List get() = listOf(commonModuleInfo) +} + private fun Map.toCommonizationParameters(): Parameters = Parameters().also { forEach { (target, moduleDescriptor) -> it.addTarget( diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/assertions.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/assertions.kt index 98451bd7966..af22e0c2da0 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/assertions.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/assertions.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.utils import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.CommonizationPerformed import org.jetbrains.kotlin.descriptors.commonizer.Result +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.test.util.DescriptorValidator.* import org.jetbrains.kotlin.types.ErrorUtils import java.io.File @@ -41,6 +43,8 @@ fun assertModulesAreEqual(expected: ModuleDescriptor, actual: ModuleDescriptor, fun assertValidModule(module: ModuleDescriptor) = validate( object : ValidationVisitor() { + override fun validateScope(scopeOwner: DeclarationDescriptor?, scope: MemberScope, collector: DiagnosticCollector) = Unit + override fun visitModuleDeclaration(descriptor: ModuleDescriptor, collector: DiagnosticCollector): Boolean { assertValid(descriptor) return super.visitModuleDeclaration(descriptor, collector)