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
@@ -155,29 +155,8 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
}
}
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtPureElement): IrProperty {
val startOffset = ktElement.pureStartOffsetOrUndefined
val endOffset = ktElement.pureEndOffsetOrUndefined
val backingField =
if (propertyDescriptor.getter == null)
context.symbolTable.declareField(
startOffset, endOffset, IrDeclarationOrigin.FAKE_OVERRIDE,
propertyDescriptor, propertyDescriptor.type.toIrType()
)
else
null
return IrPropertyImpl(
startOffset, endOffset,
IrDeclarationOrigin.FAKE_OVERRIDE,
false,
propertyDescriptor,
backingField,
propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) },
propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) }
)
}
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtPureElement): IrProperty =
PropertyGenerator(this).generateFakeOverrideProperty(propertyDescriptor, ktElement)
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtPureElement): IrSimpleFunction =
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
@@ -42,7 +42,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
fun generateUnboundSymbolsAsDependencies(irModule: IrModuleFragment) {
ExternalDependenciesGenerator(
irModule.descriptor, context.symbolTable, context.irBuiltIns
).generateUnboundSymbolsAsDependencies(irModule)
).generateUnboundSymbolsAsDependencies(irModule, context.bindingContext)
}
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
@@ -23,13 +24,15 @@ import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyDelegate
import org.jetbrains.kotlin.ir.util.declareFieldWithOverrides
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.pureEndOffsetOrUndefined
import org.jetbrains.kotlin.psi2ir.pureStartOffsetOrUndefined
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.hasBackingField
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
class PropertyGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
@@ -106,7 +109,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
propertyDescriptor
).buildWithScope { irProperty ->
irProperty.backingField =
if (propertyDescriptor.hasBackingField())
if (propertyDescriptor.hasBackingField(context.bindingContext))
generatePropertyBackingField(ktProperty, propertyDescriptor) { irField ->
ktProperty.initializer?.let { ktInitializer ->
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
@@ -119,8 +122,30 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
irProperty.setter = generateSetterIfRequired(ktProperty, propertyDescriptor)
}
private fun PropertyDescriptor.hasBackingField(): Boolean =
get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false
fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtPureElement): IrProperty {
val startOffset = ktElement.pureStartOffsetOrUndefined
val endOffset = ktElement.pureEndOffsetOrUndefined
val backingField =
if (propertyDescriptor.hasBackingField(context.bindingContext))
context.symbolTable.declareFieldWithOverrides(
startOffset, endOffset, IrDeclarationOrigin.FAKE_OVERRIDE,
propertyDescriptor, propertyDescriptor.type.toIrType(),
{ it.hasBackingField(context.bindingContext) }
)
else
null
return IrPropertyImpl(
startOffset, endOffset,
IrDeclarationOrigin.FAKE_OVERRIDE,
false,
propertyDescriptor,
backingField,
propertyDescriptor.getter?.let { FunctionGenerator(declarationGenerator).generateFakeOverrideFunction(it, ktElement) },
propertyDescriptor.setter?.let { FunctionGenerator(declarationGenerator).generateFakeOverrideFunction(it, ktElement) }
)
}
private fun generateGetterIfRequired(ktProperty: KtProperty, property: PropertyDescriptor): IrSimpleFunction? {
val getter = property.getter ?: return null
@@ -138,3 +163,4 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
return variableDescriptor as? PropertyDescriptor ?: TODO("not a property?")
}
}
@@ -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
}
}