Provide parent reference for temporary variables immediately

This commit is contained in:
Dmitry Petrov
2018-12-20 12:34:05 +03:00
parent 4e53e7d663
commit 57c12476d7
9 changed files with 191 additions and 8 deletions
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
@@ -31,11 +31,13 @@ class AnonymousInitializerGenerator(
fun generateAnonymousInitializerDeclaration(
ktAnonymousInitializer: KtAnonymousInitializer,
classDescriptor: ClassDescriptor
irClass: IrClass
): IrDeclaration =
context.symbolTable.declareAnonymousInitializer(
ktAnonymousInitializer.startOffsetSkippingComments, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
ktAnonymousInitializer.startOffsetSkippingComments, ktAnonymousInitializer.endOffset,
IrDeclarationOrigin.DEFINED, irClass.descriptor
).buildWithScope { irAnonymousInitializer ->
irAnonymousInitializer.parent = irClass
val bodyGenerator = createBodyGenerator(irAnonymousInitializer.symbol)
val statementGenerator = bodyGenerator.createStatementGenerator()
val ktBody = ktAnonymousInitializer.body!!
@@ -365,9 +365,9 @@ class ClassGenerator(
private fun generateMembersDeclaredInClassBody(irClass: IrClass, ktClassOrObject: KtPureClassOrObject) {
// generate real body declarations
ktClassOrObject.getBody()?.let { ktClassBody ->
ktClassOrObject.body?.let { ktClassBody ->
ktClassBody.declarations.mapTo(irClass.declarations) { ktDeclaration ->
declarationGenerator.generateClassMemberDeclaration(ktDeclaration, irClass.descriptor)
declarationGenerator.generateClassMemberDeclaration(ktDeclaration, irClass)
}
}
@@ -384,12 +384,20 @@ class ClassGenerator(
fun generateEnumEntry(ktEnumEntry: KtEnumEntry): IrEnumEntry {
val enumEntryDescriptor = getOrFail(BindingContext.CLASS, ktEnumEntry)
// TODO this is a hack, pass declaration parent through generator chain instead
val enumClassDescriptor = enumEntryDescriptor.containingDeclaration as ClassDescriptor
val enumClassSymbol = context.symbolTable.referenceClass(enumClassDescriptor)
val irEnumClass = enumClassSymbol.owner
return context.symbolTable.declareEnumEntry(
ktEnumEntry.startOffsetSkippingComments,
ktEnumEntry.endOffset,
IrDeclarationOrigin.DEFINED,
enumEntryDescriptor
).buildWithScope { irEnumEntry ->
irEnumEntry.parent = irEnumClass
if (!enumEntryDescriptor.isExpect) {
irEnumEntry.initializerExpression =
createBodyGenerator(irEnumEntry.symbol)
@@ -62,10 +62,10 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
return generateClassOrObjectDeclaration(syntheticDeclaration)
}
fun generateClassMemberDeclaration(ktDeclaration: KtDeclaration, classDescriptor: ClassDescriptor): IrDeclaration =
fun generateClassMemberDeclaration(ktDeclaration: KtDeclaration, irClass: IrClass): IrDeclaration =
when (ktDeclaration) {
is KtAnonymousInitializer ->
AnonymousInitializerGenerator(this).generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor)
AnonymousInitializerGenerator(this).generateAnonymousInitializerDeclaration(ktDeclaration, irClass)
is KtSecondaryConstructor ->
FunctionGenerator(this).generateSecondaryConstructor(ktDeclaration)
is KtEnumEntry ->
@@ -20,7 +20,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
@@ -39,6 +41,16 @@ import org.jetbrains.kotlin.types.KotlinType
class Scope(val scopeOwnerSymbol: IrSymbol) {
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
private fun getVariableParent(): IrDeclarationParent {
if (!scopeOwnerSymbol.isBound) throw AssertionError("Unbound symbol: $scopeOwner")
val scopeOwnerElement = scopeOwnerSymbol.owner
return when (scopeOwnerElement) {
is IrDeclarationParent -> scopeOwnerElement
!is IrDeclaration -> throw AssertionError("Not a declaration: $scopeOwnerElement")
else -> scopeOwnerElement.parent
}
}
@Deprecated("Creates unbound symbol")
constructor(descriptor: DeclarationDescriptor) : this(createSymbolForScopeOwner(descriptor))
@@ -74,7 +86,9 @@ class Scope(val scopeOwnerSymbol: IrSymbol) {
),
irType ?: irExpression.type,
irExpression
)
).apply {
parent = getVariableParent()
}
}
}