FIR IDE: move analysis api to the analysis directory

This commit is contained in:
Ilya Kirillov
2021-09-14 15:58:04 +02:00
parent 0996513f82
commit 0c04ff98c3
75 changed files with 219 additions and 220 deletions
+37
View File
@@ -0,0 +1,37 @@
plugins {
kotlin("jvm")
id("jps-compatible")
}
kotlin {
explicitApiWarning()
}
dependencies {
compileOnly(project(":kotlin-reflect-api"))
compileOnly(project(":compiler:psi"))
compileOnly(project(":compiler:frontend"))
compileOnly(project(":core:compiler.common"))
compileOnly(project(":core:compiler.common.jvm"))
compileOnly(project(":idea-frontend-fir:idea-fir-low-level-api"))
implementation(project(":analysis:analysis-api-providers"))
compile(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) }
}
kotlin {
explicitApi()
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
testsJar()
projectTest {
dependsOn(":dist")
workingDir = rootDir
}
@@ -0,0 +1,25 @@
/*
* 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.analysis.api
@RequiresOptIn
public annotation class ForbidKtResolveInternals
public object ForbidKtResolve {
@OptIn(ForbidKtResolveInternals::class)
public inline fun <R> forbidResolveIn(actionName: String, action: () -> R): R {
if (resovleIsForbidenInActionWithName.get() != null) return action()
resovleIsForbidenInActionWithName.set(actionName)
return try {
action()
} finally {
resovleIsForbidenInActionWithName.set(null)
}
}
@ForbidKtResolveInternals
public val resovleIsForbidenInActionWithName: ThreadLocal<String?> = ThreadLocal.withInitial { null }
}
@@ -0,0 +1,14 @@
/*
* 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.analysis.api
import org.jetbrains.kotlin.analysis.api.types.KtType
public data class ImplicitReceiverSmartCast(val type: KtType, val kind: ImplicitReceiverSmartcastKind)
public enum class ImplicitReceiverSmartcastKind {
DISPATCH, EXTENSION
}
@@ -0,0 +1,138 @@
/*
* 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.analysis.api
import org.jetbrains.kotlin.analysis.api.components.*
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProvider
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderMixIn
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
/**
* The entry point into all frontend-related work. Has the following contracts:
* - Should not be accessed from event dispatch thread
* - Should not be accessed outside read action
* - Should not be leaked outside read action it was created in
* - To be sure that session is not leaked it is forbidden to store it in a variable, consider working with it only in [analyse] context
* - All entities retrieved from analysis session should not be leaked outside the read action KtAnalysisSession was created in
*
* To pass a symbol from one read action to another use [KtSymbolPointer] which can be created from a symbol by [KtSymbol.createPointer]
*
* To create analysis session consider using [analyse]
*/
public abstract class KtAnalysisSession(final override val token: ValidityToken) : ValidityTokenOwner,
KtSmartCastProviderMixIn,
KtCallResolverMixIn,
KtSamResolverMixIn,
KtDiagnosticProviderMixIn,
KtScopeProviderMixIn,
KtCompletionCandidateCheckerMixIn,
KtSymbolDeclarationOverridesProviderMixIn,
KtExpressionTypeProviderMixIn,
KtPsiTypeProviderMixIn,
KtJvmTypeMapperMixIn,
KtTypeProviderMixIn,
KtTypeInfoProviderMixIn,
KtSymbolProviderMixIn,
KtSymbolContainingDeclarationProviderMixIn,
KtSymbolInfoProviderMixIn,
KtSubtypingComponentMixIn,
KtExpressionInfoProviderMixIn,
KtCompileTimeConstantProviderMixIn,
KtSymbolsMixIn,
KtReferenceResolveMixIn,
KtReferenceShortenerMixIn,
KtImportOptimizerMixIn,
KtSymbolDeclarationRendererMixIn,
KtVisibilityCheckerMixIn,
KtMemberSymbolProviderMixin,
KtInheritorsProviderMixIn,
KtTypeCreatorMixIn {
override val analysisSession: KtAnalysisSession get() = this
public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
protected abstract val smartCastProviderImpl: KtSmartCastProvider
internal val diagnosticProvider: KtDiagnosticProvider get() = diagnosticProviderImpl
protected abstract val diagnosticProviderImpl: KtDiagnosticProvider
internal val scopeProvider: KtScopeProvider get() = scopeProviderImpl
protected abstract val scopeProviderImpl: KtScopeProvider
internal val containingDeclarationProvider: KtSymbolContainingDeclarationProvider get() = containingDeclarationProviderImpl
protected abstract val containingDeclarationProviderImpl: KtSymbolContainingDeclarationProvider
internal val symbolProvider: KtSymbolProvider get() = symbolProviderImpl
protected abstract val symbolProviderImpl: KtSymbolProvider
internal val callResolver: KtCallResolver get() = callResolverImpl
protected abstract val callResolverImpl: KtCallResolver
internal val samResolver: KtSamResolver get() = samResolverImpl
protected abstract val samResolverImpl: KtSamResolver
internal val completionCandidateChecker: KtCompletionCandidateChecker get() = completionCandidateCheckerImpl
protected abstract val completionCandidateCheckerImpl: KtCompletionCandidateChecker
internal val symbolDeclarationOverridesProvider: KtSymbolDeclarationOverridesProvider get() = symbolDeclarationOverridesProviderImpl
protected abstract val symbolDeclarationOverridesProviderImpl: KtSymbolDeclarationOverridesProvider
internal val referenceShortener: KtReferenceShortener get() = referenceShortenerImpl
protected abstract val referenceShortenerImpl: KtReferenceShortener
internal val importOptimizer: KtImportOptimizer get() = importOptimizerImpl
protected abstract val importOptimizerImpl: KtImportOptimizer
internal val symbolDeclarationRendererProvider: KtSymbolDeclarationRendererProvider get() = symbolDeclarationRendererProviderImpl
protected abstract val symbolDeclarationRendererProviderImpl: KtSymbolDeclarationRendererProvider
internal val expressionTypeProvider: KtExpressionTypeProvider get() = expressionTypeProviderImpl
protected abstract val expressionTypeProviderImpl: KtExpressionTypeProvider
internal val psiTypeProvider: KtPsiTypeProvider get() = psiTypeProviderImpl
protected abstract val psiTypeProviderImpl: KtPsiTypeProvider
internal val jvmTypeMapper: KtJvmTypeMapper get() = jvmTypeMapperImpl
protected abstract val jvmTypeMapperImpl: KtJvmTypeMapper
internal val typeProvider: KtTypeProvider get() = typeProviderImpl
protected abstract val typeProviderImpl: KtTypeProvider
internal val typeInfoProvider: KtTypeInfoProvider get() = typeInfoProviderImpl
protected abstract val typeInfoProviderImpl: KtTypeInfoProvider
internal val subtypingComponent: KtSubtypingComponent get() = subtypingComponentImpl
protected abstract val subtypingComponentImpl: KtSubtypingComponent
internal val expressionInfoProvider: KtExpressionInfoProvider get() = expressionInfoProviderImpl
protected abstract val expressionInfoProviderImpl: KtExpressionInfoProvider
internal val compileTimeConstantProvider: KtCompileTimeConstantProvider get() = compileTimeConstantProviderImpl
protected abstract val compileTimeConstantProviderImpl: KtCompileTimeConstantProvider
internal val visibilityChecker: KtVisibilityChecker get() = visibilityCheckerImpl
protected abstract val visibilityCheckerImpl: KtVisibilityChecker
internal val overrideInfoProvider: KtOverrideInfoProvider get() = overrideInfoProviderImpl
protected abstract val overrideInfoProviderImpl: KtOverrideInfoProvider
internal val inheritorsProvider: KtInheritorsProvider get() = inheritorsProviderImpl
protected abstract val inheritorsProviderImpl: KtInheritorsProvider
internal val symbolInfoProvider: KtSymbolInfoProvider get() = symbolInfoProviderImpl
protected abstract val symbolInfoProviderImpl: KtSymbolInfoProvider
@PublishedApi
internal val typesCreator: KtTypeCreator
get() = typesCreatorImpl
protected abstract val typesCreatorImpl: KtTypeCreator
}
@@ -0,0 +1,175 @@
/*
* 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.analysis.api
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.tokens.AlwaysAccessibleValidityTokenFactory
import org.jetbrains.kotlin.analysis.api.tokens.ReadActionConfinementValidityTokenFactory
import org.jetbrains.kotlin.analysis.api.tokens.ValidityTokenFactory
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@RequiresOptIn("To use analysis session, consider using analyze/analyzeWithReadAction/analyseInModalWindow methods")
public annotation class InvalidWayOfUsingAnalysisSession
@RequiresOptIn
public annotation class KtAnalysisSessionProviderInternals
/**
* Provides [KtAnalysisSession] by [contextElement]
* Should not be used directly, consider using [analyse]/[analyseWithReadAction]/[analyseInModalWindow] instead
*/
@InvalidWayOfUsingAnalysisSession
public abstract class KtAnalysisSessionProvider : Disposable {
@Suppress("LeakingThis")
@OptIn(KtInternalApiMarker::class)
public val noWriteActionInAnalyseCallChecker: NoWriteActionInAnalyseCallChecker = NoWriteActionInAnalyseCallChecker(this)
@InvalidWayOfUsingAnalysisSession
public abstract fun getAnalysisSession(contextElement: KtElement, factory: ValidityTokenFactory): KtAnalysisSession
@InvalidWayOfUsingAnalysisSession
public abstract fun getAnalysisSessionBySymbol(contextSymbol: KtSymbol): KtAnalysisSession
@InvalidWayOfUsingAnalysisSession
public inline fun <R> analyzeWithSymbolAsContext(
contextSymbol: KtSymbol,
action: KtAnalysisSession.() -> R
): R {
val analysisSession = getAnalysisSessionBySymbol(contextSymbol)
return action(analysisSession)
}
@InvalidWayOfUsingAnalysisSession
public inline fun <R> analyseInDependedAnalysisSession(
originalFile: KtFile,
elementToReanalyze: KtElement,
action: KtAnalysisSession.() -> R
): R {
val dependedAnalysisSession = getAnalysisSession(originalFile, ReadActionConfinementValidityTokenFactory)
.createContextDependentCopy(originalFile, elementToReanalyze)
return analyse(dependedAnalysisSession, ReadActionConfinementValidityTokenFactory, action)
}
@InvalidWayOfUsingAnalysisSession
public inline fun <R> analyse(contextElement: KtElement, tokenFactory: ValidityTokenFactory, action: KtAnalysisSession.() -> R): R =
analyse(getAnalysisSession(contextElement, tokenFactory), tokenFactory, action)
@OptIn(KtAnalysisSessionProviderInternals::class, KtInternalApiMarker::class)
@InvalidWayOfUsingAnalysisSession
public inline fun <R> analyse(analysisSession: KtAnalysisSession, factory: ValidityTokenFactory, action: KtAnalysisSession.() -> R): R {
noWriteActionInAnalyseCallChecker.beforeEnteringAnalysisContext()
factory.beforeEnteringAnalysisContext()
return try {
analysisSession.action()
} finally {
factory.afterLeavingAnalysisContext()
noWriteActionInAnalyseCallChecker.afterLeavingAnalysisContext()
}
}
@TestOnly
public abstract fun clearCaches()
override fun dispose() {}
public companion object {
public fun getInstance(project: Project): KtAnalysisSessionProvider =
ServiceManager.getService(project, KtAnalysisSessionProvider::class.java)
}
}
/**
* 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 analyseWithReadAction
*/
@OptIn(InvalidWayOfUsingAnalysisSession::class)
public inline fun <R> analyse(contextElement: KtElement, action: KtAnalysisSession.() -> R): R =
KtAnalysisSessionProvider.getInstance(contextElement.project)
.analyse(contextElement, ReadActionConfinementValidityTokenFactory, action)
@OptIn(InvalidWayOfUsingAnalysisSession::class)
public inline fun <R> analyseWithCustomToken(
contextElement: KtElement,
tokenFactory: ValidityTokenFactory,
action: KtAnalysisSession.() -> R
): R =
KtAnalysisSessionProvider.getInstance(contextElement.project)
.analyse(contextElement, tokenFactory, action)
/**
* UAST-specific version of [analyse] that executes the given [action] in [KtAnalysisSession] context
*/
@OptIn(InvalidWayOfUsingAnalysisSession::class)
public inline fun <R> analyseForUast(
contextElement: KtElement,
action: KtAnalysisSession.() -> R
): R =
analyseWithCustomToken(contextElement, AlwaysAccessibleValidityTokenFactory, action)
@OptIn(InvalidWayOfUsingAnalysisSession::class)
public inline fun <R> analyseInDependedAnalysisSession(
originalFile: KtFile,
elementToReanalyze: KtElement,
action: KtAnalysisSession.() -> R
): R =
KtAnalysisSessionProvider.getInstance(originalFile.project)
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, action)
/**
* Execute given [action] in [KtAnalysisSession] context like [analyse] 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 [analyse]
*
* @see KtAnalysisSession
* @see analyse
*/
public inline fun <R> analyseWithReadAction(
contextElement: KtElement,
crossinline action: KtAnalysisSession.() -> R
): R = ApplicationManager.getApplication().runReadAction(Computable {
analyse(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 [analyse]/[analyseWithReadAction]
*/
public inline fun <R> analyseInModalWindow(
contextElement: KtElement,
windowTitle: String,
crossinline action: KtAnalysisSession.() -> R
): R {
ApplicationManager.getApplication().assertIsDispatchThread()
val task = object : Task.WithResult<R, Exception>(contextElement.project, windowTitle, /*canBeCancelled*/ true) {
override fun compute(indicator: ProgressIndicator): R = analyseWithReadAction(contextElement) { action() }
}
task.queue()
return task.result
}
@@ -0,0 +1,13 @@
/*
* 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.analysis.api
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.references.KtReference
public interface KtSymbolBasedReference : KtReference {
public fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol>
}
@@ -0,0 +1,25 @@
/*
* 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.analysis.api
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.types.Variance
public sealed class KtTypeArgument : ValidityTokenOwner {
public abstract val type: KtType?
}
public class KtStarProjectionTypeArgument(override val token: ValidityToken) : KtTypeArgument() {
override val type: KtType? get() = withValidityAssertion { null }
}
public class KtTypeArgumentWithVariance(
override val type: KtType,
public val variance: Variance,
override val token: ValidityToken,
) : KtTypeArgument()
@@ -0,0 +1,38 @@
/*
* 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.analysis.api
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationListener
import com.intellij.openapi.application.ApplicationManager
@KtInternalApiMarker
public class NoWriteActionInAnalyseCallChecker(parentDisposable: Disposable) {
init {
val listener = object : ApplicationListener {
override fun writeActionFinished(action: Any) {
if (currentAnalysisContextEnteringCount.get() > 0) {
throw WriteActionStartInsideAnalysisContextException()
}
}
}
ApplicationManager.getApplication().addApplicationListener(listener, parentDisposable)
}
public fun beforeEnteringAnalysisContext() {
currentAnalysisContextEnteringCount.set(currentAnalysisContextEnteringCount.get() + 1)
}
public fun afterLeavingAnalysisContext() {
currentAnalysisContextEnteringCount.set(currentAnalysisContextEnteringCount.get() - 1)
}
private val currentAnalysisContextEnteringCount = ThreadLocal.withInitial { 0 }
}
public class WriteActionStartInsideAnalysisContextException : IllegalStateException(
"write action should be never executed inside analysis context (e,g. analyse call)"
)
@@ -0,0 +1,25 @@
/*
* 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.analysis.api
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.tokens.assertIsValidAndAccessible
public interface ValidityTokenOwner {
public val token: ValidityToken
}
public fun ValidityTokenOwner.isValid(): Boolean = token.isValid()
@Suppress("NOTHING_TO_INLINE")
public inline fun ValidityTokenOwner.assertIsValidAndAccessible() {
token.assertIsValidAndAccessible()
}
public inline fun <R> ValidityTokenOwner.withValidityAssertion(action: () -> R): R {
assertIsValidAndAccessible()
return action()
}
@@ -0,0 +1,9 @@
/*
* 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.analysis.api
@RequiresOptIn
public annotation class KtInternalApiMarker
@@ -0,0 +1,122 @@
/*
* 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.analysis.api.calls
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
import org.jetbrains.kotlin.psi.KtExpression
/**
* Represents direct or indirect (via invoke) function call from Kotlin code
*/
public sealed class KtCall {
public abstract val isErrorCall: Boolean
public abstract val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>
public abstract val targetFunction: KtCallTarget
}
/**
* Call using `()` of some variable of functional type, e.g.,
*
* fun x(f: () -> Int) {
* f() // functional type call
* }
*/
public class KtFunctionalTypeVariableCall(
public val target: KtVariableLikeSymbol,
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
override val targetFunction: KtCallTarget
) : KtCall() {
override val isErrorCall: Boolean get() = false
}
/**
* Direct or indirect call of function declared by user
*/
public sealed class KtDeclaredFunctionCall : KtCall() {
override val isErrorCall: Boolean
get() = targetFunction is KtErrorCallTarget
}
/**
* Call using () on variable on some non-functional type, considers that `invoke` function is declared somewhere
*
* fun x(y: Int) {
* y() // variable with invoke function call
* }
*
* fun Int.invoke() {}
*/
public class KtVariableWithInvokeFunctionCall(
public val target: KtVariableLikeSymbol,
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
override val targetFunction: KtCallTarget
) : KtDeclaredFunctionCall()
/**
* Simple function call, e.g.,
*
* x.toString() // function call
*/
public class KtFunctionCall(
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
override val targetFunction: KtCallTarget
) : KtDeclaredFunctionCall()
/**
* Annotation call, e.g.,
*
* @Retention(AnnotationRetention.SOURCE) // annotation call
* annotation class Ann
*/
public class KtAnnotationCall(
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
override val targetFunction: KtCallTarget
) : KtDeclaredFunctionCall()
// TODO: Add other properties, e.g., useSiteTarget
/**
* Delegated constructor call, e.g.,
*
* open class A(a: Int)
* class B(b: Int) : A(b) { // delegated constructor call (kind = SUPER_CALL)
* constructor() : this(1) // delegated constructor call (kind = THIS_CALL)
* }
*/
public class KtDelegatedConstructorCall(
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
override val targetFunction: KtCallTarget,
public val kind: KtDelegatedConstructorCallKind
) : KtDeclaredFunctionCall()
public enum class KtDelegatedConstructorCallKind { SUPER_CALL, THIS_CALL }
/**
* Represents function(s) in which call was resolved,
* Can be success [KtSuccessCallTarget] in this case there only one such function
* Or erroneous [KtErrorCallTarget] in this case there can be any count of candidates
*/
public sealed class KtCallTarget {
public abstract val candidates: Collection<KtFunctionLikeSymbol>
}
/**
* Success call of [symbol]
*/
public class KtSuccessCallTarget(public val symbol: KtFunctionLikeSymbol) : KtCallTarget() {
override val candidates: Collection<KtFunctionLikeSymbol>
get() = listOf(symbol)
}
/**
* Function all with errors, possible candidates are [candidates]
*/
public class KtErrorCallTarget(
override val candidates: Collection<KtFunctionLikeSymbol>,
public val diagnostic: KtDiagnostic
) : KtCallTarget()
@@ -0,0 +1,25 @@
/*
* 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.analysis.api.calls
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
public fun KtCallTarget.getSuccessCallSymbolOrNull(): KtFunctionLikeSymbol? = when (this) {
is KtSuccessCallTarget -> symbol
is KtErrorCallTarget -> null
}
public fun KtCallTarget.getSingleCandidateSymbolOrNull(): KtFunctionLikeSymbol? = when (this) {
is KtSuccessCallTarget -> symbol
is KtErrorCallTarget -> candidates.singleOrNull()
}
public inline fun <reified S : KtFunctionLikeSymbol> KtCall.isSuccessCallOf(predicate: (S) -> Boolean): Boolean {
if (this !is KtFunctionCall) return false
val symbol = targetFunction.getSuccessCallSymbolOrNull() ?: return false
if (symbol !is S) return false
return predicate(symbol)
}
@@ -0,0 +1,14 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
public abstract class KtAnalysisSessionComponent : ValidityTokenOwner {
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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
public interface KtAnalysisSessionMixIn {
public val analysisSession: KtAnalysisSession
}
@@ -0,0 +1,39 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.calls.KtCall
import org.jetbrains.kotlin.psi.*
public abstract class KtCallResolver : KtAnalysisSessionComponent() {
public abstract fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall?
public abstract fun resolveCall(call: KtCallElement): KtCall?
public abstract fun resolveCall(call: KtBinaryExpression): KtCall?
public abstract fun resolveCall(call: KtUnaryExpression): KtCall?
public abstract fun resolveCall(call: KtArrayAccessExpression): KtCall?
}
public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
/**
* Resolves the given simple name expression to an accessor call if that name refers to a property.
*
* This spans both Kotlin property and synthetic Java property.
*/
public fun KtSimpleNameExpression.resolveAccessorCall(): KtCall? =
analysisSession.callResolver.resolveAccessorCall(this)
public fun KtCallElement.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
public fun KtBinaryExpression.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
public fun KtUnaryExpression.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
public fun KtArrayAccessExpression.resolveCall(): KtCall? =
analysisSession.callResolver.resolveCall(this)
}
@@ -0,0 +1,18 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSimpleConstantValue
import org.jetbrains.kotlin.psi.KtExpression
public abstract class KtCompileTimeConstantProvider : KtAnalysisSessionComponent() {
public abstract fun evaluate(expression: KtExpression): KtSimpleConstantValue<*>?
}
public interface KtCompileTimeConstantProviderMixIn : KtAnalysisSessionMixIn {
public fun KtExpression.evaluate(): KtSimpleConstantValue<*>? =
analysisSession.compileTimeConstantProvider.evaluate(this)
}
@@ -0,0 +1,40 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
public abstract class KtCompletionCandidateChecker : KtAnalysisSessionComponent() {
public abstract fun checkExtensionFitsCandidate(
firSymbolForCandidate: KtCallableSymbol,
originalFile: KtFile,
nameExpression: KtSimpleNameExpression,
possibleExplicitReceiver: KtExpression?,
): KtExtensionApplicabilityResult
}
public enum class KtExtensionApplicabilityResult(public val isApplicable: Boolean) {
ApplicableAsExtensionCallable(isApplicable = true),
ApplicableAsFunctionalVariableCall(isApplicable = true),
NonApplicable(isApplicable = false),
}
public interface KtCompletionCandidateCheckerMixIn : KtAnalysisSessionMixIn {
public fun KtCallableSymbol.checkExtensionIsSuitable(
originalPsiFile: KtFile,
psiFakeCompletionExpression: KtSimpleNameExpression,
psiReceiverExpression: KtExpression?,
): KtExtensionApplicabilityResult =
analysisSession.completionCandidateChecker.checkExtensionFitsCandidate(
this,
originalPsiFile,
psiFakeCompletionExpression,
psiReceiverExpression
)
}
@@ -0,0 +1,30 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
public abstract class KtDiagnosticProvider : KtAnalysisSessionComponent() {
public abstract fun getDiagnosticsForElement(element: KtElement, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>>
public abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>>
}
public interface KtDiagnosticProviderMixIn : KtAnalysisSessionMixIn {
public fun KtElement.getDiagnostics(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnostic> =
analysisSession.diagnosticProvider.getDiagnosticsForElement(this, filter)
public fun KtFile.collectDiagnosticsForFile(filter: KtDiagnosticCheckerFilter): Collection<KtDiagnosticWithPsi<*>> =
analysisSession.diagnosticProvider.collectDiagnosticsForFile(this, filter)
}
public enum class KtDiagnosticCheckerFilter {
ONLY_COMMON_CHECKERS,
ONLY_EXTENDED_CHECKERS,
EXTENDED_AND_COMMON_CHECKERS,
}
@@ -0,0 +1,23 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.KtWhenExpression
public abstract class KtExpressionInfoProvider : KtAnalysisSessionComponent() {
public abstract fun getReturnExpressionTargetSymbol(returnExpression: KtReturnExpression): KtCallableSymbol?
public abstract fun getWhenMissingCases(whenExpression: KtWhenExpression): List<WhenMissingCase>
}
public interface KtExpressionInfoProviderMixIn : KtAnalysisSessionMixIn {
public fun KtReturnExpression.getReturnTargetSymbol(): KtCallableSymbol? =
analysisSession.expressionInfoProvider.getReturnExpressionTargetSymbol(this)
public fun KtWhenExpression.getMissingCases(): List<WhenMissingCase> = analysisSession.expressionInfoProvider.getWhenMissingCases(this)
}
@@ -0,0 +1,92 @@
/*
* 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.analysis.api.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction
public abstract class KtExpressionTypeProvider : KtAnalysisSessionComponent() {
public abstract fun getKtExpressionType(expression: KtExpression): KtType?
public abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType
public abstract fun getFunctionalTypeForKtFunction(declaration: KtFunction): KtType
public abstract fun getExpectedType(expression: PsiElement): KtType?
public abstract fun isDefinitelyNull(expression: KtExpression): Boolean
public abstract fun isDefinitelyNotNull(expression: KtExpression): Boolean
}
public interface KtExpressionTypeProviderMixIn : KtAnalysisSessionMixIn {
/**
* Get type of given expression.
*
* Return:
* - [KtExpression] type if given [KtExpression] is real expression;
* - `null` for [KtExpression] inside pacakges and import declarations;
* - `Unit` type for statements;
*/
public fun KtExpression.getKtType(): KtType? =
analysisSession.expressionTypeProvider.getKtExpressionType(this)
/**
* Returns the return type of the given [KtDeclaration] as [KtType]
*/
public fun KtDeclaration.getReturnKtType(): KtType =
analysisSession.expressionTypeProvider.getReturnTypeForKtDeclaration(this)
/**
* Returns the functional type of the given [KtFunction].
*
* For a regular function, it would be kotlin.FunctionN<Ps, R> where
* N is the number of value parameters in the function;
* Ps are types of value parameters;
* R is the return type of the function.
* Depending on the function's attributes, such as `suspend` or reflective access, different functional type,
* such as `SuspendFunction`, `KFunction`, or `KSuspendFunction`, will be constructed.
*/
public fun KtFunction.getFunctionalType(): KtType =
analysisSession.expressionTypeProvider.getFunctionalTypeForKtFunction(this)
/**
* Returns the expected [KtType] of this [PsiElement] if it is an expression. The returned value should not be a
* [org.jetbrains.kotlin.analysis.api.types.KtClassErrorType].
*/
public fun PsiElement.getExpectedType(): KtType? =
analysisSession.expressionTypeProvider.getExpectedType(this)
/**
* Returns `true` if this expression is definitely null, based on declared nullability and smart cast types derived from
* data-flow analysis facts. Examples:
* ```
* public fun <T : Any> foo(t: T, nt: T?, s: String, ns: String?) {
* t // t.isDefinitelyNull() == false && t.isDefinitelyNotNull() == true
* nt // nt.isDefinitelyNull() == false && nt.isDefinitelyNotNull() == false
* s // s.isDefinitelyNull() == false && s.isDefinitelyNotNull() == true
* ns // ns.isDefinitelyNull() == false && ns.isDefinitelyNotNull() == false
*
* if (ns != null) {
* ns // ns.isDefinitelyNull() == false && ns.isDefinitelyNotNull() == true
* } else {
* ns // ns.isDefinitelyNull() == true && ns.isDefinitelyNotNull() == false
* }
*
* ns!! // From this point on: ns.isDefinitelyNull() == false && ns.isDefinitelyNotNull() == true
* }
* ```
* Note that only nullability from "stable" smart cast types is considered. The
* [spec](https://kotlinlang.org/spec/type-inference.html#smart-cast-sink-stability) provides an explanation on smart cast stability.
*/
public fun KtExpression.isDefinitelyNull(): Boolean =
analysisSession.expressionTypeProvider.isDefinitelyNull(this)
/**
* Returns `true` if this expression is definitely not null. See [isDefinitelyNull] for examples.
*/
public fun KtExpression.isDefinitelyNotNull(): Boolean =
analysisSession.expressionTypeProvider.isDefinitelyNotNull(this)
}
@@ -0,0 +1,31 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective
public abstract class KtImportOptimizer : ValidityTokenOwner {
public abstract fun analyseImports(file: KtFile): KtImportOptimizerResult
}
public interface KtImportOptimizerMixIn : KtAnalysisSessionMixIn {
/**
* Takes [file] and inspects its imports and their usages,
* so they can be optimized based on the resulting [KtImportOptimizerResult].
*
* Does **not** change the file.
*/
public fun analyseImports(file: KtFile): KtImportOptimizerResult {
return analysisSession.importOptimizer.analyseImports(file)
}
}
public class KtImportOptimizerResult(
public val unusedImports: Set<KtImportDirective>,
)
@@ -0,0 +1,22 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
public abstract class KtInheritorsProvider : KtAnalysisSessionComponent() {
public abstract fun getInheritorsOfSealedClass(classSymbol: KtNamedClassOrObjectSymbol): List<KtNamedClassOrObjectSymbol>
public abstract fun getEnumEntries(classSymbol: KtNamedClassOrObjectSymbol): List<KtEnumEntrySymbol>
}
public interface KtInheritorsProviderMixIn : KtAnalysisSessionMixIn {
public fun KtNamedClassOrObjectSymbol.getSealedClassInheritors(): List<KtNamedClassOrObjectSymbol> =
analysisSession.inheritorsProvider.getInheritorsOfSealedClass(this)
public fun KtNamedClassOrObjectSymbol.getEnumEntries(): List<KtEnumEntrySymbol> =
analysisSession.inheritorsProvider.getEnumEntries(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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.org.objectweb.asm.Type
public abstract class KtJvmTypeMapper : KtAnalysisSessionComponent() {
public abstract fun mapTypeToJvmType(type: KtType, mode: TypeMappingMode): Type
}
public interface KtJvmTypeMapperMixIn : KtAnalysisSessionMixIn {
/**
* Create ASM JVM type by corresponding KtType
*
* @see TypeMappingMode
*/
public fun KtType.mapTypeToJvmType(mode: TypeMappingMode = TypeMappingMode.DEFAULT): Type =
analysisSession.jvmTypeMapper.mapTypeToJvmType(this, mode)
}
@@ -0,0 +1,64 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.util.ImplementationStatus
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
public abstract class KtOverrideInfoProvider : KtAnalysisSessionComponent() {
public abstract fun isVisible(memberSymbol: KtCallableSymbol, classSymbol: KtClassOrObjectSymbol): Boolean
public abstract fun getImplementationStatus(
memberSymbol: KtCallableSymbol,
parentClassSymbol: KtClassOrObjectSymbol
): ImplementationStatus?
public abstract fun getOriginalOverriddenSymbol(symbol: KtCallableSymbol): KtCallableSymbol?
public abstract fun getOriginalContainingClassForOverride(symbol: KtCallableSymbol): KtClassOrObjectSymbol?
}
public interface KtMemberSymbolProviderMixin : KtAnalysisSessionMixIn {
/** Checks if the given symbol (possibly a symbol inherited from a super class) is visible in the given class. */
public fun KtCallableSymbol.isVisibleInClass(classSymbol: KtClassOrObjectSymbol): Boolean =
analysisSession.overrideInfoProvider.isVisible(this, classSymbol)
/**
* Gets the [ImplementationStatus] of the [this] member symbol in the given [parentClassSymbol]. Or null if this symbol is not a
* member.
*/
public fun KtCallableSymbol.getImplementationStatus(parentClassSymbol: KtClassOrObjectSymbol): ImplementationStatus? =
analysisSession.overrideInfoProvider.getImplementationStatus(this, parentClassSymbol)
/**
* Gets the original symbol for the given callable symbol. In a class scope, a symbol may be derived from symbols declared in super
* classes. For example, consider
*
* ```
* public interface A<T> {
* public fun foo(t:T)
* }
*
* public interface B: A<String> {
* }
* ```
*
* In the class scope of `B`, there is a callable symbol `foo` that takes a `String`. This symbol is derived from the original symbol
* in `A` that takes the type parameter `T`. Given such a derived symbol, [originalOverriddenSymbol] recovers the original declared
* symbol.
*
* Such situation can also happens for intersection symbols (in case of multiple super types containing symbols with identical signature
* after specialization) and delegation.
*/
public val KtCallableSymbol.originalOverriddenSymbol: KtCallableSymbol?
get() = analysisSession.overrideInfoProvider.getOriginalOverriddenSymbol(this)
/**
* Gets the class symbol where the given callable symbol is declared. See [originalOverriddenSymbol] for more details.
*/
public val KtCallableSymbol.originalContainingClassForOverride: KtClassOrObjectSymbol?
get() = analysisSession.overrideInfoProvider.getOriginalContainingClassForOverride(this)
}
@@ -0,0 +1,31 @@
/*
* 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.analysis.api.components
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
public abstract class KtPsiTypeProvider : KtAnalysisSessionComponent() {
public abstract fun asPsiType(type: KtType, context: PsiElement, mode: TypeMappingMode): PsiType?
}
public interface KtPsiTypeProviderMixIn : KtAnalysisSessionMixIn {
/**
* Converts the given [KtType] to [PsiType].
*
* Returns `null` if the conversion encounters any erroneous cases, e.g., errors in type arguments.
* A client can handle such case in its own way. For instance,
* * UAST will return `UastErrorType` as a default error type.
* * LC will return `NonExistentClass` from the [context].
*/
public fun KtType.asPsiType(
context: PsiElement,
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
): PsiType? =
analysisSession.psiTypeProvider.asPsiType(this, context, mode)
}
@@ -0,0 +1,22 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.KtSymbolBasedReference
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.references.KtReference
public interface KtReferenceResolveMixIn : KtAnalysisSessionMixIn {
public fun KtReference.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference" }
return analysisSession.resolveToSymbols()
}
public fun KtReference.resolveToSymbol(): KtSymbol? {
check(this is KtSymbolBasedReference) { "To get reference symbol the one should be KtSymbolBasedReference but was ${this::class}" }
return resolveToSymbols().singleOrNull()
}
}
@@ -0,0 +1,82 @@
/*
* 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.analysis.api.components
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
public enum class ShortenOption {
/** Skip shortening references to this symbol. */
DO_NOT_SHORTEN,
/** Only shorten references to this symbol if it's already imported in the file. Otherwise, leave it as it is. */
SHORTEN_IF_ALREADY_IMPORTED,
/** Shorten references to this symbol and import it into the file. */
SHORTEN_AND_IMPORT,
/** Shorten references to this symbol and import this symbol and all its sibling symbols with star import on the parent. */
SHORTEN_AND_STAR_IMPORT
}
public abstract class KtReferenceShortener : KtAnalysisSessionComponent() {
public abstract fun collectShortenings(
file: KtFile,
selection: TextRange,
classShortenOption: (KtClassLikeSymbol) -> ShortenOption,
callableShortenOption: (KtCallableSymbol) -> ShortenOption
): ShortenCommand
}
public interface KtReferenceShortenerMixIn : KtAnalysisSessionMixIn {
public companion object {
private val defaultClassShortenOption: (KtClassLikeSymbol) -> ShortenOption = {
if (it.classIdIfNonLocal?.isNestedClass == true) {
ShortenOption.SHORTEN_IF_ALREADY_IMPORTED
} else {
ShortenOption.SHORTEN_AND_IMPORT
}
}
private val defaultCallableShortenOption: (KtCallableSymbol) -> ShortenOption = { symbol ->
if (symbol is KtEnumEntrySymbol) ShortenOption.DO_NOT_SHORTEN
else ShortenOption.SHORTEN_AND_IMPORT
}
}
/**
* Collects possible references to shorten. By default, it shortens a fully-qualified members to the outermost class and does not
* shorten enum entries.
*/
public fun collectPossibleReferenceShortenings(
file: KtFile,
selection: TextRange = file.textRange,
classShortenOption: (KtClassLikeSymbol) -> ShortenOption = defaultClassShortenOption,
callableShortenOption: (KtCallableSymbol) -> ShortenOption = defaultCallableShortenOption
): ShortenCommand =
analysisSession.referenceShortener.collectShortenings(file, selection, classShortenOption, callableShortenOption)
public fun collectPossibleReferenceShorteningsInElement(
element: KtElement,
classShortenOption: (KtClassLikeSymbol) -> ShortenOption = defaultClassShortenOption,
callableShortenOption: (KtCallableSymbol) -> ShortenOption = defaultCallableShortenOption
): ShortenCommand =
analysisSession.referenceShortener.collectShortenings(
element.containingKtFile,
element.textRange,
classShortenOption,
callableShortenOption
)
}
public interface ShortenCommand {
public fun invokeShortening()
public val isEmpty: Boolean
}
@@ -0,0 +1,22 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSamConstructorSymbol
import org.jetbrains.kotlin.name.ClassId
public abstract class KtSamResolver : KtAnalysisSessionComponent() {
public abstract fun getSamConstructor(ktClassLikeSymbol: KtClassLikeSymbol): KtSamConstructorSymbol?
}
public interface KtSamResolverMixIn : KtAnalysisSessionMixIn {
/**
* Returns [KtSamConstructorSymbol] if the given [KtClassLikeSymbol] is a functional interface type, a.k.a. SAM.
*/
public fun KtClassLikeSymbol.getSamConstructor(): KtSamConstructorSymbol? =
analysisSession.samResolver.getSamConstructor(this)
}
@@ -0,0 +1,72 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.scopes.*
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithDeclarations
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
public abstract class KtScopeProvider : KtAnalysisSessionComponent() {
public abstract fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope
public abstract fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope
public abstract fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope
public abstract fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations>
public abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope
public abstract fun getCompositeScope(subScopes: List<KtScope>): KtCompositeScope
public abstract fun getTypeScope(type: KtType): KtScope?
public abstract fun getScopeContextForPosition(
originalFile: KtFile,
positionInFakeFile: KtElement
): KtScopeContext
}
public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
public fun KtSymbolWithMembers.getMemberScope(): KtMemberScope =
analysisSession.scopeProvider.getMemberScope(this)
public fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope =
analysisSession.scopeProvider.getDeclaredMemberScope(this)
public fun KtSymbolWithMembers.getStaticMemberScope(): KtScope =
analysisSession.scopeProvider.getStaticMemberScope(this)
public fun KtFileSymbol.getFileScope(): KtDeclarationScope<KtSymbolWithDeclarations> =
analysisSession.scopeProvider.getFileScope(this)
public fun KtPackageSymbol.getPackageScope(): KtPackageScope =
analysisSession.scopeProvider.getPackageScope(this)
public fun List<KtScope>.asCompositeScope(): KtCompositeScope =
analysisSession.scopeProvider.getCompositeScope(this)
public fun KtType.getTypeScope(): KtScope? =
analysisSession.scopeProvider.getTypeScope(this)
public fun KtFile.getScopeContextForPosition(positionInFakeFile: KtElement): KtScopeContext =
analysisSession.scopeProvider.getScopeContextForPosition(this, positionInFakeFile)
public fun KtFile.getScopeContextForFile(): KtScopeContext =
analysisSession.scopeProvider.getScopeContextForPosition(this, this)
}
public data class KtScopeContext(val scopes: KtCompositeScope, val implicitReceivers: List<KtImplicitReceiver>)
public class KtImplicitReceiver(
override val token: ValidityToken,
public val type: KtType,
public val ownerSymbol: KtSymbol
) : ValidityTokenOwner
@@ -0,0 +1,23 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.ImplicitReceiverSmartCast
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.psi.KtExpression
public abstract class KtSmartCastProvider : KtAnalysisSessionComponent() {
public abstract fun getSmartCastedToType(expression: KtExpression): KtType?
public abstract fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast>
}
public interface KtSmartCastProviderMixIn : KtAnalysisSessionMixIn {
public fun KtExpression.getSmartCast(): KtType? =
analysisSession.smartCastProvider.getSmartCastedToType(this)
public fun KtExpression.getImplicitReceiverSmartCast(): Collection<ImplicitReceiverSmartCast> =
analysisSession.smartCastProvider.getImplicitReceiverSmartCast(this)
}
@@ -0,0 +1,24 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.types.KtType
public abstract class KtSubtypingComponent : KtAnalysisSessionComponent() {
public abstract fun isEqualTo(first: KtType, second: KtType): Boolean
public abstract fun isSubTypeOf(subType: KtType, superType: KtType): Boolean
}
public interface KtSubtypingComponentMixIn : KtAnalysisSessionMixIn {
infix public fun KtType.isEqualTo(other: KtType): Boolean =
analysisSession.subtypingComponent.isEqualTo(this, other)
infix public fun KtType.isSubTypeOf(superType: KtType): Boolean =
analysisSession.subtypingComponent.isSubTypeOf(this, superType)
infix public fun KtType.isNotSubTypeOf(superType: KtType): Boolean =
!analysisSession.subtypingComponent.isSubTypeOf(this, superType)
}
@@ -0,0 +1,23 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
public abstract class KtSymbolContainingDeclarationProvider : KtAnalysisSessionComponent() {
public abstract fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind?
}
public interface KtSymbolContainingDeclarationProviderMixIn : KtAnalysisSessionMixIn {
/**
* Returns containing declaration for symbol:
* for top-level declarations returns null
* for class members returns containing class
* for local declaration returns declaration it was declared it
*/
public fun KtSymbolWithKind.getContainingSymbol(): KtSymbolWithKind? =
analysisSession.containingDeclarationProvider.getContainingDeclaration(this)
}
@@ -0,0 +1,55 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
public abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() {
public abstract fun <T : KtSymbol> getAllOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol>
public abstract fun <T : KtSymbol> getDirectlyOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol>
public abstract fun isSubClassOf(subClass: KtClassOrObjectSymbol, superClass: KtClassOrObjectSymbol): Boolean
public abstract fun isDirectSubClassOf(subClass: KtClassOrObjectSymbol, superClass: KtClassOrObjectSymbol): Boolean
public abstract fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol>
}
public 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.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getDirectlyOverriddenSymbols
*/
public 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 overridden `B.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
*
* @see getAllOverriddenSymbols
*/
public fun KtCallableSymbol.getDirectlyOverriddenSymbols(): List<KtCallableSymbol> =
analysisSession.symbolDeclarationOverridesProvider.getDirectlyOverriddenSymbols(this)
public fun KtClassOrObjectSymbol.isSubClassOf(superClass: KtClassOrObjectSymbol): Boolean =
analysisSession.symbolDeclarationOverridesProvider.isSubClassOf(this, superClass)
public fun KtClassOrObjectSymbol.isDirectSubClassOf(superClass: KtClassOrObjectSymbol): Boolean =
analysisSession.symbolDeclarationOverridesProvider.isDirectSubClassOf(this, superClass)
public fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> =
analysisSession.symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this)
}
@@ -0,0 +1,136 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
/**
* KtType to string renderer options
* @see KtType
* @see KtSymbolDeclarationRendererProvider.render
*/
public data class KtTypeRendererOptions(
/**
* Render type name without package name for not local types
*/
public val shortQualifiedNames: Boolean = false,
/**
* Render public function types public functionN using Kotlin public function type syntax
* @see public function
* @sample public function0<Int> returns () -> Int
*/
public val renderFunctionType: Boolean = true,
/**
* When met type with unresolved qualifier, render it as it is resolved
* When `true` will render as `UnresolvedQualifier`
* When `false` will render as "ERROR_TYPE <symbol not found for UnresolvedQualifier>"
*/
public val renderUnresolvedTypeAsResolved: Boolean = true
) {
public companion object {
public val DEFAULT: KtTypeRendererOptions = KtTypeRendererOptions()
public val SHORT_NAMES: KtTypeRendererOptions = DEFAULT.copy(shortQualifiedNames = true)
}
}
/**
* KtSymbol to string renderer options
* @see KtSymbol
* @see KtSymbolDeclarationRendererProvider.render
*/
public data class KtDeclarationRendererOptions(
/**
* Set of modifiers that needed to be rendered
* @see RendererModifier
*/
val modifiers: Set<RendererModifier> = RendererModifier.ALL,
/**
* Type render options @see KtTypeRendererOptions
* @see KtTypeRendererOptions
*/
val typeRendererOptions: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT,
/**
* Render Unit return type for public functions
*/
val renderUnitReturnType: Boolean = false,
/**
* Normalize java-specific visibilities for java declaration
*/
val normalizedVisibilities: Boolean = false,
/**
* Render containing declarations
*/
val renderContainingDeclarations: Boolean = false,
/**
* Approximate Kotlin not-denotable types into denotable for declarations return type
*/
val approximateTypes: Boolean = false,
/**
* Declaration header is something like `public abstract class`, `public fun`, or `private public interface ` in a declaration.
*/
val renderDeclarationHeader: Boolean = true,
/**
* Whether to forcefully add `override` modifier when rendering public functions or properties. Note that the [modifiers] option still
* controls whether `override` is rendered. That is, if [modifiers] don't contain `override`, then this flag does not have any effect.
*/
val forceRenderingOverrideModifier: Boolean = false,
val renderDefaultParameterValue: Boolean = true,
) {
public companion object {
public val DEFAULT: KtDeclarationRendererOptions = KtDeclarationRendererOptions()
}
}
public enum class RendererModifier(public val includeByDefault: Boolean) {
VISIBILITY(true),
MODALITY(true),
OVERRIDE(true),
ANNOTATIONS(false),
INNER(true),
DATA(true),
INLINE(true),
EXPECT(true),
ACTUAL(true),
CONST(true),
LATEINIT(true),
FUN(true),
VALUE(true),
OPERATOR(true)
;
public companion object {
public val ALL: Set<RendererModifier> = values().toSet()
public val DEFAULT: Set<RendererModifier> = values().filterTo(mutableSetOf()) { it.includeByDefault }
public val NONE: Set<RendererModifier> = emptySet()
}
}
public abstract class KtSymbolDeclarationRendererProvider : KtAnalysisSessionComponent() {
public abstract fun render(symbol: KtSymbol, options: KtDeclarationRendererOptions): String
public abstract fun render(type: KtType, options: KtTypeRendererOptions): String
}
/**
* Provides services for rendering Symbols and Types into the Kotlin strings
*/
public interface KtSymbolDeclarationRendererMixIn : KtAnalysisSessionMixIn {
/**
* Render symbol into the representable Kotlin string
*/
public fun KtSymbol.render(options: KtDeclarationRendererOptions = KtDeclarationRendererOptions.DEFAULT): String =
analysisSession.symbolDeclarationRendererProvider.render(this, options)
/**
* Render kotlin type into the representable Kotlin type string
*/
public fun KtType.render(options: KtTypeRendererOptions = KtTypeRendererOptions.DEFAULT): String =
analysisSession.symbolDeclarationRendererProvider.render(this, options)
}
@@ -0,0 +1,51 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.Name
public abstract class KtSymbolInfoProvider : KtAnalysisSessionComponent() {
public abstract fun getDeprecation(symbol: KtSymbol): DeprecationInfo?
public abstract fun getDeprecation(symbol: KtSymbol, annotationUseSiteTarget: AnnotationUseSiteTarget?): DeprecationInfo?
public abstract fun getGetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo?
public abstract fun getSetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo?
public abstract fun getJavaGetterName(symbol: KtPropertySymbol): Name
public abstract fun getJavaSetterName(symbol: KtPropertySymbol): Name?
}
public interface KtSymbolInfoProviderMixIn : KtAnalysisSessionMixIn {
/**
* Gets the deprecation status of the given symbol. Returns null if the symbol it not deprecated.
*/
public val KtSymbol.deprecationStatus: DeprecationInfo? get() = analysisSession.symbolInfoProvider.getDeprecation(this)
/**
* Gets the deprecation status of the given symbol. Returns null if the symbol it not deprecated.
*/
public fun KtSymbol.getDeprecationStatus(annotationUseSiteTarget: AnnotationUseSiteTarget?): DeprecationInfo? =
analysisSession.symbolInfoProvider.getDeprecation(this)
/**
* Gets the deprecation status of the getter of this property symbol. Returns null if the getter it not deprecated.
*/
public val KtPropertySymbol.getterDeprecationStatus: DeprecationInfo?
get() = analysisSession.symbolInfoProvider.getGetterDeprecation(this)
/**
* Gets the deprecation status of the setter of this property symbol. Returns null if the setter it not deprecated or the property does
* not have a setter.
*/
public val KtPropertySymbol.setterDeprecationStatus: DeprecationInfo?
get() = analysisSession.symbolInfoProvider.getSetterDeprecation(this)
public val KtPropertySymbol.javaGetterName: Name get() = analysisSession.symbolInfoProvider.getJavaGetterName(this)
public val KtPropertySymbol.javaSetterName: Name? get() = analysisSession.symbolInfoProvider.getJavaSetterName(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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
public interface KtSymbolsMixIn : KtAnalysisSessionMixIn {
@Suppress("DEPRECATION")
public fun <S : KtSymbol> KtSymbolPointer<S>.restoreSymbol(): S? = restoreSymbol(analysisSession)
}
@@ -0,0 +1,57 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.Variance
public abstract class KtTypeCreator : KtAnalysisSessionComponent() {
public abstract fun buildClassType(builder: KtClassTypeBuilder): KtClassType
}
public interface KtTypeCreatorMixIn : KtAnalysisSessionMixIn
public inline fun KtTypeCreatorMixIn.buildClassType(
classId: ClassId,
build: KtClassTypeBuilder.() -> Unit = {}
): KtClassType =
analysisSession.typesCreator.buildClassType(KtClassTypeBuilder.ByClassId(classId).apply(build))
public inline fun KtTypeCreatorMixIn.buildClassType(
symbol: KtClassOrObjectSymbol,
build: KtClassTypeBuilder.() -> Unit = {}
): KtClassType =
analysisSession.typesCreator.buildClassType(KtClassTypeBuilder.BySymbol(symbol).apply(build))
public sealed class KtTypeBuilder
public sealed class KtClassTypeBuilder : KtTypeBuilder() {
private val _arguments = mutableListOf<KtTypeArgument>()
public var nullability: KtTypeNullability = KtTypeNullability.NON_NULLABLE
public val arguments: List<KtTypeArgument> get() = _arguments
public fun argument(argument: KtTypeArgument) {
_arguments += argument
}
public fun argument(type: KtType, variance: Variance = Variance.INVARIANT) {
_arguments += KtTypeArgumentWithVariance(type, variance, type.token)
}
public class ByClassId(public val classId: ClassId) : KtClassTypeBuilder()
public class BySymbol(public val symbol: KtClassOrObjectSymbol) : KtClassTypeBuilder()
}
@@ -0,0 +1,112 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.name.ClassId
public abstract class KtTypeInfoProvider : KtAnalysisSessionComponent() {
public abstract fun isFunctionalInterfaceType(type: KtType): Boolean
public abstract fun canBeNull(type: KtType): Boolean
}
public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn {
/**
* Returns true if this type is a functional interface type, a.k.a. SAM type, e.g., Runnable.
*/
public val KtType.isFunctionalInterfaceType: Boolean
get() = analysisSession.typeInfoProvider.isFunctionalInterfaceType(this)
/**
* Returns true if a public value of this type can potentially be null. This means this type is not a subtype of [Any]. However, it does not
* mean one can assign `null` to a variable of this type because it may be unknown if this type can accept `null`. For example, a public value
* of type `T:Any?` can potentially be null. But one can not assign `null` to such a variable because the instantiated type may not be
* nullable.
*/
public val KtType.canBeNull: Boolean get() = analysisSession.typeInfoProvider.canBeNull(this)
/** Returns true if the type is explicitly marked as nullable. This means it's safe to assign `null` to a variable with this type. */
public val KtType.isMarkedNullable: Boolean get() = this.nullability == KtTypeNullability.NULLABLE
public val KtType.isUnit: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.UNIT)
public val KtType.isInt: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.INT)
public val KtType.isLong: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.LONG)
public val KtType.isShort: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.SHORT)
public val KtType.isByte: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.BYTE)
public val KtType.isFloat: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.FLOAT)
public val KtType.isDouble: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.DOUBLE)
public val KtType.isChar: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.CHAR)
public val KtType.isBoolean: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.BOOLEAN)
public val KtType.isString: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.STRING)
public val KtType.isCharSequence: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.CHAR_SEQUENCE)
public val KtType.isAny: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.ANY)
public val KtType.isNothing: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.NOTHING)
public val KtType.isUInt: Boolean get() = isClassTypeWithClassId(StandardNames.FqNames.uInt)
public val KtType.isULong: Boolean get() = isClassTypeWithClassId(StandardNames.FqNames.uLong)
public val KtType.isUShort: Boolean get() = isClassTypeWithClassId(StandardNames.FqNames.uShort)
public val KtType.isUByte: Boolean get() = isClassTypeWithClassId(StandardNames.FqNames.uByte)
/** Gets the class symbol backing the given type, if available. */
public val KtType.expandedClassSymbol: KtClassOrObjectSymbol?
get() {
return when (this) {
is KtNonErrorClassType -> when (val classSymbol = classSymbol) {
is KtClassOrObjectSymbol -> classSymbol
is KtTypeAliasSymbol -> classSymbol.expandedType.expandedClassSymbol
}
else -> null
}
}
public fun KtType.isClassTypeWithClassId(classId: ClassId): Boolean {
if (this !is KtNonErrorClassType) return false
return this.classId == classId
}
public val KtType.isPrimitive: Boolean
get() {
if (this !is KtNonErrorClassType) return false
return this.classId in DefaultTypeClassIds.PRIMITIVES
}
public val KtType.defaultInitializer: String?
get() = when {
isMarkedNullable -> "null"
isInt || isLong || isShort || isByte -> "0"
isFloat -> "0.0f"
isDouble -> "0.0"
isChar -> "'\\u0000'"
isBoolean -> "false"
isUnit -> "Unit"
isString -> "\"\""
isUInt -> "0.toUInt()"
isULong -> "0.toULong()"
isUShort -> "0.toUShort()"
isUByte -> "0.toUByte()"
else -> null
}
}
public object DefaultTypeClassIds {
public val UNIT: ClassId = ClassId.topLevel(StandardNames.FqNames.unit.toSafe())
public val INT: ClassId = ClassId.topLevel(StandardNames.FqNames._int.toSafe())
public val LONG: ClassId = ClassId.topLevel(StandardNames.FqNames._long.toSafe())
public val SHORT: ClassId = ClassId.topLevel(StandardNames.FqNames._short.toSafe())
public val BYTE: ClassId = ClassId.topLevel(StandardNames.FqNames._byte.toSafe())
public val FLOAT: ClassId = ClassId.topLevel(StandardNames.FqNames._float.toSafe())
public val DOUBLE: ClassId = ClassId.topLevel(StandardNames.FqNames._double.toSafe())
public val CHAR: ClassId = ClassId.topLevel(StandardNames.FqNames._char.toSafe())
public val BOOLEAN: ClassId = ClassId.topLevel(StandardNames.FqNames._boolean.toSafe())
public val STRING: ClassId = ClassId.topLevel(StandardNames.FqNames.string.toSafe())
public val CHAR_SEQUENCE: ClassId = ClassId.topLevel(StandardNames.FqNames.charSequence.toSafe())
public val ANY: ClassId = ClassId.topLevel(StandardNames.FqNames.any.toSafe())
public val NOTHING: ClassId = ClassId.topLevel(StandardNames.FqNames.nothing.toSafe())
public val PRIMITIVES: Set<ClassId> = setOf(INT, LONG, SHORT, BYTE, FLOAT, DOUBLE, CHAR, BOOLEAN)
}
@@ -0,0 +1,101 @@
/*
* 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.analysis.api.components
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.types.KtFlexibleType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.psi.KtDoubleColonExpression
import org.jetbrains.kotlin.psi.KtTypeReference
public abstract class KtTypeProvider : KtAnalysisSessionComponent() {
public abstract val builtinTypes: KtBuiltinTypes
public abstract fun approximateToSuperPublicDenotableType(type: KtType): KtType?
public abstract fun buildSelfClassType(symbol: KtNamedClassOrObjectSymbol): KtType
public abstract fun commonSuperType(types: Collection<KtType>): KtType?
public abstract fun getKtType(ktTypeReference: KtTypeReference): KtType
public abstract fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType?
public abstract fun withNullability(type: KtType, newNullability: KtTypeNullability): KtType
}
public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
public 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.analysis.api.types.KtDenotableType]`
*/
public fun KtType.approximateToSuperPublicDenotable(): KtType? =
analysisSession.typeProvider.approximateToSuperPublicDenotableType(this)
public fun KtType.approximateToSuperPublicDenotableOrSelf(): KtType = approximateToSuperPublicDenotable() ?: this
public fun KtNamedClassOrObjectSymbol.buildSelfClassType(): KtType =
analysisSession.typeProvider.buildSelfClassType(this)
/**
* Computes the common super type of the given collection of [KtType].
*
* If the collection is empty, it returns `null`.
*/
public fun commonSuperType(types: Collection<KtType>): KtType? =
analysisSession.typeProvider.commonSuperType(types)
/**
* Resolve [KtTypeReference] and return corresponding [KtType] if resolved.
*
* This may raise an exception if the resolution ends up with an unexpected kind.
*/
public fun KtTypeReference.getKtType(): KtType =
analysisSession.typeProvider.getKtType(this)
/**
* Resolve [KtDoubleColonExpression] and return [KtType] of its receiver.
*
* Return `null` if the resolution fails or the resolved callable reference is not a reflection type.
*/
public fun KtDoubleColonExpression.getReceiverKtType(): KtType? =
analysisSession.typeProvider.getReceiverTypeForDoubleColonExpression(this)
public fun KtType.withNullability(newNullability: KtTypeNullability): KtType =
analysisSession.typeProvider.withNullability(this, newNullability)
public fun KtType.upperBoundIfFlexible(): KtType = (this as? KtFlexibleType)?.upperBound ?: this
public fun KtType.lowerBoundIfFlexible(): KtType = (this as? KtFlexibleType)?.lowerBound ?: this
}
@Suppress("PropertyName")
public abstract class KtBuiltinTypes : ValidityTokenOwner {
public abstract val INT: KtType
public abstract val LONG: KtType
public abstract val SHORT: KtType
public abstract val BYTE: KtType
public abstract val FLOAT: KtType
public abstract val DOUBLE: KtType
public abstract val BOOLEAN: KtType
public abstract val CHAR: KtType
public abstract val STRING: KtType
public abstract val UNIT: KtType
public abstract val NOTHING: KtType
public abstract val ANY: KtType
public abstract val NULLABLE_ANY: KtType
public abstract val NULLABLE_NOTHING: KtType
}
@@ -0,0 +1,30 @@
/*
* 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.analysis.api.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.psi.KtExpression
public abstract class KtVisibilityChecker : KtAnalysisSessionComponent() {
public abstract fun isVisible(
candidateSymbol: KtSymbolWithVisibility,
useSiteFile: KtFileSymbol,
position: PsiElement,
receiverExpression: KtExpression?
): Boolean
}
public interface KtVisibilityCheckerMixIn : KtAnalysisSessionMixIn {
public fun isVisible(
candidateSymbol: KtSymbolWithVisibility,
useSiteFile: KtFileSymbol,
receiverExpression: KtExpression? = null,
position: PsiElement
): Boolean =
analysisSession.visibilityChecker.isVisible(candidateSymbol, useSiteFile, position, receiverExpression)
}
@@ -0,0 +1,37 @@
/*
* 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.analysis.api.diagnostics
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import kotlin.reflect.KClass
public interface KtDiagnostic : ValidityTokenOwner {
public val severity: Severity
public val factoryName: String?
public val defaultMessage: String
}
public interface KtDiagnosticWithPsi<out PSI : PsiElement> : KtDiagnostic {
public val psi: PSI
public val textRanges: Collection<TextRange>
public val diagnosticClass: KClass<out KtDiagnosticWithPsi<PSI>>
}
public class KtNonBoundToPsiErrorDiagnostic(
override val factoryName: String?,
override val defaultMessage: String,
override val token: ValidityToken,
) : KtDiagnostic {
override val severity: Severity get() = Severity.ERROR
}
public fun KtDiagnostic.getDefaultMessageWithFactoryName(): String =
if (factoryName == null) defaultMessage
else "[$factoryName] $defaultMessage"
@@ -0,0 +1,42 @@
/*
* 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.analysis.api.scopes
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
public interface KtImportingScope : KtScope {
public val imports: List<Import>
public val isDefaultImportingScope: Boolean
}
public interface KtStarImportingScope : KtImportingScope {
override val imports: List<StarImport>
}
public interface KtNonStarImportingScope : KtImportingScope {
override val imports: List<NonStarImport>
}
public sealed class Import {
public abstract val packageFqName: FqName
public abstract val relativeClassName: FqName?
public abstract val resolvedClassId: ClassId?
}
public class NonStarImport(
public override val packageFqName: FqName,
override val relativeClassName: FqName?,
override val resolvedClassId: ClassId?,
public val callableName: Name?,
) : Import()
public class StarImport(
override val packageFqName: FqName,
override val relativeClassName: FqName?,
override val resolvedClassId: ClassId?,
) : Import()
@@ -0,0 +1,103 @@
/*
* 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.analysis.api.scopes
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithDeclarations
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
public interface KtScope : ValidityTokenOwner {
/**
* Returns a **subset** of names which current scope may contain.
* In other words `ALL_NAMES(scope)` is a subset of `scope.getAllNames()`
*/
public fun getAllPossibleNames(): Set<Name> = withValidityAssertion {
getPossibleCallableNames() + getPossibleClassifierNames()
}
/**
* Returns a **subset** of callable names which current scope may contain.
* In other words `ALL_CALLABLE_NAMES(scope)` is a subset of `scope.getCallableNames()`
*/
public fun getPossibleCallableNames(): Set<Name>
/**
* Returns a **subset** of classifier names which current scope may contain.
* In other words `ALL_CLASSIFIER_NAMES(scope)` is a subset of `scope.getClassifierNames()`
*/
public fun getPossibleClassifierNames(): Set<Name>
/**
* Return a sequence of all [KtSymbol] which current scope contain
*/
public fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
sequence {
yieldAll(getCallableSymbols())
yieldAll(getClassifierSymbols())
yieldAll(getConstructors())
}
}
/**
* Return a sequence of [KtCallableSymbol] which current scope contain if declaration name matches [nameFilter]
*/
public fun getCallableSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtCallableSymbol>
/**
* Return a sequence of [KtClassifierSymbol] which current scope contain if declaration name matches [nameFilter]
*/
public fun getClassifierSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtClassifierSymbol>
/**
* Return a sequence of [KtConstructorSymbol] which current scope contain
*/
public fun getConstructors(): Sequence<KtConstructorSymbol>
/**
* return true if the scope may contain name, false otherwise.
*
* In other words `(mayContainName(name) == false) => (name !in scope)`; vice versa is not always true
*/
public fun mayContainName(name: Name): Boolean = withValidityAssertion {
name in getPossibleCallableNames() || name in getPossibleClassifierNames()
}
}
public typealias KtScopeNameFilter = (Name) -> Boolean
public interface KtCompositeScope : KtScope {
public val subScopes: List<KtScope>
}
public interface KtMemberScope : KtDeclarationScope<KtSymbolWithMembers> {
override val owner: KtSymbolWithMembers
}
public interface KtDeclaredMemberScope : KtDeclarationScope<KtSymbolWithMembers> {
override val owner: KtSymbolWithMembers
}
public interface KtDeclarationScope<out T : KtSymbolWithDeclarations> : KtScope {
public val owner: T
}
public interface KtPackageScope : KtScope {
public val fqName: FqName
public fun getPackageSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtPackageSymbol>
override fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
super.getAllSymbols() + getPackageSymbols()
}
override fun getConstructors(): Sequence<KtConstructorSymbol> = withValidityAssertion { emptySequence() }
}
@@ -0,0 +1,113 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.components.KtSymbolInfoProviderMixIn
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.lang.reflect.InvocationTargetException
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty2
import kotlin.reflect.full.declaredMemberExtensionProperties
import kotlin.reflect.jvm.javaGetter
public object DebugSymbolRenderer {
private fun StringBuilder.appendLine(indent: Int, line: String) {
appendLine(line.prependIndent(" ".repeat(indent)))
}
private fun StringBuilder.append(indent: Int, value: String) {
append(value.prependIndent(" ".repeat(indent)))
}
public fun render(symbol: KtSymbol): String = buildString {
renderImpl(symbol)
}
public fun KtAnalysisSession.renderExtra(symbol: KtSymbol): String = buildString {
renderImpl(symbol)
KtSymbolInfoProviderMixIn::class.declaredMemberExtensionProperties.forEach { prop ->
val symbolClass = prop.parameters[1].type.classifier as? KClass<*> ?: return@forEach
if (symbolClass.isInstance(symbol)) {
@Suppress("UNCHECKED_CAST")
val value = (prop as KProperty2<KtSymbolInfoProviderMixIn, KtSymbol, Any?>).invoke(this@renderExtra, symbol)
val stringValue = renderValue(value)
appendLine(INDENT, "${prop.name}: $stringValue")
}
}
}
private fun StringBuilder.renderImpl(symbol: KtSymbol) {
val klass = symbol::class
appendLine("${klass.simpleName}:")
klass.members.filterIsInstance<KProperty<*>>().sortedBy { it.name }.forEach { property ->
if (property.name in ignoredPropertyNames) return@forEach
val getter = property.javaGetter ?: return@forEach
val value = try {
getter.invoke(symbol)
} catch (e: InvocationTargetException) {
"Could not render due to ${e.cause}"
}
val stringValue = renderValue(value)
appendLine(INDENT, "${property.name}: $stringValue")
}
}
private fun renderValue(value: Any?): String = when (value) {
null -> "null"
is String -> value
is Boolean -> value.toString()
is Long -> value.toString()
is Name -> value.asString()
is FqName -> value.asString()
is ClassId -> value.asString()
is CallableId -> value.toString()
is Enum<*> -> value.name
is List<*> -> if (value.isEmpty()) "[]" else buildString {
appendLine("[")
value.forEach {
appendLine(INDENT, renderValue(it))
}
append("]")
}
is KtType -> value.asStringForDebugging()
is KtSymbol -> {
val symbolTag = when (value) {
is KtClassLikeSymbol -> renderValue(value.classIdIfNonLocal ?: "<local>/${value.name}")
is KtFunctionSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
is KtSamConstructorSymbol -> renderValue(value.callableIdIfNonLocal ?: "<local>/${value.name}")
is KtConstructorSymbol -> "<constructor>"
is KtNamedSymbol -> renderValue(value.name)
is KtPropertyGetterSymbol -> "<getter>"
is KtPropertySetterSymbol -> "<setter>"
else -> TODO(value::class.toString())
}
"${value::class.simpleName!!}($symbolTag)"
}
is KtSimpleConstantValue<*> -> renderValue(value.value)
is KtNamedConstantValue -> "${renderValue(value.name)} = ${renderValue(value.expression)}"
is KtAnnotationCall -> buildString {
append(renderValue(value.classId))
appendLine(value.arguments.joinToString(prefix = "(", postfix = ")") { renderValue(it) })
// TODO: perhaps we want to render `psi` for all other cases as well.
append(INDENT, "psi: ${renderValue(value.psi)}")
}
is KtTypeAndAnnotations -> "${renderValue(value.annotations)} ${renderValue(value.type)}"
is DeprecationInfo -> value.toString()
else -> value::class.simpleName!!
}
private val ignoredPropertyNames = setOf("firRef", "psi", "token", "builder")
private const val INDENT = 2
}
@@ -0,0 +1,21 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtTypeAndAnnotations
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.CallableId
public abstract class KtCallableSymbol : KtSymbol, KtSymbolWithKind {
public abstract val callableIdIfNonLocal: CallableId?
public abstract val annotatedType: KtTypeAndAnnotations
public abstract val receiverType: KtTypeAndAnnotations?
public abstract val isExtension: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtCallableSymbol>
}
@@ -0,0 +1,98 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.Variance
public sealed class KtClassifierSymbol : KtSymbol, KtPossiblyNamedSymbol
public val KtClassifierSymbol.nameOrAnonymous: Name
get() = name ?: SpecialNames.ANONYMOUS
public abstract class KtTypeParameterSymbol : KtClassifierSymbol(), KtNamedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol>
public abstract val upperBounds: List<KtType>
public abstract val variance: Variance
public abstract val isReified: Boolean
}
public sealed class KtClassLikeSymbol : KtClassifierSymbol(), KtSymbolWithKind {
public abstract val classIdIfNonLocal: ClassId?
abstract override fun createPointer(): KtSymbolPointer<KtClassLikeSymbol>
}
public abstract class KtTypeAliasSymbol : KtClassLikeSymbol(),
KtSymbolWithTypeParameters,
KtSymbolWithVisibility,
KtNamedSymbol {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL
/**
* Returns type from right-hand site of type alias
* If type alias has type parameters, then those type parameters will be present in result type
*/
public abstract val expandedType: KtType
abstract override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol>
}
public sealed class KtClassOrObjectSymbol : KtClassLikeSymbol(),
KtAnnotatedSymbol,
KtSymbolWithMembers {
public abstract val classKind: KtClassKind
public abstract val superTypes: List<KtTypeAndAnnotations>
abstract override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol>
}
public abstract class KtAnonymousObjectSymbol : KtClassOrObjectSymbol() {
final override val classKind: KtClassKind get() = KtClassKind.ANONYMOUS_OBJECT
final override val classIdIfNonLocal: ClassId? get() = null
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
final override val name: Name? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousObjectSymbol>
}
public abstract class KtNamedClassOrObjectSymbol : KtClassOrObjectSymbol(),
KtSymbolWithTypeParameters,
KtSymbolWithModality,
KtSymbolWithVisibility,
KtNamedSymbol {
public abstract val isInner: Boolean
public abstract val isData: Boolean
public abstract val isInline: Boolean
public abstract val isFun: Boolean
public abstract val isExternal: Boolean
public abstract val companionObject: KtNamedClassOrObjectSymbol?
abstract override fun createPointer(): KtSymbolPointer<KtNamedClassOrObjectSymbol>
}
public enum class KtClassKind {
CLASS,
ENUM_CLASS,
ENUM_ENTRY,
ANNOTATION_CLASS,
OBJECT,
COMPANION_OBJECT,
INTERFACE,
ANONYMOUS_OBJECT;
public val isObject: Boolean get() = this == OBJECT || this == COMPANION_OBJECT || this == ANONYMOUS_OBJECT
}
@@ -0,0 +1,13 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
public abstract class KtFileSymbol : KtAnnotatedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtFileSymbol>
}
@@ -0,0 +1,72 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
public abstract class KtFunctionLikeSymbol : KtCallableSymbol(), KtSymbolWithKind {
public abstract val valueParameters: List<KtValueParameterSymbol>
/**
* Kotlin functions always have stable parameter names that can be reliably used when calling them with named arguments.
* Functions loaded from platform definitions (e.g. Java binaries or JS) may have unstable parameter names that vary from
* one platform installation to another. These names can not be used reliably for calls with named arguments.
*/
public abstract val hasStableParameterNames: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtFunctionLikeSymbol>
}
public abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
final override val callableIdIfNonLocal: CallableId? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol>
}
public abstract class KtSamConstructorSymbol : KtFunctionLikeSymbol(), KtNamedSymbol {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.SAM_CONSTRUCTOR
abstract override fun createPointer(): KtSymbolPointer<KtSamConstructorSymbol>
}
public abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
KtNamedSymbol,
KtPossibleMemberSymbol,
KtSymbolWithTypeParameters,
KtSymbolWithModality,
KtSymbolWithVisibility,
KtAnnotatedSymbol {
public abstract val isSuspend: Boolean
public abstract val isOperator: Boolean
public abstract val isExternal: Boolean
public abstract val isInline: Boolean
public abstract val isOverride: Boolean
public abstract val isInfix: Boolean
public abstract val isStatic: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtFunctionSymbol>
}
public abstract class KtConstructorSymbol : KtFunctionLikeSymbol(),
KtPossibleMemberSymbol,
KtAnnotatedSymbol,
KtSymbolWithVisibility,
KtSymbolWithTypeParameters {
public abstract val isPrimary: Boolean
public abstract val containingClassIdIfNonLocal: ClassId?
final override val callableIdIfNonLocal: CallableId? get() = null
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
}
@@ -0,0 +1,15 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.FqName
public abstract class KtPackageSymbol : KtSymbol {
public abstract val fqName: FqName
abstract override fun createPointer(): KtSymbolPointer<KtPackageSymbol>
}
@@ -0,0 +1,38 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
public sealed class KtPropertyAccessorSymbol : KtFunctionLikeSymbol(),
KtPossibleMemberSymbol,
KtSymbolWithModality,
KtSymbolWithVisibility,
KtAnnotatedSymbol,
KtSymbolWithKind {
final override val isExtension: Boolean get() = false
public abstract val isDefault: Boolean
public abstract val isInline: Boolean
public abstract val isOverride: Boolean
public abstract val hasBody: Boolean
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.ACCESSOR
abstract override fun createPointer(): KtSymbolPointer<KtPropertyAccessorSymbol>
}
public abstract class KtPropertyGetterSymbol : KtPropertyAccessorSymbol() {
abstract override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol>
}
public abstract class KtPropertySetterSymbol : KtPropertyAccessorSymbol() {
public abstract val parameter: KtValueParameterSymbol
abstract override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol>
}
@@ -0,0 +1,112 @@
/*
* 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.analysis.api.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
public interface KtSymbol : ValidityTokenOwner {
public val origin: KtSymbolOrigin
/**
* [PsiElement] which corresponds to given [KtSymbol]
* If [origin] is one of [KtSymbolOrigin.SOURCE], [KtSymbolOrigin.JAVA], [KtSymbolOrigin.LIBRARY] then the source is not null
* For other [KtSymbolOrigin] behaviour is undefined
*
* For [KtSymbolOrigin.LIBRARY] the generated by Kotlin class file source element is returned
*/
public val psi: PsiElement?
public fun createPointer(): KtSymbolPointer<KtSymbol>
}
/**
* Get symbol [PsiElement] if its type is [PSI], otherwise throws ClassCastException
*
* @see KtSymbol.psi
*/
public inline fun <reified PSI : PsiElement> KtSymbol.psi(): PSI =
psi as PSI
/**
* Get symbol [PsiElement] if its type is [PSI], otherwise null
*
* @see KtSymbol.psi
*/
public inline fun <reified PSI : PsiElement> KtSymbol.psiSafe(): PSI? =
psi as? PSI
/**
* A place where [KtSymbol] came from
*/
public enum class KtSymbolOrigin {
/**
* Declaration from Kotlin sources
*/
SOURCE,
/**
* Declaration which do not have it's PSI source and was generated, they are:
* For regular classes, implicit default constructor is generated
* For data classes the `copy`, `component{N}`, `toString`, `equals`, `hashCode` functions are generated
* For enum classes the `valueOf` & `values` functions are generated
* For lambda the `it` property is generated
*/
SOURCE_MEMBER_GENERATED,
/**
* A Kotlin declaration came from some .class file
*/
LIBRARY,
/**
* A Kotlin declaration came from some Java source file or from some Java library
*/
JAVA,
/**
* A synthetic function that is called as a lambda argument when creating a SAM interface object, e.g.,
* ```
* val isEven = <caret>IntPredicate { it % 2 == 0 }
* ```
*/
SAM_CONSTRUCTOR,
/**
* Consider the following code:
* ```
* interface A { fun x() }
* interface B { fun x() }
*
* interface C : A, B
* ```
* The intersection of functions A.foo & B.foo will create a function C.foo which will be marked with [INTERSECTION_OVERRIDE]
*/
INTERSECTION_OVERRIDE,
/**
* Member symbol which was generated by compiler when using `by` interface delegation
* e.g,
* ```
* interface A { fun x() }
* class B(a: A) : A by a
* ```
* the `B.foo` function will be generated by Kotlin compiler
*/
DELEGATED,
JAVA_SYNTHETIC_PROPERTY,
/**
* Declaration is backing field of some member property
* A symbol kind of [KtBackingFieldSymbol]
*
* @see KtBackingFieldSymbol
*/
PROPERTY_BACKING_FIELD,
}
@@ -0,0 +1,127 @@
/*
* 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.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.components.KtAnalysisSessionComponent
import org.jetbrains.kotlin.analysis.api.components.KtAnalysisSessionMixIn
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
public abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
public open fun getSymbol(psi: KtDeclaration): KtSymbol = when (psi) {
is KtParameter -> getParameterSymbol(psi)
is KtNamedFunction -> getFunctionLikeSymbol(psi)
is KtConstructor<*> -> getConstructorSymbol(psi)
is KtTypeParameter -> getTypeParameterSymbol(psi)
is KtTypeAlias -> getTypeAliasSymbol(psi)
is KtEnumEntry -> getEnumEntrySymbol(psi)
is KtFunctionLiteral -> getAnonymousFunctionSymbol(psi)
is KtProperty -> getVariableSymbol(psi)
is KtClassOrObject -> {
val literalExpression = (psi as? KtObjectDeclaration)?.parent as? KtObjectLiteralExpression
literalExpression?.let(::getAnonymousObjectSymbol) ?: getClassOrObjectSymbol(psi)
}
is KtPropertyAccessor -> getPropertyAccessorSymbol(psi)
else -> error("Cannot build symbol for ${psi::class}")
}
public abstract fun getParameterSymbol(psi: KtParameter): KtValueParameterSymbol
public abstract fun getFileSymbol(psi: KtFile): KtFileSymbol
public abstract fun getFunctionLikeSymbol(psi: KtNamedFunction): KtFunctionLikeSymbol
public abstract fun getConstructorSymbol(psi: KtConstructor<*>): KtConstructorSymbol
public abstract fun getTypeParameterSymbol(psi: KtTypeParameter): KtTypeParameterSymbol
public abstract fun getTypeAliasSymbol(psi: KtTypeAlias): KtTypeAliasSymbol
public abstract fun getEnumEntrySymbol(psi: KtEnumEntry): KtEnumEntrySymbol
public abstract fun getAnonymousFunctionSymbol(psi: KtNamedFunction): KtAnonymousFunctionSymbol
public abstract fun getAnonymousFunctionSymbol(psi: KtFunctionLiteral): KtAnonymousFunctionSymbol
public abstract fun getVariableSymbol(psi: KtProperty): KtVariableSymbol
public abstract fun getAnonymousObjectSymbol(psi: KtObjectLiteralExpression): KtAnonymousObjectSymbol
public abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol
public abstract fun getNamedClassOrObjectSymbol(psi: KtClassOrObject): KtNamedClassOrObjectSymbol?
public abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol
public abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol?
public abstract fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol>
@Suppress("PropertyName")
public abstract val ROOT_PACKAGE_SYMBOL: KtPackageSymbol
}
public interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
public fun KtDeclaration.getSymbol(): KtSymbol =
analysisSession.symbolProvider.getSymbol(this)
/**
* Creates [KtValueParameterSymbol] by [KtParameter]
*
* If [KtParameter.isFunctionTypeParameter] is `true`, i.e., if the given [KtParameter] is used as a function type parameter,
* it is not possible to create [KtValueParameterSymbol], hence an error will be raised.
*/
public fun KtParameter.getParameterSymbol(): KtValueParameterSymbol =
analysisSession.symbolProvider.getParameterSymbol(this)
/**
* Creates [KtFunctionLikeSymbol] by [KtNamedFunction]
*
* If [KtNamedFunction.getName] is `null` then returns [KtAnonymousFunctionSymbol]
* Otherwise, returns [KtFunctionSymbol]
*/
public fun KtNamedFunction.getFunctionLikeSymbol(): KtFunctionLikeSymbol =
analysisSession.symbolProvider.getFunctionLikeSymbol(this)
public fun KtConstructor<*>.getConstructorSymbol(): KtConstructorSymbol =
analysisSession.symbolProvider.getConstructorSymbol(this)
public fun KtTypeParameter.getTypeParameterSymbol(): KtTypeParameterSymbol =
analysisSession.symbolProvider.getTypeParameterSymbol(this)
public fun KtTypeAlias.getTypeAliasSymbol(): KtTypeAliasSymbol =
analysisSession.symbolProvider.getTypeAliasSymbol(this)
public fun KtEnumEntry.getEnumEntrySymbol(): KtEnumEntrySymbol =
analysisSession.symbolProvider.getEnumEntrySymbol(this)
public fun KtNamedFunction.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol =
analysisSession.symbolProvider.getAnonymousFunctionSymbol(this)
public fun KtFunctionLiteral.getAnonymousFunctionSymbol(): KtAnonymousFunctionSymbol =
analysisSession.symbolProvider.getAnonymousFunctionSymbol(this)
public fun KtProperty.getVariableSymbol(): KtVariableSymbol =
analysisSession.symbolProvider.getVariableSymbol(this)
public fun KtObjectLiteralExpression.getAnonymousObjectSymbol(): KtAnonymousObjectSymbol =
analysisSession.symbolProvider.getAnonymousObjectSymbol(this)
public fun KtClassOrObject.getClassOrObjectSymbol(): KtClassOrObjectSymbol =
analysisSession.symbolProvider.getClassOrObjectSymbol(this)
/** Gets the corresponding class or object symbol or null if the given [KtClassOrObject] is an enum entry. */
public fun KtClassOrObject.getNamedClassOrObjectSymbol(): KtNamedClassOrObjectSymbol? =
analysisSession.symbolProvider.getNamedClassOrObjectSymbol(this)
public fun KtPropertyAccessor.getPropertyAccessorSymbol(): KtPropertyAccessorSymbol =
analysisSession.symbolProvider.getPropertyAccessorSymbol(this)
public fun KtFile.getFileSymbol(): KtFileSymbol =
analysisSession.symbolProvider.getFileSymbol(this)
/**
* @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found
*/
public fun ClassId.getCorrespondingToplevelClassOrObjectSymbol(): KtClassOrObjectSymbol? =
analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(this)
public fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence<KtSymbol> =
analysisSession.symbolProvider.getTopLevelCallableSymbols(this, name)
@Suppress("PropertyName")
public val ROOT_PACKAGE_SYMBOL: KtPackageSymbol
get() = analysisSession.symbolProvider.ROOT_PACKAGE_SYMBOL
}
@@ -0,0 +1,141 @@
/*
* 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.analysis.api.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
public sealed class KtVariableLikeSymbol : KtCallableSymbol(), KtNamedSymbol, KtSymbolWithKind {
abstract override fun createPointer(): KtSymbolPointer<KtVariableLikeSymbol>
}
/**
* Backing field of some member property
*
* E.g,
* ```
* val x: Int = 10
* get() = field<caret>
* ```
*
* Symbol at caret will be resolved to a [KtBackingFieldSymbol]
*/
public abstract class KtBackingFieldSymbol : KtVariableLikeSymbol() {
public abstract val owningProperty: KtKotlinPropertySymbol
final override val name: Name get() = fieldName
final override val psi: PsiElement? get() = null
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
final override val origin: KtSymbolOrigin get() = KtSymbolOrigin.PROPERTY_BACKING_FIELD
final override val callableIdIfNonLocal: CallableId? get() = null
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtVariableLikeSymbol>
public companion object {
private val fieldName = StandardNames.BACKING_FIELD
}
}
public abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithMembers, KtSymbolWithKind {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
public abstract val containingEnumClassIdIfNonLocal: ClassId?
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
}
public sealed class KtVariableSymbol : KtVariableLikeSymbol() {
public abstract val isVal: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtVariableSymbol>
}
public abstract class KtJavaFieldSymbol :
KtVariableSymbol(),
KtSymbolWithModality,
KtSymbolWithVisibility,
KtSymbolWithKind {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
public abstract val isStatic: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol>
}
public sealed class KtPropertySymbol : KtVariableSymbol(),
KtPossibleMemberSymbol,
KtSymbolWithModality,
KtSymbolWithVisibility,
KtAnnotatedSymbol,
KtSymbolWithKind {
public abstract val hasGetter: Boolean
public abstract val hasSetter: Boolean
public abstract val getter: KtPropertyGetterSymbol?
public abstract val setter: KtPropertySetterSymbol?
public abstract val hasBackingField: Boolean
public abstract val isFromPrimaryConstructor: Boolean
public abstract val isOverride: Boolean
public abstract val isStatic: Boolean
public abstract val initializer: KtConstantValue?
abstract override fun createPointer(): KtSymbolPointer<KtPropertySymbol>
}
public abstract class KtKotlinPropertySymbol : KtPropertySymbol() {
public abstract val isLateInit: Boolean
public abstract val isConst: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtKotlinPropertySymbol>
}
public abstract class KtSyntheticJavaPropertySymbol : KtPropertySymbol() {
final override val hasBackingField: Boolean get() = true
final override val hasGetter: Boolean get() = true
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
abstract override val getter: KtPropertyGetterSymbol
public abstract val javaGetterSymbol: KtFunctionSymbol
public abstract val javaSetterSymbol: KtFunctionSymbol?
abstract override fun createPointer(): KtSymbolPointer<KtSyntheticJavaPropertySymbol>
}
public abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKind {
final override val callableIdIfNonLocal: CallableId? get() = null
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol>
}
public abstract class KtValueParameterSymbol : KtVariableLikeSymbol(), KtSymbolWithKind, KtAnnotatedSymbol {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
final override val callableIdIfNonLocal: CallableId? get() = null
final override val isExtension: Boolean get() = false
final override val receiverType: KtTypeAndAnnotations? get() = null
public abstract val hasDefaultValue: Boolean
public abstract val isVararg: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol>
}
@@ -0,0 +1,28 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtCallElement
public abstract class KtAnnotationCall : ValidityTokenOwner {
public abstract val classId: ClassId?
public abstract val useSiteTarget: AnnotationUseSiteTarget?
public abstract val psi: KtCallElement?
public abstract val arguments: List<KtNamedConstantValue>
}
public data class KtNamedConstantValue(val name: String, val expression: KtConstantValue)
public interface KtAnnotatedSymbol : KtSymbol {
public val annotations: List<KtAnnotationCall>
public fun containsAnnotation(classId: ClassId): Boolean
public val annotationClassIds: Collection<ClassId>
}
@@ -0,0 +1,13 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.types.ConstantValueKind
public sealed class KtConstantValue
public object KtUnsupportedConstantValue : KtConstantValue()
public data class KtSimpleConstantValue<T>(val constantValueKind: ConstantValueKind<T>, val value: T) : KtConstantValue()
@@ -0,0 +1,13 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
public interface KtPossibleMemberSymbol : KtSymbol {
public val dispatchType: KtType?
}
@@ -0,0 +1,24 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
public interface KtSymbolWithKind : KtSymbol {
public val symbolKind: KtSymbolKind
}
public enum class KtSymbolKind {
TOP_LEVEL,
MEMBER,
LOCAL,
ACCESSOR,
SAM_CONSTRUCTOR,
}
@@ -0,0 +1,12 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
public interface KtSymbolWithMembers : KtSymbolWithDeclarations
public interface KtSymbolWithDeclarations : KtSymbol
@@ -0,0 +1,13 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
public interface KtSymbolWithModality : KtSymbol {
public val modality: Modality
}
@@ -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.analysis.api.symbols.markers
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
public interface KtSymbolWithVisibility : KtSymbol {
public val visibility: Visibility
}
public fun Visibility.isPrivateOrPrivateToThis(): Boolean =
this == Visibilities.Private || this == Visibilities.PrivateToThis
@@ -0,0 +1,33 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.types.KtType
public abstract class KtTypeAndAnnotations : ValidityTokenOwner {
public abstract val type: KtType
public abstract val annotations: List<KtAnnotationCall>
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as KtTypeAndAnnotations
if (token != other.token) return false
if (type != other.type) return false
if (annotations != other.annotations) return false
return true
}
override fun hashCode(): Int {
var result = token.hashCode()
result = 31 * result + type.hashCode()
result = 31 * result + annotations.hashCode()
return result
}
}
@@ -0,0 +1,23 @@
/*
* 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.analysis.api.symbols.markers
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.Name
public interface KtPossiblyNamedSymbol : KtSymbol {
public val name: Name?
}
public interface KtNamedSymbol : KtPossiblyNamedSymbol {
override val name: Name
}
public interface KtSymbolWithTypeParameters : KtSymbol {
public val typeParameters: List<KtTypeParameterSymbol>
}
@@ -0,0 +1,44 @@
/*
* 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.analysis.api.symbols.pointers
import com.intellij.psi.SmartPsiElementPointer
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
public class KtPsiBasedSymbolPointer<S : KtSymbol>(private val psiPointer: SmartPsiElementPointer<out KtDeclaration>) :
KtSymbolPointer<S>() {
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
override fun restoreSymbol(analysisSession: KtAnalysisSession): S? {
val psi = psiPointer.element ?: return null
@Suppress("UNCHECKED_CAST")
return with(analysisSession) { psi.getSymbol() } as S?
}
public companion object {
public fun <S : KtSymbol> createForSymbolFromSource(symbol: S): KtPsiBasedSymbolPointer<S>? {
if (symbol.origin == KtSymbolOrigin.LIBRARY) return null
/**
* If symbol points to a generated member, we won't be able to recover it later on, because there is no corresponding
* psi by which it can be found
*/
if (symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED) return null
val psi = when (val psi = symbol.psi) {
is KtDeclaration -> psi
is KtObjectLiteralExpression -> psi.objectDeclaration
else -> null
} ?: return null
return KtPsiBasedSymbolPointer(psi.createSmartPointer())
}
}
}
@@ -0,0 +1,40 @@
/*
* 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.analysis.api.symbols.pointers
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
/**
* `KtSymbol` is valid only during read action it was created in
* To pass the symbol from one read action to another the KtSymbolPointer should be used
*
* We can restore the symbol
* * for symbol which came from Kotlin source it will be restored based on [com.intellij.psi.SmartPsiElementPointer]
* * restoring symbols which came from Java source is not supported yet
* * for library symbols:
* * for function & property symbol if its signature was not changed
* * for local variable symbol if code block it was declared in was not changed
* * for class & type alias symbols if its qualified name was not changed
* * for package symbol if the package is still exists
*
* @see org.jetbrains.kotlin.analysis.api.ReadActionConfinementValidityToken
*/
public abstract class KtSymbolPointer<out S : KtSymbol> {
/**
* @return restored symbol (possibly the new symbol instance) if one is still valid, `null` otherwise
*
* Consider using [org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol]
*/
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
public abstract fun restoreSymbol(analysisSession: KtAnalysisSession): S?
}
public inline fun <S : KtSymbol> symbolPointer(crossinline getSymbol: (KtAnalysisSession) -> S?): KtSymbolPointer<S> =
object : KtSymbolPointer<S>() {
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
override fun restoreSymbol(analysisSession: KtAnalysisSession): S? = getSymbol(analysisSession)
}
@@ -0,0 +1,14 @@
/*
* 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.analysis.api.symbols.pointers
public class CanNotCreateSymbolPointerForLocalLibraryDeclarationException(description: String) :
IllegalStateException("Could not create a symbol pointer for local symbol $description")
public class WrongSymbolForSamConstructor(symbolKind: String) :
IllegalStateException(
"For symbol with kind = KtSymbolKind.SAM_CONSTRUCTOR, KtSamConstructorSymbol should be created, but was $symbolKind"
)
@@ -0,0 +1,39 @@
/*
* 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.analysis.api.tokens
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import kotlin.reflect.KClass
public class AlwaysAccessibleValidityToken(project: Project) : ValidityToken() {
private val modificationTracker = project.createProjectWideOutOfBlockModificationTracker()
private val onCreatedTimeStamp = modificationTracker.modificationCount
override fun isValid(): Boolean {
return onCreatedTimeStamp == modificationTracker.modificationCount
}
override fun getInvalidationReason(): String {
if (onCreatedTimeStamp != modificationTracker.modificationCount) return "PSI has changed since creation"
error("Getting invalidation reason for valid validity token")
}
override fun isAccessible(): Boolean {
return true
}
override fun getInaccessibilityReason(): String {
error("Getting inaccessibility reason for validity token when it is accessible")
}
}
public object AlwaysAccessibleValidityTokenFactory : ValidityTokenFactory() {
override val identifier: KClass<out ValidityToken> = AlwaysAccessibleValidityToken::class
override fun create(project: Project): ValidityToken =
AlwaysAccessibleValidityToken(project)
}
@@ -0,0 +1,93 @@
/*
* 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.analysis.api.tokens
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.analysis.api.*
import kotlin.reflect.KClass
public class ReadActionConfinementValidityToken(project: Project) : ValidityToken() {
private val modificationTracker = project.createProjectWideOutOfBlockModificationTracker()
private val onCreatedTimeStamp = modificationTracker.modificationCount
override fun isValid(): Boolean {
return onCreatedTimeStamp == modificationTracker.modificationCount
}
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class)
override fun getInvalidationReason(): String {
if (onCreatedTimeStamp != modificationTracker.modificationCount) return "PSI has changed since creation"
error("Getting invalidation reason for valid validity token")
}
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class, ForbidKtResolveInternals::class, InvalidWayOfUsingAnalysisSession::class)
override fun isAccessible(): Boolean {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread && !allowOnEdt.get()) return false
if (ForbidKtResolve.resovleIsForbidenInActionWithName.get() != null) return false
if (!application.isReadAccessAllowed) return false
if (!ReadActionConfinementValidityTokenFactory.isInsideAnalysisContext()) return false
return true
}
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class, ForbidKtResolveInternals::class, InvalidWayOfUsingAnalysisSession::class)
override fun getInaccessibilityReason(): String {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread && !allowOnEdt.get()) return "Called in EDT thread"
if (!application.isReadAccessAllowed) return "Called outside read action"
ForbidKtResolve.resovleIsForbidenInActionWithName.get()?.let { actionName ->
return "Resolve is forbidden in $actionName"
}
if (!ReadActionConfinementValidityTokenFactory.isInsideAnalysisContext()) return "Called outside analyse method"
error("Getting inaccessibility reason for validity token when it is accessible")
}
public companion object {
@HackToForceAllowRunningAnalyzeOnEDT
public val allowOnEdt: ThreadLocal<Boolean> = ThreadLocal.withInitial { false }
}
}
public object ReadActionConfinementValidityTokenFactory : ValidityTokenFactory() {
override val identifier: KClass<out ValidityToken> = ReadActionConfinementValidityToken::class
override fun create(project: Project): ValidityToken = ReadActionConfinementValidityToken(project)
override fun beforeEnteringAnalysisContext() {
currentAnalysisContextEnteringCount.set(currentAnalysisContextEnteringCount.get() + 1)
}
override fun afterLeavingAnalysisContext() {
currentAnalysisContextEnteringCount.set(currentAnalysisContextEnteringCount.get() - 1)
}
private val currentAnalysisContextEnteringCount = ThreadLocal.withInitial { 0 }
internal fun isInsideAnalysisContext() = currentAnalysisContextEnteringCount.get() > 0
}
@RequiresOptIn("All frontend related work should not be allowed to be ran from EDT thread. Only use it as a temporary solution")
public annotation class HackToForceAllowRunningAnalyzeOnEDT
/**
* All frontend related work should not be allowed to be ran from EDT thread. Only use it as a temporary solution.
*
* @see KtAnalysisSession
* @see ReadActionConfinementValidityToken
*/
@HackToForceAllowRunningAnalyzeOnEDT
public inline fun <T> hackyAllowRunningOnEdt(action: () -> T): T {
if (ReadActionConfinementValidityToken.allowOnEdt.get()) return action()
ReadActionConfinementValidityToken.allowOnEdt.set(true)
try {
return action()
} finally {
ReadActionConfinementValidityToken.allowOnEdt.set(false)
}
}
@@ -0,0 +1,42 @@
/*
* 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.analysis.api.tokens
import com.intellij.openapi.project.Project
import kotlin.reflect.KClass
public abstract class ValidityToken {
public abstract fun isValid(): Boolean
public abstract fun getInvalidationReason(): String
public abstract fun isAccessible(): Boolean
public abstract fun getInaccessibilityReason(): String
}
public abstract class ValidityTokenFactory {
public abstract val identifier: KClass<out ValidityToken>
public abstract fun create(project: Project): ValidityToken
public open fun beforeEnteringAnalysisContext() {}
public open fun afterLeavingAnalysisContext() {}
}
@Suppress("NOTHING_TO_INLINE")
public inline fun ValidityToken.assertIsValidAndAccessible() {
if (!isValid()) {
throw InvalidEntityAccessException("Access to invalid $this: ${getInvalidationReason()}")
}
if (!isAccessible()) {
throw InaccessibleEntityAccessException("$this is inaccessible: ${getInaccessibilityReason()}")
}
}
public abstract class BadEntityAccessException() : IllegalStateException()
public class InvalidEntityAccessException(override val message: String) : BadEntityAccessException()
public class InaccessibleEntityAccessException(override val message: String) : BadEntityAccessException()
@@ -0,0 +1,84 @@
/*
* 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.analysis.api.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
public sealed interface KtType : ValidityTokenOwner {
public val nullability: KtTypeNullability
public fun asStringForDebugging(): String
}
public enum class KtTypeNullability(public val isNullable: Boolean) {
NULLABLE(true),
NON_NULLABLE(false),
UNKNOWN(false);
public companion object {
public fun create(isNullable: Boolean): KtTypeNullability = if (isNullable) NULLABLE else NON_NULLABLE
}
}
public sealed class KtClassType : KtType {
override fun toString(): String = asStringForDebugging()
}
public sealed class KtNonErrorClassType : KtClassType() {
public abstract val classId: ClassId
public abstract val classSymbol: KtClassLikeSymbol
public abstract val typeArguments: List<KtTypeArgument>
}
public abstract class KtFunctionalType : KtNonErrorClassType() {
public abstract val isSuspend: Boolean
public abstract val arity: Int
public abstract val receiverType: KtType?
public abstract val hasReceiver: Boolean
public abstract val parameterTypes: List<KtType>
public abstract val returnType: KtType
}
public abstract class KtUsualClassType : KtNonErrorClassType()
public abstract class KtClassErrorType : KtClassType() {
public abstract val error: String
public abstract val candidateClassSymbols: Collection<KtClassLikeSymbol>
}
public abstract class KtTypeParameterType : KtType {
public abstract val name: Name
public abstract val symbol: KtTypeParameterSymbol
}
public abstract class KtCapturedType : KtType {
override fun toString(): String = asStringForDebugging()
}
public abstract class KtDefinitelyNotNullType : KtType {
public abstract val original: KtType
final override val nullability: KtTypeNullability get() = KtTypeNullability.NON_NULLABLE
override fun toString(): String = asStringForDebugging()
}
public abstract class KtFlexibleType : KtType {
public abstract val lowerBound: KtType
public abstract val upperBound: KtType
override fun toString(): String = asStringForDebugging()
}
public abstract class KtIntersectionType : KtType {
public abstract val conjuncts: List<KtType>
override fun toString(): String = asStringForDebugging()
}