Skip to content

Commit edf2724

Browse files
authored
stop mangling tagged templates and backquoted strings (#7841)
1 parent cd8c272 commit edf2724

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+202
-132
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- Fix generation of interfaces for module types containing multiple type constraints. https://github.com/rescript-lang/rescript/pull/7825
2626
- JSX preserve mode: fix "make is not a valid component name". https://github.com/rescript-lang/rescript/pull/7831
2727
- Rewatch: include parser arguments of experimental features. https://github.com/rescript-lang/rescript/pull/7836
28+
- Stop mangling tagged templates and backquoted strings. https://github.com/rescript-lang/rescript/pull/7841
2829

2930
#### :memo: Documentation
3031

compiler/core/j.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ and for_ident = ident
7575
and for_direction = Js_op.direction_flag
7676
and property_map = (property_name * expression) list
7777
and length_object = Js_op.length_object
78-
and delim = External_arg_spec.delim = DNone | DStarJ | DNoQuotes
78+
and delim = External_arg_spec.delim = DNone | DStarJ | DNoQuotes | DBackQuotes
7979

8080
and expression_desc =
8181
| Length of expression * length_object

compiler/core/js_dump.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ and expression_desc cxt ~(level : int) f x : cxt =
729729
| DStarJ -> P.string f ("\"" ^ txt ^ "\"")
730730
| DNoQuotes -> P.string f txt
731731
| DNone -> Js_dump_string.pp_string f txt
732+
| DBackQuotes -> P.string f ("`" ^ txt ^ "`")
732733
in
733734
cxt
734735
| Raw_js_code {code = s; code_info = info} -> (

compiler/core/lam.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ let switch lam (lam_switch : lambda_switch) : t =
430430

431431
let stringswitch (lam : t) cases default : t =
432432
match lam with
433-
| Lconst (Const_string {s; unicode = false}) ->
433+
| Lconst (Const_string {s; delim = None | Some DNoQuotes}) ->
434434
Ext_list.assoc_by_string cases s default
435435
| _ -> Lstringswitch (lam, cases, default)
436436

@@ -471,7 +471,7 @@ module Lift = struct
471471

472472
let bool b = if b then true_ else false_
473473

474-
let string s : t = Lconst (Const_string {s; unicode = false})
474+
let string s : t = Lconst (Const_string {s; delim = None})
475475

476476
let char b : t = Lconst (Const_char b)
477477
end
@@ -488,7 +488,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
488488
Lift.int (Int32.of_float (float_of_string a))
489489
(* | Pnegfloat -> Lift.float (-. a) *)
490490
(* | Pabsfloat -> Lift.float (abs_float a) *)
491-
| Pstringlength, Const_string {s; unicode = false} ->
491+
| Pstringlength, Const_string {s; delim = None} ->
492492
Lift.int (Int32.of_int (String.length s))
493493
(* | Pnegbint Pnativeint, ( (Const_nativeint i)) *)
494494
(* -> *)
@@ -537,11 +537,11 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
537537
| Psequor, Const_js_false, Const_js_true -> true_
538538
| Psequor, Const_js_false, Const_js_false -> false_
539539
| ( Pstringadd,
540-
Const_string {s = a; unicode = false},
541-
Const_string {s = b; unicode = false} ) ->
540+
Const_string {s = a; delim = None},
541+
Const_string {s = b; delim = None} ) ->
542542
Lift.string (a ^ b)
543543
| ( (Pstringrefs | Pstringrefu),
544-
Const_string {s = a; unicode = false},
544+
Const_string {s = a; delim = None},
545545
Const_int {i = b} ) -> (
546546
try Lift.char (Char.code (String.get a (Int32.to_int b)))
547547
with _ -> default ())

compiler/core/lam_compile_const.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ and translate (x : Lam_constant.t) : J.expression =
6161
| Const_char i -> Js_of_lam_string.const_char i
6262
| Const_bigint (sign, i) -> E.bigint sign i
6363
| Const_float f -> E.float f (* TODO: preserve float *)
64-
| Const_string {s; unicode = false} -> E.str s
65-
| Const_string {s; unicode = true} -> E.str ~delim:DStarJ s
64+
| Const_string {s; delim = None | Some DNoQuotes} -> E.str s
65+
| Const_string {s; delim = Some delim} -> E.str ~delim s
6666
| Const_pointer name -> E.str name
6767
| Const_block (tag, tag_info, xs) ->
6868
Js_of_lam_block.make_block NA tag_info (E.small_int tag)

compiler/core/lam_constant_convert.ml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,8 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t =
2727
| Const_base (Const_int i) -> Const_int {i = Int32.of_int i; comment = None}
2828
| Const_base (Const_char i) -> Const_char i
2929
| Const_base (Const_string (s, opt)) ->
30-
let unicode =
31-
match opt with
32-
| Some opt -> Ast_utf8_string_interp.is_unicode_string opt
33-
| _ -> false
34-
in
35-
Const_string {s; unicode}
30+
let delim = Ast_utf8_string_interp.parse_processed_delim opt in
31+
Const_string {s; delim}
3632
| Const_base (Const_float i) -> Const_float i
3733
| Const_base (Const_int32 i) -> Const_int {i; comment = None}
3834
| Const_base (Const_int64 _) -> assert false
@@ -63,7 +59,7 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t =
6359
if Ext_string.is_valid_hash_number name then
6460
Const_int {i = Ext_string.hash_number_as_i32_exn name; comment = None}
6561
else Const_pointer name)
66-
| Const_immstring s -> Const_string {s; unicode = false}
62+
| Const_immstring s -> Const_string {s; delim = None}
6763
| Const_block (t, xs) -> (
6864
let tag = Lambda.tag_of_tag_info t in
6965
match t with
@@ -80,7 +76,7 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t =
8076
let tag_val : Lam_constant.t =
8177
if Ext_string.is_valid_hash_number s then
8278
Const_int {i = Ext_string.hash_number_as_i32_exn s; comment = None}
83-
else Const_string {s; unicode = false}
79+
else Const_string {s; delim = None}
8480
in
8581
Const_block (tag, t, [tag_val; convert_constant value])
8682
| _ -> assert false))

