Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions analysis/src/Utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ let identifyPexp pexp =
| Pexp_open _ -> "Pexp_open"
| Pexp_await _ -> "Pexp_await"
| Pexp_jsx_element _ -> "Pexp_jsx_element"
| Pexp_template _ -> "Pexp_template"

let identifyPpat pat =
match pat with
Expand Down
1 change: 1 addition & 0 deletions compiler/core/j.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ and expression_desc =
This can be constructed either in a static way [E.array_index_by_int] or a dynamic way
[E.array_index]
*)
| Template_literal of expression list * expression list
| Tagged_template of expression * expression list * expression list
| Static_index of expression * string * int32 option
(* The third argument bool indicates whether we should
Expand Down
6 changes: 5 additions & 1 deletion compiler/core/js_analyzer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ let rec no_side_effect_expression_desc (x : J.expression_desc) =
| String_append (a, b) | Seq (a, b) -> no_side_effect a && no_side_effect b
| Length (e, _) | Caml_block_tag (e, _) | Typeof e -> no_side_effect e
| Bin (op, a, b) -> op <> Eq && no_side_effect a && no_side_effect b
| Template_literal (strings, values) ->
Ext_list.for_all strings no_side_effect
&& Ext_list.for_all values no_side_effect
| Tagged_template (call_expr, strings, values) ->
no_side_effect call_expr
&& Ext_list.for_all strings no_side_effect
Expand Down Expand Up @@ -229,7 +232,8 @@ let rec eq_expression ({expression_desc = x0} : J.expression)
| _ -> false)
| Length _ | Is_null_or_undefined _ | String_append _ | Typeof _ | Js_not _
| Js_bnot _ | In _ | Cond _ | FlatCall _ | New _ | Fun _ | Raw_js_code _
| Array _ | Caml_block_tag _ | Object _ | Tagged_template _ | Await _ ->
| Array _ | Caml_block_tag _ | Object _ | Template_literal _
| Tagged_template _ | Await _ ->
false
| Spread _ -> false

Expand Down
18 changes: 18 additions & 0 deletions compiler/core/js_dump.ml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ let rec exp_need_paren ?(arrow = false) (e : J.expression) =
false
| Await _ -> false
| Spread _ -> false
| Template_literal _ -> false
| Tagged_template _ -> false
| Optional_block (e, true) when arrow -> exp_need_paren ~arrow e
| Optional_block _ -> false
Expand Down Expand Up @@ -713,6 +714,23 @@ and expression_desc cxt ~(level : int) f x : cxt =
aux cxt string_args value_args;
P.string f "`";
cxt
| Template_literal (string_args, value_args) ->
P.string f "`";
let rec aux cxt xs ys =
match (xs, ys) with
| [], [] -> ()
| [{J.expression_desc = Str {txt; _}}], [] -> P.string f txt
| {J.expression_desc = Str {txt; _}} :: x_rest, y :: y_rest ->
P.string f txt;
P.string f "${";
let cxt = expression cxt ~level f y in
P.string f "}";
aux cxt x_rest y_rest
| _ -> assert false
in
aux cxt string_args value_args;
P.string f "`";
cxt
| String_index (a, b) ->
P.group f 1 (fun _ ->
let cxt = expression ~level:15 cxt f a in
Expand Down
3 changes: 3 additions & 0 deletions compiler/core/js_exp_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ let tagged_template ?comment call_expr string_args value_args : t =
comment;
}

let template_literal ?comment string_args value_args : t =
{expression_desc = Template_literal (string_args, value_args); comment}

