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