[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
@@ -161,10 +161,11 @@ abstract class AbstractSimpleFileBenchmark {
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile)) val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project)) .uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
val session = createSession(env, scope) val session = createSession(env, scope)
val builder = RawFirBuilder(session, stubMode = false) val firProvider = session.firProvider as FirProviderImpl
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val totalTransformer = FirTotalResolveTransformer() val totalTransformer = FirTotalResolveTransformer()
val firFile = builder.buildFirFile(file).also((session.firProvider as FirProviderImpl)::recordFile) val firFile = builder.buildFirFile(file).also(firProvider::recordFile)
for (transformer in totalTransformer.transformers) { for (transformer in totalTransformer.transformers) {
transformer.transformFile(firFile, null) transformer.transformFile(firFile, null)
@@ -325,11 +325,12 @@ object KotlinToJVMBytecodeCompiler {
) )
} }
val builder = RawFirBuilder(session, stubMode = false) val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer() val resolveTransformer = FirTotalResolveTransformer()
val firFiles = ktFiles.map { val firFiles = ktFiles.map {
val firFile = builder.buildFirFile(it) val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFile firFile
}.also { }.also {
try { try {
@@ -0,0 +1,29 @@
/*
* 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.resolve.substitution
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
abstract class ConeSubstitutor : TypeSubstitutorMarker {
open fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType = substituteOrNull(type) ?: type
abstract fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
object Empty : ConeSubstitutor() {
override fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType {
return type
}
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
return null
}
}
}
fun ConeSubstitutor.substituteOrNull(type: ConeKotlinType?): ConeKotlinType? {
return type?.let { substituteOrNull(it) }
}
@@ -76,12 +76,13 @@ abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() {
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project)) .uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val session = createSession(myEnvironment, scope) val session = createSession(myEnvironment, scope)
val builder = RawFirBuilder(session, stubMode = false) val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer() val resolveTransformer = FirTotalResolveTransformer()
val firFiles = psiFiles.map { val firFiles = psiFiles.map {
val firFile = builder.buildFirFile(it) val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFile firFile
}.also { }.also {
try { try {
@@ -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.FirDependenciesSymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirLibrarySymbolProviderImpl import org.jetbrains.kotlin.fir.resolve.impl.FirLibrarySymbolProviderImpl
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl 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.scopes.impl.FirMemberScopeProvider
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
import org.jetbrains.kotlin.load.java.JavaClassFinder import org.jetbrains.kotlin.load.java.JavaClassFinder
@@ -41,7 +43,10 @@ class FirJavaModuleBasedSession(
init { init {
sessionProvider.sessionCache[moduleInfo] = this sessionProvider.sessionCache[moduleInfo] = this
val firProvider = FirProviderImpl(this)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
registerComponent(FirProvider::class, firProvider) registerComponent(FirProvider::class, firProvider)
registerComponent( registerComponent(
@@ -84,17 +89,20 @@ class FirLibrarySession private constructor(
init { init {
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope) val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
registerComponent( registerComponent(
FirSymbolProvider::class, FirSymbolProvider::class,
FirCompositeSymbolProvider( FirCompositeSymbolProvider(
listOf( listOf(
FirLibrarySymbolProviderImpl(this), FirLibrarySymbolProviderImpl(this, kotlinScopeProvider),
KotlinDeserializedJvmSymbolsProvider( KotlinDeserializedJvmSymbolsProvider(
this, sessionProvider.project, this, sessionProvider.project,
packagePartProvider, packagePartProvider,
javaSymbolProvider, javaSymbolProvider,
kotlinClassFinder, kotlinClassFinder,
javaClassFinder javaClassFinder,
kotlinScopeProvider
), ),
javaSymbolProvider, javaSymbolProvider,
FirDependenciesSymbolProviderImpl(this) 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.JavaClassUseSiteMemberScope
import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker
import org.jetbrains.kotlin.fir.resolve.* 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.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
@@ -53,6 +54,8 @@ class JavaSymbolProvider(
private val searchScope: GlobalSearchScope private val searchScope: GlobalSearchScope
) : AbstractFirSymbolProvider<FirRegularClassSymbol>() { ) : AbstractFirSymbolProvider<FirRegularClassSymbol>() {
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project) private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
private fun findClass( 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 { private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameter {
val stored = javaTypeParameterStack.safeGet(this) val stored = javaTypeParameterStack.safeGet(this)
if (stored != null) return stored.fir if (stored != null) return stored.fir
@@ -218,7 +156,8 @@ class JavaSymbolProvider(
javaClass.classKind, isTopLevel = isTopLevel, javaClass.classKind, isTopLevel = isTopLevel,
isStatic = javaClass.isStatic, isStatic = javaClass.isStatic,
javaTypeParameterStack = javaTypeParameterStack, javaTypeParameterStack = javaTypeParameterStack,
existingNestedClassifierNames = javaClass.innerClassNames.toList() existingNestedClassifierNames = javaClass.innerClassNames.toList(),
scopeProvider = scopeProvider
).apply { ).apply {
this.typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack) this.typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack) addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
@@ -356,5 +295,3 @@ fun FqName.topLevelName() =
asString().substringBefore(".") 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.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack 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.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer
@@ -37,6 +38,7 @@ class FirJavaClass internal constructor(
override val classKind: ClassKind, override val classKind: ClassKind,
isTopLevel: Boolean, isTopLevel: Boolean,
isStatic: Boolean, isStatic: Boolean,
override val scopeProvider: FirScopeProvider,
internal val javaTypeParameterStack: JavaTypeParameterStack, internal val javaTypeParameterStack: JavaTypeParameterStack,
internal val existingNestedClassifierNames: List<Name> internal val existingNestedClassifierNames: List<Name>
) : FirPureAbstractElement(), FirRegularClass, FirModifiableClass<FirRegularClass> { ) : 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.references.impl.FirResolvedNamedReferenceImpl
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.scopes.FirScope 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.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
@@ -60,7 +61,8 @@ class KotlinDeserializedJvmSymbolsProvider(
private val packagePartProvider: PackagePartProvider, private val packagePartProvider: PackagePartProvider,
private val javaSymbolProvider: JavaSymbolProvider, private val javaSymbolProvider: JavaSymbolProvider,
private val kotlinClassFinder: KotlinClassFinder, private val kotlinClassFinder: KotlinClassFinder,
private val javaClassFinder: JavaClassFinder private val javaClassFinder: JavaClassFinder,
private val kotlinScopeProvider: KotlinScopeProvider
) : AbstractFirSymbolProvider<FirClassLikeSymbol<*>>() { ) : AbstractFirSymbolProvider<FirClassLikeSymbol<*>>() {
private val classesCache = HashMap<ClassId, FirRegularClassSymbol>() private val classesCache = HashMap<ClassId, FirRegularClassSymbol>()
private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>() private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>()
@@ -141,16 +143,6 @@ class KotlinDeserializedJvmSymbolsProvider(
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
get() = classHeader.isPreRelease 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<*>? { override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? {
return findAndDeserializeClass(classId) ?: findAndDeserializeTypeAlias(classId) return findAndDeserializeClass(classId) ?: findAndDeserializeTypeAlias(classId)
} }
@@ -345,6 +337,7 @@ class KotlinDeserializedJvmSymbolsProvider(
deserializeClassToSymbol( deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session, classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session), JvmBinaryAnnotationDeserializer(session),
kotlinScopeProvider,
parentContext, this::findAndDeserializeClass parentContext, this::findAndDeserializeClass
) )
symbol.fir.declarations.filterIsInstance<FirEnumEntryImpl>().forEach { symbol.fir.declarations.filterIsInstance<FirEnumEntryImpl>().forEach {
@@ -0,0 +1,55 @@
/*
* 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.resolve.scopes
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
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.declarations.classId
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.wrapSubstitutionScopeIfNeed
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.jvm.JvmMappedScope
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
fun wrapScopeWithJvmMapped(
klass: FirClass<*>,
declaredMemberScope: FirScope,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
val classId = klass.classId
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
?: return declaredMemberScope
val symbolProvider = useSiteSession.firSymbolProvider
val javaClass = symbolProvider.getClassLikeSymbolByFqName(javaClassId)?.fir as? FirRegularClass
?: return declaredMemberScope
val preparedSignatures = JvmMappedScope.prepareSignatures(javaClass)
return if (preparedSignatures.isNotEmpty()) {
javaClass.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession).let { javaClassUseSiteScope ->
val jvmMappedScope = JvmMappedScope(declaredMemberScope, javaClassUseSiteScope, preparedSignatures)
if (klass !is FirRegularClass) {
jvmMappedScope
} else {
// We should substitute Java type parameters with base Kotlin type parameters to match overrides properly
// It's necessary for MutableMap, which has *two* JavaMappedScope inside (one for itself and another for base Map)
(klass.symbol.constructType(
klass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false
) as ConeClassLikeType).wrapSubstitutionScopeIfNeed(useSiteSession, jvmMappedScope, klass, scopeSession)
}
}
} else {
declaredMemberScope
}
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionBase import org.jetbrains.kotlin.fir.FirSessionBase
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.lexer.KotlinLexer import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.parsing.KotlinParserDefinition import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.parsing.KotlinLightParser import org.jetbrains.kotlin.parsing.KotlinLightParser
@@ -22,6 +23,7 @@ import java.nio.file.Path
class LightTree2Fir( class LightTree2Fir(
val session: FirSession = object : FirSessionBase(null) {}, val session: FirSession = object : FirSessionBase(null) {},
private val scopeProvider: FirScopeProvider,
private val stubMode: Boolean = false private val stubMode: Boolean = false
) { ) {
//private val ktDummyFile = KtFile(SingleRootFileViewProvider(PsiManager.getInstance(project), LightVirtualFile()), false) //private val ktDummyFile = KtFile(SingleRootFileViewProvider(PsiManager.getInstance(project), LightVirtualFile()), false)
@@ -64,7 +66,7 @@ class LightTree2Fir(
fun buildFirFile(code: String, fileName: String): FirFile { fun buildFirFile(code: String, fileName: String): FirFile {
val lightTree = buildLightTree(code) val lightTree = buildLightTree(code)
return DeclarationsConverter(session, stubMode, lightTree) return DeclarationsConverter(session, scopeProvider, stubMode, lightTree)
.convertFile(lightTree.root, fileName) .convertFile(lightTree.root, fileName)
} }
} }
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeModifier
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -43,6 +44,7 @@ import org.jetbrains.kotlin.name.SpecialNames
class DeclarationsConverter( class DeclarationsConverter(
session: FirSession, session: FirSession,
val scopeProvider: FirScopeProvider,
private val stubMode: Boolean, private val stubMode: Boolean,
tree: FlyweightCapableTreeStructure<LighterASTNode>, tree: FlyweightCapableTreeStructure<LighterASTNode>,
context: Context = Context() context: Context = Context()
@@ -372,6 +374,7 @@ class DeclarationsConverter(
className, className,
status, status,
classKind, classKind,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
} else { } else {
@@ -381,6 +384,7 @@ class DeclarationsConverter(
className, className,
status, status,
classKind, classKind,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
} }
@@ -485,7 +489,7 @@ class DeclarationsConverter(
val delegatedType = delegatedSuperTypeRef ?: implicitAnyType val delegatedType = delegatedSuperTypeRef ?: implicitAnyType
return withChildClassName(ANONYMOUS_OBJECT_NAME) { return withChildClassName(ANONYMOUS_OBJECT_NAME) {
FirAnonymousObjectImpl(null, session, FirAnonymousObjectSymbol()).apply { FirAnonymousObjectImpl(null, session, scopeProvider, FirAnonymousObjectSymbol()).apply {
annotations += modifiers.annotations annotations += modifiers.annotations
this.superTypeRefs += superTypeRefs this.superTypeRefs += superTypeRefs
this.typeRef = superTypeRefs.first() this.typeRef = superTypeRefs.first()
@@ -536,6 +540,7 @@ class DeclarationsConverter(
null, null,
session, session,
enumEntryName, enumEntryName,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
firEnumEntry.annotations += modifiers.annotations firEnumEntry.annotations += modifiers.annotations
@@ -1123,7 +1128,7 @@ class DeclarationsConverter(
} }
return if (!stubMode) { return if (!stubMode) {
val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText) val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText)
return DeclarationsConverter(session, stubMode, blockTree, context).convertBlockExpression(blockTree.root) return DeclarationsConverter(session, scopeProvider, stubMode, blockTree, context).convertBlockExpression(blockTree.root)
} else { } else {
FirSingleExpressionBlock( FirSingleExpressionBlock(
FirExpressionStub(null).toReturn() FirExpressionStub(null).toReturn()
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.lightTree package org.jetbrains.kotlin.fir.lightTree
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File import java.io.File
@@ -15,7 +16,7 @@ import java.nio.file.Paths
abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTestCase() { abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTestCase() {
override fun doTest(filePath: String) { override fun doTest(filePath: String) {
val firFile = LightTree2Fir(stubMode = false).buildFirFile(Paths.get(filePath)) val firFile = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = false).buildFirFile(Paths.get(filePath))
val firDump = firFile.render() val firDump = firFile.render()
val expectedFile = File(filePath.replace(".kt", ".txt")) val expectedFile = File(filePath.replace(".kt", ".txt"))
@@ -14,6 +14,7 @@ import com.intellij.testFramework.TestDataPath
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.FirSessionBase import org.jetbrains.kotlin.fir.FirSessionBase
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.parsing.* import org.jetbrains.kotlin.parsing.*
@@ -62,6 +63,7 @@ class SimpleTestCase : AbstractRawFirBuilderTestCase() {
val firFromLightTreeFile = DeclarationsConverter( val firFromLightTreeFile = DeclarationsConverter(
object : FirSessionBase(null) {}, object : FirSessionBase(null) {},
StubFirScopeProvider,
true, true,
builder.lightTree builder.lightTree
).convertFile(builder.lightTree.root) ).convertFile(builder.lightTree.root)
@@ -12,6 +12,7 @@ import com.intellij.testFramework.TestDataPath
import com.intellij.util.PathUtil import com.intellij.util.PathUtil
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -46,7 +47,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
var counter = 0 var counter = 0
var time = 0L var time = 0L
val lightTreeConverter = LightTree2Fir(stubMode = true) val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = true)
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter") if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
println("BASE PATH: $path") println("BASE PATH: $path")
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree.benchmark.generators
import com.intellij.psi.impl.DebugUtil import com.intellij.psi.impl.DebugUtil
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
@@ -16,13 +17,13 @@ import java.io.File
@State(Scope.Benchmark) @State(Scope.Benchmark)
open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase() { open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase() {
override fun generateBaseTree(text: String, file: File) { override fun generateBaseTree(text: String, file: File) {
val lightTreeConverter = LightTree2Fir(stubMode = false) val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = false)
val lightTree = lightTreeConverter.buildLightTree(text) val lightTree = lightTreeConverter.buildLightTree(text)
DebugUtil.lightTreeToString(lightTree, false) DebugUtil.lightTreeToString(lightTree, false)
} }
override fun generateFir(text: String, file: File, stubMode: Boolean) { override fun generateFir(text: String, file: File, stubMode: Boolean) {
val lightTreeConverter = LightTree2Fir(stubMode = stubMode) val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = stubMode)
val firFile = lightTreeConverter.buildFirFile(text, file.name) val firFile = lightTreeConverter.buildFirFile(text, file.name)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString() StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
} }
@@ -12,6 +12,7 @@ import com.intellij.util.PathUtil
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
import org.jetbrains.kotlin.fir.lightTree.walkTopDown import org.jetbrains.kotlin.fir.lightTree.walkTopDown
import org.jetbrains.kotlin.fir.lightTree.walkTopDownWithTestData import org.jetbrains.kotlin.fir.lightTree.walkTopDownWithTestData
@@ -43,7 +44,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
} }
private fun compareAll(stubMode: Boolean) { private fun compareAll(stubMode: Boolean) {
val lightTreeConverter = LightTree2Fir(stubMode = stubMode) val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = stubMode)
compareBase(System.getProperty("user.dir"), withTestData = false) { file -> compareBase(System.getProperty("user.dir"), withTestData = false) { file ->
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
@@ -61,7 +62,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
} }
fun testCompareDiagnostics() { fun testCompareDiagnostics() {
val lightTreeConverter = LightTree2Fir(stubMode = false) val lightTreeConverter = LightTree2Fir(scopeProvider = StubFirScopeProvider, stubMode = false)
compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file -> compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file ->
val notEditedText = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() val notEditedText = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
val text = notEditedText.replace("(<!>)|(<!.*?!>)".toRegex(), "").replaceAfter(".java", "") val text = notEditedText.replace("(<!>)|(<!.*?!>)".toRegex(), "").replaceAfter(".java", "")
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.dump.MultiModuleHtmlFirDump import org.jetbrains.kotlin.fir.dump.MultiModuleHtmlFirDump
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
@@ -58,11 +60,12 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
val session = createSession(environment, scope, librariesScope, moduleData.qualifiedName) val session = createSession(environment, scope, librariesScope, moduleData.qualifiedName)
val totalTransformer = FirTotalResolveTransformer() val totalTransformer = FirTotalResolveTransformer()
val firProvider = session.firProvider as FirProviderImpl
val firFiles = if (useLightTree) { val firFiles = if (useLightTree) {
val lightTree2Fir = LightTree2Fir(session, stubMode = false) val lightTree2Fir = LightTree2Fir(session, firProvider.kotlinScopeProvider, stubMode = false)
bench.buildFiles(lightTree2Fir, moduleData.sources.filter { it.extension == "kt" }) bench.buildFiles(lightTree2Fir, moduleData.sources.filter { it.extension == "kt" })
} else { } else {
val builder = RawFirBuilder(session, stubMode = false) val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
bench.buildFiles(builder, ktFiles) bench.buildFiles(builder, ktFiles)
} }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.references.impl.*
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -37,7 +38,7 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder<PsiElement>(session) { class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, val stubMode: Boolean) : BaseFirBuilder<PsiElement>(session) {
fun buildFirFile(file: KtFile): FirFile { fun buildFirFile(file: KtFile): FirFile {
return file.accept(Visitor(), Unit) as FirFile return file.accept(Visitor(), Unit) as FirFile
@@ -459,6 +460,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
enumEntry.toFirSourceElement(), enumEntry.toFirSourceElement(),
session, session,
enumEntry.nameAsSafeName, enumEntry.nameAsSafeName,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
enumEntry.extractAnnotationsTo(firEnumEntry) enumEntry.extractAnnotationsTo(firEnumEntry)
@@ -506,6 +508,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
classOrObject.nameAsSafeName, classOrObject.nameAsSafeName,
status, status,
classKind, classKind,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
} else { } else {
@@ -515,6 +518,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
classOrObject.nameAsSafeName, classOrObject.nameAsSafeName,
status, status,
classKind, classKind,
scopeProvider,
FirRegularClassSymbol(context.currentClassId) FirRegularClassSymbol(context.currentClassId)
) )
} }
@@ -564,7 +568,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Unit): FirElement { override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Unit): FirElement {
val objectDeclaration = expression.objectDeclaration val objectDeclaration = expression.objectDeclaration
return withChildClassName(ANONYMOUS_OBJECT_NAME) { return withChildClassName(ANONYMOUS_OBJECT_NAME) {
FirAnonymousObjectImpl(expression.toFirSourceElement(), session, FirAnonymousObjectSymbol()).apply { FirAnonymousObjectImpl(expression.toFirSourceElement(), session, scopeProvider, FirAnonymousObjectSymbol()).apply {
objectDeclaration.extractAnnotationsTo(this) objectDeclaration.extractAnnotationsTo(this)
objectDeclaration.extractSuperTypeListEntriesTo(this, null, ClassKind.CLASS) objectDeclaration.extractSuperTypeListEntriesTo(this, null, ClassKind.CLASS)
this.typeRef = superTypeRefs.first() // TODO this.typeRef = superTypeRefs.first() // TODO
@@ -72,7 +72,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
} }
protected fun KtFile.toFirFile(stubMode: Boolean): FirFile = protected fun KtFile.toFirFile(stubMode: Boolean): FirFile =
RawFirBuilder(object : FirSessionBase(null) {}, stubMode).buildFirFile(this) RawFirBuilder(object : FirSessionBase(null) {}, StubFirScopeProvider, stubMode).buildFirFile(this)
private fun FirElement.traverseChildren(result: MutableSet<FirElement> = hashSetOf()): MutableSet<FirElement> { private fun FirElement.traverseChildren(result: MutableSet<FirElement> = hashSetOf()): MutableSet<FirElement> {
if (!result.add(this)) { if (!result.add(this)) {
@@ -0,0 +1,24 @@
/*
* 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.builder
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
object StubFirScopeProvider : FirScopeProvider() {
override fun getUseSiteMemberScope(
klass: FirClass<*>,
substitutor: ConeSubstitutor,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
error("Stub")
}
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.phasedFir
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
@@ -291,7 +292,7 @@ class FirCallResolver(
symbol: FirClassSymbol<*>, symbol: FirClassSymbol<*>,
typeArguments: List<FirTypeProjection> typeArguments: List<FirTypeProjection>
): FirDelegatedConstructorCall? { ): FirDelegatedConstructorCall? {
val scope = symbol.fir.buildUseSiteMemberScope(session, scopeSession) ?: return null val scope = symbol.fir.scope(ConeSubstitutor.Empty, session, scopeSession) ?: return null
val callInfo = CallInfo( val callInfo = CallInfo(
CallKind.Function, CallKind.Function,
explicitReceiver = null, explicitReceiver = null,
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
@@ -34,6 +35,7 @@ fun deserializeClassToSymbol(
nameResolver: NameResolver, nameResolver: NameResolver,
session: FirSession, session: FirSession,
defaultAnnotationDeserializer: AbstractAnnotationDeserializer?, defaultAnnotationDeserializer: AbstractAnnotationDeserializer?,
scopeProvider: KotlinScopeProvider,
parentContext: FirDeserializationContext? = null, parentContext: FirDeserializationContext? = null,
deserializeNestedClass: (ClassId, FirDeserializationContext) -> FirRegularClassSymbol? deserializeNestedClass: (ClassId, FirDeserializationContext) -> FirRegularClassSymbol?
) { ) {
@@ -59,6 +61,7 @@ fun deserializeClassToSymbol(
classId.shortClassName, classId.shortClassName,
status, status,
ProtoEnumFlags.classKind(kind), ProtoEnumFlags.classKind(kind),
scopeProvider,
symbol symbol
) )
} else { } else {
@@ -68,6 +71,7 @@ fun deserializeClassToSymbol(
classId.shortClassName, classId.shortClassName,
status, status,
ProtoEnumFlags.classKind(kind), ProtoEnumFlags.classKind(kind),
scopeProvider,
symbol symbol
) )
} }
@@ -120,7 +124,7 @@ fun deserializeClassToSymbol(
val enumEntryId = classId.createNestedClassId(enumEntryName) val enumEntryId = classId.createNestedClassId(enumEntryName)
val symbol = FirRegularClassSymbol(enumEntryId) val symbol = FirRegularClassSymbol(enumEntryId)
FirEnumEntryImpl(null, session, enumEntryId.shortClassName, symbol).apply { FirEnumEntryImpl(null, session, enumEntryId.shortClassName, scopeProvider, symbol).apply {
resolvePhase = FirResolvePhase.DECLARATIONS resolvePhase = FirResolvePhase.DECLARATIONS
superTypeRefs += FirResolvedTypeRefImpl( superTypeRefs += FirResolvedTypeRefImpl(
null, null,
@@ -114,7 +114,9 @@ class FirDeserializationContext(
} }
// TODO: Move something here // TODO: Move something here
class FirDeserializationComponents class FirDeserializationComponents {
}
class FirMemberDeserializer(private val c: FirDeserializationContext) { class FirMemberDeserializer(private val c: FirDeserializationContext) {
private val contractDeserializer = FirContractDeserializer(c) private val contractDeserializer = FirContractDeserializer(c)
@@ -58,68 +58,8 @@ abstract class FirSymbolProvider : FirSessionComponent {
abstract fun getNestedClassifierScope(classId: ClassId): FirScope? abstract fun getNestedClassifierScope(classId: ClassId): FirScope?
abstract fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope?
protected fun wrapScopeWithJvmMapped(
klass: FirClass<*>,
declaredMemberScope: FirScope,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
val classId = klass.classId
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
?: return declaredMemberScope
val symbolProvider = useSiteSession.firSymbolProvider
val javaClass = symbolProvider.getClassLikeSymbolByFqName(javaClassId)?.fir as? FirRegularClass
?: return declaredMemberScope
val preparedSignatures = JvmMappedScope.prepareSignatures(javaClass)
return if (preparedSignatures.isNotEmpty()) {
symbolProvider.getClassUseSiteMemberScope(javaClassId, useSiteSession, scopeSession)?.let { javaClassUseSiteScope ->
val jvmMappedScope = JvmMappedScope(declaredMemberScope, javaClassUseSiteScope, preparedSignatures)
if (klass !is FirRegularClass) {
jvmMappedScope
} else {
// We should substitute Java type parameters with base Kotlin type parameters to match overrides properly
// It's necessary for MutableMap, which has *two* JavaMappedScope inside (one for itself and another for base Map)
(klass.symbol.constructType(
klass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false
) as ConeClassLikeType).wrapSubstitutionScopeIfNeed(useSiteSession, jvmMappedScope, klass, scopeSession)
}
} ?: declaredMemberScope
} else {
declaredMemberScope
}
}
fun buildDefaultUseSiteMemberScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope { fun buildDefaultUseSiteMemberScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
return scopeSession.getOrBuild(klass.symbol, USE_SITE) { TODO("REMOVE")
val declaredScope = declaredMemberScope(klass)
val wrappedDeclaredScope = wrapScopeWithJvmMapped(
klass, declaredScope, useSiteSession, scopeSession
)
val scopes = lookupSuperTypes(klass, 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) {
val useSiteMemberScope = symbol.fir.buildUseSiteMemberScope(useSiteSession, scopeSession)!!
useSiteSuperType.wrapSubstitutionScopeIfNeed(useSiteSession, useSiteMemberScope, symbol.fir, scopeSession)
} else {
null
}
}
FirClassUseSiteMemberScope(
useSiteSession,
FirSuperTypeScope.prepareSupertypeScope(useSiteSession, FirStandardOverrideChecker(useSiteSession), scopes),
wrappedDeclaredScope
)
}
} }
open fun getAllCallableNamesInPackage(fqName: FqName): Set<Name> = emptySet() open fun getAllCallableNamesInPackage(fqName: FqName): Set<Name> = emptySet()
@@ -16,8 +16,10 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.inferenceContext import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -245,7 +247,7 @@ private fun FirRegularClass.findSingleAbstractMethodByNames(
var resultMethod: FirSimpleFunction? = null var resultMethod: FirSimpleFunction? = null
var metIncorrectMember = false var metIncorrectMember = false
val classUseSiteMemberScope = session.firSymbolProvider.getClassUseSiteMemberScope(classId, session, scopeSession) val classUseSiteMemberScope = this.scope(ConeSubstitutor.Empty, session, scopeSession)
for (candidateName in samCandidateNames) { for (candidateName in samCandidateNames) {
if (classUseSiteMemberScope == null) break if (classUseSiteMemberScope == null) break
@@ -9,8 +9,11 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -21,12 +24,13 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
is ConeClassLikeType -> { is ConeClassLikeType -> {
val fullyExpandedType = fullyExpandedType(useSiteSession) val fullyExpandedType = fullyExpandedType(useSiteSession)
val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass<*> ?: return null val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass<*> ?: return null
fullyExpandedType.wrapSubstitutionScopeIfNeed(
useSiteSession, val substitution = when (fir) {
fir.buildUseSiteMemberScope(useSiteSession, scopeSession)!!, is FirTypeParametersOwner -> createSubstitution(fir.typeParameters, fullyExpandedType.typeArguments, useSiteSession)
fir, else -> emptyMap()
scopeSession }
)
fir.scope(substitutorByMap(substitution), useSiteSession, scopeSession)
} }
is ConeTypeParameterType -> { is ConeTypeParameterType -> {
// TODO: support LibraryTypeParameterSymbol or get rid of it // TODO: support LibraryTypeParameterSymbol or get rid of it
@@ -46,12 +50,14 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
) )
is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession) is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession)
is ConeIntegerLiteralType -> { is ConeIntegerLiteralType -> {
@Suppress("USELESS_CAST") // TODO: remove once fixed: https://youtrack.jetbrains.com/issue/KT-35635
scopeSession.getOrBuild( scopeSession.getOrBuild(
FirIntegerLiteralTypeScope.ILT_SYMBOL, FirIntegerLiteralTypeScope.ILT_SYMBOL,
FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY
) { ) {
FirIntegerLiteralTypeScope(useSiteSession) FirIntegerLiteralTypeScope(useSiteSession)
} } as FirScope
} }
else -> error("Failed type $this") else -> error("Failed type $this")
} }
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
abstract class SupertypeSupplier { abstract class SupertypeSupplier {
@@ -46,22 +49,15 @@ val USE_SITE = scopeSessionKey<FirClassSymbol<*>, FirScope>()
data class SubstitutionScopeKey(val type: ConeClassLikeType) : ScopeSessionKey<FirClassLikeSymbol<*>, FirClassSubstitutionScope>() data class SubstitutionScopeKey(val type: ConeClassLikeType) : ScopeSessionKey<FirClassLikeSymbol<*>, FirClassSubstitutionScope>()
fun FirClassSymbol<*>.buildUseSiteMemberScope(useSiteSession: FirSession, builder: ScopeSession): FirScope? { fun FirClassSymbol<*>.buildUseSiteMemberScope(useSiteSession: FirSession, builder: ScopeSession): FirScope? {
return when (this) { return this.fir.buildUseSiteMemberScope(useSiteSession, builder)
is FirAnonymousObjectSymbol -> useSiteSession.firSymbolProvider.buildDefaultUseSiteMemberScope(fir, useSiteSession, builder)
is FirRegularClassSymbol -> fir.buildUseSiteMemberScope(useSiteSession, builder)
}
} }
fun FirClass<*>.buildUseSiteMemberScope(useSiteSession: FirSession, builder: ScopeSession): FirScope? { fun FirClass<*>.buildUseSiteMemberScope(useSiteSession: FirSession, builder: ScopeSession): FirScope? {
if (classId.isLocal) { return this.scope(ConeSubstitutor.Empty, useSiteSession, builder)
// It's not possible to find local class by symbol
return useSiteSession.firSymbolProvider.buildDefaultUseSiteMemberScope(this, useSiteSession, builder)
}
val symbolProvider = useSiteSession.firSymbolProvider
return symbolProvider.getClassUseSiteMemberScope(classId, useSiteSession, builder)
} }
private fun createSubstitution( /* TODO REMOVE */
fun createSubstitution(
typeParameters: List<FirTypeParameter>, typeParameters: List<FirTypeParameter>,
typeArguments: Array<out ConeKotlinTypeProjection>, typeArguments: Array<out ConeKotlinTypeProjection>,
session: FirSession session: FirSession
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -147,7 +148,7 @@ private fun processConstructors(
) ?: return ProcessorAction.STOP ) ?: return ProcessorAction.STOP
} else basicScope } else basicScope
} }
is FirClassSymbol -> matchedSymbol.buildUseSiteMemberScope(session, scopeSession) is FirClassSymbol -> (matchedSymbol.fir as FirClass<*>).scope(ConeSubstitutor.Empty, session, scopeSession)
} }
val constructorName = when (matchedSymbol) { val constructorName = when (matchedSymbol) {
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -90,10 +92,10 @@ class ImplicitDispatchReceiverValue(
) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) { ) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) {
val implicitCompanionScopes: List<FirScope> = run { val implicitCompanionScopes: List<FirScope> = run {
val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList() val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList()
listOfNotNull(klass.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)) + listOfNotNull(klass.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)) +
lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull { lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull {
val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass
superClass?.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession) superClass?.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)
} }
} }
} }
@@ -12,14 +12,21 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.ConeNullability
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -262,8 +269,13 @@ class QualifiedReceiverTowerLevel(
) )
} }
else -> { else -> {
session.firSymbolProvider.getClassUseSiteMemberScope(classId, session, bodyResolveComponents.scopeSession) val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return ProcessorAction.NEXT
?: return ProcessorAction.NEXT when (symbol) {
is FirClassSymbol<*> -> symbol.fir.scope(ConeSubstitutor.Empty, session, bodyResolveComponents.scopeSession)
is FirTypeAliasSymbol ->
symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeKotlinType>()
.scope(session, bodyResolveComponents.scopeSession) ?: return ProcessorAction.NEXT
}
} }
} }
@@ -17,14 +17,6 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider() { class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider() {
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
return providers.firstNotNullResult { it.getClassUseSiteMemberScope(classId, useSiteSession, scopeSession) }
}
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> { override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
return providers.flatMap { it.getTopLevelCallableSymbols(packageFqName, name) } return providers.flatMap { it.getTopLevelCallableSymbols(packageFqName, name) }
} }
@@ -48,14 +48,6 @@ open class FirDependenciesSymbolProviderImpl(val session: FirSession) : Abstract
} }
} }
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
return dependencyProviders.firstNotNullResult { it.getClassUseSiteMemberScope(classId, useSiteSession, scopeSession) }
}
override fun getPackage(fqName: FqName): FqName? { override fun getPackage(fqName: FqName): FqName? {
return packageCache.lookupCacheOrCalculate(fqName) { return packageCache.lookupCacheOrCalculate(fqName) {
for (provider in dependencyProviders) { for (provider in dependencyProviders) {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.getOrPut import org.jetbrains.kotlin.fir.resolve.getOrPut
import org.jetbrains.kotlin.fir.scopes.FirScope 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.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -40,8 +41,11 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import java.io.InputStream import java.io.InputStream
class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider() { class FirLibrarySymbolProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinScopeProvider) : FirSymbolProvider() {
private class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName, val session: FirSession) { private class BuiltInsPackageFragment(
stream: InputStream, val fqName: FqName, val session: FirSession,
val kotlinScopeProvider: KotlinScopeProvider
) {
lateinit var version: BuiltInsBinaryVersion lateinit var version: BuiltInsBinaryVersion
val packageProto: ProtoBuf.PackageFragment = run { val packageProto: ProtoBuf.PackageFragment = run {
@@ -92,7 +96,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
} }
return lookup.getOrPut(classId, { FirRegularClassSymbol(classId) }) { symbol -> return lookup.getOrPut(classId, { FirRegularClassSymbol(classId) }) { symbol ->
if (shouldBeEnumEntry) { if (shouldBeEnumEntry) {
FirEnumEntryImpl(null, session, classId.shortClassName, symbol).apply { FirEnumEntryImpl(null, session, classId.shortClassName, kotlinScopeProvider, symbol).apply {
resolvePhase = FirResolvePhase.DECLARATIONS resolvePhase = FirResolvePhase.DECLARATIONS
} }
} else { } else {
@@ -101,7 +105,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
deserializeClassToSymbol( deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session, classId, classProto, symbol, nameResolver, session,
null, parentContext, null, kotlinScopeProvider, parentContext,
this::findAndDeserializeClass this::findAndDeserializeClass
) )
} }
@@ -123,15 +127,6 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
} }
} }
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return buildDefaultUseSiteMemberScope(symbol.fir, useSiteSession, scopeSession)
}
override fun getPackage(fqName: FqName): FqName? { override fun getPackage(fqName: FqName): FqName? {
if (allPackageFragments.containsKey(fqName)) return fqName if (allPackageFragments.containsKey(fqName)) return fqName
return null return null
@@ -145,7 +140,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
return packageFqNames.map { fqName -> return packageFqNames.map { fqName ->
val resourcePath = BuiltInSerializerProtocol.getBuiltInsFilePath(fqName) val resourcePath = BuiltInSerializerProtocol.getBuiltInsFilePath(fqName)
val inputStream = streamProvider(resourcePath) ?: throw IllegalStateException("Resource not found in classpath: $resourcePath") val inputStream = streamProvider(resourcePath) ?: throw IllegalStateException("Resource not found in classpath: $resourcePath")
BuiltInsPackageFragment(inputStream, fqName, session) BuiltInsPackageFragment(inputStream, fqName, session, kotlinScopeProvider)
} }
} }
@@ -177,6 +172,7 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
relativeClassName.shortName(), relativeClassName.shortName(),
status, status,
ClassKind.INTERFACE, ClassKind.INTERFACE,
kotlinScopeProvider,
this this
).apply klass@{ ).apply klass@{
resolvePhase = FirResolvePhase.DECLARATIONS resolvePhase = FirResolvePhase.DECLARATIONS
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.FirProvider import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.FirScope 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.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -23,7 +24,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirProviderImpl(val session: FirSession) : FirProvider() { class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinScopeProvider) : FirProvider() {
override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? {
symbol.overriddenSymbol?.let { symbol.overriddenSymbol?.let {
return getFirCallableContainerFile(it) return getFirCallableContainerFile(it)
@@ -215,25 +216,6 @@ class FirProviderImpl(val session: FirSession) : FirProvider() {
state.setFrom(newState) state.setFrom(newState)
} }
} }
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
return when (val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null) {
is FirRegularClassSymbol -> buildDefaultUseSiteMemberScope(symbol.fir, useSiteSession, scopeSession)
is FirAnonymousObjectSymbol -> buildDefaultUseSiteMemberScope(symbol.fir, useSiteSession, scopeSession)
is FirTypeAliasSymbol -> {
val expandedTypeRef = symbol.fir.expandedTypeRef as FirResolvedTypeRef
val expandedType = expandedTypeRef.type as? ConeLookupTagBasedType ?: return null
val lookupTag = expandedType.lookupTag as? ConeClassLikeLookupTag ?: return null
getClassUseSiteMemberScope(lookupTag.classId, useSiteSession, scopeSession)
}
else -> throw IllegalArgumentException("Unexpected FIR symbol in getClassUseSiteMemberScope: $symbol")
}
}
} }
private const val rebuildIndex = true private const val rebuildIndex = true
@@ -9,28 +9,6 @@ import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
abstract class ConeSubstitutor : TypeSubstitutorMarker {
open fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType = substituteOrNull(type) ?: type
abstract fun substituteOrNull(type: ConeKotlinType): ConeKotlinType?
object Empty : ConeSubstitutor() {
override fun substituteOrSelf(type: ConeKotlinType): ConeKotlinType {
return type
}
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
return null
}
}
}
fun ConeSubstitutor.substituteOrNull(type: ConeKotlinType?): ConeKotlinType? {
return type?.let { substituteOrNull(it) }
}
abstract class AbstractConeSubstitutor : ConeSubstitutor() { abstract class AbstractConeSubstitutor : ConeSubstitutor() {
protected fun wrapProjection(old: ConeKotlinTypeProjection, newType: ConeKotlinType): ConeKotlinTypeProjection { protected fun wrapProjection(old: ConeKotlinTypeProjection, newType: ConeKotlinType): ConeKotlinTypeProjection {
@@ -140,14 +118,14 @@ fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>):
return ConeSubstitutorByMap(substitution) return ConeSubstitutorByMap(substitution)
} }
class ChainedSubstitutor(private val first: ConeSubstitutor, private val second: ConeSubstitutor) : ConeSubstitutor() { data class ChainedSubstitutor(private val first: ConeSubstitutor, private val second: ConeSubstitutor) : ConeSubstitutor() {
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? { override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
first.substituteOrNull(type)?.let { return second.substituteOrSelf(it) } first.substituteOrNull(type)?.let { return second.substituteOrSelf(it) }
return second.substituteOrNull(type) return second.substituteOrNull(type)
} }
} }
class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() { data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeTypeParameterType) return null if (type !is ConeTypeParameterType) return null
return makeNullableIfNeed(type.isMarkedNullable, substitution[type.lookupTag.symbol]) return makeNullableIfNeed(type.isMarkedNullable, substitution[type.lookupTag.symbol])
@@ -0,0 +1,87 @@
/*
* 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.scopes
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.inferenceContext
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
class KotlinScopeProvider(
val declaredMemberScopeDecorator: (
klass: FirClass<*>,
declaredMemberScope: FirScope,
useSiteSession: FirSession,
scopeSession: ScopeSession
) -> FirScope = { _, declaredMemberScope, _, _ -> declaredMemberScope }
) : FirScopeProvider() {
private fun substitutor(symbol: FirRegularClassSymbol, type: ConeClassLikeType, useSiteSession: FirSession): ConeSubstitutor {
if (type.typeArguments.isEmpty()) return ConeSubstitutor.Empty
val originalSubstitution = createSubstitution(symbol.fir.typeParameters, type.typeArguments, useSiteSession)
return substitutorByMap(originalSubstitution)
}
private fun buildRawUseSiteScope(
klass: FirClass<*>,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
val declaredScope = declaredMemberScope(klass)
val decoratedDeclaredMemberScope =
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
val scopes = lookupSuperTypes(klass, 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) {
symbol.fir.scope(substitutor(symbol, useSiteSuperType, useSiteSession), useSiteSession, scopeSession)
} else {
null
}
}
FirClassUseSiteMemberScope(
useSiteSession,
FirSuperTypeScope.prepareSupertypeScope(useSiteSession, FirStandardOverrideChecker(useSiteSession), scopes),
decoratedDeclaredMemberScope
)
}
}
override fun getUseSiteMemberScope(
klass: FirClass<*>,
substitutor: ConeSubstitutor,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope {
if (substitutor == ConeSubstitutor.Empty) return buildRawUseSiteScope(klass, useSiteSession, scopeSession)
return scopeSession.getOrBuild(
klass, ConeSubstitutionScopeKey(substitutor)
) {
FirClassSubstitutionScope(useSiteSession, buildRawUseSiteScope(klass, useSiteSession, scopeSession), scopeSession, substitutor)
}
}
}
data class ConeSubstitutionScopeKey(val substitutor: ConeSubstitutor) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>() {}
fun FirClass<*>.scope(substitutor: ConeSubstitutor, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
return scopeProvider.getUseSiteMemberScope(
this, substitutor, useSiteSession, scopeSession
)
}
@@ -10,9 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -25,14 +27,16 @@ abstract class FirAbstractImportingScope(
lookupInFir: Boolean lookupInFir: Boolean
) : FirAbstractProviderBasedScope(session, lookupInFir) { ) : FirAbstractProviderBasedScope(session, lookupInFir) {
// TODO: Rewrite somehow?
private fun getStaticsScope(classId: ClassId): FirScope? { private fun getStaticsScope(classId: ClassId): FirScope? {
provider.getClassUseSiteMemberScope(classId, session, scopeSession)?.let { return it }
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: return null val symbol = provider.getClassLikeSymbolByFqName(classId) ?: return null
if (symbol is FirTypeAliasSymbol) { if (symbol is FirTypeAliasSymbol) {
val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(session) val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(session)
if (expansionSymbol != null) { if (expansionSymbol != null) {
return getStaticsScope(expansionSymbol.classId) return getStaticsScope(expansionSymbol.classId)
} }
} else {
return (symbol as FirClassSymbol<*>).fir.scope(ConeSubstitutor.Empty, session, scopeSession)
} }
return null return null
@@ -31,7 +31,7 @@ class FirClassSubstitutionScope(
private val session: FirSession, private val session: FirSession,
private val useSiteMemberScope: FirScope, private val useSiteMemberScope: FirScope,
scopeSession: ScopeSession, scopeSession: ScopeSession,
substitution: Map<FirTypeParameterSymbol, ConeKotlinType> private val substitutor: ConeSubstitutor
) : FirScope() { ) : FirScope() {
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>() private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
@@ -39,7 +39,10 @@ class FirClassSubstitutionScope(
private val fakeOverrideFields = mutableMapOf<FirFieldSymbol, FirFieldSymbol>() private val fakeOverrideFields = mutableMapOf<FirFieldSymbol, FirFieldSymbol>()
private val fakeOverrideAccessors = mutableMapOf<FirAccessorSymbol, FirAccessorSymbol>() private val fakeOverrideAccessors = mutableMapOf<FirAccessorSymbol, FirAccessorSymbol>()
private val substitutor = substitutorByMap(substitution) constructor(
session: FirSession, useSiteMemberScope: FirScope, scopeSession: ScopeSession,
substitution: Map<FirTypeParameterSymbol, ConeKotlinType>
) : this(session, useSiteMemberScope, scopeSession, substitutorByMap(substitution))
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction { override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
useSiteMemberScope.processFunctionsByName(name) process@{ original -> useSiteMemberScope.processFunctionsByName(name) process@{ original ->
@@ -101,18 +101,19 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
} }
private fun mapKtFilesToFirFiles(session: FirSession, ktFiles: List<KtFile>, firFiles: MutableList<FirFile>, useLightTree: Boolean) { private fun mapKtFilesToFirFiles(session: FirSession, ktFiles: List<KtFile>, firFiles: MutableList<FirFile>, useLightTree: Boolean) {
val firProvider = (session.firProvider as FirProviderImpl)
if (useLightTree) { if (useLightTree) {
val lightTreeBuilder = LightTree2Fir(session, stubMode = false) val lightTreeBuilder = LightTree2Fir(session, firProvider.kotlinScopeProvider, stubMode = false)
ktFiles.mapTo(firFiles) { ktFiles.mapTo(firFiles) {
val firFile = lightTreeBuilder.buildFirFile(it.text, it.name) val firFile = lightTreeBuilder.buildFirFile(it.text, it.name)
(session.firProvider as FirProviderImpl).recordFile(firFile) (session.firProvider as FirProviderImpl).recordFile(firFile)
firFile firFile
} }
} else { } else {
val firBuilder = RawFirBuilder(session, false) val firBuilder = RawFirBuilder(session, firProvider.kotlinScopeProvider, false)
ktFiles.mapTo(firFiles) { ktFiles.mapTo(firFiles) {
val firFile = firBuilder.buildFirFile(it) val firFile = firBuilder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFile firFile
} }
} }
@@ -25,13 +25,13 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.createSession import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
@@ -172,7 +172,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
val processedJavaClasses = mutableSetOf<FirJavaClass>() val processedJavaClasses = mutableSetOf<FirJavaClass>()
for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) { for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) {
if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue
val enhancementScope = javaProvider.getClassUseSiteMemberScope(javaClass.classId, session, ScopeSession()).let { val enhancementScope = javaClass.buildUseSiteMemberScope(session, ScopeSession()).let {
when (it) { when (it) {
is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first() is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first()
is JavaClassEnhancementScope -> it is JavaClassEnhancementScope -> it
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
@@ -28,6 +29,7 @@ abstract class FirAnonymousObject : FirPureAbstractElement(), FirClass<FirAnonym
abstract override val superTypeRefs: List<FirTypeRef> abstract override val superTypeRefs: List<FirTypeRef>
abstract override val declarations: List<FirDeclaration> abstract override val declarations: List<FirDeclaration>
abstract override val annotations: List<FirAnnotationCall> abstract override val annotations: List<FirAnnotationCall>
abstract override val scopeProvider: FirScopeProvider
abstract override val typeRef: FirTypeRef abstract override val typeRef: FirTypeRef
abstract override val symbol: FirAnonymousObjectSymbol abstract override val symbol: FirAnonymousObjectSymbol
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
@@ -29,6 +30,7 @@ interface FirClass<F : FirClass<F>> : FirClassLikeDeclaration<F>, FirStatement,
val superTypeRefs: List<FirTypeRef> val superTypeRefs: List<FirTypeRef>
val declarations: List<FirDeclaration> val declarations: List<FirDeclaration>
override val annotations: List<FirAnnotationCall> override val annotations: List<FirAnnotationCall>
val scopeProvider: FirScopeProvider
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitClass(this, data) override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitClass(this, data)
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -31,6 +32,7 @@ abstract class FirEnumEntry : FirPureAbstractElement(), FirRegularClass {
abstract override val status: FirDeclarationStatus abstract override val status: FirDeclarationStatus
abstract override val classKind: ClassKind abstract override val classKind: ClassKind
abstract override val declarations: List<FirDeclaration> abstract override val declarations: List<FirDeclaration>
abstract override val scopeProvider: FirScopeProvider
abstract override val symbol: FirRegularClassSymbol abstract override val symbol: FirRegularClassSymbol
abstract override val companionObject: FirRegularClass? abstract override val companionObject: FirRegularClass?
abstract override val superTypeRefs: List<FirTypeRef> abstract override val superTypeRefs: List<FirTypeRef>
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -29,6 +30,7 @@ interface FirRegularClass : FirMemberDeclaration, FirTypeParametersOwner, FirCla
override val status: FirDeclarationStatus override val status: FirDeclarationStatus
override val classKind: ClassKind override val classKind: ClassKind
override val declarations: List<FirDeclaration> override val declarations: List<FirDeclaration>
override val scopeProvider: FirScopeProvider
override val symbol: FirRegularClassSymbol override val symbol: FirRegularClassSymbol
val companionObject: FirRegularClass? val companionObject: FirRegularClass?
override val superTypeRefs: List<FirTypeRef> override val superTypeRefs: List<FirTypeRef>
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -31,6 +32,7 @@ abstract class FirSealedClass : FirPureAbstractElement(), FirRegularClass {
abstract override val status: FirDeclarationStatus abstract override val status: FirDeclarationStatus
abstract override val classKind: ClassKind abstract override val classKind: ClassKind
abstract override val declarations: List<FirDeclaration> abstract override val declarations: List<FirDeclaration>
abstract override val scopeProvider: FirScopeProvider
abstract override val symbol: FirRegularClassSymbol abstract override val symbol: FirRegularClassSymbol
abstract override val companionObject: FirRegularClass? abstract override val companionObject: FirRegularClass?
abstract override val superTypeRefs: List<FirTypeRef> abstract override val superTypeRefs: List<FirTypeRef>
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.visitors.*
class FirAnonymousObjectImpl( class FirAnonymousObjectImpl(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override val session: FirSession, override val session: FirSession,
override val scopeProvider: FirScopeProvider,
override val symbol: FirAnonymousObjectSymbol override val symbol: FirAnonymousObjectSymbol
) : FirAnonymousObject(), FirModifiableClass<FirAnonymousObject>, FirAbstractAnnotatedElement { ) : FirAnonymousObject(), FirModifiableClass<FirAnonymousObject>, FirAbstractAnnotatedElement {
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -32,6 +33,7 @@ class FirClassImpl(
override val name: Name, override val name: Name,
override var status: FirDeclarationStatus, override var status: FirDeclarationStatus,
override val classKind: ClassKind, override val classKind: ClassKind,
override val scopeProvider: FirScopeProvider,
override val symbol: FirRegularClassSymbol override val symbol: FirRegularClassSymbol
) : FirPureAbstractElement(), FirRegularClass, FirModifiableRegularClass, FirAbstractAnnotatedElement { ) : FirPureAbstractElement(), FirRegularClass, FirModifiableRegularClass, FirAbstractAnnotatedElement {
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -33,6 +34,7 @@ class FirEnumEntryImpl(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override val session: FirSession, override val session: FirSession,
override val name: Name, override val name: Name,
override val scopeProvider: FirScopeProvider,
override val symbol: FirRegularClassSymbol override val symbol: FirRegularClassSymbol
) : FirEnumEntry(), FirModifiableClass<FirRegularClass>, FirModifiableTypeParametersOwner, FirAbstractAnnotatedElement { ) : FirEnumEntry(), FirModifiableClass<FirRegularClass>, FirModifiableTypeParametersOwner, FirAbstractAnnotatedElement {
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
@@ -31,6 +32,7 @@ interface FirModifiableClass<F : FirClass<F>> : FirClass<F>, FirAbstractAnnotat
override val superTypeRefs: MutableList<FirTypeRef> override val superTypeRefs: MutableList<FirTypeRef>
override val declarations: MutableList<FirDeclaration> override val declarations: MutableList<FirDeclaration>
override val annotations: MutableList<FirAnnotationCall> override val annotations: MutableList<FirAnnotationCall>
override val scopeProvider: FirScopeProvider
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirModifiableClass<F> override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirModifiableClass<F>
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) override fun replaceResolvePhase(newResolvePhase: FirResolvePhase)
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -35,6 +36,7 @@ interface FirModifiableRegularClass : FirRegularClass, FirModifiableClass<FirReg
override var status: FirDeclarationStatus override var status: FirDeclarationStatus
override val classKind: ClassKind override val classKind: ClassKind
override val declarations: MutableList<FirDeclaration> override val declarations: MutableList<FirDeclaration>
override val scopeProvider: FirScopeProvider
override val symbol: FirRegularClassSymbol override val symbol: FirRegularClassSymbol
override var companionObject: FirRegularClass? override var companionObject: FirRegularClass?
override val superTypeRefs: MutableList<FirTypeRef> override val superTypeRefs: MutableList<FirTypeRef>
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSealedClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -33,6 +34,7 @@ class FirSealedClassImpl(
override val name: Name, override val name: Name,
override var status: FirDeclarationStatus, override var status: FirDeclarationStatus,
override val classKind: ClassKind, override val classKind: ClassKind,
override val scopeProvider: FirScopeProvider,
override val symbol: FirRegularClassSymbol override val symbol: FirRegularClassSymbol
) : FirSealedClass(), FirModifiableRegularClass, FirAbstractAnnotatedElement { ) : FirSealedClass(), FirModifiableRegularClass, FirAbstractAnnotatedElement {
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
@@ -9,8 +9,13 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
class ScopeSession { class ScopeSession {
private val scopes = hashMapOf<Any, HashMap<ScopeSessionKey<*, *>, FirScope>>() private val scopes = hashMapOf<Any, HashMap<ScopeSessionKey<*, *>, FirScope>>()
fun <ID : Any, FS : FirScope> getOrBuild(id: ID, key: ScopeSessionKey<ID, FS>, build: () -> FS): FS {
return scopes.getOrPut(id) { @Deprecated(level = DeprecationLevel.ERROR, message = "Only for getOrBuild")
fun scopes() = scopes
inline fun <reified ID : Any, reified FS : FirScope> getOrBuild(id: ID, key: ScopeSessionKey<ID, FS>, build: () -> FS): FS {
@Suppress("DEPRECATION_ERROR")
return scopes().getOrPut(id) {
hashMapOf() hashMapOf()
}.getOrPut(key) { }.getOrPut(key) {
build() build()
@@ -0,0 +1,21 @@
/*
* 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.scopes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
abstract class FirScopeProvider {
abstract fun getUseSiteMemberScope(
klass: FirClass<*>,
substitutor: ConeSubstitutor,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope
}
@@ -76,4 +76,6 @@ object FieldSets {
val visibility = field(visibilityType) val visibility = field(visibilityType)
val modality = field(modalityType, nullable = true) val modality = field(modalityType, nullable = true)
val scopeProvider = field("scopeProvider", firScopeProviderType)
} }
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.tree.generator.FieldSets.modality
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.receivers import org.jetbrains.kotlin.fir.tree.generator.FieldSets.receivers
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.returnTypeRef import org.jetbrains.kotlin.fir.tree.generator.FieldSets.returnTypeRef
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.scopeProvider
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol
@@ -216,6 +217,7 @@ object NodeConfigurator : AbstractFieldConfigurator() {
+superTypeRefs(withReplace = true) +superTypeRefs(withReplace = true)
+declarations +declarations
+annotations +annotations
+scopeProvider
} }
regularClass.configure { regularClass.configure {
@@ -60,7 +60,10 @@ val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol")
val classSymbolType = type("fir.symbols.impl", "FirClassSymbol") val classSymbolType = type("fir.symbols.impl", "FirClassSymbol")
val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol") val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol")
val firScopeProviderType = type("fir.scopes", "FirScopeProvider")
val pureAbstractElementType = generatedType("FirPureAbstractElement") val pureAbstractElementType = generatedType("FirPureAbstractElement")
val effectDeclarationType = type("fir.contracts.description", "ConeEffectDeclaration") val effectDeclarationType = type("fir.contracts.description", "ConeEffectDeclaration")
val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription") val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription")
val firDiagnosticType = generatedType("diagnostics", "FirDiagnostic") val firDiagnosticType = generatedType("diagnostics", "FirDiagnostic")
+1 -1
View File
@@ -4,5 +4,5 @@ val oo = object {
// Forbidden in KT-13510 // Forbidden in KT-13510
class Nested class Nested
fun f1() = <!UNRESOLVED_REFERENCE!>Nested<!>(11) fun f1() = <!INAPPLICABLE_CANDIDATE!>Nested<!>(11)
} }
@@ -25,15 +25,15 @@ typealias KT = KTest
typealias IT = ITest typealias IT = ITest
// Referencing Java class static members via type alias should be ok // Referencing Java class static members via type alias should be ok
val testFoo: String = JT.<!UNRESOLVED_REFERENCE!>foo<!>() val testFoo: String = JT.foo()
val seeAlsoFoo: String = JTest.foo() val seeAlsoFoo: String = JTest.foo()
// Referencing base Java class static members via type alias for derived Java class should be ok // Referencing base Java class static members via type alias for derived Java class should be ok
val testDerivedFoo: String = JD.<!UNRESOLVED_REFERENCE!>foo<!>() val testDerivedFoo: String = JD.foo()
val seeAlsoDerivedFoo: String = JDerived.foo() val seeAlsoDerivedFoo: String = JDerived.foo()
// Referencing nested classes via type alias should be prohibited // Referencing nested classes via type alias should be prohibited
// (in type position and in expression position) // (in type position and in expression position)
val testNested1: JT.Nested = JT.<!UNRESOLVED_REFERENCE!>Nested<!>() val testNested1: JT.Nested = JT.Nested()
val testNested2: KT.Nested = KT.Nested() val testNested2: KT.Nested = KT.Nested()
val testNested3: IT.Nested = IT.Nested() val testNested3: IT.Nested = IT.Nested()
val testInner1: JT.Inner = JT.<!UNRESOLVED_REFERENCE!>Inner<!>() val testInner1: JT.Inner = JT.<!UNRESOLVED_REFERENCE!>Inner<!>()
@@ -112,11 +112,12 @@ object GenerationUtils {
val librariesScope = ProjectScope.getLibrariesScope(project) val librariesScope = ProjectScope.getLibrariesScope(project)
val session = createSession(project, scope, librariesScope, "main", packagePartProvider) val session = createSession(project, scope, librariesScope, "main", packagePartProvider)
val builder = RawFirBuilder(session, stubMode = false) val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer() val resolveTransformer = FirTotalResolveTransformer()
val firFiles = files.map { val firFiles = files.map {
val firFile = builder.buildFirFile(it) val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFile firFile
}.also { }.also {
try { try {
@@ -34,12 +34,13 @@ abstract class AbstractFirVisualizer : AbstractVisualizer() {
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(environment.project)) .uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(environment.project))
val session = createSession(environment, scope) val session = createSession(environment, scope)
val builder = RawFirBuilder(session, stubMode = false) val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val transformer = FirTotalResolveTransformer() val transformer = FirTotalResolveTransformer()
val firFiles = ktFiles.map { val firFiles = ktFiles.map {
val firFile = builder.buildFirFile(it) val firFile = builder.buildFirFile(it)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFile firFile
}.also { }.also {
try { try {
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.calls.jvm.JvmCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.calls.jvm.JvmCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
@@ -31,7 +33,7 @@ class FirIdeJavaModuleBasedSession(
init { init {
registerComponent( registerComponent(
FirProvider::class, FirProvider::class,
FirIdeProvider(project, scope, this) FirIdeProvider(project, scope, this, KotlinScopeProvider(::wrapScopeWithJvmMapped))
) )
registerComponent( registerComponent(
FirSymbolProvider::class, FirSymbolProvider::class,
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.idea.stubindex.*
@@ -29,9 +30,10 @@ import org.jetbrains.kotlin.psi.KtFile
class FirIdeProvider( class FirIdeProvider(
val project: Project, val project: Project,
val scope: GlobalSearchScope, val scope: GlobalSearchScope,
val session: FirSession val session: FirSession,
kotlinScopeProvider: KotlinScopeProvider
) : FirProvider() { ) : FirProvider() {
private val cacheProvider = FirProviderImpl(session) private val cacheProvider = FirProviderImpl(session, kotlinScopeProvider)
data class FirFileWithStamp(val file: FirFile, val stamp: Long) data class FirFileWithStamp(val file: FirFile, val stamp: Long)
@@ -67,7 +69,7 @@ class FirIdeProvider(
if (fileWithStamp != null && fileWithStamp.stamp == modificationStamp) { if (fileWithStamp != null && fileWithStamp.stamp == modificationStamp) {
fileWithStamp.file fileWithStamp.file
} else { } else {
val file = RawFirBuilder(session, stubMode = false).buildFirFile(ktFile) val file = RawFirBuilder(session, cacheProvider.kotlinScopeProvider, stubMode = false).buildFirFile(ktFile)
cacheProvider.recordFile(file) cacheProvider.recordFile(file)
fileWithStamp = FirFileWithStamp(file, modificationStamp) fileWithStamp = FirFileWithStamp(file, modificationStamp)
files[ktFile] = fileWithStamp files[ktFile] = fileWithStamp
@@ -145,9 +147,4 @@ class FirIdeProvider(
getFirClassifierByFqName(classId) getFirClassifierByFqName(classId)
return cacheProvider.getNestedClassifierScope(classId) return cacheProvider.getNestedClassifierScope(classId)
} }
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
getFirClassifierByFqName(classId)
return cacheProvider.getClassUseSiteMemberScope(classId, useSiteSession, scopeSession)
}
} }
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
import org.jetbrains.kotlin.fir.java.FirLibrarySession import org.jetbrains.kotlin.fir.java.FirLibrarySession
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
@@ -86,7 +86,8 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
val session = createSession(module, provider) val session = createSession(module, provider)
sessions += session sessions += session
val builder = RawFirBuilder(session, stubMode = false) val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val psiManager = PsiManager.getInstance(project) val psiManager = PsiManager.getInstance(project)
val ideaModuleInfo = session.moduleInfo.cast<IdeaModuleInfo>() val ideaModuleInfo = session.moduleInfo.cast<IdeaModuleInfo>()
@@ -106,7 +107,7 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
files.forEach { files.forEach {
val file = psiManager.findFile(it) as? KtFile ?: return@forEach val file = psiManager.findFile(it) as? KtFile ?: return@forEach
val firFile = builder.buildFirFile(file) val firFile = builder.buildFirFile(file)
(session.firProvider as FirProviderImpl).recordFile(firFile) firProvider.recordFile(firFile)
firFiles += firFile firFiles += firFile
} }
firFilesPerSession[session] = firFiles firFilesPerSession[session] = firFiles
@@ -151,7 +152,7 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
val javaProvider = symbolProvider.providers.filterIsInstance<JavaSymbolProvider>().first() val javaProvider = symbolProvider.providers.filterIsInstance<JavaSymbolProvider>().first()
for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) { for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) {
if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue
val enhancementScope = javaProvider.getClassUseSiteMemberScope(javaClass.classId, session, ScopeSession()).let { val enhancementScope = javaClass.buildUseSiteMemberScope(session, ScopeSession()).let {
when (it) { when (it) {
is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first() is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first()
is JavaClassEnhancementScope -> it is JavaClassEnhancementScope -> it