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