@@ -388,15 +388,19 @@ let transformUppercaseCall3 jsxRuntime modulePath mapper loc attrs
388
388
let jsxExpr, key =
389
389
match (! childrenArg, keyProp) with
390
390
| None , (_ , keyExpr ) :: _ ->
391
- ( Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " jsxKeyed" )},
391
+ ( Exp. ident ~loc
392
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxKeyed" )},
392
393
[(nolabel, keyExpr)] )
393
394
| None , [] ->
394
- (Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " jsx" )}, [] )
395
+ ( Exp. ident ~loc {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsx" )},
396
+ [] )
395
397
| Some _ , (_ , keyExpr ) :: _ ->
396
- ( Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " jsxsKeyed" )},
398
+ ( Exp. ident ~loc
399
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxsKeyed" )},
397
400
[(nolabel, keyExpr)] )
398
401
| Some _ , [] ->
399
- (Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " jsxs" )}, [] )
402
+ ( Exp. ident ~loc {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxs" )},
403
+ [] )
400
404
in
401
405
Exp. apply ~loc ~attrs jsxExpr
402
406
([(nolabel, Exp. ident ~loc {txt = ident; loc}); (nolabel, props)] @ key)
@@ -425,61 +429,119 @@ let transformUppercaseCall3 jsxRuntime modulePath mapper loc attrs
425
429
])
426
430
[@@ raises Invalid_argument ]
427
431
428
- let transformLowercaseCall3 _jsxRuntime mapper loc attrs _callExpression
432
+ let transformLowercaseCall3 jsxRuntime mapper loc attrs callExpression
429
433
callArguments id =
430
- let children, nonChildrenProps = extractChildren ~loc callArguments in
431
- (* keep the v3 *)
432
- (* let record = recordFromProps callExpression nonChildrenProps in *)
433
434
let componentNameExpr = constantString ~loc id in
434
- let childrenExpr = transformChildrenIfList ~loc ~mapper children in
435
- let createElementCall =
436
- match children with
437
- (* [@JSX] div(~children=[a]), coming from <div> a </div> *)
438
- | {
439
- pexp_desc =
440
- ( Pexp_construct ({txt = Lident " ::" }, Some {pexp_desc = Pexp_tuple _})
441
- | Pexp_construct ({txt = Lident " []" }, None ) );
442
- } ->
443
- " createDOMElementVariadic"
444
- (* [@JSX] div(~children= value), coming from <div> ...(value) </div> *)
445
- | _ ->
446
- raise
447
- (Invalid_argument
448
- " A spread as a DOM element's children don't make sense written \
449
- together. You can simply remove the spread." )
450
- in
451
- let args =
452
- match nonChildrenProps with
453
- | [_justTheUnitArgumentAtEnd] ->
454
- [
455
- (* "div" *)
456
- (nolabel, componentNameExpr);
457
- (* [|moreCreateElementCallsHere|] *)
458
- (nolabel, childrenExpr);
459
- ]
460
- | nonEmptyProps ->
461
- let propsCall =
462
- Exp. apply ~loc
463
- (Exp. ident ~loc {loc; txt = Ldot (Lident " ReactDOMRe" , " domProps" )})
464
- (nonEmptyProps
465
- |> List. map (fun (label , expression ) ->
466
- (label, mapper.expr mapper expression)))
467
- in
468
- [
469
- (* "div" *)
470
- (nolabel, componentNameExpr);
471
- (* ReactDOMRe.domProps(~className=blabla, ~foo=bar, ()) *)
472
- (labelled " props" , propsCall);
473
- (* [|moreCreateElementCallsHere|] *)
474
- (nolabel, childrenExpr);
475
- ]
476
- in
477
- Exp. apply
478
- ~loc (* throw away the [@JSX] attribute and keep the others, if any *)
479
- ~attrs
480
- (* ReactDOMRe.createElement *)
481
- (Exp. ident ~loc {loc; txt = Ldot (Lident " ReactDOMRe" , createElementCall)})
482
- args
435
+ match jsxRuntime with
436
+ (* the new jsx transform *)
437
+ | "automatic" ->
438
+ let children, nonChildrenProps =
439
+ extractChildren ~remove LastPositionUnit:true ~loc callArguments
440
+ in
441
+ let argsForMake = nonChildrenProps in
442
+ let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in
443
+ let recursivelyTransformedArgsForMake =
444
+ argsForMake
445
+ |> List. map (fun (label , expression ) ->
446
+ (label, mapper.expr mapper expression))
447
+ in
448
+ let childrenArg = ref None in
449
+ let args =
450
+ recursivelyTransformedArgsForMake
451
+ @
452
+ match childrenExpr with
453
+ | Exact children -> [(labelled " children" , children)]
454
+ | ListLiteral {pexp_desc = Pexp_array list } when list = [] -> []
455
+ | ListLiteral expression ->
456
+ (* this is a hack to support react components that introspect into their children *)
457
+ childrenArg := Some expression;
458
+ [(labelled " children" , expression)]
459
+ in
460
+ let isEmptyRecord {pexp_desc} =
461
+ match pexp_desc with
462
+ | Pexp_record (labelDecls , _ ) when List. length labelDecls = 0 -> true
463
+ | _ -> false
464
+ in
465
+ let record = recordFromProps ~remove Key:true callExpression args in
466
+ let props =
467
+ if isEmptyRecord record then recordWithOnlyKey ~loc else record
468
+ in
469
+ let keyProp =
470
+ args |> List. filter (fun (arg_label , _ ) -> " key" = getLabel arg_label)
471
+ in
472
+ let jsxExpr, key =
473
+ match (! childrenArg, keyProp) with
474
+ | None , (_ , keyExpr ) :: _ ->
475
+ ( Exp. ident ~loc
476
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxKeyedDom" )},
477
+ [(nolabel, keyExpr)] )
478
+ | None , [] ->
479
+ ( Exp. ident ~loc
480
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxDom" )},
481
+ [] )
482
+ | Some _ , (_ , keyExpr ) :: _ ->
483
+ ( Exp. ident ~loc
484
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxsKeyedDom" )},
485
+ [(nolabel, keyExpr)] )
486
+ | Some _ , [] ->
487
+ ( Exp. ident ~loc
488
+ {loc; txt = Ldot (Ldot (Lident " Js" , " React" ), " jsxsDom" )},
489
+ [] )
490
+ in
491
+ Exp. apply ~loc ~attrs jsxExpr
492
+ ([(nolabel, componentNameExpr); (nolabel, props)] @ key)
493
+ | _ ->
494
+ let children, nonChildrenProps = extractChildren ~loc callArguments in
495
+ let childrenExpr = transformChildrenIfList ~loc ~mapper children in
496
+ let createElementCall =
497
+ match children with
498
+ (* [@JSX] div(~children=[a]), coming from <div> a </div> *)
499
+ | {
500
+ pexp_desc =
501
+ ( Pexp_construct ({txt = Lident " ::" }, Some {pexp_desc = Pexp_tuple _})
502
+ | Pexp_construct ({txt = Lident " []" }, None ) );
503
+ } ->
504
+ " createDOMElementVariadic"
505
+ (* [@JSX] div(~children= value), coming from <div> ...(value) </div> *)
506
+ | _ ->
507
+ raise
508
+ (Invalid_argument
509
+ " A spread as a DOM element's children don't make sense written \
510
+ together. You can simply remove the spread." )
511
+ in
512
+ let args =
513
+ match nonChildrenProps with
514
+ | [_justTheUnitArgumentAtEnd] ->
515
+ [
516
+ (* "div" *)
517
+ (nolabel, componentNameExpr);
518
+ (* [|moreCreateElementCallsHere|] *)
519
+ (nolabel, childrenExpr);
520
+ ]
521
+ | nonEmptyProps ->
522
+ let propsCall =
523
+ Exp. apply ~loc
524
+ (Exp. ident ~loc {loc; txt = Ldot (Lident " ReactDOMRe" , " domProps" )})
525
+ (nonEmptyProps
526
+ |> List. map (fun (label , expression ) ->
527
+ (label, mapper.expr mapper expression)))
528
+ in
529
+ [
530
+ (* "div" *)
531
+ (nolabel, componentNameExpr);
532
+ (* ReactDOMRe.domProps(~className=blabla, ~foo=bar, ()) *)
533
+ (labelled " props" , propsCall);
534
+ (* [|moreCreateElementCallsHere|] *)
535
+ (nolabel, childrenExpr);
536
+ ]
537
+ in
538
+ Exp. apply
539
+ ~loc (* throw away the [@JSX] attribute and keep the others, if any *)
540
+ ~attrs
541
+ (* ReactDOMRe.createElement *)
542
+ (Exp. ident ~loc
543
+ {loc; txt = Ldot (Lident " ReactDOMRe" , createElementCall)})
544
+ args
483
545
[@@ raises Invalid_argument ]
484
546
485
547
let rec recursivelyTransformNamedArgsForMake mapper expr args newtypes =
0 commit comments