[FIR2IR] Introduce & use declaration-based SymbolTable.enter(leave)Scope

This commit is contained in:
Mikhail Glukhikh
2020-06-04 12:22:36 +03:00
parent e593c7270f
commit 538535c3b7
5 changed files with 47 additions and 43 deletions
@@ -69,7 +69,7 @@ class Fir2IrClassifierStorage(
}
private fun IrClass.setThisReceiver(typeParameters: List<FirTypeParameterRef>) {
symbolTable.enterScope(descriptor)
symbolTable.enterScope(this)
val typeArguments = typeParameters.map {
IrSimpleTypeImpl(getCachedIrTypeParameter(it.symbol.fir)!!.symbol, false, emptyList(), emptyList())
}
@@ -78,7 +78,7 @@ class Fir2IrClassifierStorage(
thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()),
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
)
symbolTable.leaveScope(descriptor)
symbolTable.leaveScope(this)
}
internal fun preCacheTypeParameters(owner: FirTypeParameterRefsOwner) {
@@ -343,7 +343,7 @@ class Fir2IrClassifierStorage(
IrEnumEntryImpl(
startOffset, endOffset, origin, symbol, enumEntry.name
).apply {
declarationStorage.enterScope(descriptor)
declarationStorage.enterScope(this)
val irType = enumEntry.returnTypeRef.toIrType()
if (irParent != null) {
this.parent = irParent
@@ -359,7 +359,7 @@ class Fir2IrClassifierStorage(
IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol)
)
}
declarationStorage.leaveScope(descriptor)
declarationStorage.leaveScope(this)
}
}
enumEntryCache[enumEntry] = result
@@ -135,26 +135,26 @@ class Fir2IrDeclarationStorage(
return fileCache[firFile]!!
}
fun enterScope(descriptor: DeclarationDescriptor) {
symbolTable.enterScope(descriptor)
if (descriptor is WrappedSimpleFunctionDescriptor ||
descriptor is WrappedClassConstructorDescriptor ||
descriptor is WrappedPropertyDescriptor ||
descriptor is WrappedEnumEntryDescriptor
fun enterScope(declaration: IrDeclaration) {
symbolTable.enterScope(declaration)
if (declaration is IrSimpleFunction ||
declaration is IrConstructor ||
declaration is IrProperty ||
declaration is IrEnumEntry
) {
localStorage.enterCallable()
}
}
fun leaveScope(descriptor: DeclarationDescriptor) {
if (descriptor is WrappedSimpleFunctionDescriptor ||
descriptor is WrappedClassConstructorDescriptor ||
descriptor is WrappedPropertyDescriptor ||
descriptor is WrappedEnumEntryDescriptor
fun leaveScope(declaration: IrDeclaration) {
if (declaration is IrSimpleFunction ||
declaration is IrConstructor ||
declaration is IrProperty ||
declaration is IrEnumEntry
) {
localStorage.leaveCallable()
}
symbolTable.leaveScope(descriptor)
symbolTable.leaveScope(declaration)
}
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
@@ -485,17 +485,17 @@ class Fir2IrDeclarationStorage(
isOperator = simpleFunction?.isOperator == true
).apply {
metadata = FirMetadataSource.Function(function, descriptor)
enterScope(descriptor)
enterScope(this)
bindAndDeclareParameters(
function, irParent,
thisReceiverOwner, isStatic = simpleFunction?.isStatic == true
)
leaveScope(this)
}
}
result
}
leaveScope(created.descriptor)
if (visibility == Visibilities.LOCAL) {
localStorage.putLocalFunction(function, created)
return created
@@ -554,9 +554,9 @@ class Fir2IrDeclarationStorage(
isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false
).apply {
metadata = FirMetadataSource.Function(constructor, descriptor)
enterScope(descriptor)
enterScope(this)
bindAndDeclareParameters(constructor, irParent, isStatic = false)
leaveScope(descriptor)
leaveScope(this)
}
}
}
@@ -624,12 +624,12 @@ class Fir2IrDeclarationStorage(
property.returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
)
}
enterScope(descriptor)
enterScope(this)
bindAndDeclareParameters(
propertyAccessor, irParent,
thisReceiverOwner, isStatic = irParent !is IrClass, parentPropertyReceiverType = property.receiverTypeRef
)
leaveScope(descriptor)
leaveScope(this)
if (irParent != null) {
parent = irParent
}
@@ -717,7 +717,7 @@ class Fir2IrDeclarationStorage(
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
).apply {
metadata = FirMetadataSource.Variable(property, descriptor)
enterScope(descriptor)
enterScope(this)
if (irParent != null) {
parent = irParent
}
@@ -775,7 +775,7 @@ class Fir2IrDeclarationStorage(
startOffset, endOffset
)
}
leaveScope(descriptor)
leaveScope(this)
}
}
propertyCache[property] = result
@@ -102,7 +102,7 @@ class Fir2IrVisitor(
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement {
val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!!
val correspondingClass = irEnumEntry.correspondingClass ?: return irEnumEntry
declarationStorage.enterScope(irEnumEntry.descriptor)
declarationStorage.enterScope(irEnumEntry)
classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass)
conversionScope.withParent(correspondingClass) {
@@ -114,7 +114,7 @@ class Fir2IrVisitor(
)
)
}
declarationStorage.leaveScope(irEnumEntry.descriptor)
declarationStorage.leaveScope(irEnumEntry)
return irEnumEntry
}
@@ -176,9 +176,9 @@ class Fir2IrVisitor(
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement {
val irAnonymousInitializer = declarationStorage.getCachedIrAnonymousInitializer(anonymousInitializer)!!
declarationStorage.enterScope(irAnonymousInitializer.descriptor)
declarationStorage.enterScope(irAnonymousInitializer)
irAnonymousInitializer.body = convertToIrBlockBody(anonymousInitializer.body!!)
declarationStorage.leaveScope(irAnonymousInitializer.descriptor)
declarationStorage.leaveScope(irAnonymousInitializer)
return irAnonymousInitializer
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -46,13 +45,13 @@ internal class ClassMemberGenerator(
private fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T = conversionScope.applyParentFromStackTo(declaration)
fun convertClassContent(irClass: IrClass, klass: FirClass<*>) {
declarationStorage.enterScope(irClass.descriptor)
declarationStorage.enterScope(irClass)
conversionScope.withClass(irClass) {
val primaryConstructor = klass.getPrimaryConstructorIfAny()
val irPrimaryConstructor = primaryConstructor?.let { declarationStorage.getCachedIrConstructor(it)!! }
if (irPrimaryConstructor != null) {
with(declarationStorage) {
enterScope(irPrimaryConstructor.descriptor)
enterScope(irPrimaryConstructor)
irPrimaryConstructor.valueParameters.forEach { symbolTable.introduceValueParameter(it) }
irPrimaryConstructor.putParametersInScope(primaryConstructor)
convertFunctionContent(irPrimaryConstructor, primaryConstructor)
@@ -92,20 +91,19 @@ internal class ClassMemberGenerator(
}
annotationGenerator.generate(irClass, klass)
if (irPrimaryConstructor != null) {
declarationStorage.leaveScope(irPrimaryConstructor.descriptor)
declarationStorage.leaveScope(irPrimaryConstructor)
}
}
declarationStorage.leaveScope(irClass.descriptor)
declarationStorage.leaveScope(irClass)
}
fun <T : IrFunction> convertFunctionContent(irFunction: T, firFunction: FirFunction<*>?): T {
val descriptor = irFunction.descriptor
conversionScope.withParent(irFunction) {
if (firFunction != null) {
if (irFunction !is IrConstructor || !irFunction.isPrimary) {
// Scope for primary constructor should be entered before class declaration processing
with(declarationStorage) {
enterScope(descriptor)
enterScope(irFunction)
irFunction.valueParameters.forEach { symbolTable.introduceValueParameter(it) }
irFunction.putParametersInScope(firFunction)
}
@@ -160,18 +158,17 @@ internal class ClassMemberGenerator(
}
if (irFunction !is IrConstructor || !irFunction.isPrimary) {
// Scope for primary constructor should be left after class declaration
declarationStorage.leaveScope(descriptor)
declarationStorage.leaveScope(irFunction)
}
}
return irFunction
}
fun convertPropertyContent(irProperty: IrProperty, property: FirProperty): IrProperty {
val descriptor = irProperty.descriptor
val initializer = property.initializer
val delegate = property.delegate
val propertyType = property.returnTypeRef.toIrType()
irProperty.initializeBackingField(property, descriptor, initializerExpression = initializer ?: delegate)
irProperty.initializeBackingField(property, initializerExpression = initializer ?: delegate)
irProperty.getter?.setPropertyAccessorContent(
property, property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter
)
@@ -186,17 +183,16 @@ internal class ClassMemberGenerator(
private fun IrProperty.initializeBackingField(
property: FirProperty,
descriptor: PropertyDescriptor,
initializerExpression: FirExpression?
) {
val irField = backingField ?: return
conversionScope.withParent(irField) {
declarationStorage.enterScope(descriptor)
declarationStorage.enterScope(this@initializeBackingField)
// NB: initializer can be already converted
if (initializer == null && initializerExpression != null) {
initializer = IrExpressionBodyImpl(visitor.convertToIrExpression(initializerExpression))
}
declarationStorage.leaveScope(descriptor)
declarationStorage.leaveScope(this@initializeBackingField)
}
annotationGenerator.generate(irField, property)
}
@@ -213,7 +209,7 @@ internal class ClassMemberGenerator(
convertFunctionContent(this, propertyAccessor)
if (isDefault) {
conversionScope.withParent(this) {
declarationStorage.enterScope(descriptor)
declarationStorage.enterScope(this)
val backingField = correspondingProperty.backingField
val fieldSymbol = symbolTable.referenceField(correspondingProperty.descriptor)
val declaration = this
@@ -235,7 +231,7 @@ internal class ClassMemberGenerator(
)
)
}
declarationStorage.leaveScope(descriptor)
declarationStorage.leaveScope(this)
}
}
}
@@ -947,10 +947,18 @@ open class SymbolTable(
scopedSymbolTables.forEach { it.enterScope(owner) }
}
fun enterScope(owner: IrDeclaration) {
enterScope(owner.descriptor)
}
override fun leaveScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.leaveScope(owner) }
}
fun leaveScope(owner: IrDeclaration) {
leaveScope(owner.descriptor)
}
fun referenceValue(value: ValueDescriptor): IrValueSymbol =
when (value) {
is ParameterDescriptor ->