AA: introduce KtNotUnderContentRootModule impl to standalone mode
to gracefully handle element/file/etc without a binding module. This could happen, e.g., 1) source PSI created from KtPsiFactory, which uses literally dummy.kt 2) debugger that creates a code fragment on-the-fly 3) on-air analysis of non-physical files
This commit is contained in:
committed by
Ilya Kirillov
parent
e8e88b4eb2
commit
4531080858
+8
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.api.standalone;
|
||||
import com.intellij.mock.MockProject;
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService;
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySessionFactory;
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirNonUnderContentRootSessionFactory;
|
||||
|
||||
class RegisterComponentService {
|
||||
static void registerLLFirLibrarySessionFactory(MockProject project) {
|
||||
@@ -17,6 +18,13 @@ class RegisterComponentService {
|
||||
);
|
||||
}
|
||||
|
||||
static void registerLLFirNonUnderContentRootSessionFactory(MockProject project) {
|
||||
project.registerService(
|
||||
LLFirNonUnderContentRootSessionFactory.class,
|
||||
new LLFirNonUnderContentRootSessionFactory(project)
|
||||
);
|
||||
}
|
||||
|
||||
static void registerLLFirResolveSessionService(MockProject project) {
|
||||
project.registerService(
|
||||
LLFirResolveSessionService.class,
|
||||
|
||||
+1
@@ -144,6 +144,7 @@ public class StandaloneAnalysisAPISessionBuilder(
|
||||
)
|
||||
registerService(LLFirBuiltinsSessionFactory::class.java, LLFirBuiltinsSessionFactory(this))
|
||||
RegisterComponentService.registerLLFirLibrarySessionFactory(this)
|
||||
RegisterComponentService.registerLLFirNonUnderContentRootSessionFactory(this)
|
||||
RegisterComponentService.registerLLFirResolveSessionService(this)
|
||||
registerService(
|
||||
PackagePartProviderFactory::class.java,
|
||||
|
||||
+18
-3
@@ -6,23 +6,38 @@
|
||||
package org.jetbrains.kotlin.analysis.project.structure.impl
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiFileSystemItem
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory.findJvmRootsForJavaFiles
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
|
||||
internal class KtModuleProviderImpl(
|
||||
internal val mainModules: List<KtModule>,
|
||||
) : ProjectStructureProvider() {
|
||||
private val ktNotUnderContentRootModuleWithoutPsiFile by lazy {
|
||||
KtNotUnderContentRootModuleImpl(
|
||||
moduleDescription = "Standalone-not-under-content-root-module-without-psi-file"
|
||||
)
|
||||
}
|
||||
|
||||
private val notUnderContentRootModuleCache = ContainerUtil.createConcurrentWeakMap<PsiFile, KtNotUnderContentRootModule>()
|
||||
|
||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||
val containingFileAsPsiFile = element.containingFile
|
||||
?: error("Can't get containing PsiFile for ${element.text}")
|
||||
?: return ktNotUnderContentRootModuleWithoutPsiFile
|
||||
// If an [element] is created on the fly, e.g., via [KtPsiFactory],
|
||||
// its containing [PsiFile] may not have [VirtualFile].
|
||||
// That also means the [element] is not bound to any [KtModule] either.
|
||||
val containingFileAsVirtualFile = containingFileAsPsiFile.virtualFile
|
||||
?: error("Can't get containing VirtualFile for ${element.text} in $containingFileAsPsiFile")
|
||||
?: return notUnderContentRootModuleCache.getOrPut(containingFileAsPsiFile) {
|
||||
KtNotUnderContentRootModuleImpl(
|
||||
moduleDescription = "Standalone-not-under-content-root-module-for-$containingFileAsPsiFile",
|
||||
psiFile = containingFileAsPsiFile
|
||||
)
|
||||
}
|
||||
|
||||
return mainModules.first { module ->
|
||||
containingFileAsVirtualFile in module.contentScope
|
||||
}
|
||||
|
||||
+2
-3
@@ -28,12 +28,11 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.JdkPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.platform.konan.isNative
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -102,7 +101,7 @@ internal fun buildKtModuleProviderByCompilerConfiguration(
|
||||
): ProjectStructureProvider = buildProjectStructureProvider {
|
||||
addModule(
|
||||
buildKtSourceModule {
|
||||
val platform = TargetPlatform(setOf(JdkPlatform(JvmTarget.DEFAULT)))
|
||||
val platform = JvmPlatforms.defaultJvmPlatform
|
||||
val moduleName = compilerConfig.get(CommonConfigurationKeys.MODULE_NAME) ?: "<no module name provided>"
|
||||
|
||||
val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.analysis.project.structure.impl
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
|
||||
internal class KtNotUnderContentRootModuleImpl(
|
||||
override val directRegularDependencies: List<KtModule> = emptyList(),
|
||||
override val directRefinementDependencies: List<KtModule> = emptyList(),
|
||||
override val directFriendDependencies: List<KtModule> = emptyList(),
|
||||
override val platform: TargetPlatform = JvmPlatforms.defaultJvmPlatform,
|
||||
psiFile: PsiFile? = null,
|
||||
override val moduleDescription: String,
|
||||
) : KtNotUnderContentRootModule, KtModuleWithPlatform {
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices = super.analyzerServices
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
if (psiFile != null) GlobalSearchScope.fileScope(psiFile) else GlobalSearchScope.EMPTY_SCOPE
|
||||
}
|
||||
Reference in New Issue
Block a user