FIR IDE: add packages name completion
This commit is contained in:
committed by
TeamCityServer
parent
df93dc91d1
commit
e77783a0e5
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package <caret>
|
||||
|
||||
// EXIST: kotlin
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package kotlin.prop<caret>erties.
|
||||
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package testdata.kotlin.data
|
||||
|
||||
class TestSample() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package kotlin.<caret>
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package Test.MyTest
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package java
|
||||
|
||||
annotation class Hello
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
val v = 1
|
||||
fun f() = 2
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
fun foo() {
|
||||
val v = HashMap<String, <caret>>
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package kotlin
|
||||
|
||||
fun some() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package java.util.<caret>
|
||||
|
||||
// EXIST: concurrent
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package Tests
|
||||
|
||||
class A : java.<caret>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
package java.lang.<caret>
|
||||
|
||||
// EXIST: annotation
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ class FE10BindingContextImpl(
|
||||
private val moduleInfo = ktElement.getModuleInfo()
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
override val ktAnalysisSessionFacade = KtAnalysisSessionFe10BindingHolder.create(ktElement.getResolveState(), token)
|
||||
override val ktAnalysisSessionFacade = KtAnalysisSessionFe10BindingHolder.create(ktElement.getResolveState(), token, ktElement)
|
||||
|
||||
override val moduleDescriptor: ModuleDescriptor = KtSymbolBasedModuleDescriptorImpl(this, moduleInfo)
|
||||
|
||||
|
||||
+4
@@ -60,20 +60,24 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
|
||||
val callableContributor = FirCallableCompletionContributor(basicContext)
|
||||
val classifierContributor = FirClassifierCompletionContributor(basicContext)
|
||||
val annotationsContributor = FirAnnotationCompletionContributor(basicContext)
|
||||
val packageCompletionContributor = FirPackageCompletionContributor(basicContext)
|
||||
|
||||
when (positionContext) {
|
||||
is FirExpressionNameReferencePositionContext -> {
|
||||
complete(keywordContributor, positionContext)
|
||||
complete(packageCompletionContributor, positionContext)
|
||||
complete(callableContributor, positionContext)
|
||||
complete(classifierContributor, positionContext)
|
||||
}
|
||||
is FirTypeNameReferencePositionContext -> {
|
||||
complete(keywordContributor, positionContext)
|
||||
complete(packageCompletionContributor, positionContext)
|
||||
complete(classifierContributor, positionContext)
|
||||
}
|
||||
|
||||
is FirAnnotationTypeNameReferencePositionContext -> {
|
||||
complete(keywordContributor, positionContext)
|
||||
complete(packageCompletionContributor, positionContext)
|
||||
complete(annotationsContributor, positionContext)
|
||||
}
|
||||
|
||||
|
||||
+17
@@ -53,6 +53,16 @@ internal class KotlinFirLookupElementFactory {
|
||||
.withIcon(KotlinFirIconProvider.getIconFor(symbol))
|
||||
}
|
||||
|
||||
fun createPackageLookupElement(packageFqName: FqName): LookupElement {
|
||||
return LookupElementBuilder.create(PackageLookupObject(packageFqName), packageFqName.shortName().asString())
|
||||
.withInsertHandler(QuotedNamesAwareInsertionHandler())
|
||||
.let {
|
||||
if (!packageFqName.parent().isRoot) {
|
||||
it.appendTailText(" (${packageFqName.asString()})", true)
|
||||
} else it
|
||||
}
|
||||
}
|
||||
|
||||
fun KtAnalysisSession.createLookupElementForClassLikeSymbol(symbol: KtClassLikeSymbol, insertFqName: Boolean = true): LookupElement? {
|
||||
if (symbol !is KtNamedSymbol) return null
|
||||
return classLookupElementFactory.createLookup(symbol, insertFqName)
|
||||
@@ -76,6 +86,13 @@ private interface KotlinLookupObject {
|
||||
val shortName: Name
|
||||
}
|
||||
|
||||
private data class PackageLookupObject(
|
||||
val packageFqName: FqName,
|
||||
) : KotlinLookupObject {
|
||||
override val shortName: Name = packageFqName.shortName()
|
||||
}
|
||||
|
||||
|
||||
private data class ClassifierLookupObject(override val shortName: Name, val classId: ClassId?, val insertFqName: Boolean) : KotlinLookupObject
|
||||
|
||||
/**
|
||||
|
||||
+3
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinFirLookupElementFactory
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -27,6 +28,8 @@ internal class FirBasicCompletionContext(
|
||||
val indexHelper: IndexHelper,
|
||||
val lookupElementFactory: KotlinFirLookupElementFactory = KotlinFirLookupElementFactory(),
|
||||
) {
|
||||
val visibleScope = KotlinSourceFilterScope.projectSourceAndClassFiles(originalKtFile.resolveScope, project)
|
||||
|
||||
companion object {
|
||||
fun createFromParameters(parameters: CompletionParameters, result: CompletionResultSet): FirBasicCompletionContext? {
|
||||
val prefixMatcher = result.prefixMatcher
|
||||
|
||||
@@ -92,4 +92,12 @@ interface KtDeclarationScope<out T : KtSymbolWithDeclarations> : KtScope {
|
||||
|
||||
interface KtPackageScope : KtScope {
|
||||
val fqName: FqName
|
||||
|
||||
fun getPackageSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtPackageSymbol>
|
||||
|
||||
override fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
|
||||
super.getAllSymbols() + getPackageSymbols()
|
||||
}
|
||||
|
||||
override fun getConstructors(): Sequence<KtConstructorSymbol> = withValidityAssertion { emptySequence() }
|
||||
}
|
||||
+6
@@ -48,6 +48,9 @@ abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
|
||||
abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol?
|
||||
|
||||
abstract fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol>
|
||||
|
||||
@Suppress("PropertyName")
|
||||
abstract val ROOT_PACKAGE_SYMBOL: KtPackageSymbol
|
||||
}
|
||||
|
||||
interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
|
||||
@@ -111,4 +114,7 @@ interface KtSymbolProviderMixIn : KtAnalysisSessionMixIn {
|
||||
fun FqName.getContainingCallableSymbolsWithName(name: Name): Sequence<KtSymbol> =
|
||||
analysisSession.symbolProvider.getTopLevelCallableSymbols(this, name)
|
||||
|
||||
@Suppress("PropertyName")
|
||||
val ROOT_PACKAGE_SYMBOL: KtPackageSymbol
|
||||
get() = analysisSession.symbolProvider.ROOT_PACKAGE_SYMBOL
|
||||
}
|
||||
+12
-2
@@ -6,7 +6,9 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.*
|
||||
@@ -19,6 +21,8 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirOverrideInfoProvi
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.threadLocal
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -28,6 +32,7 @@ private constructor(
|
||||
val firResolveState: FirModuleResolveState,
|
||||
internal val firSymbolBuilder: KtSymbolByFirBuilder,
|
||||
token: ValidityToken,
|
||||
element: KtElement,
|
||||
private val mode: AnalysisSessionMode,
|
||||
) : KtAnalysisSession(token) {
|
||||
|
||||
@@ -90,19 +95,23 @@ private constructor(
|
||||
contextResolveState,
|
||||
firSymbolBuilder.createReadOnlyCopy(contextResolveState),
|
||||
token,
|
||||
originalKtFile,
|
||||
AnalysisSessionMode.DEPENDENT_COPY
|
||||
)
|
||||
}
|
||||
|
||||
val rootModuleSession: FirSession get() = firResolveState.rootModuleSession
|
||||
val firSymbolProvider: FirSymbolProvider get() = rootModuleSession.symbolProvider
|
||||
val targetPlatform: TargetPlatform get() = rootModuleSession.moduleData.platform
|
||||
val searchScope: GlobalSearchScope = KotlinSourceFilterScope.projectSourceAndClassFiles(element.resolveScope, project)
|
||||
|
||||
companion object {
|
||||
@InvalidWayOfUsingAnalysisSession
|
||||
@Deprecated("Please use org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProviderKt.analyze")
|
||||
internal fun createAnalysisSessionByResolveState(
|
||||
firResolveState: FirModuleResolveState,
|
||||
token: ValidityToken
|
||||
token: ValidityToken,
|
||||
element: KtElement,
|
||||
): KtFirAnalysisSession {
|
||||
val project = firResolveState.project
|
||||
val firSymbolBuilder = KtSymbolByFirBuilder(
|
||||
@@ -115,7 +124,8 @@ private constructor(
|
||||
firResolveState,
|
||||
firSymbolBuilder,
|
||||
token,
|
||||
AnalysisSessionMode.REGULAR
|
||||
element,
|
||||
AnalysisSessionMode.REGULAR,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class KtFirAnalysisSessionProvider(private val project: Project) : KtAnalysisSes
|
||||
return cache.getAnalysisSession(resolveState to factory.identifier) {
|
||||
val validityToken = factory.create(project)
|
||||
@Suppress("DEPRECATION")
|
||||
KtFirAnalysisSession.createAnalysisSessionByResolveState(resolveState, validityToken)
|
||||
KtFirAnalysisSession.createAnalysisSessionByResolveState(resolveState, validityToken, contextElement)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir
|
||||
|
||||
import com.google.common.collect.MapMaker
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
@@ -112,10 +113,16 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
|
||||
|
||||
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
|
||||
val exists = PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project)
|
||||
val exists =
|
||||
PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project)
|
||||
|| JavaPsiFacade.getInstance(project).findPackage(packageFqName.asString()) != null
|
||||
if (!exists) {
|
||||
return null
|
||||
}
|
||||
return createPackageSymbol(packageFqName)
|
||||
}
|
||||
|
||||
fun createPackageSymbol(packageFqName: FqName): KtFirPackageSymbol {
|
||||
return KtFirPackageSymbol(packageFqName, project, token)
|
||||
}
|
||||
|
||||
|
||||
+22
-7
@@ -107,15 +107,22 @@ internal class KtFirScopeProvider(
|
||||
|
||||
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope = withValidityAssertion {
|
||||
packageMemberScopeCache.getOrPut(packageSymbol) {
|
||||
val firPackageScope =
|
||||
FirPackageMemberScope(
|
||||
packageSymbol.fqName,
|
||||
firResolveState.rootModuleSession/*TODO use correct session here*/
|
||||
).also(firScopeStorage::register)
|
||||
KtFirPackageScope(firPackageScope, project, builder, token)
|
||||
KtFirPackageScope(
|
||||
packageSymbol.fqName,
|
||||
project,
|
||||
builder,
|
||||
this,
|
||||
token,
|
||||
analysisSession.searchScope,
|
||||
analysisSession.targetPlatform
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun registerScope(scope: FirScope) {
|
||||
firScopeStorage.register(scope)
|
||||
}
|
||||
|
||||
override fun getCompositeScope(subScopes: List<KtScope>): KtCompositeScope = withValidityAssertion {
|
||||
KtFirCompositeScope(subScopes, token)
|
||||
}
|
||||
@@ -179,7 +186,15 @@ internal class KtFirScopeProvider(
|
||||
return when (firScope) {
|
||||
is FirAbstractSimpleImportingScope -> KtFirNonStarImportingScope(firScope, builder, token)
|
||||
is FirAbstractStarImportingScope -> KtFirStarImportingScope(firScope, builder, project, token)
|
||||
is FirPackageMemberScope -> KtFirPackageScope(firScope, project, builder, token)
|
||||
is FirPackageMemberScope -> KtFirPackageScope(
|
||||
firScope.fqName,
|
||||
project,
|
||||
builder,
|
||||
this,
|
||||
token,
|
||||
analysisSession.searchScope,
|
||||
analysisSession.targetPlatform
|
||||
)
|
||||
is FirContainingNamesAwareScope -> KtFirDelegatingScopeImpl(firScope, builder, token)
|
||||
is FirMemberTypeParameterScope -> KtFirDelegatingScopeImpl(firScope, builder, token)
|
||||
else -> TODO(firScope::class.toString())
|
||||
|
||||
+38
-8
@@ -6,32 +6,45 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.searchScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.components.KtFirScopeProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.lazyThreadUnsafeWeakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtPackageScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelClassByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.search.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
|
||||
internal class KtFirPackageScope(
|
||||
firScope: FirPackageMemberScope,
|
||||
override val fqName: FqName,
|
||||
private val project: Project,
|
||||
private val builder: KtSymbolByFirBuilder,
|
||||
_scopeProvider: KtFirScopeProvider,
|
||||
override val token: ValidityToken,
|
||||
private val searchScope: GlobalSearchScope,
|
||||
private val targetPlatform: TargetPlatform,
|
||||
) : KtPackageScope {
|
||||
private val firScope by weakRef(firScope)
|
||||
override val fqName: FqName get() = firScope.fqName
|
||||
private val scopeProvider by weakRef(_scopeProvider)
|
||||
|
||||
private val firScope: FirPackageMemberScope by lazyThreadUnsafeWeakRef {
|
||||
val scope = FirPackageMemberScope(fqName, builder.rootSession)
|
||||
scopeProvider.registerScope(scope)
|
||||
scope
|
||||
}
|
||||
|
||||
override fun getPossibleCallableNames() = withValidityAssertion {
|
||||
hashSetOf<Name>().apply {
|
||||
@@ -58,5 +71,22 @@ internal class KtFirPackageScope(
|
||||
firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
|
||||
}
|
||||
|
||||
override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence()
|
||||
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = withValidityAssertion {
|
||||
sequence {
|
||||
PackageIndexUtil
|
||||
.getSubPackageFqNames(fqName, searchScope, project, nameFilter)
|
||||
.forEach {
|
||||
yield(builder.createPackageSymbol(it))
|
||||
}
|
||||
|
||||
if (targetPlatform.isJvm()) {
|
||||
JavaPsiFacade.getInstance(project).findPackage(fqName.asString())?.getSubPackages(searchScope)?.forEach { psiPackage ->
|
||||
val fqName = psiPackage.getKotlinFqName() ?: return@forEach
|
||||
if (nameFilter(fqName.shortName())) {
|
||||
yield(builder.createPackageSymbol(fqName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||
|
||||
+2
@@ -131,4 +131,6 @@ internal class KtFirSymbolProvider(
|
||||
val firs = firSymbolProvider.getTopLevelCallableSymbols(packageFqName, name)
|
||||
return firs.asSequence().map { firSymbol -> firSymbolBuilder.buildSymbol(firSymbol.fir) }
|
||||
}
|
||||
|
||||
override val ROOT_PACKAGE_SYMBOL: KtPackageSymbol = KtFirPackageSymbol(FqName.ROOT, resolveState.project, token)
|
||||
}
|
||||
+3
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
|
||||
class KtAnalysisSessionFe10BindingHolder private constructor(
|
||||
@@ -46,8 +47,8 @@ class KtAnalysisSessionFe10BindingHolder private constructor(
|
||||
|
||||
companion object {
|
||||
@InvalidWayOfUsingAnalysisSession
|
||||
fun create(firResolveState: FirModuleResolveState, token: ValidityToken): KtAnalysisSessionFe10BindingHolder {
|
||||
val firAnalysisSession = KtFirAnalysisSession.createAnalysisSessionByResolveState(firResolveState, token)
|
||||
fun create(firResolveState: FirModuleResolveState, token: ValidityToken, ktElement: KtElement): KtAnalysisSessionFe10BindingHolder {
|
||||
val firAnalysisSession = KtFirAnalysisSession.createAnalysisSessionByResolveState(firResolveState, token, ktElement)
|
||||
return KtAnalysisSessionFe10BindingHolder(firAnalysisSession)
|
||||
}
|
||||
}
|
||||
|
||||
+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.idea.frontend.api.fir.utils
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ReadOnlyWeakRef<V : Any>
|
||||
@Deprecated("Consider suing ValidityTokenOwner.weakRef instead")
|
||||
constructor(value: V, val token: ValidityToken) {
|
||||
val weakRef = WeakReference(value)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline operator fun getValue(thisRef: Any, property: KProperty<*>): V =
|
||||
weakRef.get() ?: if (token.isValid()) {
|
||||
throw EntityWasGarbageCollectedException(property.toString())
|
||||
} else {
|
||||
error("Accessing the invalid value of $property")
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun <V : Any> ValidityTokenOwner.weakRef(value: V) = ReadOnlyWeakRef(value, token)
|
||||
|
||||
internal inline fun <V : Any> ValidityTokenOwner.weakRef(value: () -> V) = ReadOnlyWeakRef(value(), token)
|
||||
+12
-10
@@ -10,21 +10,23 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ReadOnlyWeakRef<V : Any>
|
||||
@Deprecated("Consider suing ValidityTokenOwner.weakRef instead")
|
||||
constructor(value: V, val token: ValidityToken) {
|
||||
val weakRef = WeakReference(value)
|
||||
internal class LazyThreadUnsafeWeakRef<V : Any>
|
||||
constructor(_createValue: () -> V, val token: ValidityToken) {
|
||||
private var createValue: (() -> V)? = _createValue
|
||||
private var weakRef: WeakReference<V>? = null
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline operator fun getValue(thisRef: Any, property: KProperty<*>): V =
|
||||
weakRef.get() ?: if (token.isValid()) {
|
||||
inline operator fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||
if (weakRef == null) {
|
||||
weakRef = WeakReference(createValue!!())
|
||||
createValue = null
|
||||
}
|
||||
return weakRef!!.get() ?: if (token.isValid()) {
|
||||
throw EntityWasGarbageCollectedException(property.toString())
|
||||
} else {
|
||||
error("Accessing the invalid value of $property")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun <V : Any> ValidityTokenOwner.weakRef(value: V) = ReadOnlyWeakRef(value, token)
|
||||
|
||||
internal inline fun <V : Any> ValidityTokenOwner.weakRef(value: () -> V) = ReadOnlyWeakRef(value(), token)
|
||||
internal fun <V : Any> ValidityTokenOwner.lazyThreadUnsafeWeakRef(createValue: () -> V) = LazyThreadUnsafeWeakRef(createValue, token)
|
||||
Reference in New Issue
Block a user