FIR IDE: add docs for LowLevelFirApiFacade functions
This commit is contained in:
+64
-14
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.api
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||||
@@ -19,23 +20,25 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns [FirModuleResolveState] which corresponds to containing module
|
||||||
|
*/
|
||||||
fun KtElement.getResolveState(): FirModuleResolveState =
|
fun KtElement.getResolveState(): FirModuleResolveState =
|
||||||
getModuleInfo().getResolveState()
|
getModuleInfo().getResolveState()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns [FirModuleResolveState] which corresponds to containing module
|
||||||
|
*/
|
||||||
fun IdeaModuleInfo.getResolveState(): FirModuleResolveState =
|
fun IdeaModuleInfo.getResolveState(): FirModuleResolveState =
|
||||||
FirIdeResolveStateService.getInstance(project!!).getResolveState(this)
|
FirIdeResolveStateService.getInstance(project!!).getResolveState(this)
|
||||||
|
|
||||||
fun KtFile.getFirFile(resolveState: FirModuleResolveState) =
|
|
||||||
resolveState.getFirFile(this)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates [FirDeclaration] by [KtDeclaration] and runs an [action] with it
|
* Creates [FirDeclaration] by [KtDeclaration] and executes an [action] on it
|
||||||
* [this@withFirDeclaration]
|
* [FirDeclaration] passed to [action] will be resolved at least to [phase] when executing [action] on it
|
||||||
* [FirDeclaration] passed to [action] should not be leaked outside [action] lambda
|
|
||||||
* [FirDeclaration] passed to [action] will be resolved at least to [phase]
|
|
||||||
* Otherwise, some threading problems may arise,
|
|
||||||
*
|
*
|
||||||
* [this@withFirDeclaration] should be non-local declaration (should have fully qualified name)
|
* [FirDeclaration] passed to [action] should not be leaked outside [action] lambda
|
||||||
|
* Otherwise, some threading problems may arise,
|
||||||
*/
|
*/
|
||||||
@OptIn(InternalForInline::class)
|
@OptIn(InternalForInline::class)
|
||||||
inline fun <R> KtDeclaration.withFirDeclaration(
|
inline fun <R> KtDeclaration.withFirDeclaration(
|
||||||
@@ -48,16 +51,33 @@ inline fun <R> KtDeclaration.withFirDeclaration(
|
|||||||
return action(firDeclaration)
|
return action(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [FirDeclaration] by [KtDeclaration] and executes an [action] on it
|
||||||
|
* [FirDeclaration] passed to [action] will be resolved at least to [phase] when executing [action] on it
|
||||||
|
*
|
||||||
|
* If resulted [FirDeclaration] is not [F] throws [InvalidFirElementTypeException]
|
||||||
|
*
|
||||||
|
* [FirDeclaration] passed to [action] should not be leaked outside [action] lambda
|
||||||
|
* Otherwise, some threading problems may arise,
|
||||||
|
*/
|
||||||
@OptIn(InternalForInline::class)
|
@OptIn(InternalForInline::class)
|
||||||
inline fun <reified F : FirDeclaration, R> KtDeclaration.withFirDeclarationOfType(
|
inline fun <reified F : FirDeclaration, R> KtDeclaration.withFirDeclarationOfType(
|
||||||
resolveState: FirModuleResolveState,
|
resolveState: FirModuleResolveState,
|
||||||
|
phase: FirResolvePhase = FirResolvePhase.RAW_FIR,
|
||||||
action: (F) -> R
|
action: (F) -> R
|
||||||
): R {
|
): R = withFirDeclaration(resolveState, phase) { firDeclaration ->
|
||||||
val firDeclaration = resolveState.findSourceFirDeclaration(this)
|
|
||||||
if (firDeclaration !is F) throw InvalidFirElementTypeException(this, F::class, firDeclaration::class)
|
if (firDeclaration !is F) throw InvalidFirElementTypeException(this, F::class, firDeclaration::class)
|
||||||
return action(firDeclaration)
|
action(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates [FirDeclaration] by [KtLambdaExpression] and executes an [action] on it
|
||||||
|
*
|
||||||
|
* If resulted [FirDeclaration] is not [F] throws [InvalidFirElementTypeException]
|
||||||
|
*
|
||||||
|
* [FirDeclaration] passed to [action] should not be leaked outside [action] lambda
|
||||||
|
* Otherwise, some threading problems may arise,
|
||||||
|
*/
|
||||||
@OptIn(InternalForInline::class)
|
@OptIn(InternalForInline::class)
|
||||||
inline fun <reified F : FirDeclaration, R> KtLambdaExpression.withFirDeclarationOfType(
|
inline fun <reified F : FirDeclaration, R> KtLambdaExpression.withFirDeclarationOfType(
|
||||||
resolveState: FirModuleResolveState,
|
resolveState: FirModuleResolveState,
|
||||||
@@ -68,12 +88,23 @@ inline fun <reified F : FirDeclaration, R> KtLambdaExpression.withFirDeclaration
|
|||||||
return action(firDeclaration)
|
return action(firDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDiagnosticsFor(element: KtElement, resolveState: FirModuleResolveState): Collection<Diagnostic> =
|
/**
|
||||||
resolveState.getDiagnostics(element)
|
* Returns a list of Diagnostics compiler finds for given [KtElement]
|
||||||
|
*/
|
||||||
|
fun KtElement.getDiagnostics(resolveState: FirModuleResolveState): Collection<Diagnostic> =
|
||||||
|
resolveState.getDiagnostics(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of Diagnostics compiler finds for given [KtFile]
|
||||||
|
*/
|
||||||
fun KtFile.collectDiagnosticsForFile(resolveState: FirModuleResolveState): Collection<Diagnostic> =
|
fun KtFile.collectDiagnosticsForFile(resolveState: FirModuleResolveState): Collection<Diagnostic> =
|
||||||
resolveState.collectDiagnosticsForFile(this)
|
resolveState.collectDiagnosticsForFile(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a given [FirDeclaration] to [phase] and returns resolved declaration
|
||||||
|
*
|
||||||
|
* Should not be called form [withFirDeclaration], [withFirDeclarationOfType] functions, as it it may cause deadlock
|
||||||
|
*/
|
||||||
fun <D : FirDeclaration> D.resolvedFirToPhase(
|
fun <D : FirDeclaration> D.resolvedFirToPhase(
|
||||||
phase: FirResolvePhase,
|
phase: FirResolvePhase,
|
||||||
resolveState: FirModuleResolveState
|
resolveState: FirModuleResolveState
|
||||||
@@ -81,14 +112,26 @@ fun <D : FirDeclaration> D.resolvedFirToPhase(
|
|||||||
resolveState.resolvedFirToPhase(this, phase)
|
resolveState.resolvedFirToPhase(this, phase)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a [FirElement] which was created by [KtElement]
|
||||||
|
* Returned [FirElement] is guaranteed to be resolved to [FirResolvePhase.BODY_RESOLVE] phase
|
||||||
|
*/
|
||||||
fun KtElement.getOrBuildFir(
|
fun KtElement.getOrBuildFir(
|
||||||
resolveState: FirModuleResolveState,
|
resolveState: FirModuleResolveState,
|
||||||
) = resolveState.getOrBuildFirFor(this)
|
): FirElement = resolveState.getOrBuildFirFor(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a [FirElement] which was created by [KtElement], but only if it is subtype of [E], `null` otherwise
|
||||||
|
* Returned [FirElement] is guaranteed to be resolved to [FirResolvePhase.BODY_RESOLVE] phase
|
||||||
|
*/
|
||||||
inline fun <reified E : FirElement> KtElement.getOrBuildFirSafe(
|
inline fun <reified E : FirElement> KtElement.getOrBuildFirSafe(
|
||||||
resolveState: FirModuleResolveState,
|
resolveState: FirModuleResolveState,
|
||||||
) = getOrBuildFir(resolveState) as? E
|
) = getOrBuildFir(resolveState) as? E
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a [FirElement] which was created by [KtElement], but only if it is subtype of [E], throws [InvalidFirElementTypeException] otherwise
|
||||||
|
* Returned [FirElement] is guaranteed to be resolved to [FirResolvePhase.BODY_RESOLVE] phase
|
||||||
|
*/
|
||||||
inline fun <reified E : FirElement> KtElement.getOrBuildFirOfType(
|
inline fun <reified E : FirElement> KtElement.getOrBuildFirOfType(
|
||||||
resolveState: FirModuleResolveState,
|
resolveState: FirModuleResolveState,
|
||||||
): E {
|
): E {
|
||||||
@@ -97,6 +140,13 @@ inline fun <reified E : FirElement> KtElement.getOrBuildFirOfType(
|
|||||||
throw InvalidFirElementTypeException(this, E::class, fir::class)
|
throw InvalidFirElementTypeException(this, E::class, fir::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a [FirFile] which was created by [KtElement]
|
||||||
|
* Returned [FirFile] can be resolved to any phase from [FirResolvePhase.RAW_FIR] to [FirResolvePhase.BODY_RESOLVE]
|
||||||
|
*/
|
||||||
|
fun KtFile.getFirFile(resolveState: FirModuleResolveState): FirFile =
|
||||||
|
resolveState.getFirFile(this)
|
||||||
|
|
||||||
class InvalidFirElementTypeException(
|
class InvalidFirElementTypeException(
|
||||||
ktElement: KtElement,
|
ktElement: KtElement,
|
||||||
expectedFirClass: KClass<out FirElement>,
|
expectedFirClass: KClass<out FirElement>,
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.collectDiagnosticsForFile
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.collectDiagnosticsForFile
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getDiagnosticsFor
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getDiagnostics
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtDiagnosticProvider
|
import org.jetbrains.kotlin.idea.frontend.api.components.KtDiagnosticProvider
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
@@ -20,7 +20,7 @@ internal class KtFirDiagnosticProvider(
|
|||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtDiagnosticProvider(), KtFirAnalysisSessionComponent {
|
) : KtDiagnosticProvider(), KtFirAnalysisSessionComponent {
|
||||||
override fun getDiagnosticsForElement(element: KtElement): Collection<Diagnostic> = withValidityAssertion {
|
override fun getDiagnosticsForElement(element: KtElement): Collection<Diagnostic> = withValidityAssertion {
|
||||||
getDiagnosticsFor(element, firResolveState)
|
element.getDiagnostics(firResolveState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun collectDiagnosticsForFile(ktFile: KtFile): Collection<Diagnostic> =
|
override fun collectDiagnosticsForFile(ktFile: KtFile): Collection<Diagnostic> =
|
||||||
|
|||||||
Reference in New Issue
Block a user