@@ -164,7 +164,7 @@ let printSignature ~extractor ~signature =
164
164
165
165
let buf = Buffer. create 10 in
166
166
167
- let getComponentType (typ : Types.type_expr ) =
167
+ let getComponentTypeV3 (typ : Types.type_expr ) =
168
168
let reactElement =
169
169
Ctype. newconstr (Pdot (Pident (Ident. create " React" ), " element" , 0 )) []
170
170
in
@@ -183,6 +183,29 @@ let printSignature ~extractor ~signature =
183
183
| _ -> None
184
184
in
185
185
186
+ let getComponentTypeV4 (typ : Types.type_expr ) =
187
+ let reactElement =
188
+ Ctype. newconstr (Pdot (Pident (Ident. create " React" ), " element" , 0 )) []
189
+ in
190
+ match typ.desc with
191
+ | Tarrow (_, {desc = Tconstr (Path. Pident propsId, typeArgs, _)}, retType, _)
192
+ when Ident. name propsId = " props" ->
193
+ Some (typeArgs, retType)
194
+ | Tconstr
195
+ ( Pdot (Pident {name = " React" }, " component" , _),
196
+ [{desc = Tconstr (Path. Pident propsId, typeArgs, _)}],
197
+ _ )
198
+ when Ident. name propsId = " props" ->
199
+ Some (typeArgs, reactElement)
200
+ | Tconstr
201
+ ( Pdot (Pident {name = " React" }, " componentLike" , _),
202
+ [{desc = Tconstr (Path. Pident propsId, typeArgs, _)}; retType],
203
+ _ )
204
+ when Ident. name propsId = " props" ->
205
+ Some (typeArgs, retType)
206
+ | _ -> None
207
+ in
208
+
186
209
let rec processSignature ~indent (signature : Types.signature ) : unit =
187
210
match signature with
188
211
| Sig_value
@@ -193,14 +216,14 @@ let printSignature ~extractor ~signature =
193
216
when Ident. name makePropsId = Ident. name makeId ^ " Props"
194
217
&& ((* from implementation *) makePropsLoc.loc_ghost
195
218
|| (* from interface *) makePropsLoc = makeValueDesc.val_loc)
196
- && getComponentType makeValueDesc.val_type <> None ->
219
+ && getComponentTypeV3 makeValueDesc.val_type <> None ->
197
220
(*
198
221
{"name": string} => retType ~~> (~name:string) => retType
199
222
React.component<{"name": string}> ~~> (~name:string) => React.element
200
223
React.componentLike<{"name": string}, retType> ~~> (~name:string) => retType
201
224
*)
202
225
let tObj, retType =
203
- match getComponentType makeValueDesc.val_type with
226
+ match getComponentTypeV3 makeValueDesc.val_type with
204
227
| None -> assert false
205
228
| Some (tObj , retType ) -> (tObj, retType)
206
229
in
@@ -213,6 +236,60 @@ let printSignature ~extractor ~signature =
213
236
Buffer. add_string buf (indent ^ " @react.component\n " );
214
237
Buffer. add_string buf (indent ^ newItemStr ^ " \n " );
215
238
processSignature ~indent rest
239
+ | Sig_type
240
+ ( propsId,
241
+ {
242
+ type_params;
243
+ type_kind = Type_record (labelDecls, Record_optional_labels optLbls);
244
+ },
245
+ _ )
246
+ :: Sig_value (makeId (* make *) , makeValueDesc)
247
+ :: rest
248
+ when Ident. name propsId = " props"
249
+ && getComponentTypeV4 makeValueDesc.val_type <> None
250
+ && optLbls |> List. mem " key" ->
251
+ (* PPX V4 component declaration:
252
+ type props = {..., key?: _}
253
+ let v = ...
254
+ *)
255
+ let newItemStr =
256
+ let typeArgs, retType =
257
+ match getComponentTypeV4 makeValueDesc.val_type with
258
+ | Some x -> x
259
+ | None -> assert false
260
+ in
261
+ let rec mkFunType (labelDecls : Types.label_declaration list ) =
262
+ match labelDecls with
263
+ | [] -> retType
264
+ | labelDecl :: rest ->
265
+ let propType =
266
+ CompletionBackEnd. instantiateType ~type Params:type_params
267
+ ~type Args labelDecl.ld_type
268
+ in
269
+ let lblName = labelDecl.ld_id |> Ident. name in
270
+ let lbl =
271
+ if List. mem lblName optLbls then Asttypes. Optional lblName
272
+ else Labelled lblName
273
+ in
274
+ if lblName = " key" then mkFunType rest
275
+ else
276
+ {retType with desc = Tarrow (lbl, propType, mkFunType rest, Cok )}
277
+ in
278
+ let funType =
279
+ if List. length labelDecls = 1 (* No props: only "key "*) then
280
+ let tUnit =
281
+ Ctype. newconstr (Path. Pident (Ident. create " unit" )) []
282
+ in
283
+ {retType with desc = Tarrow (Nolabel , tUnit, retType, Cok )}
284
+ else mkFunType labelDecls
285
+ in
286
+ sigItemToString
287
+ (Printtyp. tree_of_value_description makeId
288
+ {makeValueDesc with val_type = funType})
289
+ in
290
+ Buffer. add_string buf (indent ^ " @react.component\n " );
291
+ Buffer. add_string buf (indent ^ newItemStr ^ " \n " );
292
+ processSignature ~indent rest
216
293
| Sig_module (id , modDecl , recStatus ) :: rest ->
217
294
let colonOrEquals =
218
295
match modDecl.md_type with
0 commit comments