[FIR2IR] Get rid of all usages of IrSymbol.owner from Fir2IrVisitor

^KT-60924
This commit is contained in:
Dmitriy Novozhilov
2023-08-22 13:29:53 +03:00
committed by Space Team
parent ba4b84a7d0
commit 5148c70579
5 changed files with 75 additions and 24 deletions
@@ -716,7 +716,7 @@ fun IrActualizedResult?.extractFirDeclarations(): Set<FirDeclaration>? {
// This method is intended to be used for default values of annotation parameters (compile-time strings, numbers, enum values, KClasses) // This method is intended to be used for default values of annotation parameters (compile-time strings, numbers, enum values, KClasses)
// where they are needed and may produce incorrect results for values that may be encountered outside annotations. // where they are needed and may produce incorrect results for values that may be encountered outside annotations.
fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents): IrExpressionBody? { fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents): IrExpressionBody? {
return when (val elem = this.accept(Fir2IrVisitor(components, Fir2IrConversionScope()), null)) { return when (val elem = this.accept(Fir2IrVisitor(components, Fir2IrConversionScope(components.configuration)), null)) {
is IrExpressionBody -> elem is IrExpressionBody -> elem
is IrExpression -> components.irFactory.createExpressionBody(elem) is IrExpression -> components.irFactory.createExpressionBody(elem)
else -> null else -> null
@@ -11,15 +11,18 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.util.isSetter import org.jetbrains.kotlin.ir.util.isSetter
import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.util.PrivateForInline import org.jetbrains.kotlin.util.PrivateForInline
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
class Fir2IrConversionScope { class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
@PublishedApi @PublishedApi
@PrivateForInline @PrivateForInline
internal val parentStack = mutableListOf<IrDeclarationParent>() internal val parentStack = mutableListOf<IrDeclarationParent>()
@@ -30,7 +33,7 @@ class Fir2IrConversionScope {
@PublishedApi @PublishedApi
@PrivateForInline @PrivateForInline
internal val currentlyGeneratedDelegatedConstructors = mutableMapOf<IrClass, IrConstructor>() internal val currentlyGeneratedDelegatedConstructors = mutableMapOf<IrClassSymbol, IrConstructor>()
inline fun <T : IrDeclarationParent, R> withParent(parent: T, f: T.() -> R): R { inline fun <T : IrDeclarationParent, R> withParent(parent: T, f: T.() -> R): R {
parentStack += parent parentStack += parent
@@ -42,16 +45,16 @@ class Fir2IrConversionScope {
} }
internal fun <T> forDelegatingConstructorCall(constructor: IrConstructor, irClass: IrClass, f: () -> T): T { internal fun <T> forDelegatingConstructorCall(constructor: IrConstructor, irClass: IrClass, f: () -> T): T {
currentlyGeneratedDelegatedConstructors[irClass] = constructor currentlyGeneratedDelegatedConstructors[irClass.symbol] = constructor
try { try {
return f() return f()
} finally { } finally {
currentlyGeneratedDelegatedConstructors.remove(irClass) currentlyGeneratedDelegatedConstructors.remove(irClass.symbol)
} }
} }
fun getConstructorForCurrentlyGeneratedDelegatedConstructor(itClass: IrClass): IrConstructor? = fun getConstructorForCurrentlyGeneratedDelegatedConstructor(itClassSymbol: IrClassSymbol): IrConstructor? =
currentlyGeneratedDelegatedConstructors[itClass] currentlyGeneratedDelegatedConstructors[itClassSymbol]
fun containingFileIfAny(): IrFile? = parentStack.getOrNull(0) as? IrFile fun containingFileIfAny(): IrFile? = parentStack.getOrNull(0) as? IrFile
@@ -81,6 +84,27 @@ class Fir2IrConversionScope {
error("Accessor of property ${property.render()} not found on parent stack") error("Accessor of property ${property.render()} not found on parent stack")
} }
@OptIn(IrSymbolInternals::class)
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
inline fun <reified D : IrDeclaration> findDeclarationInParentsStack(symbol: IrSymbol): @kotlin.internal.NoInfer D {
if (!AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
return symbol.owner as D
}
for (parent in parentStack.asReversed()) {
if ((parent as? IrDeclaration)?.symbol == symbol) {
return parent as D
}
}
/*
* In case of IDE (when allowNonCachedDeclarations is set to true) we may be in scope of some already compiled class,
* for which we have Fir2IrLazyClass in symbol
*/
if (configuration.allowNonCachedDeclarations) {
return symbol.owner as D
}
error("Declaration with symbol $symbol is not found in parents stack")
}
fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T { fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T {
declaration.parent = parentStack.last() declaration.parent = parentStack.last()
return declaration return declaration
@@ -568,7 +568,7 @@ class Fir2IrConverter(
components, fir2IrConfiguration.languageVersionSettings, moduleDescriptor, irMangler components, fir2IrConfiguration.languageVersionSettings, moduleDescriptor, irMangler
) )
components.irBuiltIns = irBuiltIns components.irBuiltIns = irBuiltIns
val conversionScope = Fir2IrConversionScope() val conversionScope = Fir2IrConversionScope(components.configuration)
val fir2irVisitor = Fir2IrVisitor(components, conversionScope) val fir2irVisitor = Fir2IrVisitor(components, conversionScope)
components.builtIns = Fir2IrBuiltIns(components, specialSymbolProvider) components.builtIns = Fir2IrBuiltIns(components, specialSymbolProvider)
components.annotationGenerator = AnnotationGenerator(components) components.annotationGenerator = AnnotationGenerator(components)
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.contracts.description.LogicOperationKind import org.jetbrains.kotlin.contracts.description.LogicOperationKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.isObject
import org.jetbrains.kotlin.diagnostics.findChildByType import org.jetbrains.kotlin.diagnostics.findChildByType
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.generators.ClassMemberGenerator import org.jetbrains.kotlin.fir.backend.generators.ClassMemberGenerator
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.fullyExpandedConeType import org.jetbrains.kotlin.fir.resolve.fullyExpandedConeType
import org.jetbrains.kotlin.fir.resolve.isIteratorNext import org.jetbrains.kotlin.fir.resolve.isIteratorNext
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -44,15 +46,12 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.defaultConstructor import org.jetbrains.kotlin.ir.util.defaultConstructor
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
@@ -652,14 +651,20 @@ class Fir2IrVisitor(
} }
// Note that this mimics psi2ir [StatementGenerator#shouldGenerateReceiverAsSingletonReference]. // Note that this mimics psi2ir [StatementGenerator#shouldGenerateReceiverAsSingletonReference].
private fun shouldGenerateReceiverAsSingletonReference(irClass: IrClass): Boolean { private fun shouldGenerateReceiverAsSingletonReference(irClassSymbol: IrClassSymbol): Boolean {
val scopeOwner = conversionScope.parent() val scopeOwner = conversionScope.parent()
return irClass.isObject && // For anonymous initializers
scopeOwner != irClass && // For anonymous initializers if ((scopeOwner as? IrDeclaration)?.symbol == irClassSymbol) return false
!((scopeOwner is IrFunction || scopeOwner is IrProperty || scopeOwner is IrField) && (scopeOwner as IrDeclaration).parent == irClass) // Members of object // Members of object
return when (scopeOwner) {
is IrFunction, is IrProperty, is IrField -> {
val parent = (scopeOwner as IrDeclaration).parent as? IrDeclaration
parent?.symbol != irClassSymbol
}
else -> true
}
} }
@OptIn(IrSymbolInternals::class)
override fun visitThisReceiverExpression( override fun visitThisReceiverExpression(
thisReceiverExpression: FirThisReceiverExpression, thisReceiverExpression: FirThisReceiverExpression,
data: Any? data: Any?
@@ -676,21 +681,40 @@ class Fir2IrVisitor(
is FirClassSymbol -> { is FirClassSymbol -> {
// Object case // Object case
val firClass = boundSymbol.fir as FirClass val firClass = boundSymbol.fir as FirClass
val irClass = if (firClass.origin == FirDeclarationOrigin.Source) { val irClassSymbol = if (firClass.origin.fromSource || firClass.origin.generated) {
// We anyway can use 'else' branch as fallback, but // We anyway can use 'else' branch as fallback, but
// this is an additional check of FIR2IR invariants // this is an additional check of FIR2IR invariants
// (source classes should be already built when we analyze bodies) // (source classes should be already built when we analyze bodies)
classifierStorage.getCachedIrClass(firClass)!! classifierStorage.getCachedIrClass(firClass)!!.symbol
} else { } else {
classifierStorage.getIrClassSymbol(boundSymbol).owner /*
* The only case when we can refer to non-source this is resolution to companion object of parent
* class in some constructor scope:
*
* // MODULE: lib
* abstract class Base {
* companion object {
* fun foo(): Int = 1
* }
* }
*
* // MODULE: app(lib)
* class Derived(
* val x: Int = foo() // this: Base.Companion
* ) : Base()
*/
classifierStorage.getIrClassSymbol(boundSymbol)
} }
if (shouldGenerateReceiverAsSingletonReference(irClass)) { if (firClass.classKind.isObject && shouldGenerateReceiverAsSingletonReference(irClassSymbol)) {
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset -> return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol) val irType = boundSymbol.defaultType().toIrType()
IrGetObjectValueImpl(startOffset, endOffset, irType, irClassSymbol)
} }
} }
val irClass = conversionScope.findDeclarationInParentsStack<IrClass>(irClassSymbol)
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass) val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
if (dispatchReceiver != null) { if (dispatchReceiver != null) {
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset -> return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
@@ -699,7 +723,7 @@ class Fir2IrVisitor(
} ?: IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol) } ?: IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
if (calleeReference.contextReceiverNumber != -1) { if (calleeReference.contextReceiverNumber != -1) {
val constructorForCurrentlyGeneratedDelegatedConstructor = val constructorForCurrentlyGeneratedDelegatedConstructor =
conversionScope.getConstructorForCurrentlyGeneratedDelegatedConstructor(irClass) conversionScope.getConstructorForCurrentlyGeneratedDelegatedConstructor(irClass.symbol)
if (constructorForCurrentlyGeneratedDelegatedConstructor != null) { if (constructorForCurrentlyGeneratedDelegatedConstructor != null) {
val constructorParameter = val constructorParameter =
@@ -740,7 +764,10 @@ class Fir2IrVisitor(
} }
is FirCallableSymbol -> { is FirCallableSymbol -> {
val irFunction = when (boundSymbol) { val irFunction = when (boundSymbol) {
is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner is FirFunctionSymbol -> {
val functionSymbol = declarationStorage.getIrFunctionSymbol(boundSymbol)
conversionScope.findDeclarationInParentsStack<IrSimpleFunction>(functionSymbol)
}
is FirPropertySymbol -> { is FirPropertySymbol -> {
val property = declarationStorage.getIrPropertySymbol(boundSymbol) as? IrPropertySymbol val property = declarationStorage.getIrPropertySymbol(boundSymbol) as? IrPropertySymbol
property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) } property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) }
@@ -26,7 +26,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
private val symbolProvider = fir2IrComponents.session.symbolProvider private val symbolProvider = fir2IrComponents.session.symbolProvider
private val declarationStorage = fir2IrComponents.declarationStorage private val declarationStorage = fir2IrComponents.declarationStorage
private val classifierStorage = fir2IrComponents.classifierStorage private val classifierStorage = fir2IrComponents.classifierStorage
private val fakeOverrideGenerator = FakeOverrideGenerator(fir2IrComponents, Fir2IrConversionScope()) private val fakeOverrideGenerator = FakeOverrideGenerator(fir2IrComponents, Fir2IrConversionScope(components.configuration))
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? { override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
val signature = symbol.signature ?: return null val signature = symbol.signature ?: return null