let runtime_var_dot ?comment (x : string) (e1 : string) : J.expression =
{
expression_desc =
Expand Down
1 change: 1 addition & 0 deletions compiler/core/js_exp_make.mli
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ val call : ?comment:string -> info:Js_call_info.t -> t -> t list -> t
val flat_call : ?comment:string -> t -> t -> t

val tagged_template : ?comment:string -> t -> t list -> t list -> t
val template_literal : ?comment:string -> t list -> t list -> t

val new_ : ?comment:string -> J.expression -> J.expression list -> t

Expand Down
4 changes: 4 additions & 0 deletions compiler/core/js_fold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ class fold =
let _self = _self#expression _x0 in
let _self = list (fun _self -> _self#expression) _self _x1 in
_self
| Template_literal (_x0, _x1) ->
let _self = list (fun _self -> _self#expression) _self _x0 in
let _self = list (fun _self -> _self#expression) _self _x1 in
_self
| Tagged_template (_x0, _x1, _x2) ->
let _self = _self#expression _x0 in
let _self = list (fun _self -> _self#expression) _self _x1 in
Expand Down
4 changes: 4 additions & 0 deletions compiler/core/js_record_fold.ml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ let expression_desc : 'a. ('a, expression_desc) fn =
let st = _self.expression _self st _x0 in
let st = list _self.expression _self st _x1 in
st
| Template_literal (_x0, _x1) ->
let st = list _self.expression _self st _x0 in
let st = list _self.expression _self st _x1 in
st
| Tagged_template (_xo, _x1, _x2) ->
let st = _self.expression _self st _xo in
let st = list _self.expression _self st _x1 in
Expand Down
3 changes: 3 additions & 0 deletions compiler/core/js_record_iter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ let expression_desc : expression_desc fn =
| Call (_x0, _x1, _x2) ->
_self.expression _self _x0;
list _self.expression _self _x1
| Template_literal (_x0, _x1) ->
list _self.expression _self _x0;
list _self.expression _self _x1
| Tagged_template (_x0, _x1, _x2) ->
_self.expression _self _x0;
list _self.expression _self _x1;
Expand Down
4 changes: 4 additions & 0 deletions compiler/core/js_record_map.ml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ let expression_desc : expression_desc fn =
let _x0 = _self.expression _self _x0 in
let _x1 = list _self.expression _self _x1 in
Call (_x0, _x1, _x2)
| Template_literal (_x0, _x1) ->
let _x0 = list _self.expression _self _x0 in
let _x1 = list _self.expression _self _x1 in
Template_literal (_x0, _x1)
| Tagged_template (_x0, _x1, _x2) ->
let _x0 = _self.expression _self _x0 in
let _x1 = list _self.expression _self _x1 in
Expand Down
2 changes: 1 addition & 1 deletion compiler/core/lam_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
| Pbigintcomp _ | Pbigintorder | Pbigintmin | Pbigintmax
(* string primitives *)
| Pstringlength | Pstringrefu | Pstringrefs | Pstringcomp _ | Pstringorder
| Pstringmin | Pstringmax
| Pstringmin | Pstringmax | Pstringtemplate _
(* array primitives *)
| Pmakearray | Parraylength | Parrayrefu | Parrayrefs
(* list primitives *)
Expand Down
3 changes: 3 additions & 0 deletions compiler/core/lam_compile_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
match args with
| [a; b] -> E.string_append a b
| _ -> assert false)
| Pstringtemplate strings ->
let string_args = List.map E.str strings in
E.template_literal string_args args
| Pinit_mod -> E.runtime_call Primitive_modules.module_ "init" args
| Pupdate_mod -> E.runtime_call Primitive_modules.module_ "update" args
| Psome -> (
Expand Down
2 changes: 2 additions & 0 deletions compiler/core/lam_convert.ml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
| Pstringmin -> prim ~primitive:Pstringmin ~args loc
| Pstringmax -> prim ~primitive:Pstringmax ~args loc
| Pstringadd -> prim ~primitive:Pstringadd ~args loc
| Pstringtemplate strings ->
prim ~primitive:(Pstringtemplate strings) ~args loc
| Pabsfloat -> assert false
| Pstringrefs -> prim ~primitive:Pstringrefs ~args loc
| Pisint -> prim ~primitive:Pisint ~args loc
Expand Down
5 changes: 3 additions & 2 deletions compiler/core/lam_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ type t =
| Pstringrefu
| Pstringrefs
| Pstringadd
| Pstringtemplate of string list
| Pstringcomp of Lam_compat.comparison
| Pstringorder
| Pstringmin
Expand Down Expand Up @@ -213,8 +214,8 @@ let eq_primitive_approx (lhs : t) (rhs : t) =
| Ppowbigint | Pnotbigint | Pandbigint | Porbigint | Pxorbigint | Plslbigint
| Pasrbigint | Pbigintorder | Pbigintmin | Pbigintmax
(* string primitives *)
| Pstringlength | Pstringrefu | Pstringrefs | Pstringadd | Pstringcomp _
| Pstringorder | Pstringmin | Pstringmax
| Pstringlength | Pstringrefu | Pstringrefs | Pstringadd | Pstringtemplate _
| Pstringcomp _ | Pstringorder | Pstringmin | Pstringmax
(* List primitives *)
| Pmakelist
(* dict primitives *)
Expand Down
1 change: 1 addition & 0 deletions compiler/core/lam_primitive.mli
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ type t =
| Pstringrefu
| Pstringrefs
| Pstringadd
| Pstringtemplate of string list
| Pstringcomp of Lam_compat.comparison
| Pstringorder
| Pstringmin
Expand Down
1 change: 1 addition & 0 deletions compiler/core/lam_print.ml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ let primitive ppf (prim : Lam_primitive.t) =
| Pnegint -> fprintf ppf "~-"
| Paddint -> fprintf ppf "+"
| Pstringadd -> fprintf ppf "+*"
| Pstringtemplate _ -> fprintf ppf "template"
| Psubint -> fprintf ppf "-"
| Pmulint -> fprintf ppf "*"
| Pdivint -> fprintf ppf "/"
Expand Down
67 changes: 32 additions & 35 deletions compiler/frontend/ast_attributes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -224,48 +224,45 @@ type as_const_payload = Int of int | Str of string * External_arg_spec.delim

let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) =
let st = ref None in
let string_payload_loc payload =
match payload with
| Parsetree.PStr [{pstr_desc = Parsetree.Pstr_eval ({pexp_loc; _}, _); _}]
->
Some pexp_loc
| _ -> None
in
Ext_list.iter attrs (fun (({txt; loc}, payload) as attr) ->
match txt with
| "as" ->
if !st = None then (
Used_attributes.mark_used_attribute attr;
match Ast_payload.is_single_int payload with
| None -> (
match payload with
| PStr
[
{
pstr_desc =
Pstr_eval
( {
pexp_desc = Pexp_constant (Pconst_string (s, delim_));
pexp_loc;
_;
},
_ );
_;
};
]
when Ast_utf8_string_interp.parse_processed_delim delim_ <> None
-> (
let delim =
match Ast_utf8_string_interp.parse_processed_delim delim_ with
| None -> assert false
| Some delim -> delim
in
st := Some (Str (s, delim));
if delim = DNoQuotes then
(* check that it is a valid object literal *)
match
Classify_function.classify
~check:(pexp_loc, Bs_flow_ast_utils.flow_deli_offset delim_)
s
with
| Js_literal _ -> ()
| _ ->
Location.raise_errorf ~loc:pexp_loc
"an object literal expected")
| _ -> Bs_syntaxerr.err loc Expect_int_or_string_or_json_literal)
match Ast_payload.is_single_string payload with
| Some (s, delim_) -> (
match Ast_utf8_string_interp.parse_processed_delim delim_ with
| None ->
Bs_syntaxerr.err loc Expect_int_or_string_or_json_literal
| Some delim -> (
let payload_loc =
match string_payload_loc payload with
| Some payload_loc -> payload_loc
| None -> loc
in
st := Some (Str (s, delim));
if delim = DNoQuotes then
(* check that it is a valid object literal *)
match
Classify_function.classify
~check:
(payload_loc, Bs_flow_ast_utils.flow_deli_offset delim_)
s
with
| Js_literal _ -> ()
| _ ->
Location.raise_errorf ~loc:payload_loc
"an object literal expected"))
| None -> Bs_syntaxerr.err loc Expect_int_or_string_or_json_literal)
| Some v -> st := Some (Int v))
else raise (Ast_untagged_variants.Error (loc, Duplicated_bs_as))
| _ -> ());
Expand Down
4 changes: 4 additions & 0 deletions compiler/frontend/bs_ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,10 @@ module E = struct
jsx_container_element ~loc ~attrs name (map_jsx_props sub props) ote
(map_jsx_children sub children)
closing_tag
| Pexp_template {tag; prefix; strings; expressions} ->
let tag = map_opt (sub.expr sub) tag in
let expressions = List.map (sub.expr sub) expressions in
template ~loc ~attrs {tag; prefix; strings; expressions}
end

module P = struct
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ module Exp = struct

let ident ?loc ?attrs a = mk ?loc ?attrs (Pexp_ident a)
let constant ?loc ?attrs a = mk ?loc ?attrs (Pexp_constant a)
let template ?loc ?attrs a = mk ?loc ?attrs (Pexp_template a)
let let_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_let (a, b, c))
let fun_ ?loc ?attrs ?(async = false) ~arity a b c d =
mk ?loc ?attrs
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ module Exp : sig

val ident : ?loc:loc -> ?attrs:attrs -> lid -> expression
val constant : ?loc:loc -> ?attrs:attrs -> constant -> expression
val template : ?loc:loc -> ?attrs:attrs -> template_literal -> expression
val let_ :
?loc:loc ->
?attrs:attrs ->
Expand Down
3 changes: 3 additions & 0 deletions compiler/ml/ast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ module E = struct
iter_loc sub lid;
sub.expr sub e
| Pexp_extension x -> sub.extension sub x
| Pexp_template {tag; expressions; _} ->
iter_opt (sub.expr sub) tag;
List.iter (sub.expr sub) expressions
| Pexp_await e -> sub.expr sub e
| Pexp_jsx_element (Jsx_fragment {jsx_fragment_children = children}) ->
iter_jsx_children sub children
Expand Down
4 changes: 4 additions & 0 deletions compiler/ml/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ module E = struct
| Pexp_open (ovf, lid, e) ->
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
| Pexp_template {tag; prefix; strings; expressions} ->
let tag = map_opt (sub.expr sub) tag in
let expressions = List.map (sub.expr sub) expressions in
template ~loc ~attrs {tag; prefix; strings; expressions}
| Pexp_await e -> await ~loc ~attrs (sub.expr sub e)
| Pexp_jsx_element
(Jsx_fragment
Expand Down
Loading
Loading