[FIR2IR] Extract ClassMemberGenerator from the main visitor

This commit is contained in:
Mikhail Glukhikh
2020-03-16 13:35:56 +03:00
parent 63aa5191da
commit 5357e7b3ab
2 changed files with 345 additions and 295 deletions
@@ -7,10 +7,8 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator import org.jetbrains.kotlin.fir.backend.generators.ClassMemberGenerator
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
@@ -33,14 +31,12 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import java.util.* import java.util.*
@@ -59,7 +55,7 @@ class Fir2IrVisitor(
private val conversionScope = Fir2IrConversionScope() private val conversionScope = Fir2IrConversionScope()
private val fakeOverrideGenerator = FakeOverrideGenerator(session, declarationStorage, conversionScope, fakeOverrideMode) private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, fakeOverrideMode)
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
@@ -97,7 +93,7 @@ class Fir2IrVisitor(
classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass) classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass) converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass)
conversionScope.withParent(correspondingClass) { conversionScope.withParent(correspondingClass) {
setClassContent(enumEntry.initializer as FirAnonymousObject) memberGenerator.convertClassContent(correspondingClass, enumEntry.initializer as FirAnonymousObject)
irEnumEntry.initializerExpression = IrExpressionBodyImpl( irEnumEntry.initializerExpression = IrExpressionBodyImpl(
IrEnumConstructorCallImpl( IrEnumConstructorCallImpl(
startOffset, endOffset, enumEntry.returnTypeRef.toIrType(), startOffset, endOffset, enumEntry.returnTypeRef.toIrType(),
@@ -109,40 +105,6 @@ class Fir2IrVisitor(
return irEnumEntry return irEnumEntry
} }
private fun IrClass.setClassContent(klass: FirClass<*>) {
declarationStorage.enterScope(descriptor)
conversionScope.withClass(this) {
val primaryConstructor = klass.getPrimaryConstructorIfAny()
val irPrimaryConstructor = primaryConstructor?.let { declarationStorage.getCachedIrConstructor(it)!! }
if (irPrimaryConstructor != null) {
with(declarationStorage) {
enterScope(irPrimaryConstructor.descriptor)
irPrimaryConstructor.valueParameters.forEach { symbolTable.introduceValueParameter(it) }
irPrimaryConstructor.putParametersInScope(primaryConstructor)
irPrimaryConstructor.setFunctionContent(irPrimaryConstructor.descriptor, primaryConstructor)
}
}
val processedCallableNames = mutableListOf<Name>()
klass.declarations.forEach {
if (it !is FirConstructor || !it.isPrimary) {
it.toIrDeclaration() ?: return@forEach
when (it) {
is FirSimpleFunction -> processedCallableNames += it.name
is FirProperty -> processedCallableNames += it.name
}
}
}
with(fakeOverrideGenerator) { addFakeOverrides(klass, processedCallableNames) }
annotations = klass.annotations.mapNotNull {
it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall
}
if (irPrimaryConstructor != null) {
declarationStorage.leaveScope(irPrimaryConstructor.descriptor)
}
}
declarationStorage.leaveScope(descriptor)
}
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement { override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement {
if (regularClass.visibility == Visibilities.LOCAL) { if (regularClass.visibility == Visibilities.LOCAL) {
val irParent = conversionScope.parentFromStack() val irParent = conversionScope.parentFromStack()
@@ -151,14 +113,14 @@ class Fir2IrVisitor(
if (irClass != null) { if (irClass != null) {
converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass) converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass)
return conversionScope.withParent(irClass) { return conversionScope.withParent(irClass) {
setClassContent(regularClass) memberGenerator.convertClassContent(irClass, regularClass)
} }
} }
converter.processLocalClassAndNestedClasses(regularClass, irParent) converter.processLocalClassAndNestedClasses(regularClass, irParent)
} }
val irClass = classifierStorage.getCachedIrClass(regularClass)!! val irClass = classifierStorage.getCachedIrClass(regularClass)!!
return conversionScope.withParent(irClass) { return conversionScope.withParent(irClass) {
setClassContent(regularClass) memberGenerator.convertClassContent(irClass, regularClass)
} }
} }
@@ -169,7 +131,7 @@ class Fir2IrVisitor(
?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent) ?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent)
converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject) converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject)
conversionScope.withParent(irAnonymousObject) { conversionScope.withParent(irAnonymousObject) {
setClassContent(anonymousObject) memberGenerator.convertClassContent(irAnonymousObject, anonymousObject)
} }
val anonymousClassType = irAnonymousObject.thisReceiver!!.type val anonymousClassType = irAnonymousObject.thisReceiver!!.type
return anonymousObject.convertWithOffsets { startOffset, endOffset -> return anonymousObject.convertWithOffsets { startOffset, endOffset ->
@@ -192,103 +154,21 @@ class Fir2IrVisitor(
// ================================================================================== // ==================================================================================
private fun <T : IrFunction> T.setFunctionContent(descriptor: FunctionDescriptor, firFunction: FirFunction<*>?): T {
conversionScope.withParent(this) {
if (firFunction != null) {
if (this !is IrConstructor || !this.isPrimary) {
// Scope for primary constructor should be entered before class declaration processing
with(declarationStorage) {
enterScope(descriptor)
valueParameters.forEach { symbolTable.introduceValueParameter(it) }
putParametersInScope(firFunction)
}
}
for ((valueParameter, firValueParameter) in valueParameters.zip(firFunction.valueParameters)) {
valueParameter.setDefaultValue(firValueParameter)
}
}
var body = firFunction?.body?.convertToIrBlockBody()
if (firFunction is FirConstructor && this is IrConstructor && !parentAsClass.isAnnotationClass) {
if (body == null) {
body = IrBlockBodyImpl(startOffset, endOffset)
}
val delegatedConstructor = firFunction.delegatedConstructor
if (delegatedConstructor != null) {
val irDelegatingConstructorCall = delegatedConstructor.toIrDelegatingConstructorCall()
body.statements += irDelegatingConstructorCall ?: delegatedConstructor.convertWithOffsets { startOffset, endOffset ->
IrErrorCallExpressionImpl(
startOffset, endOffset, returnType, "Cannot find delegated constructor call"
)
}
}
if (delegatedConstructor?.isThis == false) {
val irClass = parent as IrClass
body.statements += IrInstanceInitializerCallImpl(
startOffset, endOffset, irClass.symbol, constructedClassType
)
}
if (body.statements.isNotEmpty()) {
this.body = body
}
} else if (this !is IrConstructor) {
this.body = body
}
if (this !is IrConstructor || !this.isPrimary) {
// Scope for primary constructor should be left after class declaration
declarationStorage.leaveScope(descriptor)
}
}
return this
}
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement { override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement {
val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!! val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!!
return conversionScope.withFunction(irConstructor) { return conversionScope.withFunction(irConstructor) {
setFunctionContent(irConstructor.descriptor, constructor) memberGenerator.convertFunctionContent(irConstructor, constructor)
} }
} }
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement { override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement {
val irAnonymousInitializer = declarationStorage.getCachedIrAnonymousInitializer(anonymousInitializer)!! val irAnonymousInitializer = declarationStorage.getCachedIrAnonymousInitializer(anonymousInitializer)!!
declarationStorage.enterScope(irAnonymousInitializer.descriptor) declarationStorage.enterScope(irAnonymousInitializer.descriptor)
irAnonymousInitializer.body = anonymousInitializer.body!!.convertToIrBlockBody() irAnonymousInitializer.body = convertToIrBlockBody(anonymousInitializer.body!!)
declarationStorage.leaveScope(irAnonymousInitializer.descriptor) declarationStorage.leaveScope(irAnonymousInitializer.descriptor)
return irAnonymousInitializer return irAnonymousInitializer
} }
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrCallWithIndexedArgumentsBase? {
val constructedIrType = constructedTypeRef.toIrType()
val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
?: return null
return convertWithOffsets { startOffset, endOffset ->
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
if (constructorSymbol.fir.isFromEnumClass || constructorSymbol.fir.returnTypeRef.isEnum) {
IrEnumConstructorCallImpl(
startOffset, endOffset,
constructedIrType,
irConstructorSymbol
).apply {
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
if (typeArguments?.isNotEmpty() == true) {
val irType = (typeArguments.first() as ConeKotlinTypeProjection).type.toIrType()
putTypeArgument(0, irType)
}
}
} else {
IrDelegatingConstructorCallImpl(
startOffset, endOffset,
constructedIrType,
irConstructorSymbol
)
}.apply {
for ((index, argument) in arguments.withIndex()) {
val argumentExpression = argument.toIrExpression()
putValueArgument(index, argumentExpression)
}
}
}
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement { override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement {
val irFunction = if (simpleFunction.visibility == Visibilities.LOCAL) { val irFunction = if (simpleFunction.visibility == Visibilities.LOCAL) {
val irParent = conversionScope.parent() val irParent = conversionScope.parent()
@@ -297,7 +177,7 @@ class Fir2IrVisitor(
declarationStorage.getCachedIrFunction(simpleFunction)!! declarationStorage.getCachedIrFunction(simpleFunction)!!
} }
return conversionScope.withFunction(irFunction) { return conversionScope.withFunction(irFunction) {
setFunctionContent(irFunction.descriptor, simpleFunction) memberGenerator.convertFunctionContent(irFunction, simpleFunction)
} }
} }
@@ -305,7 +185,7 @@ class Fir2IrVisitor(
return anonymousFunction.convertWithOffsets { startOffset, endOffset -> return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
val irFunction = declarationStorage.createIrFunction(anonymousFunction, conversionScope.parent()) val irFunction = declarationStorage.createIrFunction(anonymousFunction, conversionScope.parent())
conversionScope.withFunction(irFunction) { conversionScope.withFunction(irFunction) {
setFunctionContent(irFunction.descriptor, anonymousFunction) memberGenerator.convertFunctionContent(irFunction, anonymousFunction)
} }
val type = anonymousFunction.typeRef.toIrType() val type = anonymousFunction.typeRef.toIrType()
@@ -314,13 +194,6 @@ class Fir2IrVisitor(
} }
} }
private fun IrValueParameter.setDefaultValue(firValueParameter: FirValueParameter) {
val firDefaultValue = firValueParameter.defaultValue
if (firDefaultValue != null) {
this.defaultValue = IrExpressionBodyImpl(firDefaultValue.toIrExpression())
}
}
private fun visitLocalVariable(variable: FirProperty): IrElement { private fun visitLocalVariable(variable: FirProperty): IrElement {
assert(variable.isLocal) assert(variable.isLocal)
val initializer = variable.initializer val initializer = variable.initializer
@@ -331,135 +204,20 @@ class Fir2IrVisitor(
variable, conversionScope.parentFromStack(), if (isNextVariable) IrDeclarationOrigin.FOR_LOOP_VARIABLE else null variable, conversionScope.parentFromStack(), if (isNextVariable) IrDeclarationOrigin.FOR_LOOP_VARIABLE else null
) )
if (initializer != null) { if (initializer != null) {
irVariable.initializer = initializer.toIrExpression() irVariable.initializer = convertToIrExpression(initializer)
} }
return irVariable return irVariable
} }
private fun IrProperty.createBackingField(
property: FirProperty,
origin: IrDeclarationOrigin,
descriptor: PropertyDescriptor,
visibility: Visibility,
name: Name,
isFinal: Boolean,
firInitializerExpression: FirExpression?,
type: IrType? = null
): IrField {
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
val irField = symbolTable.declareField(
startOffset, endOffset, origin, descriptor, inferredType
) { symbol ->
IrFieldImpl(
startOffset, endOffset, origin, symbol,
name, inferredType,
visibility, isFinal = isFinal, isExternal = false,
isStatic = property.isStatic || parent !is IrClass,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
)
}
return conversionScope.withParent(applyParentFromStackTo(irField)) {
declarationStorage.enterScope(descriptor)
val initializerExpression = firInitializerExpression?.toIrExpression()
initializer = initializerExpression?.let { IrExpressionBodyImpl(it) }
correspondingPropertySymbol = this@createBackingField.symbol
declarationStorage.leaveScope(descriptor)
}
}
private fun IrProperty.setPropertyContent(descriptor: PropertyDescriptor, property: FirProperty): IrProperty {
val initializer = property.initializer
val delegate = property.delegate
val irParent = this.parent
val propertyType = property.returnTypeRef.toIrType()
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
// TODO (2): backing field should be created inside declaration storage
if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) {
if (initializer != null || property.getter is FirDefaultPropertyGetter ||
property.isVar && property.setter is FirDefaultPropertySetter
) {
backingField = createBackingField(
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
Visibilities.PRIVATE, property.name, property.isVal, initializer, propertyType
)
} else if (delegate != null) {
backingField = createBackingField(
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
Visibilities.PRIVATE, Name.identifier("${property.name}\$delegate"), true, delegate
)
}
}
getter?.setPropertyAccessorContent(
property.getter, this, propertyType, property.getter is FirDefaultPropertyGetter
)
if (property.isVar) {
setter?.setPropertyAccessorContent(
property.setter, this, propertyType, property.setter is FirDefaultPropertySetter
)
}
annotations = property.annotations.mapNotNull {
it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall
}
return this
}
override fun visitProperty(property: FirProperty, data: Any?): IrElement { override fun visitProperty(property: FirProperty, data: Any?): IrElement {
if (property.isLocal) return visitLocalVariable(property) if (property.isLocal) return visitLocalVariable(property)
val irProperty = declarationStorage.getCachedIrProperty(property)!! val irProperty = declarationStorage.getCachedIrProperty(property)!!
return conversionScope.withProperty(irProperty) { return conversionScope.withProperty(irProperty) {
setPropertyContent(irProperty.descriptor, property) memberGenerator.convertPropertyContent(irProperty, property)
}
}
private fun IrFieldAccessExpression.setReceiver(declaration: IrDeclaration): IrFieldAccessExpression {
if (declaration is IrFunction) {
val dispatchReceiver = declaration.dispatchReceiverParameter
if (dispatchReceiver != null) {
receiver = IrGetValueImpl(startOffset, endOffset, dispatchReceiver.symbol)
}
}
return this
}
private fun IrFunction.setPropertyAccessorContent(
propertyAccessor: FirPropertyAccessor?,
correspondingProperty: IrProperty,
propertyType: IrType,
isDefault: Boolean
) {
conversionScope.withFunction(this) {
applyParentFromStackTo(this)
setFunctionContent(descriptor, propertyAccessor)
if (isDefault) {
conversionScope.withParent(this) {
declarationStorage.enterScope(descriptor)
val backingField = correspondingProperty.backingField
val fieldSymbol = symbolTable.referenceField(correspondingProperty.descriptor)
val declaration = this
if (backingField != null) {
body = IrBlockBodyImpl(
startOffset, endOffset,
listOf(
if (isSetter) {
IrSetFieldImpl(startOffset, endOffset, fieldSymbol, typeConverter.unitType).apply {
setReceiver(declaration)
value = IrGetValueImpl(startOffset, endOffset, propertyType, valueParameters.first().symbol)
}
} else {
IrReturnImpl(
startOffset, endOffset, typeConverter.nothingType, symbol,
IrGetFieldImpl(startOffset, endOffset, fieldSymbol, propertyType).setReceiver(declaration)
)
}
)
)
}
declarationStorage.leaveScope(descriptor)
}
}
} }
} }
// ==================================================================================
override fun visitReturnExpression(returnExpression: FirReturnExpression, data: Any?): IrElement { override fun visitReturnExpression(returnExpression: FirReturnExpression, data: Any?): IrElement {
val irTarget = conversionScope.returnTarget(returnExpression) val irTarget = conversionScope.returnTarget(returnExpression)
@@ -472,14 +230,14 @@ class Fir2IrVisitor(
is ClassConstructorDescriptor -> symbolTable.referenceConstructor(descriptor) is ClassConstructorDescriptor -> symbolTable.referenceConstructor(descriptor)
else -> symbolTable.referenceSimpleFunction(descriptor) else -> symbolTable.referenceSimpleFunction(descriptor)
}, },
result.toIrExpression() convertToIrExpression(result)
) )
} }
} }
override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: Any?): IrElement { override fun visitWrappedArgumentExpression(wrappedArgumentExpression: FirWrappedArgumentExpression, data: Any?): IrElement {
// TODO: change this temporary hack to something correct // TODO: change this temporary hack to something correct
return wrappedArgumentExpression.expression.toIrExpression() return convertToIrExpression(wrappedArgumentExpression.expression)
} }
override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: Any?): IrElement { override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: Any?): IrElement {
@@ -487,7 +245,7 @@ class Fir2IrVisitor(
return IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irReturnType, return IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irReturnType,
varargArgumentsExpression.varargElementType.toIrType(), varargArgumentsExpression.varargElementType.toIrType(),
varargArgumentsExpression.arguments.map { arg -> varargArgumentsExpression.arguments.map { arg ->
arg.toIrExpression().run { convertToIrExpression(arg).run {
if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this) if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
else this else this
} }
@@ -571,14 +329,14 @@ class Fir2IrVisitor(
val valueParameters = function?.valueParameters val valueParameters = function?.valueParameters
if (valueParameters != null) { if (valueParameters != null) {
for ((argument, parameter) in argumentMapping) { for ((argument, parameter) in argumentMapping) {
val argumentExpression = argument.toIrExpression() val argumentExpression = convertToIrExpression(argument)
putValueArgument(valueParameters.indexOf(parameter), argumentExpression) putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
} }
return this return this
} }
} }
for ((index, argument) in call.arguments.withIndex()) { for ((index, argument) in call.arguments.withIndex()) {
val argumentExpression = argument.toIrExpression() val argumentExpression = convertToIrExpression(argument)
putValueArgument(index, argumentExpression) putValueArgument(index, argumentExpression)
} }
} }
@@ -589,14 +347,14 @@ class Fir2IrVisitor(
"Cannot bind $argumentsCount arguments to $name call with $valueArgumentsCount parameters" "Cannot bind $argumentsCount arguments to $name call with $valueArgumentsCount parameters"
).apply { ).apply {
for (argument in call.arguments) { for (argument in call.arguments) {
addArgument(argument.toIrExpression()) addArgument(convertToIrExpression(argument))
} }
} }
} }
} }
is IrErrorCallExpressionImpl -> apply { is IrErrorCallExpressionImpl -> apply {
for (argument in call.arguments) { for (argument in call.arguments) {
addArgument(argument.toIrExpression()) addArgument(convertToIrExpression(argument))
} }
} }
else -> this else -> this
@@ -633,8 +391,8 @@ class Fir2IrVisitor(
private fun FirQualifiedAccess.findIrReceiver(isDispatch: Boolean): IrExpression? { private fun FirQualifiedAccess.findIrReceiver(isDispatch: Boolean): IrExpression? {
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
if (firReceiver is FirResolvedQualifier) return firReceiver.toGetObject() if (firReceiver is FirResolvedQualifier) return firReceiver.toGetObject()
return firReceiver.takeIf { it !is FirNoReceiverExpression }?.toIrExpression() return firReceiver.takeIf { it !is FirNoReceiverExpression }?.let { convertToIrExpression(it) }
?: explicitReceiver?.toIrExpression() // NB: this applies to the situation when call is unresolved ?: explicitReceiver?.let { convertToIrExpression(it) } // NB: this applies to the situation when call is unresolved
?: run { ?: run {
// Object case // Object case
val callableReference = calleeReference as? FirResolvedNamedReference val callableReference = calleeReference as? FirResolvedNamedReference
@@ -733,7 +491,7 @@ class Fir2IrVisitor(
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement { override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement {
// Generate the expression with the original type and then cast it to the smart cast type. // Generate the expression with the original type and then cast it to the smart cast type.
val value = expressionWithSmartcast.originalExpression.toIrExpression() val value = convertToIrExpression(expressionWithSmartcast.originalExpression)
val castType = expressionWithSmartcast.typeRef.toIrType() val castType = expressionWithSmartcast.typeRef.toIrType()
if (value.type == castType) return value if (value.type == castType) return value
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
@@ -796,7 +554,7 @@ class Fir2IrVisitor(
is IrFieldSymbol -> IrSetFieldImpl( is IrFieldSymbol -> IrSetFieldImpl(
startOffset, endOffset, symbol, typeConverter.unitType startOffset, endOffset, symbol, typeConverter.unitType
).apply { ).apply {
value = variableAssignment.rValue.toIrExpression() value = convertToIrExpression(variableAssignment.rValue)
} }
is IrPropertySymbol -> { is IrPropertySymbol -> {
val irProperty = symbol.owner val irProperty = symbol.owner
@@ -805,7 +563,7 @@ class Fir2IrVisitor(
IrSetFieldImpl( IrSetFieldImpl(
startOffset, endOffset, backingField.symbol, typeConverter.unitType startOffset, endOffset, backingField.symbol, typeConverter.unitType
).apply { ).apply {
value = variableAssignment.rValue.toIrExpression() value = convertToIrExpression(variableAssignment.rValue)
} }
} else { } else {
generateErrorCallExpression(startOffset, endOffset, calleeReference) generateErrorCallExpression(startOffset, endOffset, calleeReference)
@@ -813,7 +571,7 @@ class Fir2IrVisitor(
} }
is IrVariableSymbol -> { is IrVariableSymbol -> {
IrSetVariableImpl( IrSetVariableImpl(
startOffset, endOffset, irBuiltIns.unitType, symbol, variableAssignment.rValue.toIrExpression(), null startOffset, endOffset, irBuiltIns.unitType, symbol, convertToIrExpression(variableAssignment.rValue), null
) )
} }
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference) else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
@@ -852,21 +610,21 @@ class Fir2IrVisitor(
private fun FirStatement.toIrStatement(): IrStatement? { private fun FirStatement.toIrStatement(): IrStatement? {
if (this is FirTypeAlias) return null if (this is FirTypeAlias) return null
if (this is FirUnitExpression) return toIrExpression() if (this is FirUnitExpression) return convertToIrExpression(this)
if (this is FirBlock) return toIrExpression() if (this is FirBlock) return convertToIrExpression(this)
return accept(this@Fir2IrVisitor, null) as IrStatement return accept(this@Fir2IrVisitor, null) as IrStatement
} }
private fun FirExpression.toIrExpression(): IrExpression { internal fun convertToIrExpression(expression: FirExpression): IrExpression {
return when (this) { return when (expression) {
is FirBlock -> convertToIrExpressionOrBlock() is FirBlock -> expression.convertToIrExpressionOrBlock()
is FirUnitExpression -> convertWithOffsets { startOffset, endOffset -> is FirUnitExpression -> expression.convertWithOffsets { startOffset, endOffset ->
IrGetObjectValueImpl( IrGetObjectValueImpl(
startOffset, endOffset, typeConverter.unitType, startOffset, endOffset, this.typeConverter.unitType,
symbolTable.referenceClass(irBuiltIns.builtIns.unit) this.symbolTable.referenceClass(this.irBuiltIns.builtIns.unit)
) )
} }
else -> accept(this@Fir2IrVisitor, null) as IrExpression else -> expression.accept(this, null) as IrExpression
} }
} }
@@ -893,14 +651,14 @@ class Fir2IrVisitor(
return result return result
} }
private fun FirBlock.convertToIrBlockBody(): IrBlockBody { internal fun convertToIrBlockBody(block: FirBlock): IrBlockBody {
return convertWithOffsets { startOffset, endOffset -> return block.convertWithOffsets { startOffset, endOffset ->
val irStatements = mapToIrStatements() val irStatements = block.mapToIrStatements()
IrBlockBodyImpl( IrBlockBodyImpl(
startOffset, endOffset, startOffset, endOffset,
if (irStatements.isNotEmpty()) { if (irStatements.isNotEmpty()) {
irStatements.filterNotNull().takeIf { it.isNotEmpty() } irStatements.filterNotNull().takeIf { it.isNotEmpty() }
?: listOf(IrBlockImpl(startOffset, endOffset, typeConverter.unitType, null, emptyList())) ?: listOf(IrBlockImpl(startOffset, endOffset, this.typeConverter.unitType, null, emptyList()))
} else { } else {
emptyList() emptyList()
} }
@@ -912,7 +670,7 @@ class Fir2IrVisitor(
if (statements.size == 1) { if (statements.size == 1) {
val firStatement = statements.single() val firStatement = statements.single()
if (firStatement is FirExpression) { if (firStatement is FirExpression) {
return firStatement.toIrExpression() return convertToIrExpression(firStatement)
} }
} }
val type = val type =
@@ -941,7 +699,7 @@ class Fir2IrVisitor(
return when { return when {
subjectVariable != null -> subjectVariable.accept(this, null) as IrVariable subjectVariable != null -> subjectVariable.accept(this, null) as IrVariable
subjectExpression != null -> { subjectExpression != null -> {
applyParentFromStackTo(declarationStorage.declareTemporaryVariable(subjectExpression.toIrExpression(), "subject")) applyParentFromStackTo(declarationStorage.declareTemporaryVariable(convertToIrExpression(subjectExpression), "subject"))
} }
else -> null else -> null
} }
@@ -986,11 +744,11 @@ class Fir2IrVisitor(
override fun visitWhenBranch(whenBranch: FirWhenBranch, data: Any?): IrElement { override fun visitWhenBranch(whenBranch: FirWhenBranch, data: Any?): IrElement {
return whenBranch.convertWithOffsets { startOffset, endOffset -> return whenBranch.convertWithOffsets { startOffset, endOffset ->
val condition = whenBranch.condition val condition = whenBranch.condition
val irResult = whenBranch.result.toIrExpression() val irResult = convertToIrExpression(whenBranch.result)
if (condition is FirElseIfTrueCondition) { if (condition is FirElseIfTrueCondition) {
IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, typeConverter.booleanType, true), irResult) IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, typeConverter.booleanType, true), irResult)
} else { } else {
IrBranchImpl(startOffset, endOffset, condition.toIrExpression(), irResult) IrBranchImpl(startOffset, endOffset, convertToIrExpression(condition), irResult)
} }
} }
} }
@@ -1013,7 +771,7 @@ class Fir2IrVisitor(
loopMap[doWhileLoop] = this loopMap[doWhileLoop] = this
label = doWhileLoop.label?.name label = doWhileLoop.label?.name
body = doWhileLoop.block.convertToIrExpressionOrBlock() body = doWhileLoop.block.convertToIrExpressionOrBlock()
condition = doWhileLoop.condition.toIrExpression() condition = convertToIrExpression(doWhileLoop.condition)
loopMap.remove(doWhileLoop) loopMap.remove(doWhileLoop)
} }
} }
@@ -1026,7 +784,7 @@ class Fir2IrVisitor(
IrWhileLoopImpl(startOffset, endOffset, typeConverter.unitType, origin).apply { IrWhileLoopImpl(startOffset, endOffset, typeConverter.unitType, origin).apply {
loopMap[whileLoop] = this loopMap[whileLoop] = this
label = whileLoop.label?.name label = whileLoop.label?.name
condition = whileLoop.condition.toIrExpression() condition = convertToIrExpression(whileLoop.condition)
body = whileLoop.block.convertToIrExpressionOrBlock(origin) body = whileLoop.block.convertToIrExpressionOrBlock(origin)
loopMap.remove(whileLoop) loopMap.remove(whileLoop)
} }
@@ -1063,7 +821,7 @@ class Fir2IrVisitor(
override fun visitThrowExpression(throwExpression: FirThrowExpression, data: Any?): IrElement { override fun visitThrowExpression(throwExpression: FirThrowExpression, data: Any?): IrElement {
return throwExpression.convertWithOffsets { startOffset, endOffset -> return throwExpression.convertWithOffsets { startOffset, endOffset ->
IrThrowImpl(startOffset, endOffset, typeConverter.nothingType, throwExpression.exception.toIrExpression()) IrThrowImpl(startOffset, endOffset, typeConverter.nothingType, convertToIrExpression(throwExpression.exception))
} }
} }
@@ -1133,7 +891,7 @@ class Fir2IrVisitor(
return primitiveOp2( return primitiveOp2(
startOffset, endOffset, symbol!!, typeConverter.booleanType, origin, startOffset, endOffset, symbol!!, typeConverter.booleanType, origin,
comparisonExpression.left.toIrExpression(), comparisonExpression.right.toIrExpression() convertToIrExpression(comparisonExpression.left), convertToIrExpression(comparisonExpression.right)
) )
} }
@@ -1171,9 +929,12 @@ class Fir2IrVisitor(
} }
} }
val result = if (operation in UNARY_OPERATIONS) { val result = if (operation in UNARY_OPERATIONS) {
primitiveOp1(startOffset, endOffset, symbol, type, origin, arguments[0].toIrExpression()) primitiveOp1(startOffset, endOffset, symbol, type, origin, convertToIrExpression(arguments[0]))
} else { } else {
primitiveOp2(startOffset, endOffset, symbol, type, origin, arguments[0].toIrExpression(), arguments[1].toIrExpression()) primitiveOp2(
startOffset, endOffset, symbol, type, origin,
convertToIrExpression(arguments[0]), convertToIrExpression(arguments[1])
)
} }
if (operation !in NEGATED_OPERATIONS) return result if (operation !in NEGATED_OPERATIONS) return result
return primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, typeConverter.booleanType, origin, result) return primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, typeConverter.booleanType, origin, result)
@@ -1189,7 +950,7 @@ class Fir2IrVisitor(
return stringConcatenationCall.convertWithOffsets { startOffset, endOffset -> return stringConcatenationCall.convertWithOffsets { startOffset, endOffset ->
IrStringConcatenationImpl( IrStringConcatenationImpl(
startOffset, endOffset, typeConverter.stringType, startOffset, endOffset, typeConverter.stringType,
stringConcatenationCall.arguments.map { it.toIrExpression() } stringConcatenationCall.arguments.map { convertToIrExpression(it) }
) )
} }
} }
@@ -1207,7 +968,7 @@ class Fir2IrVisitor(
IrTypeOperatorCallImpl( IrTypeOperatorCallImpl(
startOffset, endOffset, irType, irTypeOperator, irTypeOperand, startOffset, endOffset, irType, irTypeOperator, irTypeOperand,
typeOperatorCall.argument.toIrExpression() convertToIrExpression(typeOperatorCall.argument)
) )
} }
} }
@@ -1221,7 +982,7 @@ class Fir2IrVisitor(
IrStatementOrigin.EXCLEXCL IrStatementOrigin.EXCLEXCL
).apply { ).apply {
putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType().makeNotNull()) putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType().makeNotNull())
putValueArgument(0, checkNotNullCall.argument.toIrExpression()) putValueArgument(0, convertToIrExpression(checkNotNullCall.argument))
} }
} }
} }
@@ -1249,7 +1010,7 @@ class Fir2IrVisitor(
if (irClassReferenceSymbol != null) { if (irClassReferenceSymbol != null) {
IrClassReferenceImpl(startOffset, endOffset, irType, irClassReferenceSymbol, irClassType) IrClassReferenceImpl(startOffset, endOffset, irType, irClassReferenceSymbol, irClassType)
} else { } else {
IrGetClassImpl(startOffset, endOffset, irType, argument.toIrExpression()) IrGetClassImpl(startOffset, endOffset, irType, convertToIrExpression(argument))
} }
} }
} }
@@ -0,0 +1,289 @@
/*
* 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.backend.generators
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
internal class ClassMemberGenerator(
private val components: Fir2IrComponents,
private val visitor: Fir2IrVisitor,
private val conversionScope: Fir2IrConversionScope,
fakeOverrideMode: FakeOverrideMode
) : Fir2IrComponents by components {
private val fakeOverrideGenerator = FakeOverrideGenerator(session, declarationStorage, conversionScope, fakeOverrideMode)
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
private fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T = conversionScope.applyParentFromStackTo(declaration)
fun convertClassContent(irClass: IrClass, klass: FirClass<*>) {
declarationStorage.enterScope(irClass.descriptor)
conversionScope.withClass(irClass) {
val primaryConstructor = klass.getPrimaryConstructorIfAny()
val irPrimaryConstructor = primaryConstructor?.let { declarationStorage.getCachedIrConstructor(it)!! }
if (irPrimaryConstructor != null) {
with(declarationStorage) {
enterScope(irPrimaryConstructor.descriptor)
irPrimaryConstructor.valueParameters.forEach { symbolTable.introduceValueParameter(it) }
irPrimaryConstructor.putParametersInScope(primaryConstructor)
convertFunctionContent(irPrimaryConstructor, primaryConstructor)
}
}
val processedCallableNames = mutableListOf<Name>()
klass.declarations.forEach {
if (it !is FirTypeAlias && (it !is FirConstructor || !it.isPrimary)) {
it.accept(visitor, null)
when (it) {
is FirSimpleFunction -> processedCallableNames += it.name
is FirProperty -> processedCallableNames += it.name
}
}
}
with(fakeOverrideGenerator) { irClass.addFakeOverrides(klass, processedCallableNames) }
annotations = klass.annotations.mapNotNull {
it.accept(visitor, null) as? IrConstructorCall
}
if (irPrimaryConstructor != null) {
declarationStorage.leaveScope(irPrimaryConstructor.descriptor)
}
}
declarationStorage.leaveScope(irClass.descriptor)
}
fun <T : IrFunction> convertFunctionContent(irFunction: T, firFunction: FirFunction<*>?): T {
val descriptor = irFunction.descriptor
conversionScope.withParent(irFunction) {
if (firFunction != null) {
if (irFunction !is IrConstructor || !irFunction.isPrimary) {
// Scope for primary constructor should be entered before class declaration processing
with(declarationStorage) {
enterScope(descriptor)
irFunction.valueParameters.forEach { symbolTable.introduceValueParameter(it) }
irFunction.putParametersInScope(firFunction)
}
}
for ((valueParameter, firValueParameter) in valueParameters.zip(firFunction.valueParameters)) {
valueParameter.setDefaultValue(firValueParameter)
}
}
var body = firFunction?.body?.let { visitor.convertToIrBlockBody(it) }
if (firFunction is FirConstructor && irFunction is IrConstructor && !parentAsClass.isAnnotationClass) {
if (body == null) {
body = IrBlockBodyImpl(startOffset, endOffset)
}
val delegatedConstructor = firFunction.delegatedConstructor
if (delegatedConstructor != null) {
val irDelegatingConstructorCall = delegatedConstructor.toIrDelegatingConstructorCall()
body.statements += irDelegatingConstructorCall ?: delegatedConstructor.convertWithOffsets { startOffset, endOffset ->
IrErrorCallExpressionImpl(
startOffset, endOffset, returnType, "Cannot find delegated constructor call"
)
}
}
if (delegatedConstructor?.isThis == false) {
val irClass = parent as IrClass
body.statements += IrInstanceInitializerCallImpl(
startOffset, endOffset, irClass.symbol, irFunction.constructedClassType
)
}
if (body.statements.isNotEmpty()) {
irFunction.body = body
}
} else if (irFunction !is IrConstructor) {
irFunction.body = body
}
if (irFunction !is IrConstructor || !irFunction.isPrimary) {
// Scope for primary constructor should be left after class declaration
declarationStorage.leaveScope(descriptor)
}
}
return irFunction
}
fun convertPropertyContent(irProperty: IrProperty, property: FirProperty): IrProperty {
val descriptor = irProperty.descriptor
val initializer = property.initializer
val delegate = property.delegate
val irParent = irProperty.parent
val propertyType = property.returnTypeRef.toIrType()
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
// TODO (2): backing field should be created inside declaration storage
if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) {
if (initializer != null || property.getter is FirDefaultPropertyGetter ||
property.isVar && property.setter is FirDefaultPropertySetter
) {
irProperty.backingField = irProperty.createBackingField(
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
Visibilities.PRIVATE, property.name, property.isVal, initializer, propertyType
)
} else if (delegate != null) {
irProperty.backingField = irProperty.createBackingField(
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
Visibilities.PRIVATE, Name.identifier("${property.name}\$delegate"), true, delegate
)
}
}
irProperty.getter?.setPropertyAccessorContent(
property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter
)
if (property.isVar) {
irProperty.setter?.setPropertyAccessorContent(
property.setter, irProperty, propertyType, property.setter is FirDefaultPropertySetter
)
}
irProperty.annotations = property.annotations.mapNotNull {
it.accept(visitor, null) as? IrConstructorCall
}
return irProperty
}
private fun IrProperty.createBackingField(
property: FirProperty,
origin: IrDeclarationOrigin,
descriptor: PropertyDescriptor,
visibility: Visibility,
name: Name,
isFinal: Boolean,
firInitializerExpression: FirExpression?,
type: IrType? = null
): IrField {
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
val irField = symbolTable.declareField(
startOffset, endOffset, origin, descriptor, inferredType
) { symbol ->
IrFieldImpl(
startOffset, endOffset, origin, symbol,
name, inferredType,
visibility, isFinal = isFinal, isExternal = false,
isStatic = property.isStatic || parent !is IrClass,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
)
}
return conversionScope.withParent(applyParentFromStackTo(irField)) {
declarationStorage.enterScope(descriptor)
if (firInitializerExpression != null) {
val initializerExpression = visitor.convertToIrExpression(firInitializerExpression)
initializer = IrExpressionBodyImpl(initializerExpression)
}
correspondingPropertySymbol = this@createBackingField.symbol
declarationStorage.leaveScope(descriptor)
}
}
private fun IrFunction.setPropertyAccessorContent(
propertyAccessor: FirPropertyAccessor?,
correspondingProperty: IrProperty,
propertyType: IrType,
isDefault: Boolean
) {
conversionScope.withFunction(this) {
applyParentFromStackTo(this)
convertFunctionContent(this, propertyAccessor)
if (isDefault) {
conversionScope.withParent(this) {
declarationStorage.enterScope(descriptor)
val backingField = correspondingProperty.backingField
val fieldSymbol = symbolTable.referenceField(correspondingProperty.descriptor)
val declaration = this
if (backingField != null) {
body = IrBlockBodyImpl(
startOffset, endOffset,
listOf(
if (isSetter) {
IrSetFieldImpl(startOffset, endOffset, fieldSymbol, typeConverter.unitType).apply {
setReceiver(declaration)
value = IrGetValueImpl(startOffset, endOffset, propertyType, valueParameters.first().symbol)
}
} else {
IrReturnImpl(
startOffset, endOffset, typeConverter.nothingType, symbol,
IrGetFieldImpl(startOffset, endOffset, fieldSymbol, propertyType).setReceiver(declaration)
)
}
)
)
}
declarationStorage.leaveScope(descriptor)
}
}
}
}
private fun IrFieldAccessExpression.setReceiver(declaration: IrDeclaration): IrFieldAccessExpression {
if (declaration is IrFunction) {
val dispatchReceiver = declaration.dispatchReceiverParameter
if (dispatchReceiver != null) {
receiver = IrGetValueImpl(startOffset, endOffset, dispatchReceiver.symbol)
}
}
return this
}
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrCallWithIndexedArgumentsBase? {
val constructedIrType = constructedTypeRef.toIrType()
val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
?: return null
return convertWithOffsets { startOffset, endOffset ->
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
if (constructorSymbol.fir.isFromEnumClass || constructorSymbol.fir.returnTypeRef.isEnum) {
IrEnumConstructorCallImpl(
startOffset, endOffset,
constructedIrType,
irConstructorSymbol
).apply {
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
if (typeArguments?.isNotEmpty() == true) {
val irType = (typeArguments.first() as ConeKotlinTypeProjection).type.toIrType()
putTypeArgument(0, irType)
}
}
} else {
IrDelegatingConstructorCallImpl(
startOffset, endOffset,
constructedIrType,
irConstructorSymbol
)
}.apply {
for ((index, argument) in arguments.withIndex()) {
val argumentExpression = visitor.convertToIrExpression(argument)
putValueArgument(index, argumentExpression)
}
}
}
}
private fun IrValueParameter.setDefaultValue(firValueParameter: FirValueParameter) {
val firDefaultValue = firValueParameter.defaultValue
if (firDefaultValue != null) {
this.defaultValue = IrExpressionBodyImpl(visitor.convertToIrExpression(firDefaultValue))
}
}
}