From 4e127011453824115393fe79072a023569a990ee Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Fri, 12 Apr 2019 13:03:05 +0300 Subject: [PATCH] [Expect/Actual] Introduce ModuleStructureOracle --- .../jetbrains/kotlin/frontend/di/injection.kt | 8 ++- .../kotlin/resolve/CompilerEnvironment.kt | 1 + .../kotlin/resolve/ModuleStructureOracle.kt | 34 ++++++++++++ .../jetbrains/kotlin/tests/di/injection.kt | 2 + .../caches/resolve/PerFileAnalysisCache.kt | 4 +- .../kotlin/idea/project/IdeaEnvironment.kt | 1 + .../idea/project/IdeaModuleStructureOracle.kt | 53 +++++++++++++++++++ .../idea/project/ResolveElementCache.kt | 3 +- 8 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/ModuleStructureOracle.kt create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaModuleStructureOracle.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index 016acb338b2..39e371332fe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -107,7 +107,8 @@ fun createContainerForBodyResolve( platform: TargetPlatform, statementFilter: StatementFilter, analyzerServices: PlatformDependentAnalyzerServices, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + moduleStructureOracle: ModuleStructureOracle ): StorageComponentContainer = createContainer("BodyResolve", analyzerServices) { configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings) @@ -117,6 +118,7 @@ fun createContainerForBodyResolve( useImpl() useImpl() + useInstance(moduleStructureOracle) } fun createContainerForLazyBodyResolve( @@ -126,7 +128,8 @@ fun createContainerForLazyBodyResolve( platform: TargetPlatform, bodyResolveCache: BodyResolveCache, analyzerServices: PlatformDependentAnalyzerServices, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + moduleStructureOracle: ModuleStructureOracle ): StorageComponentContainer = createContainer("LazyBodyResolve", analyzerServices) { configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings) @@ -136,6 +139,7 @@ fun createContainerForLazyBodyResolve( useImpl() useImpl() useImpl() + useInstance(moduleStructureOracle) } fun createContainerForLazyLocalClassifierAnalyzer( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt index 7e7d4ddf0fa..6806294da0c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt @@ -27,5 +27,6 @@ object CompilerEnvironment : TargetEnvironment("Compiler") { container.useInstance(BodyResolveCache.ThrowException) container.useImpl() container.useImpl() + container.useInstance(ModuleStructureOracle.SingleModule) } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModuleStructureOracle.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModuleStructureOracle.kt new file mode 100644 index 00000000000..fe914a7272b --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModuleStructureOracle.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.resolve + +import org.jetbrains.kotlin.descriptors.ModuleDescriptor + +interface ModuleStructureOracle { + // May be faster than `findAllImplementingModules(module).isNotEmpty()` + fun hasImplementingModules(module: ModuleDescriptor): Boolean + + fun findAllReversedDependsOnPaths(module: ModuleDescriptor): List + + fun findAllDependsOnPaths(module: ModuleDescriptor): List + + /** + * Works like all sources are effectively in one module. + * + * This is the mode CLI currently operates in. + */ + object SingleModule : ModuleStructureOracle { + override fun hasImplementingModules(module: ModuleDescriptor): Boolean = false + + override fun findAllReversedDependsOnPaths(module: ModuleDescriptor): List = listOf(ModulePath(module)) + + override fun findAllDependsOnPaths(module: ModuleDescriptor): List = listOf(ModulePath(module)) + } +} + +class ModulePath(val nodes: List) { + constructor(vararg nodes: ModuleDescriptor) : this(nodes.toList()) +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt index b85812faf8b..fe5e700ebe9 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/tests/di/injection.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.getValue import org.jetbrains.kotlin.container.useImpl +import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.frontend.di.configureModule @@ -41,6 +42,7 @@ fun createContainerForTests(project: Project, module: ModuleDescriptor): Contain LanguageVersionSettingsImpl.DEFAULT ) useImpl() + useInstance(ModuleStructureOracle.SingleModule) }) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/PerFileAnalysisCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/PerFileAnalysisCache.kt index a12e2af54d0..ab9ed91e05b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/PerFileAnalysisCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/PerFileAnalysisCache.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.frontend.di.createContainerForLazyBodyResolve import org.jetbrains.kotlin.idea.caches.project.getModuleInfo +import org.jetbrains.kotlin.idea.project.IdeaModuleStructureOracle import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.project.findAnalyzerServices import org.jetbrains.kotlin.idea.project.languageVersionSettings @@ -198,7 +199,8 @@ private object KotlinResolveDataProvider { targetPlatform, bodyResolveCache, targetPlatform.findAnalyzerServices, - analyzableElement.languageVersionSettings + analyzableElement.languageVersionSettings, + IdeaModuleStructureOracle() ).get() lazyTopDownAnalyzer.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, listOf(analyzableElement)) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt index bcd0d42360d..63d4d3f8fa8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt @@ -27,5 +27,6 @@ object IdeaEnvironment : TargetEnvironment("Idea") { container.useImpl() container.useImpl() container.useImpl() + container.useImpl() } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaModuleStructureOracle.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaModuleStructureOracle.kt new file mode 100644 index 00000000000..0f514524ec3 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaModuleStructureOracle.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.idea.project + +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors +import org.jetbrains.kotlin.resolve.ModulePath +import org.jetbrains.kotlin.resolve.ModuleStructureOracle +import java.util.* + +class IdeaModuleStructureOracle : ModuleStructureOracle { + override fun hasImplementingModules(module: ModuleDescriptor): Boolean { + return module.implementingDescriptors.isNotEmpty() + } + + override fun findAllReversedDependsOnPaths(module: ModuleDescriptor): List { + val currentPath: Stack = Stack() + + return sequence { + yieldPathsFromSubgraph(module, currentPath, getChilds = { it.implementingDescriptors }) + }.toList() + } + + override fun findAllDependsOnPaths(module: ModuleDescriptor): List { + val currentPath: Stack = Stack() + + return sequence { + yieldPathsFromSubgraph(module, currentPath, getChilds = { it.expectedByModules }) + }.toList() + } + + private suspend fun SequenceScope.yieldPathsFromSubgraph( + root: ModuleDescriptor, + currentPath: Stack, + getChilds: (ModuleDescriptor) -> List + ) { + currentPath.push(root) + + val childs = getChilds(root) + if (childs.isEmpty()) { + yield(ModulePath(currentPath.toList())) + } else { + childs.forEach { + yieldPathsFromSubgraph(it, currentPath, getChilds) + } + } + + currentPath.pop() + } +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt index 5b8467abf99..fa37f73e404 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt @@ -714,7 +714,8 @@ class ResolveElementCache( targetPlatform, statementFilter, targetPlatform.findAnalyzerServices, - file.languageVersionSettings + file.languageVersionSettings, + IdeaModuleStructureOracle() ).get() }