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