diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt index 0c3ef73a0cf..7ba844c1982 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt @@ -9,6 +9,7 @@ import com.intellij.codeInsight.completion.* import com.intellij.patterns.PlatformPatterns import com.intellij.patterns.PsiJavaPatterns import com.intellij.util.ProcessingContext +import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol @@ -62,6 +63,7 @@ private object KotlinHighLevelApiContributor : CompletionProvider().getAnalysisSessionFor(contextElement) -@Suppress("DEPRECATION") +/** + * Execute given [action] in [KtAnalysisSession] context + * Uses [contextElement] to get a module from which you would like to see the other modules + * Usually [contextElement] is some element form the module you currently analysing now + * + * Should not be called from EDT thread + * Should be called from read action + * To analyse something from EDT thread, consider using [analyseInModalWindow] + * + * @see KtAnalysisSession + * @see analyzeWithReadAction + */ +@OptIn(InvalidWayOfUsingAnalysisSession::class) inline fun analyze(contextElement: KtElement, action: KtAnalysisSession.() -> R): R = getAnalysisSessionFor(contextElement).action() + +/** + * Execute given [action] in [KtAnalysisSession] context like [analyze] does but execute it in read action + * Uses [contextElement] to get a module from which you would like to see the other modules + * Usually [contextElement] is some element form the module you currently analysing now + * + * Should be called from read action + * To analyse something from EDT thread, consider using [analyseInModalWindow] + * If you are already in read action, consider using [analyze] + * + * @see KtAnalysisSession + * @see analyze + */ inline fun analyzeWithReadAction( contextElement: KtElement, crossinline action: KtAnalysisSession.() -> R ): R = runReadAction { analyze(contextElement, action) +} + +/** + * Show a modal window with a progress bar and specified [windowTitle] + * and execute given [action] task with [KtAnalysisSession] context + * If [action] throws some exception, then [analyseInModalWindow] will rethrow it + * Should be executed from EDT only + * If you want to analyse something from non-EDT thread, consider using [analyze]/[analyzeWithReadAction] + */ +inline fun analyseInModalWindow( + contextElement: KtElement, + windowTitle: String, + crossinline action: KtAnalysisSession.() -> R +): R { + ApplicationManager.getApplication().assertIsDispatchThread() + val task = object : Task.WithResult(contextElement.project, windowTitle, /*canBeCancelled*/ true) { + override fun compute(indicator: ProgressIndicator): R = analyzeWithReadAction(contextElement) { action() } + } + task.queue() + return task.result } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt index b07b5e826b1..5df3d1ae7d9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt @@ -11,12 +11,14 @@ import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.idea.caches.project.getModuleInfo +import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProvider import org.jetbrains.kotlin.idea.frontend.api.assertIsValid import org.jetbrains.kotlin.psi.KtElement import java.util.concurrent.ConcurrentHashMap +@OptIn(InvalidWayOfUsingAnalysisSession::class) class KtFirAnalysisSessionProvider(project: Project) : KtAnalysisSessionProvider() { private val analysisSessionByModuleInfoCache = CachedValuesManager.getManager(project).createCachedValue {