FIR IDE: move analysis api to the analysis directory
This commit is contained in:
@@ -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 }
|
||||
}
|
||||
+14
@@ -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
|
||||
}
|
||||
+175
@@ -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()
|
||||
|
||||
+38
@@ -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)
|
||||
}
|
||||
+14
@@ -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
|
||||
}
|
||||
|
||||
+12
@@ -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
|
||||
}
|
||||
+39
@@ -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)
|
||||
}
|
||||
+18
@@ -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)
|
||||
}
|
||||
+40
@@ -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
|
||||
)
|
||||
}
|
||||
+30
@@ -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,
|
||||
}
|
||||
+23
@@ -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)
|
||||
}
|
||||
+92
@@ -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)
|
||||
}
|
||||
+31
@@ -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>,
|
||||
)
|
||||
+22
@@ -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)
|
||||
}
|
||||
+24
@@ -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)
|
||||
}
|
||||
+64
@@ -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)
|
||||
}
|
||||
+31
@@ -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)
|
||||
}
|
||||
+22
@@ -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()
|
||||
}
|
||||
}
|
||||
+82
@@ -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
|
||||
}
|
||||
+22
@@ -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)
|
||||
}
|
||||
+72
@@ -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
|
||||
+23
@@ -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)
|
||||
}
|
||||
+24
@@ -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)
|
||||
}
|
||||
+23
@@ -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)
|
||||
}
|
||||
+55
@@ -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)
|
||||
}
|
||||
+136
@@ -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)
|
||||
}
|
||||
+51
@@ -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)
|
||||
}
|
||||
+14
@@ -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)
|
||||
}
|
||||
+57
@@ -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()
|
||||
}
|
||||
|
||||
+112
@@ -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)
|
||||
}
|
||||
+101
@@ -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
|
||||
}
|
||||
+30
@@ -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)
|
||||
}
|
||||
+37
@@ -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"
|
||||
+42
@@ -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() }
|
||||
}
|
||||
+113
@@ -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
|
||||
}
|
||||
+21
@@ -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>
|
||||
}
|
||||
+98
@@ -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>
|
||||
}
|
||||
+72
@@ -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>
|
||||
}
|
||||
+15
@@ -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>
|
||||
}
|
||||
+38
@@ -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,
|
||||
}
|
||||
+127
@@ -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
|
||||
}
|
||||
+141
@@ -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>
|
||||
}
|
||||
+28
@@ -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>
|
||||
}
|
||||
+13
@@ -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()
|
||||
+13
@@ -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?
|
||||
}
|
||||
+24
@@ -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,
|
||||
}
|
||||
|
||||
+12
@@ -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
|
||||
+13
@@ -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
|
||||
}
|
||||
+18
@@ -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
|
||||
+33
@@ -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
|
||||
}
|
||||
}
|
||||
+23
@@ -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>
|
||||
}
|
||||
+44
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -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)
|
||||
}
|
||||
+14
@@ -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"
|
||||
)
|
||||
+39
@@ -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)
|
||||
}
|
||||
+93
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user