compiler/core/lam_convert.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
184184
let tag_val : Lam_constant.t =
185185
if Ext_string.is_valid_hash_number s then
186186
Const_int {i = Ext_string.hash_number_as_i32_exn s; comment = None}
187-
else Const_string {s; unicode = false}
187+
else Const_string {s; delim = None}
188188
in
189189
prim
190190
~primitive:(Pmakeblock (tag, info, mutable_flag))
@@ -465,7 +465,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
465465
| Lprim (Pgetglobal id, args, _) ->
466466
let args = Ext_list.map args convert_aux in
467467
if Ident.is_predef_exn id then
468-
Lam.const (Const_string {s = id.name; unicode = false})
468+
Lam.const (Const_string {s = id.name; delim = None})
469469
else (
470470
may_depend may_depends (Lam_module_ident.of_ml ~dynamic_import id);
471471
assert (args = []);

compiler/core/lam_pass_lets_dce.ml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
6363
->
6464
Hash_ident.add subst v (simplif l1);
6565
simplif l2
66-
| _, Lconst (Const_string {s; unicode = false}) ->
66+
| _, Lconst (Const_string {s; delim = None}) ->
6767
(* only "" added for later inlining *)
6868
Hash_ident.add string_table v s;
6969
Lam.let_ Alias v l1 (simplif l2)
@@ -112,7 +112,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
112112
| _ -> (
113113
let l1 = simplif l1 in
114114
match l1 with
115-
| Lconst (Const_string {s; unicode = false}) ->
115+
| Lconst (Const_string {s; delim = None}) ->
116116
Hash_ident.add string_table v s;
117117
(* we need move [simplif lbody] later, since adding Hash does have side effect *)
118118
Lam.let_ Alias v l1 (simplif lbody)
@@ -127,7 +127,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
127127
let l1 = simplif l1 in
128128

129129
match (kind, l1) with
130-
| Strict, Lconst (Const_string {s; unicode = false}) ->
130+
| Strict, Lconst (Const_string {s; delim = None}) ->
131131
Hash_ident.add string_table v s;
132132
Lam.let_ Alias v l1 (simplif l2)
133133
| _ -> Lam_util.refine_let ~kind v l1 (simplif l2))
@@ -157,7 +157,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
157157
let r' = simplif r in
158158
let opt_l =
159159
match l' with
160-
| Lconst (Const_string {s = ls; unicode = false}) -> Some ls
160+
| Lconst (Const_string {s = ls; delim = None}) -> Some ls
161161
| Lvar i -> Hash_ident.find_opt string_table i
162162
| _ -> None
163163
in
@@ -166,14 +166,13 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
166166
| Some l_s -> (
167167
let opt_r =
168168
match r' with
169-
| Lconst (Const_string {s = rs; unicode = false}) -> Some rs
169+
| Lconst (Const_string {s = rs; delim = None}) -> Some rs
170170
| Lvar i -> Hash_ident.find_opt string_table i
171171
| _ -> None
172172
in
173173
match opt_r with
174174
| None -> Lam.prim ~primitive:Pstringadd ~args:[l'; r'] loc
175-
| Some r_s -> Lam.const (Const_string {s = l_s ^ r_s; unicode = false}))
176-
)
175+
| Some r_s -> Lam.const (Const_string {s = l_s ^ r_s; delim = None})))
177176
| Lglobal_module _ -> lam
178177
| Lprim {primitive; args; loc} ->
179178
Lam.prim ~primitive ~args:(Ext_list.map args simplif) loc

