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:
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user