[LL API] Analyze code fragment in a separate 'FirSession'

Before, `KtCodeFragment`/`FirCodeFragment` was analyzed as a part of
its context `KtModule`. This has the following complications:

- In non-source sessions, diagnostic reporting is globally disabled.
  For code fragments, however, checking the code before passing it to
  the backend is essential.

- Special treatment for call ambiguities in libraries
  (`LLLibraryScopeAwareCallConflictResolverFactory`) becomes complicated
  as the conflict resolver has to be applied to a library module.

- `KtCodeFragment`s usually have a shorter lifetime than their own
  context. Caching may potentially be implemented differently for them.

^KT-61783 Fixed
This commit is contained in:
Yan Zhulanow
2023-09-04 22:16:33 +09:00
committed by Space Team
parent b32c083346
commit 715f7d1a35
10 changed files with 250 additions and 26 deletions
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileSystemItem
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.project.structure.impl.KtCodeFragmentModuleImpl
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.psiUtil.contains
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
@@ -23,6 +25,15 @@ class KtStaticModuleProvider(
// Unwrap context-dependent file copies coming from dependent sessions
val containingPsiFile = element.containingFile.originalFile
if (containingPsiFile is KtCodeFragment) {
val contextElement = containingPsiFile.context
?: throw KotlinExceptionWithAttachments("Context not found for a code fragment")
.withAttachment("codeFragment.kt", containingPsiFile.text)
val contextModule = getModule(contextElement, contextualModule)
return KtCodeFragmentModuleImpl(containingPsiFile, contextModule)
}
val containingVirtualFile = containingPsiFile.virtualFile
if (containingVirtualFile.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) {
return builtinsModule