FIR IDE: introduce scopes for HL API
This commit is contained in:
@@ -7,6 +7,7 @@ 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.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -18,6 +19,7 @@ abstract class KtAnalysisSession(project: Project) : ValidityOwner {
|
||||
override fun invalidationReason(): String = validityToken.invalidationReason()
|
||||
|
||||
abstract val symbolProvider: KtSymbolProvider
|
||||
abstract val scopeProvider: KtScopeProvider
|
||||
|
||||
abstract fun getSmartCastedToTypes(expression: KtExpression): Collection<KtType>?
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface KtScope : ValidityOwner {
|
||||
fun getAllNames(): Set<Name>
|
||||
fun getCallableNames(): Set<Name>
|
||||
fun getClassLikeSymbolNames(): Set<Name>
|
||||
|
||||
|
||||
fun getAllSymbols(): Sequence<KtSymbol>
|
||||
fun getCallableSymbols(): Sequence<KtSymbol>
|
||||
fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol>
|
||||
|
||||
fun containsName(name: Name): Boolean
|
||||
}
|
||||
|
||||
interface KtMemberScope : KtScope {
|
||||
val owner: KtClassOrObjectSymbol
|
||||
}
|
||||
|
||||
interface KtDeclaredMemberScope : KtScope {
|
||||
val owner: KtClassOrObjectSymbol
|
||||
}
|
||||
|
||||
interface KtPackageScope : KtScope, KtSubstitutedScope<KtPackageScope> {
|
||||
val owner: KtPackageSymbol
|
||||
}
|
||||
|
||||
interface KtUnsubstitutedScope<S : KtScope> : KtScope {
|
||||
fun substitute(/*substitution*/): KtSubstitutedScope<S> = TODO()
|
||||
}
|
||||
|
||||
interface KtSubstitutedScope<S> : KtScope
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.scopes
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol
|
||||
|
||||
abstract class KtScopeProvider : ValidityOwner {
|
||||
abstract fun getMemberScope(classSymbol: KtClassOrObjectSymbol): KtMemberScope
|
||||
abstract fun getDeclaredMemberScope(classSymbol: KtClassOrObjectSymbol): KtDeclaredMemberScope
|
||||
abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope
|
||||
}
|
||||
+4
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.idea.fir.*
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
|
||||
import org.jetbrains.kotlin.idea.frontend.api.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirScopeProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolProvider
|
||||
@@ -59,6 +61,8 @@ constructor(
|
||||
firSymbolBuilder
|
||||
)
|
||||
|
||||
override val scopeProvider: KtScopeProvider = KtFirScopeProvider(token, firSymbolBuilder, firSession)
|
||||
|
||||
init {
|
||||
assertIsValid()
|
||||
}
|
||||
|
||||
-1
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||
|
||||
/**
|
||||
* Maps FirElement to KtSymbol & ConeType to KtType, thread safe
|
||||
|
||||
+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.idea.frontend.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwnerByValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope
|
||||
|
||||
internal class KtFirDeclaredMemberScope(
|
||||
override val owner: KtFirClassOrObjectSymbol,
|
||||
override val token: ValidityOwner,
|
||||
builder: KtSymbolByFirBuilder
|
||||
) : KtFirDelegatingScope(builder),
|
||||
KtDeclaredMemberScope,
|
||||
KtUnsubstitutedScope<KtFirDelegatingScope>,
|
||||
ValidityOwnerByValidityToken {
|
||||
override val firScope: FirScope by weakRef(declaredMemberScope(owner.fir))
|
||||
}
|
||||
|
||||
+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.idea.frontend.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
|
||||
internal abstract class KtFirDelegatingScope(private val builder: KtSymbolByFirBuilder) : KtScope {
|
||||
abstract val firScope: FirScope
|
||||
|
||||
private var allNamesCached: Set<Name>? = null
|
||||
|
||||
override fun getAllNames(): Set<Name> = withValidityAssertion {
|
||||
if (allNamesCached == null) {
|
||||
allNamesCached = firScope.getCallableNames() + firScope.getClassifierNames()
|
||||
}
|
||||
allNamesCached!!
|
||||
}
|
||||
|
||||
override fun getCallableNames(): Set<Name> = withValidityAssertion {
|
||||
firScope.getCallableNames()
|
||||
}
|
||||
|
||||
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
|
||||
firScope.getClassifierNames()
|
||||
}
|
||||
|
||||
override fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
|
||||
sequence {
|
||||
yieldAll(getCallableSymbols())
|
||||
yieldAll(getClassClassLikeSymbols())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCallableSymbols(): Sequence<KtSymbol> = withValidityAssertion {
|
||||
sequence {
|
||||
firScope.getCallableNames().forEach { name ->
|
||||
val callables = mutableListOf<KtSymbol>()
|
||||
firScope.processFunctionsByName(name) { firSymbol ->
|
||||
(firSymbol.fir as? FirSimpleFunction)?.let { fir ->
|
||||
callables.add(builder.buildFunctionSymbol(fir))
|
||||
}
|
||||
}
|
||||
firScope.processPropertiesByName(name) { firSymbol ->
|
||||
callables.add(builder.buildSymbol(firSymbol.fir))
|
||||
}
|
||||
yieldAll(callables)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
|
||||
sequence {
|
||||
firScope.getClassifierNames().forEach { name ->
|
||||
val classLikeSymbols = mutableListOf<KtClassLikeSymbol>()
|
||||
firScope.processClassifiersByName(name) { firSymbol ->
|
||||
(firSymbol.fir as? FirClassLikeDeclaration<*>)?.let {
|
||||
classLikeSymbols.add(builder.buildClassLikeSymbol(it))
|
||||
}
|
||||
}
|
||||
yieldAll(classLikeSymbols)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun containsName(name: Name): Boolean = withValidityAssertion {
|
||||
name in getAllNames()
|
||||
}
|
||||
}
|
||||
+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.idea.frontend.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwnerByValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtUnsubstitutedScope
|
||||
|
||||
internal class KtFirMemberScope(
|
||||
override val owner: KtFirClassOrObjectSymbol,
|
||||
override val token: ValidityOwner,
|
||||
builder: KtSymbolByFirBuilder
|
||||
) : KtFirDelegatingScope(builder), KtMemberScope, KtUnsubstitutedScope<KtMemberScope>, ValidityOwnerByValidityToken {
|
||||
override val firScope: FirScope by weakRef {
|
||||
owner.fir.buildUseSiteMemberScope(owner.fir.session, ScopeSession())
|
||||
}
|
||||
}
|
||||
|
||||
+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.idea.frontend.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwnerByValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
|
||||
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.symbols.KtPackageSymbol
|
||||
|
||||
internal class KtFirPackageScope(
|
||||
override val owner: KtFirPackageSymbol,
|
||||
override val token: ValidityOwner,
|
||||
builder: KtSymbolByFirBuilder,
|
||||
session: FirSession,
|
||||
) : KtPackageScope, KtFirDelegatingScope(builder), ValidityOwnerByValidityToken {
|
||||
override val firScope: FirScope by weakRef {
|
||||
FirPackageMemberScope(owner.fqName, session)
|
||||
}
|
||||
}
|
||||
+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.idea.frontend.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwnerByValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtMemberScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtPackageScope
|
||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider
|
||||
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.withValidityAssertion
|
||||
import java.util.*
|
||||
|
||||
internal class KtFirScopeProvider(
|
||||
override val token: ValidityOwner,
|
||||
private val builder: KtSymbolByFirBuilder,
|
||||
session: FirSession
|
||||
) : KtScopeProvider(), ValidityOwnerByValidityToken {
|
||||
private val session by weakRef(session)
|
||||
|
||||
private val memberScopeCache = IdentityHashMap<KtClassOrObjectSymbol, KtMemberScope>()
|
||||
private val declaredMemberScopeCache = IdentityHashMap<KtClassOrObjectSymbol, KtDeclaredMemberScope>()
|
||||
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
|
||||
|
||||
override fun getMemberScope(classSymbol: KtClassOrObjectSymbol): KtMemberScope = withValidityAssertion {
|
||||
memberScopeCache.getOrPut(classSymbol) {
|
||||
check(classSymbol is KtFirClassOrObjectSymbol)
|
||||
KtFirMemberScope(classSymbol, token, builder)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDeclaredMemberScope(classSymbol: KtClassOrObjectSymbol): KtDeclaredMemberScope = withValidityAssertion {
|
||||
declaredMemberScopeCache.getOrPut(classSymbol) {
|
||||
check(classSymbol is KtFirClassOrObjectSymbol)
|
||||
KtFirDeclaredMemberScope(classSymbol, token, builder)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope = withValidityAssertion {
|
||||
packageMemberScopeCache.getOrPut(packageSymbol) {
|
||||
check(packageSymbol is KtFirPackageSymbol)
|
||||
KtFirPackageScope(packageSymbol, token, builder, session)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-13
@@ -24,8 +24,8 @@ class KtFirPackageSymbol(
|
||||
private val project: Project,
|
||||
override val token: ValidityOwner
|
||||
) : KtPackageSymbol(), ValidityOwnerByValidityToken {
|
||||
override val psi: PsiElement by cached {
|
||||
KtPackage(PsiManager.getInstance(project), fqName, GlobalSearchScope.allScope(project))
|
||||
override val psi: PsiElement? by cached {
|
||||
PsiPackageImpl(PsiManager.getInstance(project), fqName.asString().replace('/', '.'))
|
||||
}
|
||||
|
||||
override val origin: KtSymbolOrigin
|
||||
@@ -35,14 +35,4 @@ class KtFirPackageSymbol(
|
||||
check(session is KtFirAnalysisSession)
|
||||
session.firSymbolBuilder.createPackageSymbolIfOneExists(fqName)
|
||||
}
|
||||
}
|
||||
|
||||
class KtPackage(
|
||||
manager: PsiManager,
|
||||
private val fqName: FqName,
|
||||
private val scope: GlobalSearchScope
|
||||
) : PsiPackageImpl(manager, fqName.asString()) {
|
||||
override fun copy() = KtPackage(manager, fqName, scope)
|
||||
|
||||
override fun isValid(): Boolean = PackageIndexUtil.packageExists(fqName, scope, project)
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -22,4 +22,6 @@ class ReadOnlyWeakRef<V : Any>(value: V, val validityOwner: ValidityOwner) {
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun <V : Any> ValidityOwner.weakRef(value: V) = ReadOnlyWeakRef(value, this)
|
||||
internal inline fun <V : Any> ValidityOwner.weakRef(value: V) = ReadOnlyWeakRef(value, this)
|
||||
|
||||
internal inline fun <V : Any> ValidityOwner.weakRef(value: () -> V) = ReadOnlyWeakRef(value(), this)
|
||||
Reference in New Issue
Block a user