[Test] Support friend modules in new test infrastructure
This commit is contained in:
committed by
TeamCityServer
parent
7e92fb8eb9
commit
065255adbe
+13
-4
@@ -91,11 +91,13 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory = ::FileBasedDeclarationProviderFactory,
|
declarationProviderFactory: (StorageManager, Collection<KtFile>) -> DeclarationProviderFactory = ::FileBasedDeclarationProviderFactory,
|
||||||
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files),
|
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files),
|
||||||
klibList: List<KotlinLibrary> = emptyList(),
|
klibList: List<KotlinLibrary> = emptyList(),
|
||||||
explicitModuleDependencyList: List<ModuleDescriptorImpl> = emptyList()
|
explicitModuleDependencyList: List<ModuleDescriptorImpl> = emptyList(),
|
||||||
|
explicitModuleFriendsList: List<ModuleDescriptorImpl> = emptyList()
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
val container = createContainer(
|
val container = createContainer(
|
||||||
project, files, trace, configuration, packagePartProvider, declarationProviderFactory, CompilerEnvironment,
|
project, files, trace, configuration, packagePartProvider, declarationProviderFactory, CompilerEnvironment,
|
||||||
sourceModuleSearchScope, klibList, explicitModuleDependencyList = explicitModuleDependencyList
|
sourceModuleSearchScope, klibList, explicitModuleDependencyList = explicitModuleDependencyList,
|
||||||
|
explicitModuleFriendsList = explicitModuleFriendsList
|
||||||
)
|
)
|
||||||
|
|
||||||
val module = container.get<ModuleDescriptor>()
|
val module = container.get<ModuleDescriptor>()
|
||||||
@@ -140,7 +142,8 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files),
|
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files),
|
||||||
klibList: List<KotlinLibrary> = emptyList(),
|
klibList: List<KotlinLibrary> = emptyList(),
|
||||||
implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter? = null,
|
implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter? = null,
|
||||||
explicitModuleDependencyList: List<ModuleDescriptorImpl> = emptyList()
|
explicitModuleDependencyList: List<ModuleDescriptorImpl> = emptyList(),
|
||||||
|
explicitModuleFriendsList: List<ModuleDescriptorImpl> = emptyList()
|
||||||
): ComponentProvider {
|
): ComponentProvider {
|
||||||
val jvmTarget = configuration.get(JVMConfigurationKeys.JVM_TARGET, JvmTarget.DEFAULT)
|
val jvmTarget = configuration.get(JVMConfigurationKeys.JVM_TARGET, JvmTarget.DEFAULT)
|
||||||
val languageVersionSettings = configuration.languageVersionSettings
|
val languageVersionSettings = configuration.languageVersionSettings
|
||||||
@@ -263,9 +266,15 @@ object TopDownAnalyzerFacadeForJVM {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
addAll(explicitModuleDependencyList)
|
addAll(explicitModuleDependencyList)
|
||||||
}
|
}
|
||||||
|
val friends = buildSet {
|
||||||
|
if (dependencyModule != null) {
|
||||||
|
add(dependencyModule)
|
||||||
|
}
|
||||||
|
addAll(explicitModuleFriendsList)
|
||||||
|
}
|
||||||
module.setDependencies(
|
module.setDependencies(
|
||||||
dependencies,
|
dependencies,
|
||||||
if (dependencyModule != null) setOf(dependencyModule) else emptySet()
|
friends
|
||||||
)
|
)
|
||||||
module.initialize(
|
module.initialize(
|
||||||
CompositePackageFragmentProvider(
|
CompositePackageFragmentProvider(
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ data class TestModule(
|
|||||||
val frontendKind: FrontendKind<*>,
|
val frontendKind: FrontendKind<*>,
|
||||||
val files: List<TestFile>,
|
val files: List<TestFile>,
|
||||||
val dependencies: List<DependencyDescription>,
|
val dependencies: List<DependencyDescription>,
|
||||||
|
val friends: List<DependencyDescription>,
|
||||||
val directives: RegisteredDirectives,
|
val directives: RegisteredDirectives,
|
||||||
val languageVersionSettings: LanguageVersionSettings
|
val languageVersionSettings: LanguageVersionSettings
|
||||||
) {
|
) {
|
||||||
|
|||||||
+18
-4
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
|||||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
|
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.native.FakeTopDownAnalyzerFacadeForNative
|
import org.jetbrains.kotlin.native.FakeTopDownAnalyzerFacadeForNative
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
@@ -81,6 +82,10 @@ class ClassicFrontendFacade(
|
|||||||
moduleDescriptorProvider.getModuleDescriptor(testModule)
|
moduleDescriptorProvider.getModuleDescriptor(testModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val friendDescriptors = module.friends.filter { it.kind == DependencyKind.Source }.map {
|
||||||
|
moduleDescriptorProvider.getModuleDescriptor(dependencyProvider.getTestModule(it.moduleName))
|
||||||
|
}
|
||||||
|
|
||||||
var hasCommonModules = false
|
var hasCommonModules = false
|
||||||
sourceDependencies.forEach {
|
sourceDependencies.forEach {
|
||||||
val dependencyModule = dependencyProvider.getTestModule(it.moduleName)
|
val dependencyModule = dependencyProvider.getTestModule(it.moduleName)
|
||||||
@@ -104,6 +109,7 @@ class ClassicFrontendFacade(
|
|||||||
packagePartProviderFactory,
|
packagePartProviderFactory,
|
||||||
ktFiles,
|
ktFiles,
|
||||||
dependentDescriptors,
|
dependentDescriptors,
|
||||||
|
friendDescriptors,
|
||||||
hasCommonModules
|
hasCommonModules
|
||||||
)
|
)
|
||||||
moduleDescriptorProvider.replaceModuleDescriptorForModule(module, analysisResult.moduleDescriptor)
|
moduleDescriptorProvider.replaceModuleDescriptorForModule(module, analysisResult.moduleDescriptor)
|
||||||
@@ -135,6 +141,7 @@ class ClassicFrontendFacade(
|
|||||||
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
|
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
dependentDescriptors: List<ModuleDescriptorImpl>,
|
dependentDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
friendsDescriptors: List<ModuleDescriptorImpl>,
|
||||||
hasCommonModules: Boolean
|
hasCommonModules: Boolean
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
val targetPlatform = module.targetPlatform
|
val targetPlatform = module.targetPlatform
|
||||||
@@ -146,6 +153,7 @@ class ClassicFrontendFacade(
|
|||||||
packagePartProviderFactory,
|
packagePartProviderFactory,
|
||||||
files,
|
files,
|
||||||
dependentDescriptors,
|
dependentDescriptors,
|
||||||
|
friendsDescriptors,
|
||||||
hasCommonModules
|
hasCommonModules
|
||||||
)
|
)
|
||||||
targetPlatform.isJs() -> performJsModuleResolve(project, configuration, files, dependentDescriptors)
|
targetPlatform.isJs() -> performJsModuleResolve(project, configuration, files, dependentDescriptors)
|
||||||
@@ -163,8 +171,12 @@ class ClassicFrontendFacade(
|
|||||||
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
|
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
|
||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
dependentDescriptors: List<ModuleDescriptorImpl>,
|
dependentDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
friendsDescriptors: List<ModuleDescriptorImpl>,
|
||||||
hasCommonModules: Boolean
|
hasCommonModules: Boolean
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
|
val moduleVisibilityManager = ModuleVisibilityManager.SERVICE.getInstance(project)
|
||||||
|
configuration.getList(JVMConfigurationKeys.FRIEND_PATHS).forEach { moduleVisibilityManager.addFriendPath(it) }
|
||||||
|
|
||||||
val moduleTrace = NoScopeRecordCliBindingTrace()
|
val moduleTrace = NoScopeRecordCliBindingTrace()
|
||||||
if (!hasCommonModules) {
|
if (!hasCommonModules) {
|
||||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||||
@@ -173,13 +185,14 @@ class ClassicFrontendFacade(
|
|||||||
moduleTrace,
|
moduleTrace,
|
||||||
configuration.copy(),
|
configuration.copy(),
|
||||||
packagePartProviderFactory,
|
packagePartProviderFactory,
|
||||||
explicitModuleDependencyList = dependentDescriptors
|
explicitModuleDependencyList = dependentDescriptors,
|
||||||
|
explicitModuleFriendsList = friendsDescriptors
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleContentScope = GlobalSearchScope.allScope(project)
|
val moduleContentScope = GlobalSearchScope.allScope(project)
|
||||||
val moduleClassResolver = SingleModuleClassResolver()
|
val moduleClassResolver = SingleModuleClassResolver()
|
||||||
val moduleContext = createModuleContext(module, project, dependentDescriptors) {
|
val moduleContext = createModuleContext(module, project, dependentDescriptors, friendsDescriptors) {
|
||||||
JvmBuiltIns(it, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
|
JvmBuiltIns(it, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
|
||||||
}
|
}
|
||||||
val moduleDescriptor = moduleContext.module as ModuleDescriptorImpl
|
val moduleDescriptor = moduleContext.module as ModuleDescriptorImpl
|
||||||
@@ -242,7 +255,7 @@ class ClassicFrontendFacade(
|
|||||||
files: List<KtFile>,
|
files: List<KtFile>,
|
||||||
): AnalysisResult {
|
): AnalysisResult {
|
||||||
val moduleTrace = NoScopeRecordCliBindingTrace()
|
val moduleTrace = NoScopeRecordCliBindingTrace()
|
||||||
val moduleContext = createModuleContext(module, project, dependentDescriptors = emptyList()) {
|
val moduleContext = createModuleContext(module, project, dependentDescriptors = emptyList(), friendsDescriptors = emptyList()) {
|
||||||
DefaultBuiltIns()
|
DefaultBuiltIns()
|
||||||
}
|
}
|
||||||
return FakeTopDownAnalyzerFacadeForNative.analyzeFilesWithGivenTrace(
|
return FakeTopDownAnalyzerFacadeForNative.analyzeFilesWithGivenTrace(
|
||||||
@@ -275,6 +288,7 @@ class ClassicFrontendFacade(
|
|||||||
module: TestModule,
|
module: TestModule,
|
||||||
project: Project,
|
project: Project,
|
||||||
dependentDescriptors: List<ModuleDescriptorImpl>,
|
dependentDescriptors: List<ModuleDescriptorImpl>,
|
||||||
|
friendsDescriptors: List<ModuleDescriptorImpl>,
|
||||||
builtInsFactory: (StorageManager) -> KotlinBuiltIns,
|
builtInsFactory: (StorageManager) -> KotlinBuiltIns,
|
||||||
): ModuleContext {
|
): ModuleContext {
|
||||||
val projectContext = ProjectContext(project, "test project context")
|
val projectContext = ProjectContext(project, "test project context")
|
||||||
@@ -287,7 +301,7 @@ class ClassicFrontendFacade(
|
|||||||
add(moduleDescriptor.builtIns.builtInsModule)
|
add(moduleDescriptor.builtIns.builtInsModule)
|
||||||
addAll(dependentDescriptors)
|
addAll(dependentDescriptors)
|
||||||
}
|
}
|
||||||
moduleDescriptor.setDependencies(dependencies)
|
moduleDescriptor.setDependencies(dependencies, friendsDescriptors.toSet())
|
||||||
|
|
||||||
return projectContext.withModule(moduleDescriptor)
|
return projectContext.withModule(moduleDescriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirective
|
|||||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||||
import org.jetbrains.kotlin.test.model.BackendKinds
|
import org.jetbrains.kotlin.test.model.DependencyDescription
|
||||||
import org.jetbrains.kotlin.test.model.DependencyKind
|
import org.jetbrains.kotlin.test.model.DependencyKind
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
|
|||||||
+27
-6
@@ -30,7 +30,12 @@ class ModuleStructureExtractorImpl(
|
|||||||
) : ModuleStructureExtractor(testServices, additionalSourceProviders) {
|
) : ModuleStructureExtractor(testServices, additionalSourceProviders) {
|
||||||
companion object {
|
companion object {
|
||||||
private val allowedExtensionsForFiles = listOf(".kt", ".kts", ".java")
|
private val allowedExtensionsForFiles = listOf(".kt", ".kts", ".java")
|
||||||
private val moduleDirectiveRegex = """([\w-]+)(\((.*)\))?""".toRegex()
|
/*
|
||||||
|
* ([\w-]+) module name
|
||||||
|
* \((.*?)\) module dependencies
|
||||||
|
* (\((.*?)\))? module friends
|
||||||
|
*/
|
||||||
|
private val moduleDirectiveRegex = """([\w-]+)(\((.*?)\)(\((.*?)\))?)?""".toRegex()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun splitTestDataByModules(
|
override fun splitTestDataByModules(
|
||||||
@@ -66,6 +71,7 @@ class ModuleStructureExtractorImpl(
|
|||||||
private var currentModuleTargetBackend: TargetBackend? = null
|
private var currentModuleTargetBackend: TargetBackend? = null
|
||||||
private var currentModuleLanguageVersionSettingsBuilder: LanguageVersionSettingsBuilder = initLanguageSettingsBuilder()
|
private var currentModuleLanguageVersionSettingsBuilder: LanguageVersionSettingsBuilder = initLanguageSettingsBuilder()
|
||||||
private var dependenciesOfCurrentModule = mutableListOf<DependencyDescription>()
|
private var dependenciesOfCurrentModule = mutableListOf<DependencyDescription>()
|
||||||
|
private var friendsOfCurrentModule = mutableListOf<DependencyDescription>()
|
||||||
private var filesOfCurrentModule = mutableListOf<TestFile>()
|
private var filesOfCurrentModule = mutableListOf<TestFile>()
|
||||||
|
|
||||||
private var currentFileName: String? = null
|
private var currentFileName: String? = null
|
||||||
@@ -146,12 +152,16 @@ class ModuleStructureExtractorImpl(
|
|||||||
} else {
|
} else {
|
||||||
finishGlobalDirectives()
|
finishGlobalDirectives()
|
||||||
}
|
}
|
||||||
val (moduleName, dependencies) = splitRawModuleStringToNameAndDependencies(values.joinToString(separator = " "))
|
val (moduleName, dependencies, friends) = splitRawModuleStringToNameAndDependencies(values.joinToString(separator = " "))
|
||||||
currentModuleName = moduleName
|
currentModuleName = moduleName
|
||||||
dependencies.mapTo(dependenciesOfCurrentModule) { name ->
|
dependencies.mapTo(dependenciesOfCurrentModule) { name ->
|
||||||
val kind = defaultsProvider.defaultDependencyKind
|
val kind = defaultsProvider.defaultDependencyKind
|
||||||
DependencyDescription(name, kind, DependencyRelation.Dependency)
|
DependencyDescription(name, kind, DependencyRelation.Dependency)
|
||||||
}
|
}
|
||||||
|
friends.mapTo(friendsOfCurrentModule) { name ->
|
||||||
|
val kind = defaultsProvider.defaultDependencyKind
|
||||||
|
DependencyDescription(name, kind, DependencyRelation.Dependency)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ModuleStructureDirectives.DEPENDENCY,
|
ModuleStructureDirectives.DEPENDENCY,
|
||||||
ModuleStructureDirectives.DEPENDS_ON -> {
|
ModuleStructureDirectives.DEPENDS_ON -> {
|
||||||
@@ -190,12 +200,15 @@ class ModuleStructureExtractorImpl(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun splitRawModuleStringToNameAndDependencies(moduleDirectiveString: String): Pair<String, List<String>> {
|
private fun splitRawModuleStringToNameAndDependencies(moduleDirectiveString: String): ModuleNameAndDependeciens {
|
||||||
val matchResult = moduleDirectiveRegex.matchEntire(moduleDirectiveString)
|
val matchResult = moduleDirectiveRegex.matchEntire(moduleDirectiveString)
|
||||||
?: error("\"$moduleDirectiveString\" doesn't matches with pattern \"moduleName(dep1, dep2)\"")
|
?: error("\"$moduleDirectiveString\" doesn't matches with pattern \"moduleName(dep1, dep2)\"")
|
||||||
val (name, _, dependencies) = matchResult.destructured
|
val (name, _, dependencies, _, friends) = matchResult.destructured
|
||||||
if (dependencies.isBlank()) return name to emptyList()
|
return ModuleNameAndDependeciens(
|
||||||
return name to dependencies.split(" ")
|
name,
|
||||||
|
dependencies.takeIf { it.isNotBlank() }?.split(" ") ?: emptyList(),
|
||||||
|
friends.takeIf { it.isNotBlank() }?.split(" ") ?: emptyList(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun finishGlobalDirectives() {
|
private fun finishGlobalDirectives() {
|
||||||
@@ -216,6 +229,7 @@ class ModuleStructureExtractorImpl(
|
|||||||
frontendKind = currentModuleFrontendKind ?: defaultsProvider.defaultFrontend,
|
frontendKind = currentModuleFrontendKind ?: defaultsProvider.defaultFrontend,
|
||||||
files = filesOfCurrentModule,
|
files = filesOfCurrentModule,
|
||||||
dependencies = dependenciesOfCurrentModule,
|
dependencies = dependenciesOfCurrentModule,
|
||||||
|
friends = friendsOfCurrentModule,
|
||||||
directives = moduleDirectives,
|
directives = moduleDirectives,
|
||||||
languageVersionSettings = currentModuleLanguageVersionSettingsBuilder.build()
|
languageVersionSettings = currentModuleLanguageVersionSettingsBuilder.build()
|
||||||
)
|
)
|
||||||
@@ -273,6 +287,7 @@ class ModuleStructureExtractorImpl(
|
|||||||
currentModuleLanguageVersionSettingsBuilder = initLanguageSettingsBuilder()
|
currentModuleLanguageVersionSettingsBuilder = initLanguageSettingsBuilder()
|
||||||
filesOfCurrentModule = mutableListOf()
|
filesOfCurrentModule = mutableListOf()
|
||||||
dependenciesOfCurrentModule = mutableListOf()
|
dependenciesOfCurrentModule = mutableListOf()
|
||||||
|
friendsOfCurrentModule = mutableListOf()
|
||||||
directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions)
|
directivesBuilder = RegisteredDirectivesParser(directivesContainer, assertions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +317,12 @@ class ModuleStructureExtractorImpl(
|
|||||||
return defaultsProvider.newLanguageSettingsBuilder()
|
return defaultsProvider.newLanguageSettingsBuilder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class ModuleNameAndDependeciens(
|
||||||
|
val name: String,
|
||||||
|
val dependencies: List<String>,
|
||||||
|
val friends: List<String>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private operator fun RegisteredDirectives.plus(other: RegisteredDirectives?): RegisteredDirectives {
|
private operator fun RegisteredDirectives.plus(other: RegisteredDirectives?): RegisteredDirectives {
|
||||||
|
|||||||
Reference in New Issue
Block a user