FIR IDE: split KtAnalysisSession into mixins

This commit is contained in:
Ilya Kirillov
2021-02-19 16:40:54 +01:00
parent 141b6b0e55
commit ca4ec997ee
26 changed files with 364 additions and 254 deletions
@@ -5,24 +5,9 @@
package org.jetbrains.kotlin.idea.frontend.api package org.jetbrains.kotlin.idea.frontend.api
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
import org.jetbrains.kotlin.idea.frontend.api.components.* import org.jetbrains.kotlin.idea.frontend.api.components.*
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.idea.frontend.api.scopes.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithDeclarations
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.KtSimpleReference
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
/** /**
@@ -37,175 +22,69 @@ import org.jetbrains.kotlin.psi.*
* *
* To create analysis session consider using [analyze] * To create analysis session consider using [analyze]
*/ */
abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner { abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner,
protected abstract val smartCastProvider: KtSmartCastProvider KtSmartCastProviderMixIn,
protected abstract val diagnosticProvider: KtDiagnosticProvider KtCallResolverMixIn,
protected abstract val scopeProvider: KtScopeProvider KtDiagnosticProviderMixIn,
protected abstract val containingDeclarationProvider: KtSymbolContainingDeclarationProvider KtScopeProviderMixIn,
protected abstract val symbolProvider: KtSymbolProvider KtCompletionCandidateCheckerMixIn,
protected abstract val callResolver: KtCallResolver KtTypeRendererMixIn,
protected abstract val completionCandidateChecker: KtCompletionCandidateChecker KtSymbolDeclarationOverridesProviderMixIn,
protected abstract val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider KtExpressionTypeProviderMixIn,
protected abstract val referenceShortener: KtReferenceShortener KtTypeProviderMixIn,
KtSymbolProviderMixIn,
KtSymbolContainingDeclarationProviderMixIn,
KtSubtypingComponentMixIn,
KtExpressionInfoProviderMixIn,
KtSymbolsMixIn,
KtReferenceResolveMixIn,
KtReferenceShortenerMixIn {
@Suppress("LeakingThis") override val analysisSession: KtAnalysisSession get() = this
protected open val typeRenderer: KtTypeRenderer = KtDefaultTypeRenderer(this, token)
protected abstract val expressionTypeProvider: KtExpressionTypeProvider
protected abstract val typeProvider: KtTypeProvider
protected abstract val subtypingComponent: KtSubtypingComponent
protected abstract val expressionHandlingComponent: KtExpressionHandlingComponent
abstract fun createContextDependentCopy(originalKtFile: KtFile, fakeKtElement: KtElement): KtAnalysisSession abstract fun createContextDependentCopy(originalKtFile: KtFile, fakeKtElement: KtElement): KtAnalysisSession
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
protected abstract val smartCastProviderImpl: KtSmartCastProvider
/** internal val diagnosticProvider: KtDiagnosticProvider get() = diagnosticProviderImpl
* Return a list of **all** symbols which are overridden by symbol protected abstract val diagnosticProviderImpl: KtDiagnosticProvider
*
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, all two super declarations `B.foo`, `C.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getDirectlyOverriddenSymbols
*/
fun KtCallableSymbol.getAllOverriddenSymbols(): List<KtCallableSymbol> =
symbolDeclarationOverridesProvider.getAllOverriddenSymbols(this)
/** internal val scopeProvider: KtScopeProvider get() = scopeProviderImpl
* Return a list of symbols which are **directly** overridden by symbol protected abstract val scopeProviderImpl: KtScopeProvider
**
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, only declarations directly overriden `B.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getAllOverriddenSymbols
*/
fun KtCallableSymbol.getDirectlyOverriddenSymbols(): List<KtCallableSymbol> =
symbolDeclarationOverridesProvider.getDirectlyOverriddenSymbols(this)
fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> = internal val containingDeclarationProvider: KtSymbolContainingDeclarationProvider get() = containingDeclarationProviderImpl
symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this) protected abstract val containingDeclarationProviderImpl: KtSymbolContainingDeclarationProvider
fun KtExpression.getSmartCast(): KtType? = smartCastProvider.getSmartCastedToType(this) internal val symbolProvider: KtSymbolProvider get() = symbolProviderImpl
protected abstract val symbolProviderImpl: KtSymbolProvider
fun KtExpression.getImplicitReceiverSmartCast(): Collection<ImplicitReceiverSmartCast> = internal val callResolver: KtCallResolver get() = callResolverImpl
smartCastProvider.getImplicitReceiverSmartCast(this) protected abstract val callResolverImpl: KtCallResolver
fun KtExpression.getKtType(): KtType = expressionTypeProvider.getKtExpressionType(this) internal val completionCandidateChecker: KtCompletionCandidateChecker get() = completionCandidateCheckerImpl
protected abstract val completionCandidateCheckerImpl: KtCompletionCandidateChecker
fun KtDeclaration.getReturnKtType(): KtType = expressionTypeProvider.getReturnTypeForKtDeclaration(this) internal val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider get() = symbolDeclarationOverridesProviderImpl
protected abstract val symbolDeclarationOverridesProviderImpl: KtSymbolDeclarationOverridesProvider
infix fun KtType.isEqualTo(other: KtType): Boolean = subtypingComponent.isEqualTo(this, other) internal val referenceShortener: KtReferenceShortener get() = referenceShortenerImpl
protected abstract val referenceShortenerImpl: KtReferenceShortener
infix fun KtType.isSubTypeOf(superType: KtType): Boolean = subtypingComponent.isSubTypeOf(this, superType)
infix fun KtType.isNotSubTypeOf(superType: KtType): Boolean = !subtypingComponent.isSubTypeOf(this, superType) @Suppress("LeakingThis")
protected open val typeRendererImpl: KtTypeRenderer = KtDefaultTypeRenderer(this, token)
internal val typeRenderer: KtTypeRenderer get() = typeRendererImpl
fun PsiElement.getExpectedType(): KtType? = expressionTypeProvider.getExpectedType(this) internal val expressionTypeProvider: KtExpressionTypeProvider get() = expressionTypeProviderImpl
protected abstract val expressionTypeProviderImpl: KtExpressionTypeProvider
val builtinTypes: KtBuiltinTypes get() = typeProvider.builtinTypes internal val typeProvider: KtTypeProvider get() = typeProviderImpl
protected abstract val typeProviderImpl: KtTypeProvider
/** internal val subtypingComponent: KtSubtypingComponent get() = subtypingComponentImpl
* Approximates [KtType] with the a supertype which can be rendered in a source code protected abstract val subtypingComponentImpl: KtSubtypingComponent
*
* Return `null` if the type do not need approximation and can be rendered as is
* Otherwise, for type `T` return type `S` such `T <: S` and `T` and every it type argument is [org.jetbrains.kotlin.idea.frontend.api.types.KtDenotableType]`
*/
fun KtType.approximateToSuperPublicDenotable(): KtType? = typeProvider.approximateToSuperPublicDenotableType(this)
fun KtClassOrObjectSymbol.buildSelfClassType(): KtType = typeProvider.buildSelfClassType(this) internal val expressionInfoProvider: KtExpressionInfoProvider get() = expressionInfoProviderImpl
protected abstract val expressionInfoProviderImpl: KtExpressionInfoProvider
fun KtElement.getDiagnostics(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnostic> =
diagnosticProvider.getDiagnosticsForElement(this, filter)
fun KtFile.collectDiagnosticsForFile(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> =
diagnosticProvider.collectDiagnosticsForFile(this, filter)
fun KtSymbolWithKind.getContainingSymbol(): KtSymbolWithKind? = containingDeclarationProvider.getContainingDeclaration(this)
fun KtSymbolWithMembers.getMemberScope(): KtMemberScope = scopeProvider.getMemberScope(this)
fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope = scopeProvider.getDeclaredMemberScope(this)
fun KtFileSymbol.getFileScope(): KtDeclarationScope<KtSymbolWithDeclarations> = scopeProvider.getFileScope(this)
fun KtPackageSymbol.getPackageScope(): KtPackageScope = scopeProvider.getPackageScope(this)
fun List<KtScope>.asCompositeScope(): KtCompositeScope = scopeProvider.getCompositeScope(this)
fun KtType.getTypeScope(): KtScope? = scopeProvider.getTypeScope(this)
fun KtFile.getScopeContextForPosition(positionInFakeFile: KtElement): KtScopeContext =
scopeProvider.getScopeContextForPosition(this, positionInFakeFile)
fun KtDeclaration.getSymbol(): KtSymbol = symbolProvider.getSymbol(this)
fun KtParameter.getParameterSymbol(): KtParameterSymbol = symbolProvider.getParameterSymbol(this)
fun KtNamedFunction.getFunctionSymbol(): KtFunctionSymbol = symbolProvider.getFunctionSymbol(this)
fun KtConstructor<*>.getConstructorSymbol(): KtConstructorSymbol = symbolProvider.getConstructorSymbol(this)
fun KtTypeParameter.getTypeParameterSymbol(): KtTypeParameterSymbol = symbolProvider.getTypeParameterSymbol(this)
fun KtTypeAlias.getTypeAliasSymbol(): KtTypeAliasSymbol = symbolProvider.getTypeAliasSymbol(this)
fun KtEnumEntry.getEnumEntrySymbol(): KtEnumEntrySymbol = symbolProvider.getEnumEntrySymbol(this)
fun KtNamedFunction.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol = symbolProvider.getAnonymousFunctionSymbol(this)
fun KtLambdaExpression.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol = symbolProvider.getAnonymousFunctionSymbol(this)
fun KtProperty.getVariableSymbol(): KtVariableSymbol = symbolProvider.getVariableSymbol(this)
fun KtObjectLiteralExpression.getAnonymousObjectSymbol(): KtAnonymousObjectSymbol = symbolProvider.getAnonymousObjectSymbol(this)
fun KtClassOrObject.getClassOrObjectSymbol(): KtClassOrObjectSymbol = symbolProvider.getClassOrObjectSymbol(this)
fun KtPropertyAccessor.getPropertyAccessorSymbol(): KtPropertyAccessorSymbol = symbolProvider.getPropertyAccessorSymbol(this)
fun KtFile.getFileSymbol(): KtFileSymbol = symbolProvider.getFileSymbol(this)
/**
* @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found
*/
fun ClassId.getCorrespondingToplevelClassOrObjectSymbol(): KtClassOrObjectSymbol? = symbolProvider.getClassOrObjectSymbolByClassId(this)
fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence<KtSymbol> = symbolProvider.getTopLevelCallableSymbols(this, name)
fun <S : KtSymbol> KtSymbolPointer<S>.restoreSymbol(): S? = restoreSymbol(this@KtAnalysisSession)
fun KtCallExpression.resolveCall(): KtCall? = callResolver.resolveCall(this)
fun KtBinaryExpression.resolveCall(): KtCall? = callResolver.resolveCall(this)
fun KtReference.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" }
return this@KtAnalysisSession.resolveToSymbols()
}
fun KtSimpleReference<*>.resolveToSymbol(): KtSymbol? {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference but was ${this::class}" }
return resolveToSymbols().singleOrNull()
}
fun KtCallableSymbol.checkExtensionIsSuitable(
originalPsiFile: KtFile,
psiFakeCompletionExpression: KtSimpleNameExpression,
psiReceiverExpression: KtExpression?,
): Boolean = completionCandidateChecker.checkExtensionFitsCandidate(
this,
originalPsiFile,
psiFakeCompletionExpression,
psiReceiverExpression
)
fun KtType.render(options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String =
typeRenderer.render(this, options)
fun KtReturnExpression.getReturnTargetSymbol(): KtCallableSymbol? =
expressionHandlingComponent.getReturnExpressionTargetSymbol(this)
fun collectPossibleReferenceShortenings(file: KtFile, selection: TextRange): ShortenCommand =
referenceShortener.collectShortenings(file, selection)
} }
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.idea.frontend.api.components package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
abstract class KtAnalysisSessionComponent : ValidityTokenOwner { abstract class KtAnalysisSessionComponent : ValidityTokenOwner {
protected abstract val analysisSession: KtAnalysisSession protected abstract val analysisSession: KtAnalysisSession
} }
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2021 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.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
interface KtAnalysisSessionMixIn {
val analysisSession: KtAnalysisSession
}
@@ -13,3 +13,12 @@ abstract class KtCallResolver : KtAnalysisSessionComponent() {
abstract fun resolveCall(call: KtCallExpression): KtCall? abstract fun resolveCall(call: KtCallExpression): KtCall?
abstract fun resolveCall(call: KtBinaryExpression): KtCall? abstract fun resolveCall(call: KtBinaryExpression): KtCall?
} }
interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
fun KtCallExpression.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
fun KtBinaryExpression.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.frontend.api.components package org.jetbrains.kotlin.idea.frontend.api.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -19,3 +18,17 @@ abstract class KtCompletionCandidateChecker : KtAnalysisSessionComponent() {
possibleExplicitReceiver: KtExpression?, possibleExplicitReceiver: KtExpression?,
): Boolean ): Boolean
} }
interface KtCompletionCandidateCheckerMixIn : KtAnalysisSessionMixIn {
fun KtCallableSymbol.checkExtensionIsSuitable(
originalPsiFile: KtFile,
psiFakeCompletionExpression: KtSimpleNameExpression,
psiReceiverExpression: KtExpression?,
): Boolean =
analysisSession.completionCandidateChecker.checkExtensionFitsCandidate(
this,
originalPsiFile,
psiFakeCompletionExpression,
psiReceiverExpression
)
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.frontend.api.components package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -14,6 +15,14 @@ abstract class KtDiagnosticProvider : KtAnalysisSessionComponent() {
abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>>
} }
interface KtDiagnosticProviderMixIn : KtAnalysisSessionMixIn {
fun KtElement.getDiagnostics(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnostic> =
analysisSession.diagnosticProvider.getDiagnosticsForElement(this, filter)
fun KtFile.collectDiagnosticsForFile(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> =
analysisSession.diagnosticProvider.collectDiagnosticsForFile(this, filter)
}
enum class KtDiagnosticCheckerFilter { enum class KtDiagnosticCheckerFilter {
ONLY_COMMON_CHECKERS, ONLY_COMMON_CHECKERS,
ONLY_EXTENDED_CHECKERS, ONLY_EXTENDED_CHECKERS,
@@ -1,14 +0,0 @@
/*
* Copyright 2010-2020 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.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.psi.KtReturnExpression
abstract class KtExpressionHandlingComponent : KtAnalysisSessionComponent() {
abstract fun getReturnExpressionTargetSymbol(returnExpression: KtReturnExpression): KtCallableSymbol?
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2020 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.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.psi.KtReturnExpression
abstract class KtExpressionInfoProvider : KtAnalysisSessionComponent() {
abstract fun getReturnExpressionTargetSymbol(returnExpression: KtReturnExpression): KtCallableSymbol?
}
interface KtExpressionInfoProviderMixIn : KtAnalysisSessionMixIn {
fun KtReturnExpression.getReturnTargetSymbol(): KtCallableSymbol? =
analysisSession.expressionInfoProvider.getReturnExpressionTargetSymbol(this)
}
@@ -17,3 +17,14 @@ abstract class KtExpressionTypeProvider : KtAnalysisSessionComponent() {
abstract fun getExpectedType(expression: PsiElement): KtType? abstract fun getExpectedType(expression: PsiElement): KtType?
} }
interface KtExpressionTypeProviderMixIn : KtAnalysisSessionMixIn {
fun KtExpression.getKtType(): KtType =
analysisSession.expressionTypeProvider.getKtExpressionType(this)
fun KtDeclaration.getReturnKtType(): KtType =
analysisSession.expressionTypeProvider.getReturnTypeForKtDeclaration(this)
fun PsiElement.getExpectedType(): KtType? =
analysisSession.expressionTypeProvider.getExpectedType(this)
}
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2021 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.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.KtSymbolBasedReference
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.KtSimpleReference
interface KtReferenceResolveMixIn : KtAnalysisSessionMixIn {
fun KtReference.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" }
return analysisSession.resolveToSymbols()
}
fun KtSimpleReference<*>.resolveToSymbol(): KtSymbol? {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference but was ${this::class}" }
return resolveToSymbols().singleOrNull()
}
}
@@ -12,6 +12,11 @@ abstract class KtReferenceShortener : KtAnalysisSessionComponent() {
abstract fun collectShortenings(file: KtFile, selection: TextRange): ShortenCommand abstract fun collectShortenings(file: KtFile, selection: TextRange): ShortenCommand
} }
interface KtReferenceShortenerMixIn : KtAnalysisSessionMixIn {
fun collectPossibleReferenceShortenings(file: KtFile, selection: TextRange): ShortenCommand =
analysisSession.referenceShortener.collectShortenings(file, selection)
}
interface ShortenCommand { interface ShortenCommand {
fun invokeShortening() fun invokeShortening()
} }
@@ -29,4 +29,27 @@ abstract class KtScopeProvider : KtAnalysisSessionComponent() {
): KtScopeContext ): KtScopeContext
} }
interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
fun KtSymbolWithMembers.getMemberScope(): KtMemberScope =
analysisSession.scopeProvider.getMemberScope(this)
fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope =
analysisSession.scopeProvider.getDeclaredMemberScope(this)
fun KtFileSymbol.getFileScope(): KtDeclarationScope<KtSymbolWithDeclarations> =
analysisSession.scopeProvider.getFileScope(this)
fun KtPackageSymbol.getPackageScope(): KtPackageScope =
analysisSession.scopeProvider.getPackageScope(this)
fun List<KtScope>.asCompositeScope(): KtCompositeScope =
analysisSession.scopeProvider.getCompositeScope(this)
fun KtType.getTypeScope(): KtScope? =
analysisSession.scopeProvider.getTypeScope(this)
fun KtFile.getScopeContextForPosition(positionInFakeFile: KtElement): KtScopeContext =
analysisSession.scopeProvider.getScopeContextForPosition(this, positionInFakeFile)
}
data class KtScopeContext(val scopes: KtCompositeScope, val implicitReceiversTypes: List<KtType>) data class KtScopeContext(val scopes: KtCompositeScope, val implicitReceiversTypes: List<KtType>)
@@ -13,3 +13,11 @@ abstract class KtSmartCastProvider : KtAnalysisSessionComponent() {
abstract fun getSmartCastedToType(expression: KtExpression): KtType? abstract fun getSmartCastedToType(expression: KtExpression): KtType?
abstract fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast> abstract fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast>
} }
interface KtSmartCastProviderMixIn : KtAnalysisSessionMixIn {
fun KtExpression.getSmartCast(): KtType? =
analysisSession.smartCastProvider.getSmartCastedToType(this)
fun KtExpression.getImplicitReceiverSmartCast(): Collection<ImplicitReceiverSmartCast> =
analysisSession.smartCastProvider.getImplicitReceiverSmartCast(this)
}
@@ -11,3 +11,14 @@ abstract class KtSubtypingComponent : KtAnalysisSessionComponent() {
abstract fun isEqualTo(first: KtType, second: KtType): Boolean abstract fun isEqualTo(first: KtType, second: KtType): Boolean
abstract fun isSubTypeOf(subType: KtType, superType: KtType): Boolean abstract fun isSubTypeOf(subType: KtType, superType: KtType): Boolean
} }
interface KtSubtypingComponentMixIn : KtAnalysisSessionMixIn {
infix fun KtType.isEqualTo(other: KtType): Boolean =
analysisSession.subtypingComponent.isEqualTo(this, other)
infix fun KtType.isSubTypeOf(superType: KtType): Boolean =
analysisSession.subtypingComponent.isSubTypeOf(this, superType)
infix fun KtType.isNotSubTypeOf(superType: KtType): Boolean =
!analysisSession.subtypingComponent.isSubTypeOf(this, superType)
}
@@ -8,11 +8,16 @@ package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
abstract class KtSymbolContainingDeclarationProvider : KtAnalysisSessionComponent() { abstract class KtSymbolContainingDeclarationProvider : KtAnalysisSessionComponent() {
abstract fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind?
}
interface KtSymbolContainingDeclarationProviderMixIn : KtAnalysisSessionMixIn {
/** /**
* Returns containing declaration for symbol: * Returns containing declaration for symbol:
* for top-level declarations returns null * for top-level declarations returns null
* for class members returns containing class * for class members returns containing class
* for local declaration returns declaration it was declared it * for local declaration returns declaration it was declared it
*/ */
abstract fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind? fun KtSymbolWithKind.getContainingSymbol(): KtSymbolWithKind? =
analysisSession.containingDeclarationProvider.getContainingDeclaration(this)
} }
@@ -10,24 +10,37 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() { abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() {
/** abstract fun <T : KtSymbol> getAllOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol>
* Returns symbols that are overridden by requested abstract fun <T : KtSymbol> getDirectlyOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol>
*/
abstract fun <T : KtSymbol> getAllOverriddenSymbols(
callableSymbol: T,
): List<KtCallableSymbol>
/**
* Returns symbols that are overridden by requested
*/
abstract fun <T : KtSymbol> getDirectlyOverriddenSymbols(
callableSymbol: T,
): List<KtCallableSymbol>
/**
* If [symbol] origin is [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE]
* Then returns the symbols which [symbol] overrides, otherwise empty collection
*/
abstract fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol> abstract fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol>
} }
interface KtSymbolDeclarationOverridesProviderMixIn : KtAnalysisSessionMixIn {
/**
* Return a list of **all** symbols which are overridden by symbol
*
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, all two super declarations `B.foo`, `C.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getDirectlyOverriddenSymbols
*/
fun KtCallableSymbol.getAllOverriddenSymbols(): List<KtCallableSymbol> =
analysisSession.symbolDeclarationOverridesProvider.getAllOverriddenSymbols(this)
/**
* Return a list of symbols which are **directly** overridden by symbol
**
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, only declarations directly overriden `B.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getAllOverriddenSymbols
*/
fun KtCallableSymbol.getDirectlyOverriddenSymbols(): List<KtCallableSymbol> =
analysisSession.symbolDeclarationOverridesProvider.getDirectlyOverriddenSymbols(this)
fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> =
analysisSession.symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this)
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2021 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.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
interface KtSymbolsMixIn : KtAnalysisSessionMixIn {
@Suppress("DEPRECATION")
fun <S : KtSymbol> KtSymbolPointer<S>.restoreSymbol(): S? = restoreSymbol(analysisSession)
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.frontend.api.components package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
@@ -18,6 +17,23 @@ abstract class KtTypeProvider : KtAnalysisSessionComponent() {
abstract fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType abstract fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType
} }
interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
val builtinTypes: KtBuiltinTypes
get() = analysisSession.typeProvider.builtinTypes
/**
* Approximates [KtType] with the a supertype which can be rendered in a source code
*
* Return `null` if the type do not need approximation and can be rendered as is
* Otherwise, for type `T` return type `S` such `T <: S` and `T` and every it type argument is [org.jetbrains.kotlin.idea.frontend.api.types.KtDenotableType]`
*/
fun KtType.approximateToSuperPublicDenotable(): KtType? =
analysisSession.typeProvider.approximateToSuperPublicDenotableType(this)
fun KtClassOrObjectSymbol.buildSelfClassType(): KtType =
analysisSession.typeProvider.buildSelfClassType(this)
}
@Suppress("PropertyName") @Suppress("PropertyName")
abstract class KtBuiltinTypes : ValidityTokenOwner { abstract class KtBuiltinTypes : ValidityTokenOwner {
@@ -14,6 +14,11 @@ abstract class KtTypeRenderer : KtAnalysisSessionComponent() {
abstract fun render(type: KtType, options: KtTypeRendererOptions): String abstract fun render(type: KtType, options: KtTypeRendererOptions): String
} }
interface KtTypeRendererMixIn : KtAnalysisSessionMixIn {
fun KtType.render(options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String =
analysisSession.typeRenderer.render(this, options)
}
data class KtTypeRendererOptions( data class KtTypeRendererOptions(
val renderFqNames: Boolean, val renderFqNames: Boolean,
val renderFunctionTypes: Boolean val renderFunctionTypes: Boolean
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.components.KtAnalysisSessionComponent import org.jetbrains.kotlin.idea.frontend.api.components.KtAnalysisSessionComponent
import org.jetbrains.kotlin.idea.frontend.api.components.KtAnalysisSessionMixIn
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -43,10 +44,61 @@ abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol
abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol
/**
* @return symbol with specified [classId] or `null` in case such symbol is not found
*/
abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol? abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol?
abstract fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol> abstract fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol>
} }
interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
fun KtDeclaration.getSymbol(): KtSymbol =
analysisSession.symbolProvider.getSymbol(this)
fun KtParameter.getParameterSymbol(): KtParameterSymbol =
analysisSession.symbolProvider.getParameterSymbol(this)
fun KtNamedFunction.getFunctionSymbol(): KtFunctionSymbol =
analysisSession.symbolProvider.getFunctionSymbol(this)
fun KtConstructor<*>.getConstructorSymbol(): KtConstructorSymbol =
analysisSession.symbolProvider.getConstructorSymbol(this)
fun KtTypeParameter.getTypeParameterSymbol(): KtTypeParameterSymbol =
analysisSession.symbolProvider.getTypeParameterSymbol(this)
fun KtTypeAlias.getTypeAliasSymbol(): KtTypeAliasSymbol =
analysisSession.symbolProvider.getTypeAliasSymbol(this)
fun KtEnumEntry.getEnumEntrySymbol(): KtEnumEntrySymbol =
analysisSession.symbolProvider.getEnumEntrySymbol(this)
fun KtNamedFunction.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol =
analysisSession.symbolProvider.getAnonymousFunctionSymbol(this)
fun KtLambdaExpression.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol =
analysisSession.symbolProvider.getAnonymousFunctionSymbol(this)
fun KtProperty.getVariableSymbol(): KtVariableSymbol =
analysisSession.symbolProvider.getVariableSymbol(this)
fun KtObjectLiteralExpression.getAnonymousObjectSymbol(): KtAnonymousObjectSymbol =
analysisSession.symbolProvider.getAnonymousObjectSymbol(this)
fun KtClassOrObject.getClassOrObjectSymbol(): KtClassOrObjectSymbol =
analysisSession.symbolProvider.getClassOrObjectSymbol(this)
fun KtPropertyAccessor.getPropertyAccessorSymbol(): KtPropertyAccessorSymbol =
analysisSession.symbolProvider.getPropertyAccessorSymbol(this)
fun KtFile.getFileSymbol(): KtFileSymbol =
analysisSession.symbolProvider.getFileSymbol(this)
/**
* @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found
*/
fun ClassId.getCorrespondingToplevelClassOrObjectSymbol(): KtClassOrObjectSymbol? =
analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(this)
fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence<KtSymbol> =
analysisSession.symbolProvider.getTopLevelCallableSymbols(this, name)
}
@@ -16,13 +16,11 @@ import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.ReadActionConfinementValidityToken import org.jetbrains.kotlin.idea.frontend.api.ReadActionConfinementValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.assertIsValidAndAccessible import org.jetbrains.kotlin.idea.frontend.api.assertIsValidAndAccessible
import org.jetbrains.kotlin.idea.frontend.api.components.*
import org.jetbrains.kotlin.idea.frontend.api.fir.components.* import org.jetbrains.kotlin.idea.frontend.api.fir.components.*
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EnclosingDeclarationContext import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EnclosingDeclarationContext
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.recordCompletionContext import org.jetbrains.kotlin.idea.frontend.api.fir.utils.recordCompletionContext
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.threadLocal import org.jetbrains.kotlin.idea.frontend.api.fir.utils.threadLocal
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolProvider
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -38,22 +36,33 @@ private constructor(
assertIsValidAndAccessible() assertIsValidAndAccessible()
} }
override val smartCastProvider: KtSmartCastProvider = KtFirSmartcastProvider(this, token) override val smartCastProviderImpl = KtFirSmartcastProvider(this, token)
override val expressionTypeProvider: KtExpressionTypeProvider = KtFirExpressionTypeProvider(this, token)
public override val diagnosticProvider: KtDiagnosticProvider = KtFirDiagnosticProvider(this, token)
override val containingDeclarationProvider = KtFirSymbolContainingDeclarationProvider(this, token)
override val callResolver: KtCallResolver = KtFirCallResolver(this, token)
override val scopeProvider by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) }
override val symbolProvider: KtSymbolProvider =
KtFirSymbolProvider(this, firResolveState.rootModuleSession.symbolProvider, firResolveState, firSymbolBuilder, token)
override val completionCandidateChecker: KtCompletionCandidateChecker = KtFirCompletionCandidateChecker(this, token)
override val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider =
KtFirSymbolDeclarationOverridesProvider(this, token)
override val referenceShortener: KtReferenceShortener = KtFirReferenceShortener(this, token, firResolveState)
override val expressionHandlingComponent: KtExpressionHandlingComponent = KtFirExpressionHandlingComponent(this, token) override val expressionTypeProviderImpl = KtFirExpressionTypeProvider(this, token)
override val typeProvider: KtTypeProvider = KtFirTypeProvider(this, token)
override val subtypingComponent: KtSubtypingComponent = KtFirSubtypingComponent(this, token) override val diagnosticProviderImpl = KtFirDiagnosticProvider(this, token)
override val containingDeclarationProviderImpl = KtFirSymbolContainingDeclarationProvider(this, token)
override val callResolverImpl = KtFirCallResolver(this, token)
override val scopeProviderImpl by threadLocal { KtFirScopeProvider(this, firSymbolBuilder, project, firResolveState, token) }
override val symbolProviderImpl =
KtFirSymbolProvider(this, firResolveState.rootModuleSession.symbolProvider, firResolveState, firSymbolBuilder, token)
override val completionCandidateCheckerImpl = KtFirCompletionCandidateChecker(this, token)
override val symbolDeclarationOverridesProviderImpl =
KtFirSymbolDeclarationOverridesProvider(this, token)
override val referenceShortenerImpl = KtFirReferenceShortener(this, token, firResolveState)
override val expressionInfoProviderImpl = KtFirExpressionInfoProvider(this, token)
override val typeProviderImpl = KtFirTypeProvider(this, token)
override val subtypingComponentImpl = KtFirSubtypingComponent(this, token)
override fun createContextDependentCopy(originalKtFile: KtFile, fakeKtElement: KtElement): KtAnalysisSession { override fun createContextDependentCopy(originalKtFile: KtFile, fakeKtElement: KtElement): KtAnalysisSession {
check(context == KtFirAnalysisSessionContext.DefaultContext) { check(context == KtFirAnalysisSessionContext.DefaultContext) {
@@ -7,29 +7,37 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.components.KtAnalysisSessionComponent
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KT_DIAGNOSTIC_CONVERTER
internal interface KtFirAnalysisSessionComponent { internal interface KtFirAnalysisSessionComponent {
val analysisSession: KtFirAnalysisSession val analysisSession: KtFirAnalysisSession
val rootModuleSession: FirSession get() = analysisSession.firResolveState.rootModuleSession val rootModuleSession: FirSession get() = analysisSession.firResolveState.rootModuleSession
val firSymbolBuilder get() = analysisSession.firSymbolBuilder val firSymbolBuilder get() = analysisSession.firSymbolBuilder
val firResolveState get() = analysisSession.firResolveState val firResolveState get() = analysisSession.firResolveState
fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.buildKtType(this) fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.buildKtType(this)
fun FirPsiDiagnostic<*>.asKtDiagnostic(): KtDiagnosticWithPsi<*> = fun FirPsiDiagnostic<*>.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
(analysisSession.diagnosticProvider as KtFirDiagnosticProvider).firDiagnosticAsKtDiagnostic(this) KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic<*>)
fun ConeDiagnostic.asKtDiagnostic(source: FirSourceElement): KtDiagnostic? = fun ConeDiagnostic.asKtDiagnostic(source: FirSourceElement): KtDiagnosticWithPsi<*>? {
(analysisSession.diagnosticProvider as KtFirDiagnosticProvider).coneDiagnosticAsKtDiagnostic(this, source) val firDiagnostic = toFirDiagnostic(source) ?: return null
check(firDiagnostic is FirPsiDiagnostic<*>)
return firDiagnostic.asKtDiagnostic()
}
fun createTypeCheckerContext() = ConeTypeCheckerContext( fun createTypeCheckerContext() = ConeTypeCheckerContext(
isErrorTypeEqualsToAnything = true, isErrorTypeEqualsToAnything = true,
@@ -5,12 +5,6 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.components package org.jetbrains.kotlin.idea.frontend.api.fir.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
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.getDiagnostics import org.jetbrains.kotlin.idea.fir.low.level.api.api.getDiagnostics
@@ -19,7 +13,6 @@ import org.jetbrains.kotlin.idea.frontend.api.components.KtDiagnosticCheckerFilt
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.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KT_DIAGNOSTIC_CONVERTER
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -38,19 +31,10 @@ internal class KtFirDiagnosticProvider(
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> = override fun collectDiagnosticsForFile(ktFile: KtFile, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> =
ktFile.collectDiagnosticsForFile(firResolveState, filter.asLLFilter()).map { it.asKtDiagnostic() } ktFile.collectDiagnosticsForFile(firResolveState, filter.asLLFilter()).map { it.asKtDiagnostic() }
fun firDiagnosticAsKtDiagnostic(diagnostic: FirPsiDiagnostic<*>): KtDiagnosticWithPsi<*> {
return KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, diagnostic as FirDiagnostic<*>)
}
private fun KtDiagnosticCheckerFilter.asLLFilter() = when (this) { private fun KtDiagnosticCheckerFilter.asLLFilter() = when (this) {
KtDiagnosticCheckerFilter.ONLY_COMMON_CHECKERS -> DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS KtDiagnosticCheckerFilter.ONLY_COMMON_CHECKERS -> DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
KtDiagnosticCheckerFilter.ONLY_EXTENDED_CHECKERS -> DiagnosticCheckerFilter.ONLY_EXTENDED_CHECKERS KtDiagnosticCheckerFilter.ONLY_EXTENDED_CHECKERS -> DiagnosticCheckerFilter.ONLY_EXTENDED_CHECKERS
KtDiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS -> DiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS KtDiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS -> DiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS
} }
fun coneDiagnosticAsKtDiagnostic(coneDiagnostic: ConeDiagnostic, source: FirSourceElement): KtDiagnosticWithPsi<*>? {
val firDiagnostic = coneDiagnostic.toFirDiagnostic(source) ?: return null
check(firDiagnostic is FirPsiDiagnostic<*>)
return firDiagnosticAsKtDiagnostic(firDiagnostic)
}
} }
@@ -8,16 +8,15 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.components.KtExpressionHandlingComponent import org.jetbrains.kotlin.idea.frontend.api.components.KtExpressionInfoProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.psi.KtReturnExpression import org.jetbrains.kotlin.psi.KtReturnExpression
internal class KtFirExpressionHandlingComponent( internal class KtFirExpressionInfoProvider(
override val analysisSession: KtFirAnalysisSession, override val analysisSession: KtFirAnalysisSession,
override val token: ValidityToken, override val token: ValidityToken,
) : KtExpressionHandlingComponent(), KtFirAnalysisSessionComponent { ) : KtExpressionInfoProvider(), KtFirAnalysisSessionComponent {
override fun getReturnExpressionTargetSymbol(returnExpression: KtReturnExpression): KtCallableSymbol? { override fun getReturnExpressionTargetSymbol(returnExpression: KtReturnExpression): KtCallableSymbol? {
val fir = returnExpression.getOrBuildFirSafe<FirReturnExpression>(firResolveState) ?: return null val fir = returnExpression.getOrBuildFirSafe<FirReturnExpression>(firResolveState) ?: return null
val firTargetSymbol = fir.target.labeledElement val firTargetSymbol = fir.target.labeledElement
@@ -10,13 +10,10 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe
import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
internal class KtFirSmartcastProvider( internal class KtFirSmartcastProvider(