FIR IDE: split ValidityToken.isValid into isValid & isAccessible

This commit is contained in:
Ilya Kirillov
2020-12-17 14:51:21 +01:00
parent a2befd4635
commit 9c26edbaaa
9 changed files with 48 additions and 28 deletions
@@ -13,21 +13,30 @@ class ReadActionConfinementValidityToken(project: Project) : ValidityToken() {
private val modificationTracker = project.createProjectWideOutOfBlockModificationTracker()
private val onCreatedTimeStamp = modificationTracker.modificationCount
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class)
override fun isValid(): Boolean {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread && !allowOnEdt.get()) return false
if (!application.isReadAccessAllowed) return false
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)
override fun isAccessible(): Boolean {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread && !allowOnEdt.get()) return false
if (!application.isReadAccessAllowed) return false
return true
}
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::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"
if (onCreatedTimeStamp != modificationTracker.modificationCount) return "PSI has changed since creation"
error("Getting invalidation reason for valid validity token")
error("Getting inaccessibility reason for validity token when it is accessible")
}
companion object {
@@ -8,14 +8,23 @@ package org.jetbrains.kotlin.idea.frontend.api
abstract class ValidityToken {
abstract fun isValid(): Boolean
abstract fun getInvalidationReason(): String
abstract fun isAccessible(): Boolean
abstract fun getInaccessibilityReason(): String
}
@Suppress("NOTHING_TO_INLINE")
inline fun ValidityToken.assertIsValid() {
inline fun ValidityToken.assertIsValidAndAccessible() {
if (!isValid()) {
throw InvalidEntityAccessException("Access to invalid $this, invalidation reason is ${getInvalidationReason()}")
throw InvalidEntityAccessException("Access to invalid $this: ${getInvalidationReason()}")
}
if (!isAccessible()) {
throw InaccessibleEntityAccessException("$this is inaccessible: ${getInaccessibilityReason()}")
}
}
class InvalidEntityAccessException(override val message: String): IllegalStateException()
abstract class BadEntityAccessException(): IllegalStateException()
class InvalidEntityAccessException(override val message: String) : BadEntityAccessException()
class InaccessibleEntityAccessException(override val message: String): BadEntityAccessException()
@@ -9,12 +9,14 @@ interface ValidityTokenOwner {
val token: ValidityToken
}
fun ValidityTokenOwner.isValid(): Boolean = token.isValid()
@Suppress("NOTHING_TO_INLINE")
inline fun ValidityTokenOwner.assertIsValid() {
token.assertIsValid()
inline fun ValidityTokenOwner.assertIsValidAndAccessible() {
token.assertIsValidAndAccessible()
}
inline fun <R> ValidityTokenOwner.withValidityAssertion(action: () -> R): R {
assertIsValid()
assertIsValidAndAccessible()
return action()
}