[FIR] extract exception handing into a service to have additional implementation for the ide

This commit is contained in:
Ilya Kirillov
2022-12-28 14:44:43 +01:00
committed by Space Team
parent 90436abb23
commit 79fe4100aa
5 changed files with 62 additions and 33 deletions
@@ -14,11 +14,13 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirIdePredica
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirIdeRegisteredPluginAnnotations import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirIdeRegisteredPluginAnnotations
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSourcesSession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirExceptionHandler
import org.jetbrains.kotlin.analysis.project.structure.KtCompilerPluginsProvider import org.jetbrains.kotlin.analysis.project.structure.KtCompilerPluginsProvider
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.moduleScopeProvider import org.jetbrains.kotlin.analysis.project.structure.moduleScopeProvider
import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
import org.jetbrains.kotlin.fir.FirExceptionHandler
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.SessionConfiguration import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.caches.FirCachesFactory import org.jetbrains.kotlin.fir.caches.FirCachesFactory
@@ -39,6 +41,8 @@ internal fun LLFirSession.registerIdeComponents(project: Project) {
register(IdeSessionComponents::class, IdeSessionComponents.create(this)) register(IdeSessionComponents::class, IdeSessionComponents.create(this))
register(FirCachesFactory::class, FirThreadSafeCachesFactory) register(FirCachesFactory::class, FirThreadSafeCachesFactory)
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider()) register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
register(FirExceptionHandler::class, LLFirExceptionHandler)
} }
internal inline fun createCompositeSymbolProvider( internal inline fun createCompositeSymbolProvider(
@@ -0,0 +1,20 @@
/*
* 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.low.level.api.fir.util
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirExceptionHandler
import org.jetbrains.kotlin.fir.declarations.FirFile
internal object LLFirExceptionHandler : FirExceptionHandler() {
override fun handleExceptionOnElementAnalysis(element: FirElement, throwable: Throwable): Nothing {
throw throwable
}
override fun handleExceptionOnFileAnalysis(file: FirFile, throwable: Throwable): Nothing {
throw throwable
}
}
@@ -77,6 +77,7 @@ fun FirSession.registerCliCompilerOnlyComponents() {
register(FirCachesFactory::class, FirThreadUnsafeCachesFactory) register(FirCachesFactory::class, FirThreadUnsafeCachesFactory)
register(SealedClassInheritorsProvider::class, SealedClassInheritorsProviderImpl) register(SealedClassInheritorsProvider::class, SealedClassInheritorsProviderImpl)
register(FirLazyDeclarationResolver::class, FirDummyCompilerLazyDeclarationResolver) register(FirLazyDeclarationResolver::class, FirDummyCompilerLazyDeclarationResolver)
register(FirExceptionHandler::class, FirCliExceptionHandler)
register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotationsImpl(this)) register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotationsImpl(this))
register(FirPredicateBasedProvider::class, FirPredicateBasedProviderImpl(this)) register(FirPredicateBasedProvider::class, FirPredicateBasedProviderImpl(this))
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.fir.types.builder.*
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.wrapIntoFileAnalysisExceptionIfNeeded
import org.jetbrains.kotlin.util.wrapIntoSourceCodeAnalysisExceptionIfNeeded
// TODO: rewrite // TODO: rewrite
fun FirBlock.returnExpressions(): List<FirExpression> = listOfNotNull(statements.lastOrNull() as? FirExpression) fun FirBlock.returnExpressions(): List<FirExpression> = listOfNotNull(statements.lastOrNull() as? FirExpression)
@@ -137,16 +139,40 @@ fun FirDeclarationStatus.copy(
} }
} }
inline fun <R> whileAnalysing(@Suppress("UNUSED_PARAMETER") session: FirSession, element: FirElement, block: () -> R) = inline fun <R> whileAnalysing(session: FirSession, element: FirElement, block: () -> R): R {
org.jetbrains.kotlin.util.whileAnalysing(element.source, block) return try {
block()
} catch (throwable: Throwable) {
session.exceptionHandler.handleExceptionOnElementAnalysis(element, throwable)
}
}
inline fun <R> withFileAnalysisExceptionWrapping(file: FirFile, block: () -> R): R { inline fun <R> withFileAnalysisExceptionWrapping(file: FirFile, block: () -> R): R {
return org.jetbrains.kotlin.util.withFileAnalysisExceptionWrapping( return try {
file.sourceFile?.path, block()
file.source, } catch (throwable: Throwable) {
{ file.sourceFileLinesMapping?.getLineAndColumnByOffset(it) }, file.moduleData.session.exceptionHandler.handleExceptionOnFileAnalysis(file, throwable)
block, }
) }
abstract class FirExceptionHandler : FirSessionComponent {
abstract fun handleExceptionOnElementAnalysis(element: FirElement, throwable: Throwable): Nothing
abstract fun handleExceptionOnFileAnalysis(file: FirFile, throwable: Throwable): Nothing
}
val FirSession.exceptionHandler: FirExceptionHandler by FirSession.sessionComponentAccessor()
object FirCliExceptionHandler : FirExceptionHandler() {
override fun handleExceptionOnElementAnalysis(element: FirElement, throwable: Throwable): Nothing {
throw throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element.source)
}
override fun handleExceptionOnFileAnalysis(file: FirFile, throwable: Throwable): Nothing {
throw throwable.wrapIntoFileAnalysisExceptionIfNeeded(
file.sourceFile?.path,
file.source
) { file.sourceFileLinesMapping?.getLineAndColumnByOffset(it) }
}
} }
@JvmInline @JvmInline
@@ -17,16 +17,8 @@ class SourceCodeAnalysisException(val source: KtSourceElement, override val caus
override val message get() = cause.classNameAndMessage override val message get() = cause.classNameAndMessage
} }
inline fun <R> whileAnalysing(element: KtSourceElement?, block: () -> R): R {
return try {
block()
} catch (throwable: Throwable) {
throw throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element)
}
}
@PublishedApi fun Throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element: KtSourceElement?) = when (this) {
internal fun Throwable.wrapIntoSourceCodeAnalysisExceptionIfNeeded(element: KtSourceElement?) = when (this) {
is SourceCodeAnalysisException -> this is SourceCodeAnalysisException -> this
is IndexNotReadyException -> this is IndexNotReadyException -> this
is ControlFlowException -> this is ControlFlowException -> this
@@ -49,21 +41,7 @@ class FileAnalysisException(
} }
} }
inline fun <R> withFileAnalysisExceptionWrapping( fun Throwable.wrapIntoFileAnalysisExceptionIfNeeded(
filePath: String?,
fileSource: AbstractKtSourceElement?,
crossinline linesMapping: (Int) -> Pair<Int, Int>?,
block: () -> R,
): R {
return try {
block()
} catch (throwable: Throwable) {
throw throwable.wrapIntoFileAnalysisExceptionIfNeeded(filePath, fileSource) { linesMapping(it) }
}
}
@PublishedApi
internal fun Throwable.wrapIntoFileAnalysisExceptionIfNeeded(
filePath: String?, filePath: String?,
fileSource: AbstractKtSourceElement?, fileSource: AbstractKtSourceElement?,
linesMapping: (Int) -> Pair<Int, Int>?, linesMapping: (Int) -> Pair<Int, Int>?,