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 com.intellij.mock.MockProject;
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService;
|
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.LLFirLibrarySessionFactory;
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirNonUnderContentRootSessionFactory;
|
||||||
|
|
||||||
class RegisterComponentService {
|
class RegisterComponentService {
|
||||||
static void registerLLFirLibrarySessionFactory(MockProject project) {
|
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) {
|
static void registerLLFirResolveSessionService(MockProject project) {
|
||||||
project.registerService(
|
project.registerService(
|
||||||
LLFirResolveSessionService.class,
|
LLFirResolveSessionService.class,
|
||||||
|
|||||||
+1
@@ -144,6 +144,7 @@ public class StandaloneAnalysisAPISessionBuilder(
|
|||||||
)
|
)
|
||||||
registerService(LLFirBuiltinsSessionFactory::class.java, LLFirBuiltinsSessionFactory(this))
|
registerService(LLFirBuiltinsSessionFactory::class.java, LLFirBuiltinsSessionFactory(this))
|
||||||
RegisterComponentService.registerLLFirLibrarySessionFactory(this)
|
RegisterComponentService.registerLLFirLibrarySessionFactory(this)
|
||||||
|
RegisterComponentService.registerLLFirNonUnderContentRootSessionFactory(this)
|
||||||
RegisterComponentService.registerLLFirResolveSessionService(this)
|
RegisterComponentService.registerLLFirResolveSessionService(this)
|
||||||
registerService(
|
registerService(
|
||||||
PackagePartProviderFactory::class.java,
|
PackagePartProviderFactory::class.java,
|
||||||
|
|||||||
+18
-3
@@ -6,23 +6,38 @@
|
|||||||
package org.jetbrains.kotlin.analysis.project.structure.impl
|
package org.jetbrains.kotlin.analysis.project.structure.impl
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.PsiFileSystemItem
|
import com.intellij.psi.PsiFileSystemItem
|
||||||
import com.intellij.psi.PsiJavaFile
|
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.api.standalone.base.project.structure.StandaloneProjectFactory.findJvmRootsForJavaFiles
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
|
|
||||||
internal class KtModuleProviderImpl(
|
internal class KtModuleProviderImpl(
|
||||||
internal val mainModules: List<KtModule>,
|
internal val mainModules: List<KtModule>,
|
||||||
) : ProjectStructureProvider() {
|
) : 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 {
|
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||||
val containingFileAsPsiFile = element.containingFile
|
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],
|
// If an [element] is created on the fly, e.g., via [KtPsiFactory],
|
||||||
// its containing [PsiFile] may not have [VirtualFile].
|
// its containing [PsiFile] may not have [VirtualFile].
|
||||||
// That also means the [element] is not bound to any [KtModule] either.
|
// That also means the [element] is not bound to any [KtModule] either.
|
||||||
val containingFileAsVirtualFile = containingFileAsPsiFile.virtualFile
|
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 ->
|
return mainModules.first { module ->
|
||||||
containingFileAsVirtualFile in module.contentScope
|
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.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
|
||||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
import org.jetbrains.kotlin.platform.js.isJs
|
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.jvm.isJvm
|
||||||
import org.jetbrains.kotlin.platform.konan.isNative
|
import org.jetbrains.kotlin.platform.konan.isNative
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -102,7 +101,7 @@ internal fun buildKtModuleProviderByCompilerConfiguration(
|
|||||||
): ProjectStructureProvider = buildProjectStructureProvider {
|
): ProjectStructureProvider = buildProjectStructureProvider {
|
||||||
addModule(
|
addModule(
|
||||||
buildKtSourceModule {
|
buildKtSourceModule {
|
||||||
val platform = TargetPlatform(setOf(JdkPlatform(JvmTarget.DEFAULT)))
|
val platform = JvmPlatforms.defaultJvmPlatform
|
||||||
val moduleName = compilerConfig.get(CommonConfigurationKeys.MODULE_NAME) ?: "<no module name provided>"
|
val moduleName = compilerConfig.get(CommonConfigurationKeys.MODULE_NAME) ?: "<no module name provided>"
|
||||||
|
|
||||||
val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
|
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