Fix IR declaration parents.

- Reparent declarations in FileClassLowering, InterfaceLowering,
  StaticDefaultFunctionsLowering, EnumClassLowering, and
  RenameFieldsLowering
- Set correspondingPropertySymbol in MoveCompanionObjectFieldsLowering
- Reparent field initializers in MoveCompanionObjectFieldsLowering and
  EnumClassLowering
- Ensure that parents are unique in PropertiesLowering
- Set declaration parent in SharedVariableManager
- Set field declaration parents in CallableReferenceLowering
- Set declaration parents in FunctionNVarargInvokeLowering
- Set declaration parents for external declaration fields
This commit is contained in:
Steven Schäfer
2019-04-03 13:37:36 +02:00
committed by max-kammerer
parent f39908b411
commit 8c06f7daae
12 changed files with 47 additions and 29 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -80,7 +81,7 @@ class PropertiesLowering(
).apply {
descriptor.bind(this)
extensionReceiverParameter = declaration.getter?.extensionReceiverParameter
extensionReceiverParameter = declaration.getter?.extensionReceiverParameter?.copyTo(this)
body = IrBlockBodyImpl(-1, -1)
@@ -106,7 +106,7 @@ class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPas
if (declaration !in sharedVariables) return declaration
val newDeclaration = context.sharedVariablesManager.declareSharedVariable(declaration)
newDeclaration.parent = irFunction
newDeclaration.parent = declaration.parent
transformedSymbols[declaration.symbol] = newDeclaration.symbol
return context.sharedVariablesManager.defineSharedValue(declaration, newDeclaration)
@@ -193,6 +193,7 @@ class JvmSharedVariablesManager(
).apply {
(descriptor as WrappedVariableDescriptor).bind(this)
initializer = refConstructorCall
parent = originalDeclaration.parent
}
}
@@ -450,6 +450,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
visibility = JavaVisibilities.PACKAGE_VISIBILITY
isFinal = true
}.also {
it.parent = functionReferenceClass
functionReferenceClass.declarations.add(it)
}
@@ -153,7 +153,7 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
}
})
body = enumConstructor.body // will be transformed later
body = enumConstructor.body?.patchDeclarationParents(this)
loweredEnumConstructors[enumConstructor.symbol] = this
metadata = enumConstructor.metadata
@@ -219,7 +219,9 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
context.declarationFactory.getFieldForEnumEntry(
enumEntry, (enumEntry.correspondingClass ?: enumEntry.parentAsClass).defaultType
).also {
it.initializer = IrExpressionBodyImpl(enumEntry.initializerExpression!!)
it.initializer = IrExpressionBodyImpl(
enumEntry.initializerExpression!!.patchDeclarationParents(it)
)
it.annotations.addAll(enumEntry.annotations)
enumEntryFields.add(it)
enumEntriesByField[it] = enumEntry
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
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.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
@@ -93,8 +90,14 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
parent = irFile
declarations.addAll(fileClassMembers)
createImplicitParameterDeclarationWithWrappedDescriptor()
// TODO: figure out why reparenting leads to failing tests.
// fileClassMembers.forEach { it.parent = this }
fileClassMembers.forEach {
it.parent = this
if (it is IrProperty) {
it.getter?.let { it.parent = this }
it.setter?.let { it.parent = this }
it.backingField?.let { it.parent = this }
}
}
metadata = irFile.metadata
val partClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.fileClassFqName)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
@@ -71,7 +72,8 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
isSuspend = false
).apply {
descriptor.bind(this)
dispatchReceiverParameter = irClass.thisReceiver
parent = irClass
dispatchReceiverParameter = irClass.thisReceiver?.copyTo(this)
val varargParameterDescriptor = WrappedValueParameterDescriptor()
val varargParam = IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
@@ -86,6 +88,7 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
).apply {
varargParameterDescriptor.bind(this)
}
varargParam.parent = this
valueParameters.add(varargParam)
val irBuilder = context.createIrBuilder(symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
body = irBuilder.irBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
@@ -49,7 +50,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
if (function.modality != Modality.ABSTRACT && function.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
val element = context.declarationFactory.getDefaultImplsFunction(function)
members.add(element)
element.body = function.body
element.body = function.body?.patchDeclarationParents(element)
function.body = null
//TODO reset modality to abstract
}
@@ -111,7 +112,9 @@ internal fun createStaticFunctionWithReceivers(
val mapping: Map<IrValueParameter, IrValueParameter> =
(listOfNotNull(oldFunction.dispatchReceiverParameter, oldFunction.extensionReceiverParameter) + oldFunction.valueParameters)
.zip(valueParameters).toMap()
body = oldFunction.body?.transform(VariableRemapper(mapping), null)
body = oldFunction.body
?.transform(VariableRemapper(mapping), null)
?.patchDeclarationParents(this)
metadata = oldFunction.metadata
}
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
@@ -188,11 +185,9 @@ private class MoveCompanionObjectFieldsLowering(val context: CommonBackendContex
}
val oldInitializer = oldField.initializer
if (oldInitializer != null) {
field.initializer = oldInitializer.replaceThisByStaticReference(
context,
propertyParent,
propertyParent.thisReceiver!!
) as IrExpressionBody
field.initializer = oldInitializer
.replaceThisByStaticReference(context, propertyParent, propertyParent.thisReceiver!!)
.patchDeclarationParents(field) as IrExpressionBody
}
return field
@@ -109,8 +109,9 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
val parent = expression.propertyContainerChild?.parent
val context = this@PropertyReferenceLowering.context
return when {
// FileClassLowering creates a class to which all package-level declarations are moved. However, it does not
// fix the declarations' parents (yet), which is why we check for both a file class and a package fragment.
// FileClassLowering creates a class to which all package-level declarations are moved. However, there
// can still be external declarations at the package level, which is why we check for both a file class
// and a package fragment.
parent is IrPackageFragment || (parent is IrClass && parent.origin == IrDeclarationOrigin.FILE_CLASS) ->
irCall(context.ir.symbols.getOrCreateKotlinPackage).apply {
putValueArgument(0, expression.parentJavaClassReference)
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -97,7 +98,9 @@ private class FieldRenamer(private val newNames: Map<IrField, Name>) : IrElement
).also {
descriptor.bind(it)
it.parent = declaration.parent
it.initializer = declaration.initializer?.transform(this, null)
it.initializer = declaration.initializer
?.transform(this, null)
?.patchDeclarationParents(it)
it.metadata = declaration.metadata
newSymbols[declaration] = symbol
@@ -54,10 +54,15 @@ class PatchDeclarationParentsVisitor() : IrElementVisitorVoid {
}
override fun visitProperty(declaration: IrProperty) {
declaration.getter?.let { it.correspondingProperty = declaration }
declaration.setter?.let { it.correspondingProperty = declaration }
declaration.backingField?.let { it.correspondingProperty = declaration }
declaration.getter?.let {
it.correspondingPropertySymbol = declaration.symbol
}
declaration.setter?.let {
it.correspondingPropertySymbol = declaration.symbol
}
declaration.backingField?.let {
it.correspondingPropertySymbol = declaration.symbol
}
super.visitProperty(declaration)
}