[FIR] Refactoring: create use-site scopes via scope provider

This commit is contained in:
Simon Ogorodnik
2019-12-19 01:31:12 +03:00
committed by Mikhail Glukhikh
parent 5f08fe88a5
commit 1715f1a864
64 changed files with 536 additions and 296 deletions
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirDependenciesSymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirLibrarySymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberScopeProvider
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
import org.jetbrains.kotlin.load.java.JavaClassFinder
@@ -41,7 +43,10 @@ class FirJavaModuleBasedSession(
init {
sessionProvider.sessionCache[moduleInfo] = this
val firProvider = FirProviderImpl(this)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
registerComponent(FirProvider::class, firProvider)
registerComponent(
@@ -84,17 +89,20 @@ class FirLibrarySession private constructor(
init {
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
registerComponent(
FirSymbolProvider::class,
FirCompositeSymbolProvider(
listOf(
FirLibrarySymbolProviderImpl(this),
FirLibrarySymbolProviderImpl(this, kotlinScopeProvider),
KotlinDeserializedJvmSymbolsProvider(
this, sessionProvider.project,
packagePartProvider,
javaSymbolProvider,
kotlinClassFinder,
javaClassFinder
javaClassFinder,
kotlinScopeProvider
),
javaSymbolProvider,
FirDependenciesSymbolProviderImpl(this)
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2019 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.fir.java
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope
import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.ConeSubstitutionScopeKey
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScopeWithLazyNestedScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
class JavaScopeProvider(
val declaredMemberScopeDecorator: (
klass: FirClass<*>,
declaredMemberScope: FirScope,
useSiteSession: FirSession,
scopeSession: ScopeSession
) -> FirScope = { _, declaredMemberScope, _, _ -> declaredMemberScope },
val symbolProvider: JavaSymbolProvider
) : FirScopeProvider() {
override fun getUseSiteMemberScope(
klass: FirClass<*>,
substitutor: ConeSubstitutor,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
val baseScope = buildJavaEnhancementScope(useSiteSession, klass.symbol as FirRegularClassSymbol, scopeSession, mutableSetOf())
if (substitutor == ConeSubstitutor.Empty) return baseScope
return scopeSession.getOrBuild(klass, ConeSubstitutionScopeKey(substitutor)) {
FirClassSubstitutionScope(useSiteSession, baseScope, scopeSession, substitutor)
}
}
private fun buildJavaEnhancementScope(
useSiteSession: FirSession,
symbol: FirRegularClassSymbol,
scopeSession: ScopeSession,
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
): JavaClassEnhancementScope {
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
JavaClassEnhancementScope(
useSiteSession,
buildUseSiteMemberScopeWithJavaTypes(symbol.fir, useSiteSession, scopeSession, visitedSymbols)
)
}
}
private fun buildUseSiteMemberScopeWithJavaTypes(
regularClass: FirRegularClass,
useSiteSession: FirSession,
scopeSession: ScopeSession,
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
): JavaClassUseSiteMemberScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val declaredScope = if (regularClass is FirJavaClass) declaredMemberScopeWithLazyNestedScope(
regularClass,
existingNames = regularClass.existingNestedClassifierNames,
symbolProvider = symbolProvider
) else declaredMemberScope(regularClass)
val wrappedDeclaredScope = declaredMemberScopeDecorator(regularClass, declaredScope, useSiteSession, scopeSession)
val superTypeEnhancementScopes =
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNull { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirRegularClassSymbol && visitedSymbols.add(symbol)) {
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
val scope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, visitedSymbols)
visitedSymbols.remove(symbol)
useSiteSuperType.wrapSubstitutionScopeIfNeed(useSiteSession, scope, symbol.fir, scopeSession)
} else {
null
}
}
JavaClassUseSiteMemberScope(
regularClass, useSiteSession,
FirSuperTypeScope.prepareSupertypeScope(
useSiteSession,
JavaOverrideChecker(
useSiteSession,
if (regularClass is FirJavaClass) regularClass.javaTypeParameterStack
else JavaTypeParameterStack.EMPTY
),
superTypeEnhancementScopes
), wrappedDeclaredScope
)
}
}
}
private val JAVA_ENHANCEMENT = scopeSessionKey<FirRegularClassSymbol, JavaClassEnhancementScope>()
private val JAVA_USE_SITE = scopeSessionKey<FirRegularClassSymbol, JavaClassUseSiteMemberScope>()
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope
import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.CallableId
@@ -53,6 +54,8 @@ class JavaSymbolProvider(
private val searchScope: GlobalSearchScope
) : AbstractFirSymbolProvider<FirRegularClassSymbol>() {
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
private fun findClass(
@@ -77,71 +80,6 @@ class JavaSymbolProvider(
}
}
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, mutableSetOf())
}
private fun buildJavaEnhancementScope(
useSiteSession: FirSession,
symbol: FirRegularClassSymbol,
scopeSession: ScopeSession,
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
): JavaClassEnhancementScope {
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
JavaClassEnhancementScope(
useSiteSession,
buildJavaUseSiteMemberScope(symbol.fir, useSiteSession, scopeSession, visitedSymbols)
)
}
}
private fun buildJavaUseSiteMemberScope(
regularClass: FirRegularClass,
useSiteSession: FirSession,
scopeSession: ScopeSession,
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
): JavaClassUseSiteMemberScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val declaredScope = if (regularClass is FirJavaClass) declaredMemberScopeWithLazyNestedScope(
regularClass,
existingNames = regularClass.existingNestedClassifierNames,
symbolProvider = this
) else declaredMemberScope(regularClass)
val wrappedDeclaredScope = wrapScopeWithJvmMapped(regularClass, declaredScope, useSiteSession, scopeSession)
val superTypeEnhancementScopes =
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNull { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNull null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirRegularClassSymbol && visitedSymbols.add(symbol)) {
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
val scope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, visitedSymbols)
visitedSymbols.remove(symbol)
useSiteSuperType.wrapSubstitutionScopeIfNeed(useSiteSession, scope, symbol.fir, scopeSession)
} else {
null
}
}
JavaClassUseSiteMemberScope(
regularClass, useSiteSession,
FirSuperTypeScope.prepareSupertypeScope(
useSiteSession,
JavaOverrideChecker(
useSiteSession,
if (regularClass is FirJavaClass) regularClass.javaTypeParameterStack
else JavaTypeParameterStack.EMPTY
),
superTypeEnhancementScopes
), wrappedDeclaredScope
)
}
}
private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameter {
val stored = javaTypeParameterStack.safeGet(this)
if (stored != null) return stored.fir
@@ -218,7 +156,8 @@ class JavaSymbolProvider(
javaClass.classKind, isTopLevel = isTopLevel,
isStatic = javaClass.isStatic,
javaTypeParameterStack = javaTypeParameterStack,
existingNestedClassifierNames = javaClass.innerClassNames.toList()
existingNestedClassifierNames = javaClass.innerClassNames.toList(),
scopeProvider = scopeProvider
).apply {
this.typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
@@ -356,5 +295,3 @@ fun FqName.topLevelName() =
asString().substringBefore(".")
private val JAVA_ENHANCEMENT = scopeSessionKey<FirRegularClassSymbol, JavaClassEnhancementScope>()
private val JAVA_USE_SITE = scopeSessionKey<FirRegularClassSymbol, JavaClassUseSiteMemberScope>()
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer
@@ -37,6 +38,7 @@ class FirJavaClass internal constructor(
override val classKind: ClassKind,
isTopLevel: Boolean,
isStatic: Boolean,
override val scopeProvider: FirScopeProvider,
internal val javaTypeParameterStack: JavaTypeParameterStack,
internal val existingNestedClassifierNames: List<Name>
) : FirPureAbstractElement(), FirRegularClass, FirModifiableClass<FirRegularClass> {
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
@@ -60,7 +61,8 @@ class KotlinDeserializedJvmSymbolsProvider(
private val packagePartProvider: PackagePartProvider,
private val javaSymbolProvider: JavaSymbolProvider,
private val kotlinClassFinder: KotlinClassFinder,
private val javaClassFinder: JavaClassFinder
private val javaClassFinder: JavaClassFinder,
private val kotlinScopeProvider: KotlinScopeProvider
) : AbstractFirSymbolProvider<FirClassLikeSymbol<*>>() {
private val classesCache = HashMap<ClassId, FirRegularClassSymbol>()
private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>()
@@ -141,16 +143,6 @@ class KotlinDeserializedJvmSymbolsProvider(
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
get() = classHeader.isPreRelease
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) as? FirClassSymbol ?: return null
if (classId in handledByJava) return null
return buildDefaultUseSiteMemberScope((symbol.fir as FirClass<*>), useSiteSession, scopeSession)
}
override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? {
return findAndDeserializeClass(classId) ?: findAndDeserializeTypeAlias(classId)
}
@@ -345,6 +337,7 @@ class KotlinDeserializedJvmSymbolsProvider(
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session),
kotlinScopeProvider,
parentContext, this::findAndDeserializeClass
)
symbol.fir.declarations.filterIsInstance<FirEnumEntryImpl>().forEach {