[FIR2IR] Introduce special FirProvider with plugin-generated files
For declarations generated by plugins, fir2ir creates special synthetic FIR files, which are not registered in the regular FirProvider. This leads to incorrect determination of ir parent for generated declarations, because `irParent` utility relies on file returned from fir provider To fix this issue, the new FirProvider for fir2ir is introduced, which wraps the original provider and allows to register newly created files Note that this means that it's illegal anymore to use FirProvider from session anywhere in fir2ir. `firProvider` from `Fir2IrComponents` should be used instead
This commit is contained in:
committed by
Space Team
parent
d85d671b26
commit
8ebb412705
+5
-5
@@ -24,7 +24,8 @@ import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.serialization.*
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
|
||||
@@ -292,10 +293,9 @@ class FirJvmSerializerExtension(
|
||||
return false
|
||||
}
|
||||
|
||||
val grandParent =
|
||||
containerSymbol.classId.outerClassId?.let {
|
||||
session.firProvider.getFirClassifierByFqName(it) as? FirRegularClass
|
||||
}
|
||||
val grandParent = containerSymbol.classId.outerClassId?.let {
|
||||
session.symbolProvider.getRegularClassSymbolByClassId(it)?.fir
|
||||
}
|
||||
return grandParent != null &&
|
||||
(grandParent.classKind == ClassKind.INTERFACE || grandParent.classKind == ClassKind.ANNOTATION_CLASS)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.builder.buildPackageDirective
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildFile
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isJava
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionApiInternals
|
||||
import org.jetbrains.kotlin.fir.extensions.declarationGenerators
|
||||
@@ -30,13 +32,15 @@ import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolved
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.originalConstructorIfTypeAlias
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -48,7 +52,10 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.GeneratedByPlugin
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
||||
@@ -575,7 +582,8 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
|
||||
}
|
||||
}
|
||||
|
||||
fun FirClass.irOrigin(firProvider: FirProvider): IrDeclarationOrigin = when {
|
||||
context(Fir2IrComponents)
|
||||
fun FirClass.irOrigin(): IrDeclarationOrigin = when {
|
||||
firProvider.getFirClassifierContainerFileIfAny(symbol) != null -> IrDeclarationOrigin.DEFINED
|
||||
isJava -> IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
else -> when (val origin = origin) {
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ class Fir2IrAnnotationsFromPluginRegistrar(private val components: Fir2IrCompone
|
||||
// we need to use the original session of the declaration
|
||||
val containingSession = moduleData.session
|
||||
val topmostParent = topmostParent(containingSession)
|
||||
return containingSession.firProvider.getContainingFile(topmostParent.symbol)
|
||||
return components.firProvider.getContainingFile(topmostParent.symbol)
|
||||
}
|
||||
|
||||
private fun FirDeclaration.topmostParent(session: FirSession): FirDeclaration {
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
@@ -335,8 +334,7 @@ class Fir2IrClassifierStorage(
|
||||
): IrEnumEntry {
|
||||
getCachedIrEnumEntry(enumEntry)?.let { return it }
|
||||
|
||||
val firProviderForEntry = enumEntry.moduleData.session.firProvider
|
||||
val containingFile = firProviderForEntry.getFirCallableContainerFile(enumEntry.symbol)
|
||||
val containingFile = firProvider.getFirCallableContainerFile(enumEntry.symbol)
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val predefinedOrigin = predefinedOrigin ?: if (containingFile != null) {
|
||||
|
||||
@@ -19,6 +19,13 @@ interface Fir2IrComponents {
|
||||
val session: FirSession
|
||||
val scopeSession: ScopeSession
|
||||
|
||||
/**
|
||||
* It's important to use this fir provider in fir2ir instead of provider from session,
|
||||
* because this provider will also contain synthetic fir files for declarations generated
|
||||
* by frontend plugins
|
||||
*/
|
||||
val firProvider: FirProviderWithGeneratedFiles
|
||||
|
||||
val converter: Fir2IrConverter
|
||||
|
||||
val symbolTable: SymbolTable
|
||||
|
||||
@@ -32,6 +32,7 @@ class Fir2IrComponentsStorage(
|
||||
specialSymbolProvider: Fir2IrSpecialSymbolProvider,
|
||||
initializedIrBuiltIns: IrBuiltInsOverFir?
|
||||
) : Fir2IrComponents {
|
||||
override val firProvider: FirProviderWithGeneratedFiles = FirProviderWithGeneratedFiles(session)
|
||||
override val signatureComposer: FirBasedSignatureComposer = commonMemberStorage.firSignatureComposer
|
||||
override val symbolTable: SymbolTable = commonMemberStorage.symbolTable
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.overrides.FakeOverrideRebuilder
|
||||
import org.jetbrains.kotlin.backend.common.sourceElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
@@ -721,7 +720,9 @@ class Fir2IrConverter(
|
||||
|
||||
val allFirFiles = buildList {
|
||||
addAll(firFiles)
|
||||
addAll(session.createFilesWithGeneratedDeclarations())
|
||||
val generatedFiles = session.createFilesWithGeneratedDeclarations()
|
||||
addAll(generatedFiles)
|
||||
generatedFiles.forEach { components.firProvider.recordFile(it) }
|
||||
}
|
||||
|
||||
components.converter.runSourcesConversion(
|
||||
|
||||
+21
-6
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.fir.backend.generators.isExternalParent
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol
|
||||
@@ -894,8 +897,7 @@ class Fir2IrDeclarationStorage(
|
||||
classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return it.symbol }
|
||||
val irParentClass = firDeclaration.containingClassLookupTag()?.let { classifierStorage.findIrClass(it) }!!
|
||||
|
||||
val firProviderForSymbol = firVariableSymbol.moduleData.session.firProvider
|
||||
val containingFile = firProviderForSymbol.getFirCallableContainerFile(firVariableSymbol)
|
||||
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
|
||||
|
||||
classifierStorage.getOrCreateIrEnumEntry(
|
||||
firDeclaration,
|
||||
@@ -1330,10 +1332,23 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
val firProviderForSymbol = firBasedSymbol.moduleData.session.firProvider
|
||||
/**
|
||||
* In `allowNonCachedDeclarations` mode there is a situation possible when we get source declaration
|
||||
* from session which is different from one which we convert right now. So we need to take an original firProvider
|
||||
* for this declaration to correctly find containig file and properly generate NonCachedSourceFileFacadeClass if needed
|
||||
*/
|
||||
val firProvider = if (configuration.allowNonCachedDeclarations) {
|
||||
when {
|
||||
firBasedSymbol.moduleData == session.moduleData -> components.firProvider
|
||||
else -> firBasedSymbol.moduleData.session.firProvider
|
||||
}
|
||||
} else {
|
||||
components.firProvider
|
||||
}
|
||||
|
||||
val containerFile = when (firBasedSymbol) {
|
||||
is FirCallableSymbol -> firProviderForSymbol.getFirCallableContainerFile(firBasedSymbol)
|
||||
is FirClassLikeSymbol -> firProviderForSymbol.getFirClassifierContainerFileIfAny(firBasedSymbol)
|
||||
is FirCallableSymbol -> firProvider.getFirCallableContainerFile(firBasedSymbol)
|
||||
is FirClassLikeSymbol -> firProvider.getFirClassifierContainerFileIfAny(firBasedSymbol)
|
||||
else -> error("Unknown symbol: $firBasedSymbol")
|
||||
}
|
||||
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
|
||||
class FirProviderWithGeneratedFiles(val session: FirSession) : FirProvider() {
|
||||
private val generatedFilesProvider = FirProviderImpl(session, session.kotlinScopeProvider)
|
||||
|
||||
private val providers: List<FirProvider> = listOf(session.firProvider, generatedFilesProvider)
|
||||
|
||||
override val symbolProvider: FirSymbolProvider
|
||||
get() = providers.first().symbolProvider
|
||||
|
||||
override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? {
|
||||
return providers.firstNotNullOfOrNull { it.getFirClassifierByFqName(classId) }
|
||||
}
|
||||
|
||||
override fun getFirClassifierContainerFile(fqName: ClassId): FirFile {
|
||||
return getFirClassifierContainerFileIfAny(fqName) ?: error("Couldn't find container for $fqName")
|
||||
}
|
||||
|
||||
override fun getFirClassifierContainerFileIfAny(fqName: ClassId): FirFile? {
|
||||
return providers.firstNotNullOfOrNull { it.getFirClassifierContainerFileIfAny(fqName) }
|
||||
}
|
||||
|
||||
override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? {
|
||||
return providers.firstNotNullOfOrNull { it.getFirCallableContainerFile(symbol) }
|
||||
}
|
||||
|
||||
override fun getFirScriptContainerFile(symbol: FirScriptSymbol): FirFile? {
|
||||
return providers.firstNotNullOfOrNull { it.getFirScriptContainerFile(symbol) }
|
||||
}
|
||||
|
||||
override fun getFirScriptByFilePath(path: String): FirScriptSymbol? {
|
||||
return providers.firstNotNullOfOrNull { it.getFirScriptByFilePath(path) }
|
||||
}
|
||||
|
||||
override fun getFirFilesByPackage(fqName: FqName): List<FirFile> {
|
||||
return providers.flatMap { it.getFirFilesByPackage(fqName) }
|
||||
}
|
||||
|
||||
override fun getClassNamesInPackage(fqName: FqName): Set<Name> {
|
||||
return providers.flatMapTo(mutableSetOf()) { it.getClassNamesInPackage(fqName) }
|
||||
}
|
||||
|
||||
fun recordFile(file: FirFile) {
|
||||
generatedFilesProvider.recordFile(file)
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -15,14 +15,16 @@ import org.jetbrains.kotlin.fir.hasEnumEntries
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.toLookupTag
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassPublicSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -203,7 +205,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
// finding the parent class that actually contains the [klass] in the tree - it is the root one that should be created on the fly
|
||||
val classOrLocalParent = generateSequence(klass) { c ->
|
||||
(c as? FirRegularClass)?.containingClassForLocalAttr?.let { lookupTag ->
|
||||
(session.firProvider.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirClass)?.takeIf {
|
||||
(firProvider.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirClass)?.takeIf {
|
||||
it.declarations.contains(c)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||
import org.jetbrains.kotlin.fir.lazy.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.unwrapUseSiteSubstitutionOverrides
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
@@ -72,7 +71,7 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
|
||||
irParent: IrDeclarationParent,
|
||||
symbol: IrClassSymbol
|
||||
): Fir2IrLazyClass = firClass.convertWithOffsets { startOffset, endOffset ->
|
||||
val firClassOrigin = firClass.irOrigin(session.firProvider)
|
||||
val firClassOrigin = firClass.irOrigin()
|
||||
Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol, irParent)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user