Skip to content

Commit f755a1c

Browse files
authored
Add @as support for obj ppx (#6412)
* Support field aliases for obj ppx * Update changelog * Format * Fix ci error * Fixes after review * Format * Update changelog wording
1 parent 7e2e81f commit f755a1c

File tree

6 files changed

+90
-35
lines changed

6 files changed

+90
-35
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#### :rocket: New Feature
2121

2222
- Support renaming fields in inline records with `@as` attribute. [#6391](https://github.com/rescript-lang/rescript-compiler/pull/6391)
23+
- Support renaming object fields of `@obj` external ppx with `@as` attribute. [#6391](https://github.com/rescript-lang/rescript-compiler/pull/6412)
2324
- Add builtin abstract types for File and Blob APIs. https://github.com/rescript-lang/rescript-compiler/pull/6383
2425
- Untagged variants: Support `promise`, RegExes, Dates, File and Blob. https://github.com/rescript-lang/rescript-compiler/pull/6383
2526
- Support aliased types as payloads to untagged variants. https://github.com/rescript-lang/rescript-compiler/pull/6394

jscomp/frontend/ast_external_process.ml

+33-19
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,14 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
398398
| _ ->
399399
Location.raise_errorf ~loc
400400
"expect label, optional, or unit here")
401-
| Labelled name -> (
401+
| Labelled label -> (
402+
let fieldName =
403+
match
404+
Ast_attributes.iter_process_bs_string_as param_type.attr
405+
with
406+
| Some alias -> alias
407+
| None -> label
408+
in
402409
let obj_arg_type = refine_obj_arg_type ~nolabel:false ty in
403410
match obj_arg_type with
404411
| Ignore ->
@@ -407,39 +414,39 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
407414
result_types )
408415
| Arg_cst _ ->
409416
( {
410-
obj_arg_label = External_arg_spec.obj_label name;
417+
obj_arg_label = External_arg_spec.obj_label fieldName;
411418
obj_arg_type;
412419
},
413420
arg_types,
414421
(* ignored in [arg_types], reserved in [result_types] *)
415422
result_types )
416423
| Nothing ->
417424
( {
418-
obj_arg_label = External_arg_spec.obj_label name;
425+
obj_arg_label = External_arg_spec.obj_label fieldName;
419426
obj_arg_type;
420427
},
421428
param_type :: arg_types,
422-
Parsetree.Otag ({Asttypes.txt = name; loc}, [], ty)
429+
Parsetree.Otag ({Asttypes.txt = fieldName; loc}, [], ty)
423430
:: result_types )
424431
| Int _ ->
425432
( {
426-
obj_arg_label = External_arg_spec.obj_label name;
433+
obj_arg_label = External_arg_spec.obj_label fieldName;
427434
obj_arg_type;
428435
},
429436
param_type :: arg_types,
430437
Otag
431-
( {Asttypes.txt = name; loc},
438+
( {Asttypes.txt = fieldName; loc},
432439
[],
433440
Ast_literal.type_int ~loc () )
434441
:: result_types )
435442
| Poly_var_string _ ->
436443
( {
437-
obj_arg_label = External_arg_spec.obj_label name;
444+
obj_arg_label = External_arg_spec.obj_label fieldName;
438445
obj_arg_type;
439446
},
440447
param_type :: arg_types,
441448
Otag
442-
( {Asttypes.txt = name; loc},
449+
( {Asttypes.txt = fieldName; loc},
443450
[],
444451
Ast_literal.type_string ~loc () )
445452
:: result_types )
@@ -449,11 +456,18 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
449456
| Extern_unit -> assert false
450457
| Poly_var _ ->
451458
Location.raise_errorf ~loc
452-
"%@obj label %s does not support such arg type" name
459+
"%@obj label %s does not support such arg type" label
453460
| Unwrap ->
454461
Location.raise_errorf ~loc
455-
"%@obj label %s does not support %@unwrap arguments" name)
456-
| Optional name -> (
462+
"%@obj label %s does not support %@unwrap arguments" label)
463+
| Optional label -> (
464+
let fieldName =
465+
match
466+
Ast_attributes.iter_process_bs_string_as param_type.attr
467+
with
468+
| Some alias -> alias
469+
| None -> label
470+
in
457471
let obj_arg_type = get_opt_arg_type ~nolabel:false ty in
458472
match obj_arg_type with
459473
| Ignore ->
@@ -469,35 +483,35 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
469483
in
470484
( {
471485
obj_arg_label =
472-
External_arg_spec.optional for_sure_not_nested name;
486+
External_arg_spec.optional for_sure_not_nested fieldName;
473487
obj_arg_type;
474488
},
475489
param_type :: arg_types,
476490
Parsetree.Otag
477-
( {Asttypes.txt = name; loc},
491+
( {Asttypes.txt = fieldName; loc},
478492
[],
479493
Ast_comb.to_undefined_type loc ty )
480494
:: result_types )
481495
| Int _ ->
482496
( {
483-
obj_arg_label = External_arg_spec.optional true name;
497+
obj_arg_label = External_arg_spec.optional true fieldName;
484498
obj_arg_type;
485499
},
486500
param_type :: arg_types,
487501
Otag
488-
( {Asttypes.txt = name; loc},
502+
( {Asttypes.txt = fieldName; loc},
489503
[],
490504
Ast_comb.to_undefined_type loc
491505
@@ Ast_literal.type_int ~loc () )
492506
:: result_types )
493507
| Poly_var_string _ ->
494508
( {
495-
obj_arg_label = External_arg_spec.optional true name;
509+
obj_arg_label = External_arg_spec.optional true fieldName;
496510
obj_arg_type;
497511
},
498512
param_type :: arg_types,
499513
Otag
500-
( {Asttypes.txt = name; loc},
514+
( {Asttypes.txt = fieldName; loc},
501515
[],
502516
Ast_comb.to_undefined_type loc
503517
@@ Ast_literal.type_string ~loc () )
@@ -511,10 +525,10 @@ let process_obj (loc : Location.t) (st : external_desc) (prim_name : string)
511525
| Extern_unit -> assert false
512526
| Poly_var _ ->
513527
Location.raise_errorf ~loc
514-
"%@obj label %s does not support such arg type" name
528+
"%@obj label %s does not support such arg type" label
515529
| Unwrap ->
516530
Location.raise_errorf ~loc
517-
"%@obj label %s does not support %@unwrap arguments" name)
531+
"%@obj label %s does not support %@unwrap arguments" label)
518532
in
519533
(new_arg_label :: arg_labels, new_arg_types, output_tys))
520534
in

jscomp/syntax/tests/ppx/react/expected/mangleKeyword.res.txt

+27-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
11
@@jsxConfig({version: 3})
22

3-
module C30 = {
4-
@obj external makeProps: (~_open: 'T_open, ~key: string=?, unit) => {"_open": 'T_open} = ""
3+
module C3A0 = {
4+
@obj
5+
external makeProps: (
6+
~_open: 'T_open,
7+
~_type: string,
8+
~key: string=?,
9+
unit,
10+
) => {"_open": 'T_open, "_type": string} = ""
511

6-
@react.component let make = @warning("-16") (~_open) => React.string(_open)
12+
@react.component
13+
let make =
14+
@warning("-16")
15+
(@as("open") ~_open) => @warning("-16") (@as("type") ~_type: string) => React.string(_open)
716
let make = {
8-
let \"MangleKeyword$C30" = (\"Props": {"_open": 'T_open}) => make(~_open=\"Props"["_open"])
9-
\"MangleKeyword$C30"
17+
let \"MangleKeyword$C3A0" = (\"Props": {"_open": 'T_open, "_type": string}) =>
18+
make(~_type=\"Props"["_type"], ~_open=\"Props"["_open"])
19+
\"MangleKeyword$C3A0"
1020
}
1121
}
12-
module C31 = {
13-
@obj external makeProps: (~_open: string, ~key: string=?, unit) => {"_open": string} = ""
14-
external make: React.componentLike<{"_open": string}, React.element> = "default"
22+
module C3A1 = {
23+
@obj
24+
external makeProps: (
25+
~_open: string,
26+
~_type: string,
27+
~key: string=?,
28+
unit,
29+
) => {"_open": string, "_type": string} = ""
30+
external make: @as("open")
31+
React.componentLike<{"_open": string, "_type": string}, React.element> = "default"
1532
}
1633

17-
let c30 = React.createElement(C30.make, C30.makeProps(~_open="x", ()))
18-
let c31 = React.createElement(C31.make, C31.makeProps(~_open="x", ()))
34+
let c3a0 = React.createElement(C3A0.make, C3A0.makeProps(~_open="x", ~_type="t", ()))
35+
let c3a1 = React.createElement(C3A1.make, C3A1.makeProps(~_open="x", ~_type="t", ()))
1936

2037
@@jsxConfig({version: 4, mode: "classic"})
2138

jscomp/syntax/tests/ppx/react/mangleKeyword.res

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
@@jsxConfig({version: 3})
22

3-
module C30 = {
3+
module C3A0 = {
44
@react.component
5-
let make = (~_open) => React.string(_open)
5+
let make =
6+
(@as("open") ~_open, @as("type") ~_type: string) => React.string(_open)
67
}
7-
module C31 = {
8+
module C3A1 = {
89
@react.component
9-
external make: (~_open: string) => React.element = "default"
10+
external make: (@as("open") ~_open: string, @as("type") ~_type: string) => React.element =
11+
"default"
1012
}
1113

12-
let c30 = <C30 _open="x" />
13-
let c31 = <C31 _open="x" />
14+
let c3a0 = <C3A0 _open="x" _type="t" />
15+
let c3a1 = <C3A1 _open="x" _type="t" />
1416

1517
@@jsxConfig({version: 4, mode: "classic"})
1618

jscomp/test/external_ppx.js

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/external_ppx.res

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ external make_config: (~length: 'a, ~width: int) => unit = ""
99

1010
@obj external opt_make: (~length: int, ~width: int=?) => (_ as 'event) = ""
1111

12+
@obj
13+
external renamed_make: (
14+
@as("type") ~_type: string,
15+
@as("WIDTH") ~width: int=?,
16+
~normal: float,
17+
) => (_ as 'event) = ""
18+
19+
let renamed = renamed_make(~_type="123", ~normal=12.)
20+
1221
@obj
1322
external ff: (
1423
~hi: int,

0 commit comments

Comments
 (0)