From c2c85365e6f616ae8edbf75b3e4a206d51bd8a56 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 16 Apr 2020 09:50:07 +0300 Subject: [PATCH] Use FIR metadata in FIR2IR data class member generator (KT-38156) --- .../generators/ClassMemberGenerator.kt | 5 +- .../generators/DataClassMembersGenerator.kt | 72 +++++++++++++++---- .../jvm/codegen/FirBasedClassCodegen.kt | 4 +- ...GetterAndGetFunctionDifferentReturnType.kt | 1 - .../box/reflection/modifiers/classes.kt | 1 - .../reflection/properties/genericProperty.kt | 1 - 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index de53fbfe748..2d34c498647 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -126,11 +126,12 @@ internal class ClassMemberGenerator( irFunction.body = IrSyntheticBodyImpl(startOffset, endOffset, kind) } irFunction.parent is IrClass && irFunction.parentAsClass.isData -> { + val classId = firFunction?.symbol?.callableId?.classId when { DataClassMembersGenerator.isComponentN(irFunction) -> - DataClassMembersGenerator(components).generateDataClassComponentBody(irFunction) + DataClassMembersGenerator(components).generateDataClassComponentBody(irFunction, classId!!) DataClassMembersGenerator.isCopy(irFunction) -> - DataClassMembersGenerator(components).generateDataClassCopyBody(irFunction) + DataClassMembersGenerator(components).generateDataClassCopyBody(irFunction, classId!!) else -> irFunction.body = firFunction?.body?.let { visitor.convertToIrBlockBody(it) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt index 176626fb7ad..e755641f1f4 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt @@ -7,12 +7,24 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.fir.backend.Fir2IrComponents +import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction +import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitStringTypeRef import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase @@ -25,6 +37,8 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name class DataClassMembersGenerator(val components: Fir2IrComponents) { @@ -32,17 +46,17 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) { // TODO: generateInlineClassMembers fun generateDataClassMembers(klass: FirClass<*>, irClass: IrClass): List = - MyDataClassMethodsGenerator(irClass, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER).generate(klass) + MyDataClassMethodsGenerator(irClass, klass.symbol.classId, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER).generate(klass) - fun generateDataClassComponentBody(irFunction: IrFunction) = - MyDataClassMethodsGenerator(irFunction.parentAsClass, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER) + fun generateDataClassComponentBody(irFunction: IrFunction, classId: ClassId) = + MyDataClassMethodsGenerator(irFunction.parentAsClass, classId, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER) .generateComponentBody(irFunction) - fun generateDataClassCopyBody(irFunction: IrFunction) = - MyDataClassMethodsGenerator(irFunction.parentAsClass, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER) + fun generateDataClassCopyBody(irFunction: IrFunction, classId: ClassId) = + MyDataClassMethodsGenerator(irFunction.parentAsClass, classId, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER) .generateCopyBody(irFunction) - private inner class MyDataClassMethodsGenerator(val irClass: IrClass, val origin: IrDeclarationOrigin) { + private inner class MyDataClassMethodsGenerator(val irClass: IrClass, val classId: ClassId, val origin: IrDeclarationOrigin) { private val irDataClassMembersGenerator = object : DataClassMembersGenerator( IrGeneratorContextBase(components.irBuiltIns), components.symbolTable, @@ -137,11 +151,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) { val equalsFunction = createSyntheticIrFunction( equalsName, components.irBuiltIns.booleanType, - ).apply { - valueParameters = listOf( - createSyntheticIrParameter(this, Name.identifier("other"), components.irBuiltIns.anyNType) - ) - } + ) { createSyntheticIrParameter(it, Name.identifier("other"), components.irBuiltIns.anyNType) } irDataClassMembersGenerator.generateEqualsMethod(equalsFunction, properties) irClass.declarations.add(equalsFunction) } @@ -184,7 +194,11 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) { fun generateCopyBody(irFunction: IrFunction) = irDataClassMembersGenerator.generateCopyFunction(irFunction, irClass.primaryConstructor!!.symbol) - private fun createSyntheticIrFunction(name: Name, returnType: IrType): IrFunction { + private fun createSyntheticIrFunction( + name: Name, + returnType: IrType, + valueParameterBuilder: (IrFunction) -> IrValueParameter? = { null } + ): IrFunction { val functionDescriptor = WrappedSimpleFunctionDescriptor() val thisReceiverDescriptor = WrappedValueParameterDescriptor() return components.symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, functionDescriptor) { symbol -> @@ -205,7 +219,39 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) { isFakeOverride = false, isOperator = false ).apply { - metadata = MetadataSource.Function(functionDescriptor) + val irValueParameter = valueParameterBuilder(this)?.let { + this.valueParameters = listOf(it) + it + } + metadata = FirMetadataSource.Function( + buildSimpleFunction { + this.name = name + this.symbol = FirNamedFunctionSymbol(CallableId(classId.packageFqName, classId.relativeClassName, name)) + this.status = FirDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL) + this.session = components.session + this.returnTypeRef = when (returnType) { + components.irBuiltIns.booleanType -> FirImplicitBooleanTypeRef(null) + components.irBuiltIns.intType -> FirImplicitIntTypeRef(null) + components.irBuiltIns.stringType -> FirImplicitStringTypeRef(null) + else -> throw AssertionError("Should not be here") + } + if (irValueParameter != null) { + this.valueParameters.add( + buildValueParameter { + this.name = irValueParameter.name + this.session = components.session + this.returnTypeRef = FirImplicitNullableAnyTypeRef(null) + this.symbol = FirVariableSymbol(irValueParameter.name) + isCrossinline = false + isNoinline = false + isVararg = false + } + ) + } + }, + descriptor + ) + } }.apply { parent = irClass diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FirBasedClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FirBasedClassCodegen.kt index fcf713b508d..ef7db0d003e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FirBasedClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FirBasedClassCodegen.kt @@ -132,7 +132,9 @@ class FirBasedClassCodegen internal constructor( } null -> { } - else -> error("Incorrect metadata source $metadata for:\n${method.dump()}") + else -> { + error("Incorrect metadata source $metadata for:\n${method.dump()}") + } } } diff --git a/compiler/testData/codegen/box/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt b/compiler/testData/codegen/box/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt index 30dd67019ba..4a59a148652 100644 --- a/compiler/testData/codegen/box/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt +++ b/compiler/testData/codegen/box/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/reflection/modifiers/classes.kt b/compiler/testData/codegen/box/reflection/modifiers/classes.kt index 9b02f8e5983..31e798ed5b1 100644 --- a/compiler/testData/codegen/box/reflection/modifiers/classes.kt +++ b/compiler/testData/codegen/box/reflection/modifiers/classes.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/reflection/properties/genericProperty.kt b/compiler/testData/codegen/box/reflection/properties/genericProperty.kt index 8ba6bd6e9a8..a376406c87f 100644 --- a/compiler/testData/codegen/box/reflection/properties/genericProperty.kt +++ b/compiler/testData/codegen/box/reflection/properties/genericProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE