diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index e63d4641745643f33a81f0445d6b64ad56d18675..38b094436be6757af1bb9fce53ef262989cd8fb1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -248,26 +248,35 @@ class Fir2IrDeclarationStorage( } private fun T.declareDefaultSetterParameter(type: IrType): T { - val parent = this - val descriptor = WrappedValueParameterDescriptor() valueParameters = listOf( - symbolTable.declareValueParameter( - startOffset, endOffset, origin, descriptor, type - ) { symbol -> - irFactory.createValueParameter( - startOffset, endOffset, IrDeclarationOrigin.DEFINED, symbol, - Name.special(""), 0, type, - varargElementType = null, - isCrossinline = false, isNoinline = false, isAssignable = false - ).apply { - this.parent = parent - descriptor.bind(this) - } - } + createDefaultSetterParameter(startOffset, endOffset, origin, type, parent = this) ) return this } + internal fun createDefaultSetterParameter( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + type: IrType, + parent: IrFunction + ): IrValueParameter { + val descriptor = WrappedValueParameterDescriptor() + return symbolTable.declareValueParameter( + startOffset, endOffset, origin, descriptor, type + ) { symbol -> + irFactory.createValueParameter( + startOffset, endOffset, IrDeclarationOrigin.DEFINED, symbol, + Name.special(""), 0, type, + varargElementType = null, + isCrossinline = false, isNoinline = false, isAssignable = false + ).apply { + this.parent = parent + descriptor.bind(this) + } + } + } + private fun T.declareParameters( function: FirFunction<*>?, containingClass: IrClass?, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index 1652f5d9a8065339f4094e9f6e9a591a5e4515d0..e63dc047653a5f5c6ce3691fce337def05d69325 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -24,6 +24,9 @@ import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.fir.backend.ConversionTypeContext +import org.jetbrains.kotlin.fir.backend.ConversionTypeOrigin +import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol class Fir2IrLazyProperty( components: Fir2IrComponents, @@ -110,7 +113,8 @@ class Fir2IrLazyProperty( with(declarationStorage) { createBackingField( fir, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor, - components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), Name.identifier("${fir.name}\$delegate"), true, fir.delegate + components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), + Name.identifier("${fir.name}\$delegate"), true, fir.delegate ) } } @@ -123,29 +127,59 @@ class Fir2IrLazyProperty( } override var getter: IrSimpleFunction? by lazyVar { - declarationStorage.createIrPropertyAccessor( - fir.getter, fir, this, type, parent, parent as? IrClass, false, + Fir2IrLazyPropertyAccessor( + components, startOffset, endOffset, when { origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR else -> origin }, - startOffset, endOffset - ) + fir.getter, isSetter = false, fir, containingClass, + Fir2IrSimpleFunctionSymbol( + signatureComposer.composeAccessorSignature(fir, isSetter = false, containingClass.symbol.toLookupTag())!! + ), + isFakeOverride + ).apply { + parent = this@Fir2IrLazyProperty.parent + correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol + with(classifierStorage) { + setTypeParameters( + this@Fir2IrLazyProperty.fir, ConversionTypeContext( + definitelyNotNull = false, + origin = ConversionTypeOrigin.DEFAULT + ) + ) + } + } } override var setter: IrSimpleFunction? by lazyVar { - if (!fir.isVar) return@lazyVar null - declarationStorage.createIrPropertyAccessor( - fir.setter, fir, this, type, parent, parent as? IrClass, true, + if (!fir.isVar) null else Fir2IrLazyPropertyAccessor( + components, startOffset, endOffset, when { + origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR else -> origin }, - startOffset, endOffset - ) + fir.setter, isSetter = true, fir, containingClass, + Fir2IrSimpleFunctionSymbol( + signatureComposer.composeAccessorSignature(fir, isSetter = true, containingClass.symbol.toLookupTag())!! + ), + isFakeOverride + ).apply { + parent = this@Fir2IrLazyProperty.parent + correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol + with(classifierStorage) { + setTypeParameters( + this@Fir2IrLazyProperty.fir, ConversionTypeContext( + definitelyNotNull = false, + origin = ConversionTypeOrigin.SETTER + ) + ) + } + } } override var metadata: MetadataSource? diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt new file mode 100644 index 0000000000000000000000000000000000000000..f98d825db7a0222f4e6764138981d721590c67c1 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt @@ -0,0 +1,157 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.fir.lazy + +import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fir.backend.* +import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter +import org.jetbrains.kotlin.fir.backend.generateOverriddenAccessorSymbols +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar +import org.jetbrains.kotlin.ir.expressions.IrBody +import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.isNonCompanionObject +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource + +class Fir2IrLazyPropertyAccessor( + components: Fir2IrComponents, + override val startOffset: Int, + override val endOffset: Int, + override var origin: IrDeclarationOrigin, + private val firAccessor: FirPropertyAccessor?, + private val isSetter: Boolean, + private val firParentProperty: FirProperty, + firParentClass: FirRegularClass, + override val symbol: Fir2IrSimpleFunctionSymbol, + override val isFakeOverride: Boolean +) : IrSimpleFunction(), AbstractFir2IrLazyDeclaration, Fir2IrComponents by components { + init { + symbol.bind(this) + } + + override val fir: FirMemberDeclaration + get() = firAccessor ?: firParentProperty + + override var annotations: List by createLazyAnnotations() + override lateinit var typeParameters: List + override lateinit var parent: IrDeclarationParent + override var correspondingPropertySymbol: IrPropertySymbol? = null + + override val isTailrec: Boolean + get() = fir.isTailRec + + override val isSuspend: Boolean + get() = fir.isSuspend + + override val isOperator: Boolean + get() = fir.isOperator + + override val isInfix: Boolean + get() = fir.isInfix + + @ObsoleteDescriptorBasedAPI + override val descriptor: FunctionDescriptor + get() = symbol.descriptor + + override val isInline: Boolean + get() = fir.isInline + + override val isExternal: Boolean + get() = fir.isExternal + + override val isExpect: Boolean + get() = fir.isExpect + + override var body: IrBody? = null + + override val name: Name + get() = Name.special("<${if (isSetter) "set" else "get"}-${firParentProperty.name}>") + + @Suppress("SetterBackingFieldAssignment") + override var visibility: DescriptorVisibility = components.visibilityConverter.convertToDescriptorVisibility(fir.visibility) + set(_) { + error("Mutating Fir2Ir lazy elements is not possible") + } + + override val modality: Modality + get() = fir.modality!! + + override var attributeOwnerId: IrAttributeContainer = this + + override var returnType: IrType by lazyVar { + if (isSetter) irBuiltIns.unitType else firParentProperty.returnTypeRef.toIrType(typeConverter) + } + + override var dispatchReceiverParameter: IrValueParameter? by lazyVar { + val containingClass = parent as? IrClass + if (containingClass != null && !firParentProperty.isStatic && + !(containingClass.isNonCompanionObject && firParentProperty.hasAnnotation(ClassId.topLevel(JVM_STATIC_ANNOTATION_FQ_NAME))) + ) { + declarationStorage.enterScope(this) + declareThisReceiverParameter( + symbolTable, + thisType = containingClass.thisReceiver?.type ?: error("No this receiver for containing class"), + thisOrigin = origin + ).apply { + declarationStorage.leaveScope(this@Fir2IrLazyPropertyAccessor) + } + } else null + } + + override var extensionReceiverParameter: IrValueParameter? by lazyVar { + firParentProperty.receiverTypeRef?.let { + declarationStorage.enterScope(this) + declareThisReceiverParameter( + symbolTable, + thisType = it.toIrType(typeConverter), + thisOrigin = origin, + ).apply { + declarationStorage.leaveScope(this@Fir2IrLazyPropertyAccessor) + } + } + } + + override var valueParameters: List by lazyVar { + if (!isSetter) emptyList() + else { + declarationStorage.enterScope(this) + listOf( + declarationStorage.createDefaultSetterParameter( + startOffset, endOffset, origin, + (firAccessor?.valueParameters?.firstOrNull()?.returnTypeRef ?: firParentProperty.returnTypeRef).toIrType( + typeConverter, ConversionTypeContext.DEFAULT.inSetter() + ), + this@Fir2IrLazyPropertyAccessor + ) + ).apply { + declarationStorage.leaveScope(this@Fir2IrLazyPropertyAccessor) + } + } + } + + override var overriddenSymbols: List by lazyVar { + firParentProperty.generateOverriddenAccessorSymbols(firParentClass, !isSetter, session, scopeSession, declarationStorage) + } + + override var metadata: MetadataSource? + get() = null + set(_) = error("We should never need to store metadata of external declarations.") + + override val containerSource: DeserializedContainerSource? + get() = firParentProperty.containerSource + +} \ No newline at end of file diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt index 9378ae7aabd0c80a47fa12896de6d4ecbc5ad409..d7f4b67e9f3d356a389d63c501548f4153a787e5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.isNonCompanionObject -import org.jetbrains.kotlin.ir.util.isObject import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME class Fir2IrLazySimpleFunction(