compiler/frontend/ast_utf8_string_interp.ml

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -275,35 +275,69 @@ module Delim = struct
275275
| None -> Some External_arg_spec.DNone
276276
| Some "json" -> Some DNoQuotes
277277
| Some "*j" -> Some DStarJ
278+
| Some "bq" -> Some DBackQuotes
278279
| _ -> None
279280

280281
type interpolation =
281-
| Js (* string interpolation *)
282+
| BackQuotes (* string interpolation *)
283+
| Js (* simple double quoted string *)
282284
| Unrecognized (* no interpolation: delimiter not recognized *)
283-
let parse_unprocessed = function
284-
| "js" -> Js
285+
let parse_unprocessed is_template = function
286+
| "js" -> if is_template then BackQuotes else Js
285287
| _ -> Unrecognized
286288

287289
let escaped_j_delimiter = "*j" (* not user level syntax allowed *)
290+
let escaped_back_quote_delimiter = "bq"
291+
let some_escaped_back_quote_delimiter = Some "bq"
288292
let unescaped_js_delimiter = "js"
289-
let escaped = Some escaped_j_delimiter
293+
let some_escaped_j_delimiter = Some escaped_j_delimiter
290294
end
291295

292296
let transform_exp (e : Parsetree.expression) s delim : Parsetree.expression =
293-
match Delim.parse_unprocessed delim with
297+
let is_template =
298+
Ext_list.exists e.pexp_attributes (fun ({txt}, _) ->
299+
match txt with
300+
| "res.template" | "res.taggedTemplate" -> true
301+
| _ -> false)
302+
in
303+
match Delim.parse_unprocessed is_template delim with
294304
| Js ->
295305
let js_str = Ast_utf8_string.transform e.pexp_loc s in
296-
{e with pexp_desc = Pexp_constant (Pconst_string (js_str, Delim.escaped))}
306+
{
307+
e with
308+
pexp_desc =
309+
Pexp_constant (Pconst_string (js_str, Delim.some_escaped_j_delimiter));
310+
}
311+
| BackQuotes ->
312+
{
313+
e with
314+
pexp_desc =
315+
Pexp_constant
316+
(Pconst_string (s, Delim.some_escaped_back_quote_delimiter));
317+
}
297318
| Unrecognized -> e
298319

299320
let transform_pat (p : Parsetree.pattern) s delim : Parsetree.pattern =
300-
match Delim.parse_unprocessed delim with
321+
match Delim.parse_unprocessed false delim with
301322
| Js ->
302323
let js_str = Ast_utf8_string.transform p.ppat_loc s in
303-
{p with ppat_desc = Ppat_constant (Pconst_string (js_str, Delim.escaped))}
324+
{
325+
p with
326+
ppat_desc =
327+
Ppat_constant (Pconst_string (js_str, Delim.some_escaped_j_delimiter));
328+
}
329+
| BackQuotes ->
330+
{
331+
p with
332+
ppat_desc =
333+
Ppat_constant
334+
(Pconst_string (s, Delim.some_escaped_back_quote_delimiter));
335+
}
304336
| Unrecognized -> p
305337

306-
let is_unicode_string opt = Ext_string.equal opt Delim.escaped_j_delimiter
338+
let is_unicode_string opt =
339+
Ext_string.equal opt Delim.escaped_j_delimiter
340+
|| Ext_string.equal opt Delim.escaped_back_quote_delimiter
307341

308342
let is_unescaped s = Ext_string.equal s Delim.unescaped_js_delimiter
309343

compiler/frontend/external_arg_spec.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
(** type definitions for arguments to a function declared external *)
2626

27-
type delim = DNone | DStarJ | DNoQuotes
27+
type delim = DNone | DStarJ | DNoQuotes | DBackQuotes
2828

2929
type cst = Arg_int_lit of int | Arg_string_lit of string * delim
3030

0 commit comments

Comments
 (0)