Track fake overrides for IrField
This commit is contained in:
+2
-23
@@ -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> {
|
||||
|
||||
+33
-7
@@ -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, "") }
|
||||
}
|
||||
|
||||
+5
-4
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user