Generate references to overridden declarations as a separate pass

NB currently it relies on overriddenDescriptors in a FunctionDescriptor,
thus maybe incorrect for transformed declarations.
This commit is contained in:
Dmitry Petrov
2018-01-19 10:08:18 +03:00
parent 9570b64953
commit e5295d0f78
110 changed files with 1864 additions and 5 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.patchOverriddenFunctionsFromDescriptors
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
@@ -47,8 +48,10 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
GeneratorContext(configuration, moduleDescriptor, bindingContext)
fun generateModuleFragment(context: GeneratorContext, ktFiles: Collection<KtFile>): IrModuleFragment {
val irModule = ModuleGenerator(context).generateModuleFragment(ktFiles)
val moduleGenerator = ModuleGenerator(context)
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
postprocess(context, irModule)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule)
return irModule
}
@@ -58,5 +61,6 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
postprocessingSteps.forEach { it.postprocess(context, irElement) }
irElement.patchDeclarationParents()
irElement.patchOverriddenFunctionsFromDescriptors(context.symbolTable)
}
}
@@ -36,7 +36,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
irModule.files.addAll(generateFiles(ktFiles))
}
private fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
ExternalDependenciesGenerator(context.symbolTable, context.irBuiltIns).generateUnboundSymbolsAsDependencies(irModule)
}
@@ -26,6 +26,8 @@ interface IrSimpleFunction : IrFunction, IrSymbolDeclaration<IrSimpleFunctionSym
val isTailrec: Boolean
val isSuspend: Boolean
val overriddenSymbols: MutableList<IrSimpleFunctionSymbol>
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.FUNCTION
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.SmartList
class IrFunctionImpl(
startOffset: Int,
@@ -62,6 +63,8 @@ class IrFunctionImpl(
override val descriptor: FunctionDescriptor = symbol.descriptor
override val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = SmartList()
constructor(
startOffset: Int,
endOffset: Int,
@@ -108,13 +108,21 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapTypeAliasDeclaration(declaration.descriptor)
)
override fun visitFunction(declaration: IrFunction): IrFunction =
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrFunction =
IrFunctionImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapFunctionDeclaration(declaration.descriptor),
declaration.body?.transform()
).transformParameters(declaration)
).transformParameters(declaration).apply {
descriptor.overriddenDescriptors.mapIndexedTo(overriddenSymbols) { index, overriddenDescriptor ->
val oldOverriddenSymbol = declaration.overriddenSymbols.getOrNull(index)
if (overriddenDescriptor.original == oldOverriddenSymbol?.descriptor?.original)
oldOverriddenSymbol
else
IrSimpleFunctionSymbolImpl(overriddenDescriptor.original)
}
}
override fun visitConstructor(declaration: IrConstructor): IrConstructor =
IrConstructorImpl(
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -105,6 +106,9 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
mapDeclarationOrigin(declaration.origin),
symbolRemapper.getDeclaredFunction(declaration.symbol)
).apply {
declaration.overriddenSymbols.mapTo(overriddenSymbols) {
symbolRemapper.getReferencedFunction(it) as IrSimpleFunctionSymbol
}
transformFunctionChildren(declaration)
}
@@ -83,8 +83,18 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
override fun visitFunction(declaration: IrFunction, data: String) {
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: String) {
declaration.dumpLabeledElementWith(data) {
if (declaration.overriddenSymbols.isNotEmpty()) {
indented("overridden") {
for (overriddenSymbol in declaration.overriddenSymbols) {
if (overriddenSymbol.isBound)
overriddenSymbol.owner.render()
else
printer.println("UNBOUND: ", DescriptorRenderer.COMPACT.render(overriddenSymbol.descriptor))
}
}
}
declaration.typeParameters.dumpElements()
declaration.dispatchReceiverParameter?.accept(this, "\$this")
declaration.extensionReceiverParameter?.accept(this, "\$receiver")
@@ -204,6 +214,10 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
indented(body)
}
private fun IrElement.render() {
printer.println(accept(elementRenderer, null))
}
private fun IrElement.dumpLabeledSubTree(label: String) {
printer.println(accept(elementRenderer, null).withLabel(label))
indented {
@@ -211,6 +225,11 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
private inline fun indented(label: String, body: () -> Unit) {
printer.println("$label:")
indented(body)
}
private inline fun indented(body: () -> Unit) {
printer.pushIndent()
body()
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun <T : IrElement> T.patchOverriddenFunctionsFromDescriptors(symbolTable: SymbolTable) =
apply {
acceptVoid(PatchOverriddenFunctionsFromDescriptorsVisitor(symbolTable))
}
class PatchOverriddenFunctionsFromDescriptorsVisitor(
private val symbolTable: SymbolTable
) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
declaration.descriptor.overriddenDescriptors.mapTo(declaration.overriddenSymbols) {
symbolTable.referenceSimpleFunction(it.original)
}
super.visitSimpleFunction(declaration)
}
}