Track fake overrides for IrField

This commit is contained in:
Georgy Bronnikov
2018-08-15 14:33:13 +03:00
parent 01d5e227f0
commit 50e8f7efc7
40 changed files with 341 additions and 70 deletions
@@ -41,6 +41,11 @@ interface IrSymbolDeclaration<out S : IrSymbol> : IrDeclaration, IrSymbolOwner {
override val symbol: S
}
interface IrOverridableDeclaration<S : IrSymbol> : IrDeclaration {
val overriddenSymbols: MutableList<S>
}
interface IrDeclarationWithVisibility : IrDeclaration {
val visibility: Visibility
}
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
interface IrField : IrSymbolDeclaration<IrFieldSymbol>, IrDeclarationWithVisibility {
interface IrField : IrSymbolDeclaration<IrFieldSymbol>, IrOverridableDeclaration<IrFieldSymbol>, IrDeclarationWithVisibility {
override val descriptor: PropertyDescriptor
val name: Name
@@ -23,4 +23,4 @@ interface IrField : IrSymbolDeclaration<IrFieldSymbol>, IrDeclarationWithVisibil
var initializer: IrExpressionBody?
var correspondingProperty: IrProperty?
}
}
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface IrSimpleFunction : IrFunction, IrSymbolDeclaration<IrSimpleFunctionSymbol> {
interface IrSimpleFunction : IrFunction, IrSymbolDeclaration<IrSimpleFunctionSymbol>, IrOverridableDeclaration<IrSimpleFunctionSymbol> {
val modality: Modality
val isTailrec: Boolean
val isSuspend: Boolean
var correspondingProperty: IrProperty?
val overriddenSymbols: MutableList<IrSimpleFunctionSymbol>
}
val IrFunction.isPropertyAccessor: Boolean
@@ -88,6 +88,7 @@ class IrFieldImpl(
override var initializer: IrExpressionBody? = null
override var correspondingProperty: IrProperty? = null
override val overriddenSymbols: MutableList<IrFieldSymbol> = mutableListOf()
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitField(this, data)
@@ -20,14 +20,14 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.declarations.lazy.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.hasBackingField
import org.jetbrains.kotlin.types.KotlinType
class DeclarationStubGenerator(
@@ -79,10 +79,10 @@ class DeclarationStubGenerator(
throw AssertionError("Unexpected member descriptor: $descriptor")
}
internal fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
internal fun generatePropertyStub(descriptor: PropertyDescriptor, bindingContext: BindingContext? = null): IrProperty =
IrPropertyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irProperty ->
val getterDescriptor = descriptor.getter
if (getterDescriptor == null) {
if (descriptor.hasBackingField(bindingContext)) {
irProperty.backingField =
symbolTable.declareField(
UNDEFINED_OFFSET,
@@ -91,7 +91,8 @@ class DeclarationStubGenerator(
descriptor.original,
descriptor.type.toIrType()
)
} else {
}
if (getterDescriptor != null) {
irProperty.getter = generateFunctionStub(getterDescriptor)
}
@@ -243,6 +243,15 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
declaration.initializer?.transform()
).apply {
transformAnnotations(declaration)
if (declaration.origin == IrDeclarationOrigin.FAKE_OVERRIDE) {
descriptor.overriddenDescriptors.mapIndexedTo(overriddenSymbols) { index, overriddenDescriptor ->
val oldOverriddenSymbol = declaration.overriddenSymbols.getOrNull(index)
if (overriddenDescriptor.original == oldOverriddenSymbol?.descriptor?.original)
oldOverriddenSymbol
else
IrFieldSymbolImpl(overriddenDescriptor.original)
}
}
}
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrLocalDelegatedProperty =
@@ -22,10 +22,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.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -175,6 +172,9 @@ open class DeepCopyIrTreeWithSymbols(
declaration.type.remapType()
).apply {
transformAnnotations(declaration)
declaration.overriddenSymbols.mapTo(overriddenSymbols) {
symbolRemapper.getReferencedField(it)
}
initializer = declaration.initializer?.transform()
}
@@ -144,6 +144,16 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
override fun visitField(declaration: IrField, data: String) {
declaration.dumpLabeledElementWith(data) {
dumpAnnotations(declaration)
declaration.overriddenSymbols.dumpItems("overridden") {
it.dumpDeclarationElementOrDescriptor()
}
declaration.initializer?.accept(this, "")
}
}
private fun List<IrElement>.dumpElements() {
forEach { it.accept(this@DumpIrTreeVisitor, "") }
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.resolve.BindingContext
class ExternalDependenciesGenerator(
moduleDescriptor: ModuleDescriptor,
@@ -30,11 +31,11 @@ class ExternalDependenciesGenerator(
moduleDescriptor, symbolTable, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, irBuiltIns.languageVersionSettings
)
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
DependencyGenerationTask(irModule).run()
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment, bindingContext: BindingContext? = null) {
DependencyGenerationTask(irModule, bindingContext).run()
}
private inner class DependencyGenerationTask(val irModule: IrModuleFragment) {
private inner class DependencyGenerationTask(val irModule: IrModuleFragment, val bindingContext: BindingContext?) {
fun run() {
stubGenerator.unboundSymbolGeneration = true
@@ -48,7 +49,7 @@ class ExternalDependenciesGenerator(
stubGenerator.generateEnumEntryStub(it.descriptor)
}
ArrayList(symbolTable.unboundFields).forEach {
stubGenerator.generatePropertyStub(it.descriptor)
stubGenerator.generatePropertyStub(it.descriptor, bindingContext)
}
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
stubGenerator.generateFunctionStub(it.descriptor)
@@ -124,8 +124,7 @@ open class SymbolTable : ReferenceSymbolTable {
private var currentScope: Scope? = null
override fun get(d: D): S? {
val scope = currentScope
?: throw AssertionError("No active scope")
val scope = currentScope ?: return null
return scope[d]
}
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.IrType
@@ -17,10 +19,11 @@ fun SymbolTable.declareSimpleFunctionWithOverrides(
descriptor: FunctionDescriptor
) =
declareSimpleFunction(startOffset, endOffset, origin, descriptor).also { declaration ->
generateOverriddenSymbols(declaration, this)
generateOverriddenFunctionSymbols(declaration, this)
}
fun generateOverriddenSymbols(
fun generateOverriddenFunctionSymbols(
declaration: IrSimpleFunction,
symbolTable: SymbolTable
) {
@@ -28,3 +31,27 @@ fun generateOverriddenSymbols(
symbolTable.referenceSimpleFunction(it.original)
}
}
fun SymbolTable.declareFieldWithOverrides(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: PropertyDescriptor,
type: IrType,
hasBackingField: (PropertyDescriptor) -> Boolean
) =
declareField(startOffset, endOffset, origin, descriptor, type).also { declaration ->
generateOverriddenFieldSymbols(declaration, this, hasBackingField)
}
fun generateOverriddenFieldSymbols(
declaration: IrField,
symbolTable: SymbolTable,
hasBackingField: (PropertyDescriptor) -> Boolean
) {
declaration.descriptor.overriddenDescriptors.mapNotNullTo(declaration.overriddenSymbols) {
if (hasBackingField(it)) {
symbolTable.referenceField(it.original)
} else null
}
}