Skip to content

Commit 7c36067

Browse files
committed
Refactor delimiters: processed and unprocessed.
Unprocessed delimiters include j and js. They are converted in the front-end. Processed delimiters are: - DNone: no delimiter - DStarJ: result of processing j or js - DJson: coming from @as(json`....`)
1 parent 3b35c50 commit 7c36067

13 files changed

+74716
-62981
lines changed

jscomp/core/j.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ and for_ident = ident
7676
and for_direction = Js_op.direction_flag
7777
and property_map = (property_name * expression) list
7878
and length_object = Js_op.length_object
79-
and delim = | DNone | DJ | DJS | DStarJ | DJson
79+
and delim = | DNone | DStarJ | DJson
8080

8181
and expression_desc =
8282
| Length of expression * length_object

jscomp/core/js_dump.ml

+6-4
Original file line numberDiff line numberDiff line change
@@ -597,10 +597,12 @@ and expression_desc cxt ~(level : int) f x : cxt =
597597
(*TODO --
598598
when utf8-> it will not escape '\\' which is definitely not we want
599599
*)
600-
if delim = DJ || delim = DStarJ then
601-
P.string f ("\"" ^ txt ^ "\"")
602-
else if delim = DJson then P.string f txt
603-
else Js_dump_string.pp_string f txt;
600+
let () =
601+
match delim with
602+
| DStarJ -> P.string f ("\"" ^ txt ^ "\"")
603+
| DJson -> P.string f txt
604+
| DNone -> Js_dump_string.pp_string f txt
605+
in
604606
cxt
605607
| Raw_js_code { code = s; code_info = info } -> (
606608
match info with

jscomp/core/lam_compile_const.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ and translate (x : Lam_constant.t) : J.expression =
7171
(* https://github.com/google/closure-library/blob/master/closure%2Fgoog%2Fmath%2Flong.js *)
7272
| Const_float f -> E.float f (* TODO: preserve float *)
7373
| Const_string { s; unicode = false } -> E.str s
74-
| Const_string { s; unicode = true } -> E.str ~delim:DJ s
74+
| Const_string { s; unicode = true } -> E.str ~delim:DStarJ s
7575
| Const_pointer name -> E.str name
7676
| Const_block (tag, tag_info, xs) ->
7777
Js_of_lam_block.make_block NA tag_info (E.small_int tag)

jscomp/frontend/ast_attributes.ml

+2-8
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,6 @@ type as_const_payload = Int of int | Str of string * J.delim
282282

283283
let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) =
284284
let st = ref None in
285-
let process_delim = function
286-
| None -> Some J.DNone
287-
| Some "json" -> Some DJson
288-
| Some "*j" -> Some DStarJ
289-
| _ -> None
290-
in
291285
Ext_list.iter attrs (fun (({ txt; loc }, payload) as attr) ->
292286
match txt with
293287
| "bs.as" | "as" ->
@@ -311,9 +305,9 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) =
311305
_;
312306
};
313307
]
314-
when process_delim delim_ <> None -> (
308+
when Ast_utf8_string_interp.parse_processed_delim delim_ <> None -> (
315309
let delim =
316-
match process_delim delim_ with
310+
match Ast_utf8_string_interp.parse_processed_delim delim_ with
317311
| None -> assert false
318312
| Some delim -> delim
319313
in

jscomp/frontend/ast_utf8_string_interp.ml

+31-17
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ type pos = {
4747
(** Note the position is about code point *)
4848

4949
type segment = { start : pos; finish : pos; kind : kind; content : string }
50-
5150
type segments = segment list
5251

5352
type cxt = {
@@ -324,13 +323,23 @@ let concat_ident : Longident.t = Ldot (Lident "Pervasives", "^")
324323
(* Longident.parse "Js.String.make" *)
325324
let to_string_ident : Longident.t = Ldot (Ldot (Lident "Js", "String2"), "make")
326325

327-
let escaped_j_delimiter = "*j" (* not user level syntax allowed *)
328-
329-
let unescaped_j_delimiter = "j"
326+
module Delim = struct
327+
let parse_processed = function
328+
| None -> Some J.DNone
329+
| Some "json" -> Some DJson
330+
| Some "*j" -> Some DStarJ
331+
| _ -> None
330332

331-
let unescaped_js_delimiter = "js"
333+
let parse_unprocessed = function
334+
| "js" -> `string_interpolation
335+
| "j" -> `old_unsafe_interpolation
336+
| _ -> `no_interpolation
332337

333-
let escaped = Some escaped_j_delimiter
338+
let escaped_j_delimiter = "*j" (* not user level syntax allowed *)
339+
let unescaped_j_delimiter = "j"
340+
let unescaped_js_delimiter = "js"
341+
let escaped = Some escaped_j_delimiter
342+
end
334343

335344
let border = String.length "{j|"
336345

@@ -340,7 +349,7 @@ let aux loc (segment : segment) ~to_string_ident : Parsetree.expression =
340349
match kind with
341350
| String ->
342351
let loc = update border start finish loc in
343-
Ast_compatible.const_exp_string content ?delimiter:escaped ~loc
352+
Ast_compatible.const_exp_string content ?delimiter:Delim.escaped ~loc
344353
| Var (soffset, foffset) ->
345354
let loc =
346355
{
@@ -362,7 +371,7 @@ let concat_exp a_loc x ~(lhs : Parsetree.expression) : Parsetree.expression =
362371
(* Invariant: the [lhs] is always of type string *)
363372
let rec handle_segments loc (rev_segments : segment list) =
364373
match rev_segments with
365-
| [] -> Ast_compatible.const_exp_string ~loc "" ?delimiter:escaped
374+
| [] -> Ast_compatible.const_exp_string ~loc "" ?delimiter:Delim.escaped
366375
| [ segment ] -> aux loc segment ~to_string_ident (* string literal *)
367376
| { content = "" } :: rest -> handle_segments loc rest
368377
| a :: rest -> concat_exp loc a ~lhs:(handle_segments loc rest)
@@ -389,15 +398,20 @@ let transform_interp loc s =
389398
Location.raise_errorf ~loc:(update border start pos loc) "%a" pp_error error
390399

391400
let transform (e : Parsetree.expression) s delim : Parsetree.expression =
392-
if Ext_string.equal delim unescaped_js_delimiter then
393-
let js_str = Ast_utf8_string.transform e.pexp_loc s in
394-
{ e with pexp_desc = Pexp_constant (Pconst_string (js_str, escaped)) }
395-
else if Ext_string.equal delim unescaped_j_delimiter then
396-
transform_interp e.pexp_loc s
397-
else e
401+
match Delim.parse_unprocessed delim with
402+
| `string_interpolation ->
403+
let js_str = Ast_utf8_string.transform e.pexp_loc s in
404+
{
405+
e with
406+
pexp_desc = Pexp_constant (Pconst_string (js_str, Delim.escaped));
407+
}
408+
| `old_unsafe_interpolation -> transform_interp e.pexp_loc s
409+
| `no_interpolation -> e
398410

399-
let is_unicode_string opt = Ext_string.equal opt escaped_j_delimiter
411+
let is_unicode_string opt = Ext_string.equal opt Delim.escaped_j_delimiter
400412

401413
let is_unescaped s =
402-
Ext_string.equal s unescaped_j_delimiter
403-
|| Ext_string.equal s unescaped_js_delimiter
414+
Ext_string.equal s Delim.unescaped_j_delimiter
415+
|| Ext_string.equal s Delim.unescaped_js_delimiter
416+
417+
let parse_processed_delim = Delim.parse_processed

jscomp/frontend/ast_utf8_string_interp.mli

+1-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ type pos = { lnum : int; offset : int; byte_bol : int }
3838
(** Note the position is about code point *)
3939

4040
type segment = { start : pos; finish : pos; kind : kind; content : string }
41-
4241
type segments = segment list
4342

4443
type cxt = {
@@ -55,11 +54,8 @@ type cxt = {
5554
type exn += Error of pos * pos * error
5655

5756
val empty_segment : segment -> bool
58-
5957
val transform_test : string -> segment list
60-
6158
val transform : Parsetree.expression -> string -> string -> Parsetree.expression
62-
6359
val is_unicode_string : string -> bool
64-
6560
val is_unescaped : string -> bool
61+
val parse_processed_delim : string option -> J.delim option

jscomp/frontend/bs_ast_invariant.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ let check_constant loc kind (const : Parsetree.constant) =
7878
if Ast_utf8_string_interp.is_unescaped s then
7979
Bs_warnings.error_unescaped_delimiter loc s
8080
| `pat ->
81-
if s = "j" then
81+
if Ast_utf8_string_interp.parse_processed_delim (Some s) = Some DStarJ
82+
then
8283
Location.raise_errorf ~loc
8384
"Unicode string is not allowed in pattern match")
8485
| Pconst_integer (s, None) -> (

jscomp/main/builtin_cmi_datasets.ml

+2-2
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)