[Analysis API] forbid providing custom KtLifetimeToken for every analyze call
^KT-60488 fixed
This commit is contained in:
committed by
Space Team
parent
b617b24d48
commit
4b523825be
@@ -22,50 +22,40 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
* Uses [useSiteKtElement] as an [KtElement] which containing module is a use-site module,
|
||||
* i.e, the module from which perspective the project will be analyzed.
|
||||
*
|
||||
* [nonDefaultLifetimeTokenFactory] represents lifetime and accessibility guaranties
|
||||
* which will be applied to the [org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner] instances created during code analysis.
|
||||
*
|
||||
* @see KtAnalysisSession
|
||||
* @see KtLifetimeTokenFactory
|
||||
* @see analyzeWithReadAction
|
||||
*/
|
||||
public inline fun <R> analyze(
|
||||
useSiteKtElement: KtElement,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory? = null,
|
||||
action: KtAnalysisSession.() -> R
|
||||
): R =
|
||||
KtAnalysisSessionProvider.getInstance(useSiteKtElement.project)
|
||||
.analyse(useSiteKtElement, nonDefaultLifetimeTokenFactory, action)
|
||||
.analyse(useSiteKtElement, action)
|
||||
|
||||
|
||||
/**
|
||||
* Execute given [action] in [KtAnalysisSession] context
|
||||
* Uses [useSiteKtModule] as use-site module, i.e, the module from which perspective the project will be analyzed.
|
||||
*
|
||||
* [nonDefaultLifetimeTokenFactory] represents lifetime and accessibility guaranties
|
||||
* which will be applied to the [org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner] instances created during code analysis.
|
||||
*
|
||||
* @see KtAnalysisSession
|
||||
* @see KtLifetimeTokenFactory
|
||||
*/
|
||||
public inline fun <R> analyze(
|
||||
useSiteKtModule: KtModule,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory? = null,
|
||||
crossinline action: KtAnalysisSession.() -> R
|
||||
): R {
|
||||
val sessionProvider = KtAnalysisSessionProvider.getInstance(useSiteKtModule.project)
|
||||
return sessionProvider.analyze(useSiteKtModule, nonDefaultLifetimeTokenFactory, action)
|
||||
return sessionProvider.analyze(useSiteKtModule, action)
|
||||
}
|
||||
|
||||
|
||||
public inline fun <R> analyzeInDependedAnalysisSession(
|
||||
originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory? = null,
|
||||
action: KtAnalysisSession.() -> R
|
||||
): R =
|
||||
KtAnalysisSessionProvider.getInstance(originalFile.project)
|
||||
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, nonDefaultLifetimeTokenFactory, action)
|
||||
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, action)
|
||||
|
||||
/**
|
||||
* Execute given [action] in [KtAnalysisSession] context like [analyze] does but execute it in read action
|
||||
@@ -81,10 +71,9 @@ public inline fun <R> analyzeInDependedAnalysisSession(
|
||||
*/
|
||||
public inline fun <R> analyzeWithReadAction(
|
||||
contextElement: KtElement,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory? = null,
|
||||
crossinline action: KtAnalysisSession.() -> R
|
||||
): R = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
analyze(contextElement, nonDefaultLifetimeTokenFactory, action)
|
||||
analyze(contextElement, action)
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -97,13 +86,12 @@ public inline fun <R> analyzeWithReadAction(
|
||||
public inline fun <R> analyzeInModalWindow(
|
||||
contextElement: KtElement,
|
||||
windowTitle: String,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory? = null,
|
||||
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 =
|
||||
analyzeWithReadAction(contextElement, nonDefaultLifetimeTokenFactory) { action() }
|
||||
analyzeWithReadAction(contextElement) { action() }
|
||||
}
|
||||
task.queue()
|
||||
return task.result
|
||||
|
||||
+6
-6
@@ -9,19 +9,19 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
|
||||
@KtAnalysisApiInternals
|
||||
public abstract class KtDefaultLifetimeTokenProvider {
|
||||
public abstract fun getDefaultLifetimeTokenFactory(): KtLifetimeTokenFactory
|
||||
public abstract class KtLifetimeTokenProvider {
|
||||
public abstract fun getLifetimeTokenFactory(): KtLifetimeTokenFactory
|
||||
|
||||
public companion object {
|
||||
@KtAnalysisApiInternals
|
||||
public fun getService(project: Project): KtDefaultLifetimeTokenProvider =
|
||||
project.getService(KtDefaultLifetimeTokenProvider::class.java)
|
||||
public fun getService(project: Project): KtLifetimeTokenProvider =
|
||||
project.getService(KtLifetimeTokenProvider::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@KtAnalysisApiInternals
|
||||
public class KtReadActionConfinementDefaultLifetimeTokenProvider: KtDefaultLifetimeTokenProvider() {
|
||||
override fun getDefaultLifetimeTokenFactory(): KtLifetimeTokenFactory {
|
||||
public class KtReadActionConfinementLifetimeTokenProvider : KtLifetimeTokenProvider() {
|
||||
override fun getLifetimeTokenFactory(): KtLifetimeTokenFactory {
|
||||
return KtReadActionConfinementLifetimeTokenFactory
|
||||
}
|
||||
}
|
||||
+16
-26
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.impl.NoWriteActionInAnalyseCallChecker
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtDefaultLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
@@ -21,63 +21,53 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
* Provides [KtAnalysisSession] by [contextElement]
|
||||
* Should not be used directly, consider using [analyse]/[analyzeWithReadAction]/[analyzeInModalWindow] instead
|
||||
*/
|
||||
@KtAnalysisApiInternals
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
public abstract class KtAnalysisSessionProvider(public val project: Project) : Disposable {
|
||||
@KtAnalysisApiInternals
|
||||
public val tokenFactory: KtLifetimeTokenFactory = KtLifetimeTokenProvider.getService(project).getLifetimeTokenFactory()
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
public val noWriteActionInAnalyseCallChecker: NoWriteActionInAnalyseCallChecker = NoWriteActionInAnalyseCallChecker(this)
|
||||
|
||||
public abstract fun getAnalysisSession(useSiteKtElement: KtElement, factory: KtLifetimeTokenFactory): KtAnalysisSession
|
||||
public abstract fun getAnalysisSession(useSiteKtElement: KtElement): KtAnalysisSession
|
||||
|
||||
public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule, factory: KtLifetimeTokenFactory): KtAnalysisSession
|
||||
public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule): KtAnalysisSession
|
||||
|
||||
public inline fun <R> analyseInDependedAnalysisSession(
|
||||
originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory?,
|
||||
action: KtAnalysisSession.() -> R
|
||||
action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val factory =
|
||||
nonDefaultLifetimeTokenFactory ?: KtDefaultLifetimeTokenProvider.getService(project).getDefaultLifetimeTokenFactory()
|
||||
|
||||
val originalAnalysisSession = getAnalysisSession(originalFile, factory)
|
||||
val originalAnalysisSession = getAnalysisSession(originalFile)
|
||||
val dependedAnalysisSession = originalAnalysisSession
|
||||
.createContextDependentCopy(originalFile, elementToReanalyze)
|
||||
return analyse(dependedAnalysisSession, factory, action)
|
||||
return analyse(dependedAnalysisSession, action)
|
||||
}
|
||||
|
||||
public inline fun <R> analyse(
|
||||
useSiteKtElement: KtElement,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory?,
|
||||
action: KtAnalysisSession.() -> R
|
||||
action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val factory =
|
||||
nonDefaultLifetimeTokenFactory ?: KtDefaultLifetimeTokenProvider.getService(project).getDefaultLifetimeTokenFactory()
|
||||
return analyse(getAnalysisSession(useSiteKtElement, factory), factory, action)
|
||||
return analyse(getAnalysisSession(useSiteKtElement), action)
|
||||
}
|
||||
|
||||
public inline fun <R> analyze(
|
||||
useSiteKtModule: KtModule,
|
||||
nonDefaultLifetimeTokenFactory: KtLifetimeTokenFactory?,
|
||||
action: KtAnalysisSession.() -> R
|
||||
action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val factory =
|
||||
nonDefaultLifetimeTokenFactory ?: KtDefaultLifetimeTokenProvider.getService(project).getDefaultLifetimeTokenFactory()
|
||||
|
||||
return analyse(getAnalysisSessionByUseSiteKtModule(useSiteKtModule, factory), factory, action)
|
||||
return analyse(getAnalysisSessionByUseSiteKtModule(useSiteKtModule), action)
|
||||
}
|
||||
|
||||
public inline fun <R> analyse(
|
||||
analysisSession: KtAnalysisSession,
|
||||
factory: KtLifetimeTokenFactory,
|
||||
action: KtAnalysisSession.() -> R
|
||||
action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
noWriteActionInAnalyseCallChecker.beforeEnteringAnalysisContext()
|
||||
factory.beforeEnteringAnalysisContext(analysisSession.token)
|
||||
tokenFactory.beforeEnteringAnalysisContext(analysisSession.token)
|
||||
return try {
|
||||
analysisSession.action()
|
||||
} finally {
|
||||
factory.afterLeavingAnalysisContext(analysisSession.token)
|
||||
tokenFactory.afterLeavingAnalysisContext(analysisSession.token)
|
||||
noWriteActionInAnalyseCallChecker.afterLeavingAnalysisContext()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user