FIR IDE: separate ValidityOwner to ValidityTokenOwner & ValidityToken

This commit is contained in:
Ilya Kirillov
2020-07-10 13:38:37 +03:00
parent 6a6580dd97
commit c0f5c90231
35 changed files with 162 additions and 132 deletions
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.frontend.api
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
@@ -13,11 +12,7 @@ import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
abstract class KtAnalysisSession(project: Project) : ValidityOwner {
protected open val validityToken = ReadActionConfinementValidityToken(project)
override fun isValid(): Boolean = validityToken.isValid()
override fun invalidationReason(): String = validityToken.invalidationReason()
abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTokenOwner {
abstract val symbolProvider: KtSymbolProvider
abstract val scopeProvider: KtScopeProvider
@@ -9,33 +9,10 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
interface ValidityOwner {
fun isValid(): Boolean
fun invalidationReason(): String
}
@Suppress("NOTHING_TO_INLINE")
inline fun ValidityOwner.assertIsValid() {
assert(isValid()) { "Access to invalid $this, invalidation reason is ${invalidationReason()}" }
}
inline fun <R> ValidityOwner.withValidityAssertion(action: () -> R): R {
assertIsValid()
return action()
}
interface ValidityOwnerByValidityToken : ValidityOwner {
val token: ValidityOwner
override fun isValid(): Boolean = token.isValid()
override fun invalidationReason(): String = token.invalidationReason()
}
class ReadActionConfinementValidityToken(project: Project) : ValidityOwner {
class ReadActionConfinementValidityToken(project: Project) : ValidityToken() {
private val modificationTracker = KotlinModificationTrackerService.getInstance(project).modificationTracker
private val onCreatedTimeStamp = modificationTracker.modificationCount
override fun isValid(): Boolean {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread) return false
@@ -43,11 +20,11 @@ class ReadActionConfinementValidityToken(project: Project) : ValidityOwner {
return onCreatedTimeStamp == modificationTracker.modificationCount
}
override fun invalidationReason(): String {
override fun getInvalidationReason(): String {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread) 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 invalidatable")
error("Getting invalidation reason for valid validity token")
}
}
@@ -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.idea.frontend.api
abstract class ValidityToken {
abstract fun isValid(): Boolean
abstract fun getInvalidationReason(): String
}
@Suppress("NOTHING_TO_INLINE")
inline fun ValidityToken.assertIsValid() {
if (!isValid()) {
throw InvalidEntityAccessException("Access to invalid $this, invalidation reason is ${getInvalidationReason()}")
}
}
class InvalidEntityAccessException(override val message: String): IllegalStateException()
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.frontend.api
interface ValidityTokenOwner {
val token: ValidityToken
}
@Suppress("NOTHING_TO_INLINE")
inline fun ValidityTokenOwner.assertIsValid() {
token.assertIsValid()
}
inline fun <R> ValidityTokenOwner.withValidityAssertion(action: () -> R): R {
assertIsValid()
return action()
}
@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.idea.frontend.api.scopes
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.name.Name
interface KtScope : ValidityOwner {
interface KtScope : ValidityTokenOwner {
// TODO check that names are accessible
// maybe return some kind of lazy set
fun getAllNames(): Set<Name>
@@ -5,14 +5,14 @@
package org.jetbrains.kotlin.idea.frontend.api.scopes
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
abstract class KtScopeProvider : ValidityOwner {
abstract class KtScopeProvider : ValidityTokenOwner {
abstract fun getMemberScope(classSymbol: KtClassOrObjectSymbol): KtMemberScope
abstract fun getDeclaredMemberScope(classSymbol: KtClassOrObjectSymbol): KtDeclaredMemberScope
abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
interface KtSymbol : ValidityOwner {
interface KtSymbol : ValidityTokenOwner {
val origin: KtSymbolOrigin
val psi: PsiElement?
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
abstract class KtSymbolProvider : ValidityOwner {
abstract class KtSymbolProvider : ValidityTokenOwner {
open fun getSymbol(psi: KtDeclaration): KtSymbol = when (psi) {
is KtParameter -> getParameterSymbol(psi)
is KtNamedFunction -> getFunctionSymbol(psi)
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.idea.frontend.api.types
import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
interface KtType : ValidityOwner {
interface KtType : ValidityTokenOwner {
fun isEqualTo(other: KtType): Boolean
fun isSubTypeOf(superType: KtType): Boolean