@@ -20,6 +20,7 @@ import java.io.File
2020import org.jetbrains.kotlin.backend.common.FileLoweringPass
2121import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
2222import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
23+ import org.jetbrains.kotlin.backend.common.ir.remapTypeParameters
2324import org.jetbrains.kotlin.backend.common.ir.setDeclarationsParent
2425import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
2526import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
@@ -56,6 +57,7 @@ import org.jetbrains.kotlin.ir.types.IrType
5657import org.jetbrains.kotlin.ir.types.IrTypeArgument
5758import org.jetbrains.kotlin.ir.types.createType
5859import org.jetbrains.kotlin.ir.util.defaultType
60+ import org.jetbrains.kotlin.ir.util.remapTypes
5961import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
6062import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
6163import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -125,6 +127,11 @@ class ReactFunctionCallTransformer(
125127 result = false
126128 }
127129
130+ if (declaration.isInline) {
131+ messageCollector.report(CompilerMessageSeverity .ERROR , " RFunction annotated function cannot be inline" , location)
132+ result = false
133+ }
134+
128135 if (declaration.extensionReceiverParameter?.type != classes.react.RBuilder ) {
129136 messageCollector.report(CompilerMessageSeverity .ERROR , " RFunction annotated function must be an extension function of react.RBuilder" , location)
130137 result = false
@@ -148,35 +155,40 @@ class ReactFunctionCallTransformer(
148155 val body = (declaration.body as ? IrBlockBody ) ? : return
149156 val parent = declaration.parent as IrDeclarationContainer
150157
151- val props = context.buildPropsInterface(declaration)
152- props .parent = parent
153- newDeclarations.add(props )
158+ val propsClass = context.buildPropsInterface(declaration)
159+ propsClass .parent = parent
160+ newDeclarations.add(propsClass )
154161
155- val component = buildRFunctionProperty(parent, declaration, props, body)
162+ val component = buildRFunctionProperty(parent, declaration, propsClass, body).apply {
163+ val substitutionMap = (propsClass.typeParameters + declaration.typeParameters).associate { it.symbol to context.irBuiltIns.anyNType }
164+ if (substitutionMap.isNotEmpty()) remapTypes(TypeSubstituteRemapper (substitutionMap))
165+ }
156166 newDeclarations.add(component)
157167
158- declaration.body = buildNewBody(props, component, declaration)
168+ val propsType = propsClass.symbol.createType(false , propsClass.typeParameters.map { context.irBuiltIns.anyNType as IrTypeArgument })
169+ declaration.body = buildNewBody(propsClass, propsType, component, declaration)
159170 }
160171
161172 private fun IrGeneratorContext.buildPropsInterface (declaration : IrSimpleFunction ): IrClass {
162173 val irClass = buildExternalInterface(
163174 name = " ${declaration.name} FuncProps" ,
164175 visibility = DescriptorVisibilities .PRIVATE ,
165- superTypes = listOf (classes.react.RProps )
176+ superTypes = listOf (classes.react.RProps ),
177+ typeParameters = declaration.typeParameters
166178 )
167179 for (valueParameter in declaration.valueParameters) {
168180 addExternalVarProperty(
169181 container = irClass,
170182 name = valueParameter.name,
171- type = valueParameter.type
183+ type = valueParameter.type.remapTypeParameters(declaration, irClass)
172184 )
173185 }
174186 return irClass
175187 }
176188
177189 private fun buildRFunctionProperty (parent : IrDeclarationParent , declaration : IrSimpleFunction , propsClass : IrClass , body : IrBlockBody ): IrProperty {
178190 val fieldType = classes.react.RClass (propsClass.defaultType)
179- val name = " ${declaration.name} _RFUNC" .toUpperCase ()
191+ val name = " ${declaration.name} _RFUNC" .uppercase ()
180192
181193 return context.buildStaticProperty(parent, fieldType, name) {
182194 irExprBody(irCall_rFunction(propsClass.defaultType, " ${declaration.name} " ) { function ->
@@ -247,11 +259,11 @@ class ReactFunctionCallTransformer(
247259 }
248260 }
249261
250- private fun buildNewBody (propsClass : IrClass , componentProperty : IrProperty , declaration : IrSimpleFunction ): IrBody {
262+ private fun buildNewBody (propsClass : IrClass , propsType : IrType , componentProperty : IrProperty , declaration : IrSimpleFunction ): IrBody {
251263 return context.irBuilder(declaration.symbol).run {
252264 irBlockBody {
253265 + irCall_invoke(
254- propsClass.defaultType ,
266+ propsType ,
255267 irGet(declaration.extensionReceiverParameter!! ),
256268 irCall(componentProperty.getter!! , origin = IrStatementOrigin .GET_PROPERTY )
257269 ) { function ->
@@ -263,7 +275,7 @@ class ReactFunctionCallTransformer(
263275
264276 + irCall(property.setter!! , origin = IrStatementOrigin .EQ ).apply {
265277 val callee = functions.react.RElementBuilder .attrs.owner.getter!!
266- this .dispatchReceiver = IrCallImpl (startOffset, endOffset, propsClass.defaultType , callee.symbol, callee.typeParameters.size, callee.valueParameters.size, IrStatementOrigin .GET_PROPERTY ).apply {
278+ this .dispatchReceiver = IrCallImpl (startOffset, endOffset, propsType , callee.symbol, callee.typeParameters.size, callee.valueParameters.size, IrStatementOrigin .GET_PROPERTY ).apply {
267279 this .dispatchReceiver = irGet(rElementBuilder)
268280 }
269281 this .putValueArgument(0 , irGet(valueParameter))
0 commit comments