From 13ed5111e32c0d23c5c01d1ea9f8c4212f6ac7b2 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Fri, 28 Aug 2026 15:44:25 +0200 Subject: [PATCH] Prune unused vendored Flow parser modules Signed-off-by: Christoph Knittel --- compiler/flow_parser/README.md | 7 + compiler/flow_parser/collections/dune | 1 + compiler/flow_parser/collections/iMap.ml | 13 - compiler/flow_parser/collections/iSet.ml | 14 - compiler/flow_parser/collections/immQueue.ml | 54 - compiler/flow_parser/collections/immQueue.mli | 37 - compiler/flow_parser/collections/intKey.ml | 12 - .../flow_parser/collections/priorityQueue.ml | 101 - compiler/flow_parser/collections/sMap.ml | 13 - .../flow_parser/collections/union_find.ml | 90 - .../flow_parser/collections/wrappedMap.ml | 157 - .../flow_parser/collections/wrappedMap.mli | 10 - .../flow_parser/collections/wrappedMap_sig.ml | 55 - compiler/flow_parser/flow_sedlexing/dune | 3 +- compiler/flow_parser/flow_sedlexing_ppx/dune | 1 + compiler/flow_parser/parser/comment_utils.ml | 47 - compiler/flow_parser/parser/dune | 28 + .../flow_parser/parser/estree_translator.ml | 3101 ----------------- compiler/flow_parser/parser/jsdoc.ml | 308 -- compiler/flow_parser/parser/jsdoc.mli | 58 - compiler/flow_parser/parser/offset_utils.ml | 172 - compiler/flow_parser/parser/offset_utils.mli | 56 - compiler/flow_parser/parser/relativeLoc.ml | 35 - compiler/flow_parser/parser/relativeLoc.mli | 27 - .../flow_parser/parser/token_translator.ml | 66 - .../flow_parser/parser/translator_intf.ml | 26 - 26 files changed, 39 insertions(+), 4453 deletions(-) delete mode 100644 compiler/flow_parser/collections/iMap.ml delete mode 100644 compiler/flow_parser/collections/iSet.ml delete mode 100644 compiler/flow_parser/collections/immQueue.ml delete mode 100644 compiler/flow_parser/collections/immQueue.mli delete mode 100644 compiler/flow_parser/collections/intKey.ml delete mode 100644 compiler/flow_parser/collections/priorityQueue.ml delete mode 100644 compiler/flow_parser/collections/sMap.ml delete mode 100644 compiler/flow_parser/collections/union_find.ml delete mode 100644 compiler/flow_parser/collections/wrappedMap.ml delete mode 100644 compiler/flow_parser/collections/wrappedMap.mli delete mode 100644 compiler/flow_parser/collections/wrappedMap_sig.ml delete mode 100644 compiler/flow_parser/parser/comment_utils.ml delete mode 100644 compiler/flow_parser/parser/estree_translator.ml delete mode 100644 compiler/flow_parser/parser/jsdoc.ml delete mode 100644 compiler/flow_parser/parser/jsdoc.mli delete mode 100644 compiler/flow_parser/parser/offset_utils.ml delete mode 100644 compiler/flow_parser/parser/offset_utils.mli delete mode 100644 compiler/flow_parser/parser/relativeLoc.ml delete mode 100644 compiler/flow_parser/parser/relativeLoc.mli delete mode 100644 compiler/flow_parser/parser/token_translator.ml delete mode 100644 compiler/flow_parser/parser/translator_intf.ml diff --git a/compiler/flow_parser/README.md b/compiler/flow_parser/README.md index df4bf9c2ee..b45114cc91 100644 --- a/compiler/flow_parser/README.md +++ b/compiler/flow_parser/README.md @@ -24,6 +24,13 @@ call uses an empty-list comparison to retain OCaml 5.0 compatibility. The Sedlex PPX uses `Ast_helper.Exp.fun_` to generate single-argument functions with newer ppxlib versions. +Only modules in the dependency closure of ReScript's expression and program +parser entry points are retained. Upstream ESTree translation, JSDoc parsing, +location translation, token translation, and unused collection helpers are +omitted. The core statement, declaration, type, JSX, pattern, comment, and AST +modules remain because the parser connects them transitively and `%raw` +validates both complete JavaScript programs and individual expressions. + Vendored sources are excluded from the repository-wide OCamlformat check so that they remain comparable with their upstream versions. diff --git a/compiler/flow_parser/collections/dune b/compiler/flow_parser/collections/dune index d400009883..2cd0c8c91e 100644 --- a/compiler/flow_parser/collections/dune +++ b/compiler/flow_parser/collections/dune @@ -3,4 +3,5 @@ (library (name collections) (wrapped false) + (modules Flow_map Flow_set SSet StringKey) (libraries base)) diff --git a/compiler/flow_parser/collections/iMap.ml b/compiler/flow_parser/collections/iMap.ml deleted file mode 100644 index 93c66823eb..0000000000 --- a/compiler/flow_parser/collections/iMap.ml +++ /dev/null @@ -1,13 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -include WrappedMap.Make (IntKey) - -let pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit = - (fun pp_data -> make_pp IntKey.pp pp_data) - -let show pp_data x = Format.asprintf "%a" (pp pp_data) x diff --git a/compiler/flow_parser/collections/iSet.ml b/compiler/flow_parser/collections/iSet.ml deleted file mode 100644 index 471f51dda4..0000000000 --- a/compiler/flow_parser/collections/iSet.ml +++ /dev/null @@ -1,14 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -include Flow_set.Make (IntKey) - -let pp = make_pp IntKey.pp - -let show iset = Format.asprintf "%a" pp iset - -let to_string = show diff --git a/compiler/flow_parser/collections/immQueue.ml b/compiler/flow_parser/collections/immQueue.ml deleted file mode 100644 index 3f326a4585..0000000000 --- a/compiler/flow_parser/collections/immQueue.ml +++ /dev/null @@ -1,54 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -type 'a t = { - incoming: 'a list; - outgoing: 'a list; - length: int; -} - -let empty = { incoming = []; outgoing = []; length = 0 } - -let length t = t.length - -let is_empty t = length t = 0 - -let push t x = { t with incoming = x :: t.incoming; length = t.length + 1 } - -let prepare_for_read t = - match t.outgoing with - | [] -> { t with incoming = []; outgoing = List.rev t.incoming } - | _ -> t - -let pop t = - let t = prepare_for_read t in - match t.outgoing with - | [] -> (None, t) - | hd :: tl -> (Some hd, { t with outgoing = tl; length = t.length - 1 }) - -let peek t = - let t = prepare_for_read t in - match t.outgoing with - | [] -> (None, t) - | hd :: _ -> (Some hd, t) - -let exists t ~f = List.exists f t.outgoing || List.exists f t.incoming - -let iter t ~f = - List.iter f t.outgoing; - List.iter f (List.rev t.incoming) - -let from_list x = { incoming = []; outgoing = x; length = List.length x } - -let to_list x = x.outgoing @ List.rev x.incoming - -let concat t = - { - incoming = []; - outgoing = Base.List.concat_map ~f:to_list t; - length = List.map (fun u -> u.length) t |> List.fold_left ( + ) 0; - } diff --git a/compiler/flow_parser/collections/immQueue.mli b/compiler/flow_parser/collections/immQueue.mli deleted file mode 100644 index 67743a82b5..0000000000 --- a/compiler/flow_parser/collections/immQueue.mli +++ /dev/null @@ -1,37 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(* - * Immutable queue implementation. Modeled loosely after the mutable stdlib - * Queue. push, pop, etc. are amortized O(1). - *) - -type 'a t - -val empty : 'a t - -val push : 'a t -> 'a -> 'a t - -val pop : 'a t -> 'a option * 'a t - -val peek : 'a t -> 'a option * 'a t - -val is_empty : 'a t -> bool - -val length : 'a t -> int - -val exists : 'a t -> f:('a -> bool) -> bool - -val iter : 'a t -> f:('a -> unit) -> unit - -(* from_list: the head of the list is the first one to be popped *) -val from_list : 'a list -> 'a t - -(* to_list: the head of the list is the first one to be popped *) -val to_list : 'a t -> 'a list - -val concat : 'a t list -> 'a t diff --git a/compiler/flow_parser/collections/intKey.ml b/compiler/flow_parser/collections/intKey.ml deleted file mode 100644 index 4701376db4..0000000000 --- a/compiler/flow_parser/collections/intKey.ml +++ /dev/null @@ -1,12 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -type t = int - -let compare = ( - ) - -let pp = Format.pp_print_int diff --git a/compiler/flow_parser/collections/priorityQueue.ml b/compiler/flow_parser/collections/priorityQueue.ml deleted file mode 100644 index cc2b52866f..0000000000 --- a/compiler/flow_parser/collections/priorityQueue.ml +++ /dev/null @@ -1,101 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module Make (Ord : Set.OrderedType) = struct - type elt = Ord.t - - type t = { - mutable __queue: elt option array; - mutable size: int; - } - - let rec make_empty n = { __queue = Array.make n None; size = 0 } - - and is_empty t = t.size = 0 - - and pop t = - if t.size = 0 then failwith "Popping from an empty priority queue"; - let v = t.__queue.(0) in - t.size <- t.size - 1; - - if t.size <> 0 then ( - let last = t.__queue.(t.size) in - t.__queue.(t.size) <- None; - __bubble_down t.__queue t.size last 0 - ); - - match v with - | None -> failwith "Attempting to return a null value" - | Some v -> v - - and push t element = - if Array.length t.__queue = t.size then ( - let new_queue = Array.make ((Array.length t.__queue * 2) + 1) None in - Array.blit t.__queue 0 new_queue 0 (Array.length t.__queue); - t.__queue <- new_queue - ); - - t.__queue.(t.size) <- Some element; - __bubble_up t.__queue t.size; - t.size <- t.size + 1; - () - - and __swap arr i j = - let tmp = arr.(i) in - arr.(i) <- arr.(j); - arr.(j) <- tmp - - and __bubble_up arr index = - if index = 0 then (); - let pindex = (index - 1) / 2 in - match (arr.(index), arr.(pindex)) with - | (None, _) - | (_, None) -> - failwith "Unexpected null index found when calling __bubble_up" - | (Some e, Some p) -> - if Ord.compare e p < 0 then ( - __swap arr index pindex; - __bubble_up arr pindex - ) - - and __bubble_down arr size value index = - let right_child_index = (index * 2) + 2 in - let left_child_index = right_child_index - 1 in - if right_child_index < size then - match (arr.(right_child_index), arr.(left_child_index), value) with - | (None, _, _) - | (_, None, _) - | (_, _, None) -> - failwith "Unexpected null index found when calling __bubble_down" - | (Some r, Some l, Some v) -> - let (smaller_child, smaller_child_index) = - if Ord.compare r l < 0 then - (r, right_child_index) - else - (l, left_child_index) - in - if Ord.compare v smaller_child <= 0 then - arr.(index) <- value - else ( - arr.(index) <- arr.(smaller_child_index); - __bubble_down arr size value smaller_child_index - ) - else if left_child_index < size then - match (arr.(left_child_index), value) with - | (None, _) - | (_, None) -> - failwith "Unexpected null index found when calling __bubble_down" - | (Some l, Some v) -> - if Ord.compare v l <= 0 then - arr.(index) <- value - else ( - arr.(index) <- arr.(left_child_index); - arr.(left_child_index) <- value - ) - else - arr.(index) <- value -end diff --git a/compiler/flow_parser/collections/sMap.ml b/compiler/flow_parser/collections/sMap.ml deleted file mode 100644 index e179a06c9c..0000000000 --- a/compiler/flow_parser/collections/sMap.ml +++ /dev/null @@ -1,13 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -include WrappedMap.Make (StringKey) - -let pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit = - (fun pp_data -> make_pp StringKey.pp pp_data) - -let show pp_data x = Format.asprintf "%a" (pp pp_data) x diff --git a/compiler/flow_parser/collections/union_find.ml b/compiler/flow_parser/collections/union_find.ml deleted file mode 100644 index 2b4b466f51..0000000000 --- a/compiler/flow_parser/collections/union_find.ml +++ /dev/null @@ -1,90 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -type ident = int - -exception Tvar_not_found of ident - -module Make (Constraints : sig - type t -end) = -struct - (** A root structure carries the actual non-trivial state of a tvar, and - consists of: - - - rank, which is a quantity roughly corresponding to the longest chain of - gotos pointing to the tvar. It's an implementation detail of the unification - algorithm that simply has to do with efficiently finding the root of a tree. - We merge a tree with another tree by converting the root with the lower rank - to a goto node, and making it point to the root with the higher rank. See - http://en.wikipedia.org/wiki/Disjoint-set_data_structure for more details on - this data structure and supported operations. - - - constraints, which carry type information that narrows down the possible - solutions of the tvar (see below). *) - type root = { - mutable rank: int; - mutable constraints: Constraints.t; - } - - (** Type variables are unknowns, and we are ultimately interested in constraints - on their solutions for type inference. - - Type variables form nodes in a "union-find" forest: each tree denotes a set - of type variables that are considered by the type system to be equivalent. - - There are two kinds of nodes: Goto nodes and Root nodes. - - - All Goto nodes of a tree point, directly or indirectly, to the Root node - of the tree. - - A Root node holds the actual non-trivial state of a tvar, represented by a - root structure (see below). *) - type node_ = - | Goto of { mutable parent: ident } - | Root of root - - type node = node_ ref - - type graph = node IMap.t - - let create_root constraints = ref (Root { rank = 0; constraints }) - - let create_goto parent = ref (Goto { parent }) - - (* Find the root of a type variable, potentially traversing a chain of type - variables, while short-circuiting all the type variables in the chain to the - root during traversal to speed up future traversals. *) - let rec find_root graph id = - match IMap.find_opt id graph with - | None -> raise (Tvar_not_found id) - | Some node -> - (match !node with - | Root root -> (id, node, root) - | Goto goto -> - let ((root_id, _, _) as root) = find_root graph goto.parent in - goto.parent <- root_id; - root) - - let find_root_id graph id = - let (root_id, _, _) = find_root graph id in - root_id - - (* Find the constraints of a type variable in the graph. - - Recall that type variables are either roots or goto nodes. (See - Constraint for details.) If the type variable is a root, the - constraints are stored with the type variable. Otherwise, the type variable - is a goto node, and it points to another type variable: a linked list of such - type variables must be traversed until a root is reached. *) - let find_constraints graph id = - let (root_id, _, root) = find_root graph id in - (root_id, root.constraints) - - let find_graph graph id = - let (_, constraints) = find_constraints graph id in - constraints -end diff --git a/compiler/flow_parser/collections/wrappedMap.ml b/compiler/flow_parser/collections/wrappedMap.ml deleted file mode 100644 index 777ed8ad48..0000000000 --- a/compiler/flow_parser/collections/wrappedMap.ml +++ /dev/null @@ -1,157 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module type S = WrappedMap_sig.S - -module Make (Ord : Map.OrderedType) : S with type key = Ord.t = struct - include Flow_map.Make (Ord) - - let union ?combine x y = - let combine = - match combine with - | None -> (fun _ fst _ -> Some fst) - | Some f -> f - in - union combine x y - - let rec fold_left_env env l ~init ~f = - match l with - | [] -> (env, init) - | x :: xs -> - let (env, init) = f env init x in - fold_left_env env xs ~init ~f - - let merge_env env s1 s2 ~combine = - let (env, map) = - fold_left_env - env - ~init:empty - ~f:(fun env map (key, v2) -> - let v1opt = find_opt key s1 in - let (env, vopt) = combine env key v1opt (Some v2) in - let map = - match vopt with - | None -> map - | Some v -> add key v map - in - (env, map)) - (bindings s2) - in - fold_left_env - env - ~init:map - ~f:(fun env map (key, v1) -> - let v2opt = find_opt key s2 in - match v2opt with - | None -> - let (env, vopt) = combine env key (Some v1) None in - let map = - match vopt with - | None -> map - | Some v -> add key v map - in - (env, map) - | Some _ -> (env, map)) - (bindings s1) - - let union_env env s1 s2 ~combine = - let f env key o1 o2 = - match (o1, o2) with - | (None, None) -> (env, None) - | (Some v, None) - | (None, Some v) -> - (env, Some v) - | (Some v1, Some v2) -> combine env key v1 v2 - in - merge_env env s1 s2 ~combine:f - - let values m = fold (fun _ v acc -> v :: acc) m [] - - let fold_env env f m init = fold (fun key v (env, acc) -> f env key v acc) m (env, init) - - let elements m = fold (fun k v acc -> (k, v) :: acc) m [] - - let map_env f env m = - fold_env - env - (fun env key v map -> - let (env, v) = f env key v in - (env, add key v map)) - m - empty - - let of_list elts = - List.fold_left - begin - (fun acc (key, value) -> add key value acc) - end - empty - elts - - let of_function domain f = - List.fold_left - begin - (fun acc key -> add key (f key) acc) - end - empty - domain - - let add ?combine key new_value map = - match combine with - | None -> add key new_value map - | Some combine -> - adjust - key - (fun opt -> - match opt with - | None -> new_value - | Some old_value -> combine old_value new_value) - map - - let ident_map f coll = - let changed = ref false in - let new_map = - map - (fun x -> - let new_item = f x in - if new_item != x then changed := true; - new_item) - coll - in - if !changed then - new_map - else - coll - - let for_all2 ~f m1 m2 = - let key_bool_map = merge (fun k v1opt v2opt -> Some (f k v1opt v2opt)) m1 m2 in - for_all (fun _k b -> b) key_bool_map - - let make_pp pp_key pp_data fmt x = - Format.fprintf fmt "@[{"; - let bindings = bindings x in - (match bindings with - | [] -> () - | _ -> Format.fprintf fmt " "); - ignore - (List.fold_left - (fun sep (key, data) -> - if sep then Format.fprintf fmt ";@ "; - Format.fprintf fmt "@["; - pp_key fmt key; - Format.fprintf fmt " ->@ "; - pp_data fmt data; - Format.fprintf fmt "@]"; - true) - false - bindings - ); - (match bindings with - | [] -> () - | _ -> Format.fprintf fmt " "); - Format.fprintf fmt "}@]" -end diff --git a/compiler/flow_parser/collections/wrappedMap.mli b/compiler/flow_parser/collections/wrappedMap.mli deleted file mode 100644 index cc0e9bad66..0000000000 --- a/compiler/flow_parser/collections/wrappedMap.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module type S = WrappedMap_sig.S - -module Make (Ord : Map.OrderedType) : S with type key = Ord.t diff --git a/compiler/flow_parser/collections/wrappedMap_sig.ml b/compiler/flow_parser/collections/wrappedMap_sig.ml deleted file mode 100644 index d8abefca90..0000000000 --- a/compiler/flow_parser/collections/wrappedMap_sig.ml +++ /dev/null @@ -1,55 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module type S = sig - include Flow_map.S - - val add : ?combine:('a -> 'a -> 'a) -> key -> 'a -> 'a t -> 'a t - - val union : ?combine:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t - - val union_env : - 'a -> 'b t -> 'b t -> combine:('a -> key -> 'b -> 'b -> 'a * 'b option) -> 'a * 'b t - - val merge_env : - 'a -> - 'b t -> - 'c t -> - combine:('a -> key -> 'b option -> 'c option -> 'a * 'd option) -> - 'a * 'd t - - val keys : 'a t -> key list - - val ordered_keys : 'a t -> key list - - val values : 'a t -> 'a list - - val fold_env : 'a -> ('a -> key -> 'b -> 'c -> 'a * 'c) -> 'b t -> 'c -> 'a * 'c - - val map_env : ('c -> key -> 'a -> 'c * 'b) -> 'c -> 'a t -> 'c * 'b t - - val of_list : (key * 'a) list -> 'a t - - val of_function : key list -> (key -> 'a) -> 'a t - - val elements : 'a t -> (key * 'a) list - - val ident_map : ('a -> 'a) -> 'a t -> 'a t - - val ident_map_key : ?combine:('a -> 'a -> 'a) -> (key -> key) -> 'a t -> 'a t - - val for_all2 : f:(key -> 'a option -> 'b option -> bool) -> 'a t -> 'b t -> bool - - val make_pp : - (Format.formatter -> key -> unit) -> - (Format.formatter -> 'a -> unit) -> - Format.formatter -> - 'a t -> - unit - - val of_increasing_iterator_unchecked : (unit -> key * 'a) -> int -> 'a t -end diff --git a/compiler/flow_parser/flow_sedlexing/dune b/compiler/flow_parser/flow_sedlexing/dune index 00afcea04a..ddb928c04c 100644 --- a/compiler/flow_parser/flow_sedlexing/dune +++ b/compiler/flow_parser/flow_sedlexing/dune @@ -1,3 +1,4 @@ (library (name flow_sedlexing) - (wrapped false)) + (wrapped false) + (modules Flow_sedlexing)) diff --git a/compiler/flow_parser/flow_sedlexing_ppx/dune b/compiler/flow_parser/flow_sedlexing_ppx/dune index 8c8933bf8a..03c4007c20 100644 --- a/compiler/flow_parser/flow_sedlexing_ppx/dune +++ b/compiler/flow_parser/flow_sedlexing_ppx/dune @@ -1,6 +1,7 @@ (library (name flow_sedlexing_ppx) (kind ppx_rewriter) + (modules Flow_sedlex Ppx_sedlex Sedlex_cset) (libraries ppxlib flow_sedlexing) (ppx_runtime_libraries flow_sedlexing) (preprocess diff --git a/compiler/flow_parser/parser/comment_utils.ml b/compiler/flow_parser/parser/comment_utils.ml deleted file mode 100644 index 738f230ef6..0000000000 --- a/compiler/flow_parser/parser/comment_utils.ml +++ /dev/null @@ -1,47 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(* returns all of the comments that start before `loc`, and discards the rest *) -let comments_before_loc loc comments = - let rec helper loc acc = function - | ((c_loc, _) as comment) :: rest when Loc.compare c_loc loc < 0 -> - helper loc (comment :: acc) rest - | _ -> List.rev acc - in - helper loc [] comments - -class ['loc] inline_comments_stripper = - object - inherit ['loc] Flow_ast_mapper.mapper - - method! syntax_opt - : 'internal. - ('loc, 'internal) Flow_ast.Syntax.t option -> ('loc, 'internal) Flow_ast.Syntax.t option = - (fun _ -> None) - end - -let strip_inlined_comments p = (new inline_comments_stripper)#program p - -let strip_inlined_comments_expression expr = (new inline_comments_stripper)#expression expr - -let strip_comments_list - ?(preserve_docblock = false) ((loc, program) : ('loc, 'loc) Flow_ast.Program.t) = - let { Flow_ast.Program.all_comments; _ } = program in - ( loc, - { - program with - Flow_ast.Program.all_comments = - ( if preserve_docblock then - comments_before_loc loc all_comments - else - [] - ); - } - ) - -let strip_all_comments ?(preserve_docblock = false) p = - p |> strip_comments_list ~preserve_docblock |> strip_inlined_comments diff --git a/compiler/flow_parser/parser/dune b/compiler/flow_parser/parser/dune index d3851f347d..4b03556b33 100644 --- a/compiler/flow_parser/parser/dune +++ b/compiler/flow_parser/parser/dune @@ -1,6 +1,34 @@ (library (name flow_parser) (wrapped false) + (modules + Comment_attachment + Declaration_parser + Enum_parser + Expression_parser + File_key + Flow_ast + Flow_ast_mapper + Flow_ast_utils + Flow_lexer + Js_id + Js_id_unicode + Jsx_parser + Lex_env + Lex_result + Loc + Match_pattern_parser + Object_parser + Parse_error + Parse_error_utils + Parser_common + Parser_env + Parser_flow + Pattern_cover + Pattern_parser + Statement_parser + Token + Type_parser) (libraries base wtf8 flow_sedlexing collections) (preprocess (pps ppx_gen_rec ppx_deriving.std flow_sedlexing_ppx))) diff --git a/compiler/flow_parser/parser/estree_translator.ml b/compiler/flow_parser/parser/estree_translator.ml deleted file mode 100644 index 6cd5e0c4ae..0000000000 --- a/compiler/flow_parser/parser/estree_translator.ml +++ /dev/null @@ -1,3101 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module Ast = Flow_ast - -module type Config = sig - val include_locs : bool - - val include_filename : bool -end - -module Translate (Impl : Translator_intf.S) (Config : Config) : sig - type t - - val program : Offset_utils.t option -> (Loc.t, Loc.t) Ast.Program.t -> t - - val expression : Offset_utils.t option -> (Loc.t, Loc.t) Ast.Expression.t -> t - - val errors : (Loc.t * Parse_error.t) list -> t -end -with type t = Impl.t = struct - type t = Impl.t - - type functions = { - program: (Loc.t, Loc.t) Ast.Program.t -> t; - expression: (Loc.t, Loc.t) Ast.Expression.t -> t; - } - - open Ast - open Impl - - let array_of_list fn list = array (List.rev_map fn list |> List.rev) - - let option f = function - | Some v -> f v - | None -> null - - let hint f = function - | Ast.Type.Available v -> f v - | Ast.Type.Missing _ -> null - - let position p = obj [("line", int p.Loc.line); ("column", int p.Loc.column)] - - let loc location = - let source = - if Config.include_filename then - match Loc.source location with - | Some file_key -> string (File_key.suffix file_key) - | None -> null - else - null - in - obj - [ - ("source", source); - ("start", position location.Loc.start); - ("end", position location.Loc._end); - ] - - let errors l = - let error (location, e) = - obj [("loc", loc location); ("message", string (Parse_error.PP.error e))] - in - array_of_list error l - - let format_internal_comments = function - | None -> None - | Some { Ast.Syntax.leading; trailing; internal } -> - Flow_ast_utils.mk_comments_opt ~leading ~trailing:(internal @ trailing) () - - (* This is basically a lightweight class. We close over some state and then return more than one - * function that can access that state. We don't need most class features though, so let's avoid - * the dynamic dispatch and the disruptive change. *) - let make_functions offset_table = - let range offset_table location = - Loc.( - array - [ - int (Offset_utils.offset offset_table location.start); - int (Offset_utils.offset offset_table location._end); - ] - ) - in - (* Optional-chain rewrite: mirror upstream Hermes' mapChainExpression by - emitting `OptionalMember`/`OptionalCall` AST nodes as - `MemberExpression`/`CallExpression` with `optional` flags, wrapped in a - single `ChainExpression` at the chain root. Plain `Member`/`Call` inside - an optional chain mark a parenthesis boundary: emit with `optional: - false` and reset the chain state for their children so an inner optional - access starts a new chain. The chain state is threaded explicitly as - the [in_optional_chain] argument of [expression] (and propagated through - [call_node_properties] / [member_node_properties]). *) - let rec node _type location ?comments props = - let locs = - if Config.include_locs then - (* sorted backwards due to the rev_append below *) - let range = - match offset_table with - | Some table -> [("range", range table location)] - | None -> [] - in - range @ [("loc", loc location)] - else - [] - in - let comments = - let open Ast.Syntax in - match comments with - | Some c -> - (match c with - | { leading = _ :: _ as l; trailing = _ :: _ as t; _ } -> - [("leadingComments", comment_list l); ("trailingComments", comment_list t)] - | { leading = _ :: _ as l; trailing = []; _ } -> [("leadingComments", comment_list l)] - | { leading = []; trailing = _ :: _ as t; _ } -> [("trailingComments", comment_list t)] - | _ -> []) - | None -> [] - in - let prefix = locs @ comments @ [("type", string _type)] in - obj (List.rev_append prefix props) - and program (loc, { Ast.Program.statements; interpreter; comments; all_comments }) = - let body = statement_list statements in - let props = [("body", body); ("comments", comment_list all_comments)] in - let props = - match interpreter with - | Some (loc, value) -> - let directive = node "InterpreterDirective" loc [("value", string value)] in - props @ [("interpreter", directive)] - | None -> props - in - node ?comments "Program" loc props - and statement_list statements = array_of_list statement statements - and statement = - let open Statement in - function - | (loc, Empty { Empty.comments }) -> node ?comments "EmptyStatement" loc [] - | (loc, Block b) -> block (loc, b) - | (loc, Expression { Expression.expression = expr; directive; comments }) -> - node - ?comments - "ExpressionStatement" - loc - [("expression", expression expr); ("directive", option string directive)] - | (loc, If { If.test; consequent; alternate; comments }) -> - let alternate = - match alternate with - | None -> null - | Some (_, { If.Alternate.body; comments = alternate_comments }) -> - statement (Comment_attachment.statement_add_comments body alternate_comments) - in - node - ?comments - "IfStatement" - loc - [ - ("test", expression test); ("consequent", statement consequent); ("alternate", alternate); - ] - | (loc, Labeled { Labeled.label; body; comments }) -> - node - ?comments - "LabeledStatement" - loc - [("label", identifier label); ("body", statement body)] - | (loc, Break { Break.label; comments }) -> - node ?comments "BreakStatement" loc [("label", option identifier label)] - | (loc, Continue { Continue.label; comments }) -> - node ?comments "ContinueStatement" loc [("label", option identifier label)] - | (loc, With { With._object; body; comments }) -> - node - ?comments - "WithStatement" - loc - [("object", expression _object); ("body", statement body)] - | (loc, TypeAlias alias) -> type_alias (loc, alias) - | (loc, OpaqueType opaque_t) -> opaque_type ~declare:false (loc, opaque_t) - | (loc, Match { Match.arg; cases; match_keyword_loc = _; comments }) -> - node - ?comments - "MatchStatement" - loc - [("argument", expression arg); ("cases", array_of_list match_statement_case cases)] - | (loc, Switch { Switch.discriminant; cases; comments; exhaustive_out = _ }) -> - node - ?comments - "SwitchStatement" - loc - [("discriminant", expression discriminant); ("cases", array_of_list case cases)] - | ( loc, - RecordDeclaration - { RecordDeclaration.id; tparams; implements; body; comments; invalid_syntax = _ } - ) -> - let record_property - ( loc, - { RecordDeclaration.Property.key; annot; default_value; comments; invalid_syntax = _ } - ) = - let (key, computed, comments) = property_key ~comments key in - if computed then failwith "Records cannot have computed keys"; - node - ?comments - "RecordDeclarationProperty" - loc - [ - ("key", key); - ("typeAnnotation", type_annotation annot); - ("defaultValue", option expression default_value); - ] - in - let record_static_property - ( loc, - { RecordDeclaration.StaticProperty.key; annot; value; comments; invalid_syntax = _ } - ) = - let (key, computed, comments) = property_key ~comments key in - if computed then failwith "Records cannot have computed keys"; - node - ?comments - "RecordDeclarationStaticProperty" - loc - [("key", key); ("typeAnnotation", type_annotation annot); ("value", expression value)] - in - - let record_element element = - let open RecordDeclaration.Body in - match element with - | Property prop -> record_property prop - | StaticProperty prop -> record_static_property prop - | Method meth -> class_method meth - in - let record_body (loc, { RecordDeclaration.Body.body; comments }) = - node - ?comments - "RecordDeclarationBody" - loc - [("elements", array_of_list record_element body)] - in - let record_implements (loc, { Class.Implements.Interface.id; targs }) = - let id = - match id with - | Type.Generic.Identifier.Unqualified id -> identifier id - | Type.Generic.Identifier.Qualified q -> generic_type_qualified_identifier q - | Type.Generic.Identifier.ImportTypeAnnot it -> import_type it - in - node - "RecordDeclarationImplements" - loc - [("id", id); ("typeArguments", option type_args targs)] - in - let implements = - match implements with - | Some (_, { Class.Implements.interfaces; comments = _ }) -> - array_of_list record_implements interfaces - | None -> array [] - in - node - ?comments - "RecordDeclaration" - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("implements", implements); - ("body", record_body body); - ] - | (loc, Return { Return.argument; comments; return_out = _ }) -> - node ?comments "ReturnStatement" loc [("argument", option expression argument)] - | (loc, Throw { Throw.argument; comments }) -> - node ?comments "ThrowStatement" loc [("argument", expression argument)] - | (loc, Try { Try.block = block_; handler; finalizer; comments }) -> - node - ?comments - "TryStatement" - loc - [ - ("block", block block_); - ("handler", option catch handler); - ("finalizer", option block finalizer); - ] - | (loc, While { While.test; body; comments }) -> - node ?comments "WhileStatement" loc [("test", expression test); ("body", statement body)] - | (loc, DoWhile { DoWhile.body; test; comments }) -> - node ?comments "DoWhileStatement" loc [("body", statement body); ("test", expression test)] - | (loc, For { For.init = init_; test; update; body; comments }) -> - let init = function - | For.InitDeclaration init -> variable_declaration init - | For.InitExpression expr -> expression expr - in - node - ?comments - "ForStatement" - loc - [ - ("init", option init init_); - ("test", option expression test); - ("update", option expression update); - ("body", statement body); - ] - | (loc, ForIn { ForIn.left; right; body; each; comments }) -> - let left = - match left with - | ForIn.LeftDeclaration left -> variable_declaration left - | ForIn.LeftPattern left -> pattern left - in - node - ?comments - "ForInStatement" - loc - [ - ("left", left); - ("right", expression right); - ("body", statement body); - ("each", bool each); - ] - | (loc, ForOf { ForOf.await; left; right; body; comments }) -> - let left = - match left with - | ForOf.LeftDeclaration left -> variable_declaration left - | ForOf.LeftPattern left -> pattern left - in - node - ?comments - "ForOfStatement" - loc - [ - ("left", left); - ("right", expression right); - ("body", statement body); - ("await", bool await); - ] - | (loc, EnumDeclaration enum) -> enum_declaration (loc, enum) - | (loc, Debugger { Debugger.comments }) -> node ?comments "DebuggerStatement" loc [] - | (loc, ClassDeclaration c) -> class_declaration (loc, c) - | (loc, InterfaceDeclaration i) -> interface_declaration (loc, i) - | (loc, VariableDeclaration var) -> variable_declaration (loc, var) - | (loc, FunctionDeclaration fn) -> function_declaration (loc, fn) - | (loc, ComponentDeclaration c) -> component_declaration (loc, c) - | (loc, DeclareVariable d) -> declare_variable (loc, d) - | (loc, DeclareFunction d) -> declare_function (loc, d) - | (loc, DeclareClass d) -> declare_class (loc, d) - | (loc, DeclareComponent d) -> declare_component (loc, d) - | (loc, DeclareEnum enum) -> declare_enum (loc, enum) - | (loc, DeclareInterface i) -> declare_interface (loc, i) - | (loc, DeclareTypeAlias a) -> declare_type_alias (loc, a) - | (loc, DeclareOpaqueType t) -> opaque_type ~declare:true (loc, t) - | (loc, DeclareModule { DeclareModule.id; body; comments }) -> - let id = - match id with - | DeclareModule.Literal lit -> string_literal lit - | DeclareModule.Identifier id -> identifier id - in - node ?comments "DeclareModule" loc [("id", id); ("body", block body)] - | (loc, DeclareNamespace ns) -> declare_namespace (loc, ns) - | ( loc, - DeclareExportDeclaration - { DeclareExportDeclaration.specifiers; declaration; default; source; comments } - ) -> begin - match specifiers with - | Some (ExportNamedDeclaration.ExportBatchSpecifier (_, None)) -> - node - ?comments - "DeclareExportAllDeclaration" - loc - [("source", option string_literal source)] - | _ -> - let declaration = - match declaration with - | Some (DeclareExportDeclaration.Variable v) -> declare_variable v - | Some (DeclareExportDeclaration.Function f) -> declare_function f - | Some (DeclareExportDeclaration.Class c) -> declare_class c - | Some (DeclareExportDeclaration.Component c) -> declare_component c - | Some (DeclareExportDeclaration.DefaultType t) -> _type t - | Some (DeclareExportDeclaration.NamedType t) -> type_alias t - | Some (DeclareExportDeclaration.NamedOpaqueType t) -> opaque_type ~declare:true t - | Some (DeclareExportDeclaration.Interface i) -> interface_declaration i - | Some (DeclareExportDeclaration.Enum enum) -> declare_enum enum - | Some (DeclareExportDeclaration.Namespace n) -> declare_namespace n - | None -> null - in - node - ?comments - "DeclareExportDeclaration" - loc - [ - ( "default", - bool - (match default with - | Some _ -> true - | None -> false) - ); - ("declaration", declaration); - ("specifiers", export_specifiers specifiers); - ("source", option string_literal source); - ] - end - | (loc, DeclareModuleExports { DeclareModuleExports.annot; comments }) -> - node ?comments "DeclareModuleExports" loc [("typeAnnotation", type_annotation annot)] - | ( loc, - ExportNamedDeclaration - { ExportNamedDeclaration.specifiers; declaration; source; export_kind; comments } - ) -> begin - match specifiers with - | Some (ExportNamedDeclaration.ExportBatchSpecifier (_, exported)) -> - node - ?comments - "ExportAllDeclaration" - loc - [ - ("source", option string_literal source); - ("exported", option identifier exported); - ("exportKind", string (string_of_export_kind export_kind)); - ] - | _ -> - node - ?comments - "ExportNamedDeclaration" - loc - [ - ("declaration", option statement declaration); - ("specifiers", export_specifiers specifiers); - ("source", option string_literal source); - ("exportKind", string (string_of_export_kind export_kind)); - ] - end - | ( loc, - ExportDefaultDeclaration - { - ExportDefaultDeclaration.declaration; - default = _ (* TODO: confirm we shouldn't use this *); - comments; - } - ) -> - let declaration = - match declaration with - | ExportDefaultDeclaration.Declaration stmt -> statement stmt - | ExportDefaultDeclaration.Expression expr -> expression expr - in - node - ?comments - "ExportDefaultDeclaration" - loc - [ - ("declaration", declaration); - ("exportKind", string (string_of_export_kind Statement.ExportValue)); - ] - | (loc, ExportAssignment { ExportAssignment.rhs; comments }) -> - (match rhs with - | ExportAssignment.Expression expr -> - node ?comments "ExportAssignment" loc [("expression", expression expr)] - | ExportAssignment.DeclareFunction (fn_loc, decl) -> - node ?comments "ExportAssignment" loc [("expression", declare_function (fn_loc, decl))]) - | (loc, NamespaceExportDeclaration { NamespaceExportDeclaration.id; comments }) -> - node ?comments "NamespaceExportDeclaration" loc [("id", identifier id)] - | ( loc, - ImportDeclaration - { ImportDeclaration.specifiers; default; import_kind; source; attributes; comments } - ) -> - let specifiers = - match specifiers with - | Some (ImportDeclaration.ImportNamedSpecifiers specifiers) -> - List.map - (fun { ImportDeclaration.local; remote; remote_name_def_loc = _; kind; kind_loc } -> - import_named_specifier local remote kind kind_loc) - specifiers - | Some (ImportDeclaration.ImportNamespaceSpecifier id) -> [import_namespace_specifier id] - | None -> [] - in - let specifiers = - match default with - | Some default -> import_default_specifier default :: specifiers - | None -> specifiers - in - let import_kind = - match import_kind with - | ImportDeclaration.ImportType -> "type" - | ImportDeclaration.ImportTypeof -> "typeof" - | ImportDeclaration.ImportValue -> "value" - in - let attributes_json = - match attributes with - | None -> [] - | Some (_, attrs) -> [("attributes", array (List.map import_attribute attrs))] - in - node - ?comments - "ImportDeclaration" - loc - ([ - ("specifiers", array specifiers); - ("source", string_literal source); - ("importKind", string import_kind); - ] - @ attributes_json - ) - | ( loc, - ImportEqualsDeclaration - { - ImportEqualsDeclaration.id = ident; - module_reference; - import_kind; - is_export; - comments; - } - ) -> - let module_reference_json = - let open ImportEqualsDeclaration in - match module_reference with - | ExternalModuleReference (annot_loc, lit) -> - node - "ExternalModuleReference" - annot_loc - [("expression", string_literal (annot_loc, lit))] - | Identifier git -> - let open Type.Generic.Identifier in - let generic_id = function - | Unqualified id -> identifier id - | Qualified q -> generic_type_qualified_identifier q - | ImportTypeAnnot it -> import_type it - in - generic_id git - in - let import_kind_str = - match import_kind with - | ImportDeclaration.ImportType -> "type" - | ImportDeclaration.ImportTypeof -> "typeof" - | ImportDeclaration.ImportValue -> "value" - in - node - ?comments - "ImportEqualsDeclaration" - loc - [ - ("id", identifier ident); - ("moduleReference", module_reference_json); - ("importKind", string import_kind_str); - ("isExport", bool is_export); - ] - and expression ?(in_optional_chain = false) expr = - let open Expression in - match expr with - | (loc, This { This.comments }) -> node ?comments "ThisExpression" loc [] - | (loc, Super { Super.comments }) -> node ?comments "Super" loc [] - | (loc, Array { Array.elements; trailing_comma; comments }) -> - node - ?comments:(format_internal_comments comments) - "ArrayExpression" - loc - [ - ("elements", array_of_list array_element elements); - ("trailingComma", bool trailing_comma); - ] - | (loc, Object { Object.properties; comments }) -> - node - ?comments:(format_internal_comments comments) - "ObjectExpression" - loc - [("properties", array_of_list object_property properties)] - | (loc, Function _function) -> function_expression (loc, _function) - | ( loc, - ArrowFunction - { - Function.params = (_, { Function.Params.comments = params_comments; _ }) as params; - async; - effect_ = _; - predicate = predicate_; - tparams; - return; - body; - comments = func_comments; - sig_loc = _; - (* TODO: arrows shouldn't have these: *) - id = _; - generator = _; - } - ) -> - let (body, expression) = - match body with - | Function.BodyBlock b -> (block b, false) - | Function.BodyExpression expr -> (expression expr, true) - in - let comments = - Flow_ast_utils.merge_comments - ~outer:func_comments - ~inner:(format_internal_comments params_comments) - in - node - ?comments - "ArrowFunctionExpression" - loc - [ - ("id", null); - ("params", function_params params); - ("body", body); - ("async", bool async); - ("generator", bool false); - ("predicate", option predicate predicate_); - ("expression", bool expression); - ("returnType", function_return_type return); - ("typeParameters", option type_parameter_declaration tparams); - ] - | (loc, Sequence { Sequence.expressions; comments }) -> - node - ?comments - "SequenceExpression" - loc - [("expressions", array_of_list expression expressions)] - | (loc, Unary { Unary.operator; argument; comments }) -> - Unary.( - (match operator with - | Await -> node ?comments "AwaitExpression" loc [("argument", expression argument)] - | Nonnull -> - node - ?comments - "NonNullExpression" - loc - [("argument", expression argument); ("chain", bool false)] - | _ -> - let operator = - match operator with - | Minus -> "-" - | Plus -> "+" - | Not -> "!" - | BitNot -> "~" - | Typeof -> "typeof" - | Void -> "void" - | Delete -> "delete" - | Nonnull - | Await -> - failwith "matched above" - in - node - ?comments - "UnaryExpression" - loc - [ - ("operator", string operator); - ("prefix", bool true); - ("argument", expression argument); - ]) - ) - | (loc, Binary { Binary.left; operator; right; comments }) -> - node - ?comments - "BinaryExpression" - loc - [ - ("operator", string (Flow_ast_utils.string_of_binary_operator operator)); - ("left", expression left); - ("right", expression right); - ] - | (loc, TypeCast { TypeCast.expression = expr; annot; comments }) -> - node - ?comments - "TypeCastExpression" - loc - [("expression", expression expr); ("typeAnnotation", type_annotation annot)] - | (loc, AsExpression { AsExpression.expression = expr; annot = (_, annot); comments }) -> - node - ?comments - "AsExpression" - loc - [("expression", expression expr); ("typeAnnotation", _type annot)] - | (loc, TSSatisfies { TSSatisfies.expression = expr; annot = (_, annot); comments }) -> - node - ?comments - "SatisfiesExpression" - loc - [("expression", expression expr); ("typeAnnotation", _type annot)] - | (loc, AsConstExpression { AsConstExpression.expression = expr; comments }) -> - node ?comments "AsConstExpression" loc [("expression", expression expr)] - | (loc, Assignment { Assignment.left; operator; right; comments }) -> - let operator = - match operator with - | None -> "=" - | Some op -> Flow_ast_utils.string_of_assignment_operator op - in - node - ?comments - "AssignmentExpression" - loc - [("operator", string operator); ("left", pattern left); ("right", expression right)] - | (loc, Update { Update.operator; argument; prefix; comments }) -> - let operator = - match operator with - | Update.Increment -> "++" - | Update.Decrement -> "--" - in - node - ?comments - "UpdateExpression" - loc - [ - ("operator", string operator); ("argument", expression argument); ("prefix", bool prefix); - ] - | (loc, Logical { Logical.left; operator; right; comments }) -> - let operator = - match operator with - | Logical.Or -> "||" - | Logical.And -> "&&" - | Logical.NullishCoalesce -> "??" - in - node - ?comments - "LogicalExpression" - loc - [("operator", string operator); ("left", expression left); ("right", expression right)] - | (loc, Conditional { Conditional.test; consequent; alternate; comments }) -> - node - ?comments - "ConditionalExpression" - loc - [ - ("test", expression test); - ("consequent", expression consequent); - ("alternate", expression alternate); - ] - | (loc, New { New.callee; targs; arguments; comments }) -> - let (arguments, comments) = - match arguments with - | Some ((_, { ArgList.comments = args_comments; _ }) as arguments) -> - ( arg_list ~in_optional_chain:false arguments, - Flow_ast_utils.merge_comments - ~inner:(format_internal_comments args_comments) - ~outer:comments - ) - | None -> (array [], comments) - in - node - ?comments - "NewExpression" - loc - [ - ("callee", expression callee); - ("typeArguments", option call_type_args targs); - ("arguments", arguments); - ] - | ( loc, - Call - ({ Call.comments; arguments = (_, { ArgList.comments = args_comments; _ }); _ } as call) - ) -> - let comments = - Flow_ast_utils.merge_comments - ~inner:(format_internal_comments args_comments) - ~outer:comments - in - (* Plain Call inside an optional chain marks a parenthesis boundary: - reset chain state for children so an inner optional access starts a - new chain. Otherwise, normal call. Either way emit CallExpression - with optional=false. *) - node - ?comments - "CallExpression" - loc - (call_node_properties ~in_optional_chain:false call @ [("optional", bool false)]) - | ( loc, - OptionalCall - { - OptionalCall.call = - { Call.comments; arguments = (_, { ArgList.comments = args_comments; _ }); _ } as - call; - optional; - filtered_out = _; - } - ) -> - let comments = - Flow_ast_utils.merge_comments - ~inner:(format_internal_comments args_comments) - ~outer:comments - in - (match optional with - | OptionalCall.AssertNonnull -> - (* AssertNonnull (`expr!()`): emit CallExpression with - optional=false and the callee wrapped in NonNullExpression - (chain: true). Not part of the optional-chain rewrite, so - no ChainExpression wrap. *) - let wrap_callee callee = - node "NonNullExpression" loc [("argument", callee); ("chain", bool true)] - in - node - ?comments - "CallExpression" - loc - (call_node_properties ~in_optional_chain:false ~wrap_callee call - @ [("optional", bool false)] - ) - | OptionalCall.Optional - | OptionalCall.NonOptional -> - let optional_value = - match optional with - | OptionalCall.Optional -> bool true - | _ -> bool false - in - let emit_inner () = - node - ?comments - "CallExpression" - loc - (call_node_properties ~in_optional_chain:true call @ [("optional", optional_value)]) - in - if in_optional_chain then - emit_inner () - else - node "ChainExpression" loc [("expression", emit_inner ())]) - | (loc, Member ({ Member.comments; _ } as member)) -> - (* Plain Member inside an optional chain marks a parenthesis boundary; - reset chain state for children so an inner optional access starts a - new chain. Either way emit MemberExpression with optional=false. *) - node - ?comments - "MemberExpression" - loc - (member_node_properties ~in_optional_chain:false member @ [("optional", bool false)]) - | ( loc, - OptionalMember - { OptionalMember.member = { Member.comments; _ } as member; optional; filtered_out = _ } - ) -> - (match optional with - | OptionalMember.AssertNonnull -> - let wrap_receiver receiver = - node "NonNullExpression" loc [("argument", receiver); ("chain", bool true)] - in - node - ?comments - "MemberExpression" - loc - (member_node_properties ~in_optional_chain:false ~wrap_receiver member - @ [("optional", bool false)] - ) - | OptionalMember.Optional - | OptionalMember.NonOptional -> - let optional_value = - match optional with - | OptionalMember.Optional -> bool true - | _ -> bool false - in - let emit_inner () = - node - ?comments - "MemberExpression" - loc - (member_node_properties ~in_optional_chain:true member - @ [("optional", optional_value)] - ) - in - if in_optional_chain then - emit_inner () - else - node "ChainExpression" loc [("expression", emit_inner ())]) - | (loc, Yield { Yield.argument; delegate; comments; result_out = _ }) -> - node - ?comments - "YieldExpression" - loc - [("argument", option expression argument); ("delegate", bool delegate)] - | (_loc, Identifier id) -> identifier id - | (loc, StringLiteral lit) -> string_literal (loc, lit) - | (loc, BooleanLiteral lit) -> boolean_literal (loc, lit) - | (loc, NullLiteral lit) -> null_literal (loc, lit) - | (loc, NumberLiteral lit) -> number_literal (loc, lit) - | (loc, BigIntLiteral lit) -> bigint_literal (loc, lit) - | (loc, RegExpLiteral lit) -> regexp_literal (loc, lit) - | (loc, ModuleRefLiteral lit) -> module_ref_literal (loc, lit) - | (loc, TemplateLiteral lit) -> template_literal (loc, lit) - | (loc, TaggedTemplate tagged) -> tagged_template (loc, tagged) - | (loc, Class c) -> class_expression (loc, c) - | (loc, JSXElement element) -> jsx_element (loc, element) - | (loc, JSXFragment fragment) -> jsx_fragment (loc, fragment) - | (loc, Match { Match.arg; cases; comments; match_keyword_loc = _ }) -> - node - ?comments - "MatchExpression" - loc - [("argument", expression arg); ("cases", array_of_list match_expression_case cases)] - | (loc, MetaProperty { MetaProperty.meta; property; comments }) -> - node - ?comments - "MetaProperty" - loc - [("meta", identifier meta); ("property", identifier property)] - | (loc, Record { Record.constructor; targs; properties; comments }) -> - let properties = - let (props_loc, { Expression.Object.properties = props; comments = props_comments }) = - properties - in - node - ?comments:(format_internal_comments props_comments) - "RecordExpressionProperties" - props_loc - [("properties", array_of_list object_property props)] - in - node - ?comments - "RecordExpression" - loc - [ - ("recordConstructor", expression constructor); - ("typeArguments", option call_type_args targs); - ("properties", properties); - ] - | (loc, Import { Import.argument; options; comments }) -> - let fields = - ("source", expression argument) - :: - (match options with - | Some opts -> [("options", expression opts)] - | None -> []) - in - node ?comments "ImportExpression" loc fields - and match_expression_case case = match_case "MatchExpressionCase" ~on_case_body:expression case - and match_case - : 'B. string -> on_case_body:('B -> Impl.t) -> (Loc.t, Loc.t, 'B) Match.Case.t -> Impl.t = - fun kind - ~on_case_body - ( loc, - { - Match.Case.pattern; - body; - guard; - comments; - invalid_syntax = _; - case_match_root_loc = _; - } - ) -> - node - ?comments - kind - loc - [ - ("pattern", match_pattern pattern); - ("body", on_case_body body); - ("guard", option expression guard); - ] - and match_statement_case case = match_case "MatchStatementCase" ~on_case_body:statement case - and match_pattern (loc, pattern) = - let open MatchPattern in - let literal x = node "MatchLiteralPattern" loc [("literal", x)] in - match pattern with - | WildcardPattern { WildcardPattern.comments; _ } -> - node ?comments "MatchWildcardPattern" loc [] - | StringPattern lit -> literal (string_literal (loc, lit)) - | BooleanPattern lit -> literal (boolean_literal (loc, lit)) - | NullPattern comments -> literal (null_literal (loc, comments)) - | NumberPattern lit -> literal (number_literal (loc, lit)) - | BigIntPattern lit -> literal (bigint_literal (loc, lit)) - | UnaryPattern { UnaryPattern.operator; argument; comments } -> - let operator = - match operator with - | UnaryPattern.Minus -> "-" - | UnaryPattern.Plus -> "+" - in - let argument = - match argument with - | (loc, UnaryPattern.NumberLiteral lit) -> number_literal (loc, lit) - | (loc, UnaryPattern.BigIntLiteral lit) -> bigint_literal (loc, lit) - in - node - ?comments - "MatchUnaryPattern" - loc - [("operator", string operator); ("argument", argument)] - | BindingPattern binding -> match_binding_pattern (loc, binding) - | IdentifierPattern id -> match_identifier_pattern id - | MemberPattern member -> match_member_pattern member - | ObjectPattern obj -> match_object_pattern "MatchObjectPattern" (loc, obj) - | ArrayPattern arr -> match_array_pattern (loc, arr) - | InstancePattern { InstancePattern.constructor; properties; comments } -> - let constructor = - match constructor with - | InstancePattern.IdentifierConstructor id -> match_identifier_pattern id - | InstancePattern.MemberConstructor member -> match_member_pattern member - in - node - ?comments - "MatchInstancePattern" - loc - [ - ("targetConstructor", constructor); - ("properties", match_object_pattern "MatchInstanceObjectPattern" properties); - ] - | OrPattern { OrPattern.patterns; comments } -> - node ?comments "MatchOrPattern" loc [("patterns", array_of_list match_pattern patterns)] - | AsPattern { AsPattern.pattern; target; comments } -> - let target = - match target with - | AsPattern.Binding (loc, binding) -> match_binding_pattern (loc, binding) - | AsPattern.Identifier id -> identifier id - in - node ?comments "MatchAsPattern" loc [("pattern", match_pattern pattern); ("target", target)] - and match_identifier_pattern id = - let (loc, _) = id in - node "MatchIdentifierPattern" loc [("id", identifier id)] - and match_member_pattern (loc, { MatchPattern.MemberPattern.base; property; comments }) = - let open MatchPattern.MemberPattern in - let member_base = function - | BaseIdentifier id -> match_identifier_pattern id - | BaseMember member -> match_member_pattern member - in - let member_property = function - | PropertyString lit -> string_literal lit - | PropertyNumber lit -> number_literal lit - | PropertyBigInt lit -> bigint_literal lit - | PropertyIdentifier id -> identifier id - in - node - ?comments - "MatchMemberPattern" - loc - [("base", member_base base); ("property", member_property property)] - and match_binding_pattern (loc, { MatchPattern.BindingPattern.kind; id; comments }) = - let kind = Flow_ast_utils.string_of_variable_kind kind in - node ?comments "MatchBindingPattern" loc [("id", identifier id); ("kind", string kind)] - and match_array_pattern (loc, { MatchPattern.ArrayPattern.elements; rest; comments }) = - let open MatchPattern.ArrayPattern in - node - ?comments:(format_internal_comments comments) - "MatchArrayPattern" - loc - [ - ("elements", array_of_list (fun { Element.pattern; _ } -> match_pattern pattern) elements); - ("rest", option match_rest_pattern rest); - ] - and match_object_pattern kind (loc, { MatchPattern.ObjectPattern.properties; rest; comments }) = - let open MatchPattern.ObjectPattern in - let property_key key = - match key with - | Property.StringLiteral lit -> string_literal lit - | Property.NumberLiteral lit -> number_literal lit - | Property.BigIntLiteral lit -> bigint_literal lit - | Property.Identifier id -> identifier id - in - let property = function - | (loc, Property.Valid { Property.key; pattern; shorthand; comments }) -> - node - ?comments - "MatchObjectPatternProperty" - loc - [ - ("key", property_key key); - ("pattern", match_pattern pattern); - ("shorthand", bool shorthand); - ] - | (loc, Property.InvalidShorthand id) -> - node - "MatchObjectPatternProperty" - loc - [ - ("key", identifier id); - ("pattern", match_identifier_pattern id); - ("shorthand", bool true); - ] - in - node - ?comments:(format_internal_comments comments) - kind - loc - [ - ("properties", array_of_list property properties); ("rest", option match_rest_pattern rest); - ] - and match_rest_pattern (loc, { MatchPattern.RestPattern.argument; comments }) = - node ?comments "MatchRestPattern" loc [("argument", option match_binding_pattern argument)] - and function_declaration - ( loc, - { - Function.id; - params = (_, { Function.Params.comments = params_comments; _ }) as params; - async; - generator; - effect_; - predicate = predicate_; - tparams; - return; - body; - comments = func_comments; - sig_loc = _; - } - ) = - let body = - match body with - | Function.BodyBlock b -> b - | Function.BodyExpression _ -> failwith "Unexpected FunctionDeclaration with BodyExpression" - in - let comments = - Flow_ast_utils.merge_comments - ~outer:func_comments - ~inner:(format_internal_comments params_comments) - in - let (node_name, nonhook_attrs) = - if effect_ = Function.Hook then - ("HookDeclaration", [("async", bool async)]) - else - ( "FunctionDeclaration", - [ - ("async", bool async); - ("generator", bool generator); - ("predicate", option predicate predicate_); - ("expression", bool false); - ] - ) - in - node - ?comments - node_name - loc - ([ - (* estree hasn't come around to the idea that function decls can have - optional ids, but acorn, babel, espree and esprima all have, so let's - do it too. see https://github.com/estree/estree/issues/98 *) - ("id", option identifier id); - ("params", function_params params); - ("body", block body); - ("returnType", function_return_type return); - ("typeParameters", option type_parameter_declaration tparams); - ] - @ nonhook_attrs - ) - and function_expression - ( loc, - { - Function.id; - params = (_, { Function.Params.comments = params_comments; _ }) as params; - async; - generator; - effect_ = _; - predicate = predicate_; - tparams; - return; - body; - comments = func_comments; - sig_loc = _; - } - ) = - let body = - match body with - | Function.BodyBlock b -> b - | Function.BodyExpression _ -> failwith "Unexpected FunctionExpression with BodyExpression" - in - let comments = - Flow_ast_utils.merge_comments - ~outer:func_comments - ~inner:(format_internal_comments params_comments) - in - node - ?comments - "FunctionExpression" - loc - [ - ("id", option identifier id); - ("params", function_params params); - ("body", block body); - ("async", bool async); - ("generator", bool generator); - ("predicate", option predicate predicate_); - ("expression", bool false); - ("returnType", function_return_type return); - ("typeParameters", option type_parameter_declaration tparams); - ] - and identifier (loc, { Identifier.name; comments }) = - node - "Identifier" - ?comments - loc - [("name", string name); ("typeAnnotation", null); ("optional", bool false)] - and private_identifier (loc, { PrivateName.name; comments }) = - node - ?comments - "PrivateIdentifier" - loc - [("name", string name); ("typeAnnotation", null); ("optional", bool false)] - and pattern_identifier - loc { Pattern.Identifier.name = (_, { Identifier.name; comments }); annot; optional } = - node - ?comments - "Identifier" - loc - [ - ("name", string name); - ("typeAnnotation", hint type_annotation annot); - ("optional", bool optional); - ] - and arg_list ~in_optional_chain (_loc, { Expression.ArgList.arguments; comments = _ }) = - (* ESTree does not have a unique node for argument lists, so there's nowhere to - include the loc. *) - array_of_list (expression_or_spread ~in_optional_chain) arguments - and case (loc, { Statement.Switch.Case.test; case_test_loc = _; consequent; comments }) = - node - ?comments - "SwitchCase" - loc - [("test", option expression test); ("consequent", array_of_list statement consequent)] - and catch (loc, { Statement.Try.CatchClause.param; body; comments }) = - node ?comments "CatchClause" loc [("param", option pattern param); ("body", block body)] - and block (loc, { Statement.Block.body; comments }) = - node - ?comments:(format_internal_comments comments) - "BlockStatement" - loc - [("body", statement_list body)] - and declare_variable (loc, { Statement.DeclareVariable.declarations; kind; comments }) = - let kind_str = Flow_ast_utils.string_of_variable_kind kind in - node - ?comments - "DeclareVariable" - loc - [ - ("declarations", array_of_list variable_declarator declarations); ("kind", string kind_str); - ] - and declare_function - ( loc, - { - Statement.DeclareFunction.id; - annot; - predicate = predicate_; - comments; - implicit_declare; - } - ) = - let id_loc = - match id with - | Some id -> Loc.btwn (fst id) (fst annot) - | None -> fst annot - in - let (name, predicate) = - match annot with - | (_, (_, Type.Function { Type.Function.effect_ = Function.Hook; _ })) -> ("DeclareHook", []) - | _ -> ("DeclareFunction", [("predicate", option predicate predicate_)]) - in - let annot_field = - (* Only output if we aren't putting the annot on the `id` *) - if Option.is_none id then - [("typeAnnotation", type_annotation annot)] - else - [] - in - node - ?comments - name - loc - ([ - ( "id", - match id with - | Some id -> - pattern_identifier - id_loc - { - Pattern.Identifier.name = id; - annot = Ast.Type.Available annot; - optional = false; - } - | None -> null - ); - ("implicitDeclare", bool implicit_declare); - ] - @ annot_field - @ predicate - ) - and declare_class - ( loc, - { - Statement.DeclareClass.id; - tparams; - body; - extends; - implements; - mixins; - abstract; - comments; - } - ) = - (* TODO: extends shouldn't return an array *) - let rec declare_class_extends_to_estree (loc, ext) = - match ext with - | Statement.DeclareClass.ExtendsIdent generic -> interface_extends (loc, generic) - | Statement.DeclareClass.ExtendsCall { callee; arg } -> - node - "DeclareClassExtendsCall" - loc - [("callee", generic_type callee); ("argument", declare_class_extends_to_estree arg)] - in - let extends = - match extends with - | Some ext -> array [declare_class_extends_to_estree ext] - | None -> array [] - in - let implements = - match implements with - | Some (_, { Class.Implements.interfaces; comments = _ }) -> - array_of_list class_implements interfaces - | None -> array [] - in - node - ?comments - "DeclareClass" - loc - ([ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("body", object_type ~include_inexact:false body); - ("extends", extends); - ("implements", implements); - ("mixins", array_of_list interface_extends mixins); - ] - @ - if abstract then - [("abstract", bool abstract)] - else - [] - ) - and declare_component (loc, component) = - let { - Statement.DeclareComponent.id; - tparams; - params = - (_, { Statement.ComponentDeclaration.Params.comments = params_comments; _ }) as params; - renders; - comments = component_comments; - } = - component - in - let comments = - Flow_ast_utils.merge_comments - ~outer:component_comments - ~inner:(format_internal_comments params_comments) - in - node - ?comments - "DeclareComponent" - loc - [ - ("id", identifier id); - ("params", component_params params); - ("rendersType", renders_annotation renders); - ("typeParameters", option type_parameter_declaration tparams); - ] - and component_type (loc, component) = - let { - Type.Component.tparams; - params = (_, { Type.Component.Params.comments = params_comments; _ }) as params; - renders; - comments = component_comments; - } = - component - in - let comments = - Flow_ast_utils.merge_comments - ~outer:component_comments - ~inner:(format_internal_comments params_comments) - in - let (_, { Type.Component.Params.params = param_list; rest; comments = _ }) = params in - node - ?comments - "ComponentTypeAnnotation" - loc - [ - ("params", component_type_params param_list); - ("rest", option component_type_rest_param rest); - ("rendersType", renders_annotation renders); - ("typeParameters", option type_parameter_declaration tparams); - ] - and component_type_params params = - let open Type.Component in - let params = - List.map - (fun (loc, { Param.name; annot; optional }) -> - let (_, annot') = annot in - component_type_param ~optional loc (Some name) annot') - params - in - array params - and component_type_rest_param rest = - let open Type.Component in - let (loc, { RestParam.argument; annot; optional; comments }) = rest in - component_type_param - ?comments - ~optional - loc - (Option.map (fun i -> Statement.ComponentDeclaration.Param.Identifier i) argument) - annot - and component_type_param ?comments ~optional loc name annot = - let name' = - match name with - | Some (Statement.ComponentDeclaration.Param.Identifier id) -> option identifier (Some id) - | Some (Statement.ComponentDeclaration.Param.StringLiteral id) -> - option string_literal (Some id) - | None -> option identifier None - in - node - ?comments - "ComponentTypeParameter" - loc - [("name", name'); ("typeAnnotation", _type annot); ("optional", bool optional)] - and declare_enum (loc, { Statement.EnumDeclaration.id; body; const_; comments }) = - let props = [("id", identifier id); ("body", enum_body body)] in - let props = - if const_ then - ("const", bool true) :: props - else - props - in - node ?comments "DeclareEnum" loc props - and declare_interface (loc, { Statement.Interface.id; tparams; body; extends; comments }) = - node - ?comments - "DeclareInterface" - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("body", object_type ~include_inexact:false body); - ("extends", array_of_list interface_extends extends); - ] - and declare_namespace - (loc, { Statement.DeclareNamespace.id; body; comments; implicit_declare; keyword }) = - let (id, global) = - match id with - | Statement.DeclareNamespace.Local id -> (identifier id, false) - | Statement.DeclareNamespace.Global id -> (identifier id, true) - in - let keyword_str = - match keyword with - | Statement.DeclareNamespace.Namespace -> "namespace" - | Statement.DeclareNamespace.Module -> "module" - in - let props = - [ - ("id", id); - ("body", block body); - ("implicitDeclare", bool implicit_declare); - ("keyword", string keyword_str); - ] - in - let props = - if global then - ("global", bool global) :: props - else - props - in - node ?comments "DeclareNamespace" loc props - and string_of_export_kind = function - | Statement.ExportType -> "type" - | Statement.ExportValue -> "value" - and export_specifiers = - let open Statement.ExportNamedDeclaration in - function - | Some (ExportSpecifiers specifiers) -> array_of_list export_specifier specifiers - | Some (ExportBatchSpecifier (loc, Some name)) -> - array [node "ExportNamespaceSpecifier" loc [("exported", identifier name)]] - | Some (ExportBatchSpecifier (_, None)) -> - (* this should've been handled by callers, since this represents an - ExportAllDeclaration, not a specifier. *) - array [] - | None -> array [] - and declare_type_alias (loc, { Statement.TypeAlias.id; tparams; right; comments }) = - node - ?comments - "DeclareTypeAlias" - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("right", _type right); - ] - and type_alias (loc, { Statement.TypeAlias.id; tparams; right; comments }) = - node - ?comments - "TypeAlias" - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("right", _type right); - ] - and opaque_type - ~declare - ( loc, - { - Statement.OpaqueType.id; - tparams; - impl_type; - lower_bound; - upper_bound; - legacy_upper_bound; - comments; - } - ) = - let name = - if declare then - "DeclareOpaqueType" - else - "OpaqueType" - in - node - ?comments - name - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("impltype", option _type impl_type); - ("lowerBound", option _type lower_bound); - ("upperBound", option _type upper_bound); - ("supertype", option _type legacy_upper_bound); - ] - and class_declaration ast = class_helper "ClassDeclaration" ast - and class_expression ast = class_helper "ClassExpression" ast - and class_helper - node_type - (loc, { Class.id; extends; body; tparams; implements; class_decorators; abstract; comments }) - = - let (super, super_targs, comments) = - match extends with - | Some (_, { Class.Extends.expr; targs; comments = extends_comments }) -> - (Some expr, targs, Flow_ast_utils.merge_comments ~outer:comments ~inner:extends_comments) - | None -> (None, None, comments) - in - let (implements, comments) = - match implements with - | Some (_, { Class.Implements.interfaces; comments = implements_comments }) -> - ( array_of_list class_implements interfaces, - Flow_ast_utils.merge_comments ~outer:comments ~inner:implements_comments - ) - | None -> (array [], comments) - in - node - ?comments - node_type - loc - ([ - (* estree hasn't come around to the idea that class decls can have - optional ids, but acorn, babel, espree and esprima all have, so let's - do it too. see https://github.com/estree/estree/issues/98 *) - ("id", option identifier id); - ("body", class_body body); - ("typeParameters", option type_parameter_declaration tparams); - ("superClass", option expression super); - ("superTypeArguments", option type_args super_targs); - ("implements", implements); - ("decorators", array_of_list class_decorator class_decorators); - ] - @ - if abstract then - [("abstract", bool abstract)] - else - [] - ) - and class_decorator (loc, { Class.Decorator.expression = expr; comments }) = - node ?comments "Decorator" loc [("expression", expression expr)] - and class_implements (loc, { Class.Implements.Interface.id; targs }) = - let id = - match id with - | Type.Generic.Identifier.Unqualified id -> identifier id - | Type.Generic.Identifier.Qualified q -> generic_type_qualified_identifier q - | Type.Generic.Identifier.ImportTypeAnnot it -> import_type it - in - node "ClassImplements" loc [("id", id); ("typeParameters", option type_args targs)] - and class_body (loc, { Class.Body.body; comments }) = - node ?comments "ClassBody" loc [("body", array_of_list class_element body)] - and ts_accessibility_to_string ts_accessibility = - match ts_accessibility with - | Some (_, { Class.TSAccessibility.kind = Class.TSAccessibility.Public; _ }) -> Some "public" - | Some (_, { Class.TSAccessibility.kind = Class.TSAccessibility.Protected; _ }) -> - Some "protected" - | Some (_, { Class.TSAccessibility.kind = Class.TSAccessibility.Private; _ }) -> - Some "private" - | None -> None - and class_element = - Class.Body.( - function - | Method m -> class_method m - | PrivateField p -> class_private_field p - | Property p -> class_property p - | StaticBlock (loc, { Class.StaticBlock.body; comments }) -> - node - ?comments:(format_internal_comments comments) - "StaticBlock" - loc - [("body", statement_list body)] - | DeclareMethod dm -> class_declare_method dm - | AbstractMethod am -> class_abstract_method am - | AbstractProperty ap -> class_abstract_property ap - | IndexSignature i -> object_type_indexer i - ) - and class_method - ( loc, - { - Class.Method.key; - value; - kind; - static; - override; - ts_accessibility; - decorators; - comments; - } - ) = - let (key, computed, comments) = - let open Expression.Object.Property in - match key with - | StringLiteral lit -> (string_literal lit, false, comments) - | NumberLiteral lit -> (number_literal lit, false, comments) - | BigIntLiteral lit -> (bigint_literal lit, false, comments) - | Identifier id -> (identifier id, false, comments) - | PrivateName name -> (private_identifier name, false, comments) - | Computed (_, { ComputedKey.expression = expr; comments = computed_comments }) -> - ( expression expr, - true, - Flow_ast_utils.merge_comments ~outer:comments ~inner:computed_comments - ) - in - let kind = - Class.Method.( - match kind with - | Constructor -> "constructor" - | Method -> "method" - | Get -> "get" - | Set -> "set" - ) - in - node - ?comments - "MethodDefinition" - loc - ([ - ("key", key); - ("value", function_expression value); - ("kind", string kind); - ("static", bool static); - ("computed", bool computed); - ("decorators", array_of_list class_decorator decorators); - ] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ - match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> [] - ) - and class_declare_method - (loc, { Class.DeclareMethod.kind; key; annot; static; override; optional; comments }) = - let (key, computed, comments) = - let open Expression.Object.Property in - match key with - | StringLiteral lit -> (string_literal lit, false, comments) - | NumberLiteral lit -> (number_literal lit, false, comments) - | BigIntLiteral lit -> (bigint_literal lit, false, comments) - | Identifier id -> (identifier id, false, comments) - | PrivateName name -> (private_identifier name, false, comments) - | Computed (_, { ComputedKey.expression = expr; comments = computed_comments }) -> - ( expression expr, - true, - Flow_ast_utils.merge_comments ~outer:comments ~inner:computed_comments - ) - in - let kind_prop = - let open Class.Method in - match kind with - | Get -> [("kind", string "get")] - | Set -> [("kind", string "set")] - | Method - | Constructor -> - [] - in - node - ?comments - "DeclareMethodDefinition" - loc - ([ - ("key", key); - ("value", type_annotation annot); - ("static", bool static); - ("optional", bool optional); - ("computed", bool computed); - ] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ kind_prop - ) - and class_abstract_method - (loc, { Class.AbstractMethod.key; annot; override; ts_accessibility; comments }) = - let (key, computed, comments) = property_key ~comments key in - node - ?comments - "AbstractMethodDefinition" - loc - ([("key", key); ("value", function_type annot); ("computed", bool computed)] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ - match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> [] - ) - and class_abstract_property - ( loc, - { - Class.AbstractProperty.key; - annot; - override; - ts_accessibility; - variance = variance_; - comments; - } - ) = - let (key, computed, comments) = property_key ~comments key in - node - ?comments - "AbstractPropertyDefinition" - loc - ([ - ("key", key); - ("value", hint type_annotation annot); - ("computed", bool computed); - ("variance", option variance variance_); - ] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ - match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> [] - ) - and class_private_field - ( loc, - { - Class.PrivateField.key; - value; - annot; - static; - override; - optional; - variance = variance_; - ts_accessibility; - decorators; - comments; - } - ) = - let (value, declare) = - match value with - | Class.Property.Declared -> (None, true) - | Class.Property.Uninitialized -> (None, false) - | Class.Property.Initialized x -> (Some x, false) - in - let props = - [ - ("key", private_identifier key); - ("value", option expression value); - ("typeAnnotation", hint type_annotation annot); - ("computed", bool false); - ("static", bool static); - ("optional", bool optional); - ("variance", option variance variance_); - ] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ (match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> []) - @ ( if decorators = [] then - [] - else - [("decorators", array_of_list class_decorator decorators)] - ) - @ - if declare then - [("declare", bool declare)] - else - [] - in - node ?comments "PropertyDefinition" loc props - and property_key ~comments = function - | Expression.Object.Property.StringLiteral lit -> (string_literal lit, false, comments) - | Expression.Object.Property.NumberLiteral lit -> (number_literal lit, false, comments) - | Expression.Object.Property.BigIntLiteral lit -> (bigint_literal lit, false, comments) - | Expression.Object.Property.Identifier id -> (identifier id, false, comments) - | Expression.Object.Property.PrivateName name -> (private_identifier name, false, comments) - | Expression.Object.Property.Computed - (_, { ComputedKey.expression = expr; comments = key_comments }) -> - (expression expr, true, Flow_ast_utils.merge_comments ~outer:comments ~inner:key_comments) - and class_property (loc, prop) = class_property_helper "PropertyDefinition" loc prop - and class_property_helper - type_ - loc - { - Class.Property.key; - value; - annot; - static; - override; - optional; - variance = variance_; - ts_accessibility; - decorators; - comments; - } = - let (key, computed, comments) = property_key ~comments key in - let (value, declare) = - match value with - | Class.Property.Declared -> (None, true) - | Class.Property.Uninitialized -> (None, false) - | Class.Property.Initialized x -> (Some x, false) - in - let props = - [ - ("key", key); - ("value", option expression value); - ("typeAnnotation", hint type_annotation annot); - ("computed", bool computed); - ("static", bool static); - ("optional", bool optional); - ("variance", option variance variance_); - ] - @ ( if override then - [("override", bool override)] - else - [] - ) - @ (match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> []) - @ ( if decorators = [] then - [] - else - [("decorators", array_of_list class_decorator decorators)] - ) - @ - if declare then - [("declare", bool declare)] - else - [] - in - node ?comments type_ loc props - and component_declaration (loc, component) = - let open Statement.ComponentDeclaration in - let { - id; - tparams; - params = (_, { Params.comments = params_comments; _ }) as params; - body; - renders; - async; - comments = component_comments; - sig_loc = _; - } = - component - in - let comments = - Flow_ast_utils.merge_comments - ~outer:component_comments - ~inner:(format_internal_comments params_comments) - in - let (node_type, implicit_declare) = - match body with - | None -> ("DeclareComponent", true) - | Some _ -> ("ComponentDeclaration", false) - in - node - ?comments - node_type - loc - [ - ("async", bool async); - ("body", option block body); - ("id", identifier id); - ("implicitDeclare", bool implicit_declare); - ("params", component_params params); - ("rendersType", renders_annotation renders); - ("typeParameters", option type_parameter_declaration tparams); - ] - and component_params = - let open Statement.ComponentDeclaration.Params in - function - | ( _, - { - params; - rest = Some (rest_loc, { Statement.ComponentDeclaration.RestParam.argument; comments }); - comments = _; - } - ) -> - let rest = node ?comments "RestElement" rest_loc [("argument", pattern argument)] in - let rev_params = List.rev_map component_param params in - let params = List.rev (rest :: rev_params) in - array params - | (_, { params; rest = None; comments = _ }) -> - let params = List.map component_param params in - array params - and component_param param = - let open Statement.ComponentDeclaration.Param in - let (loc, { name; local; default; shorthand }) = param in - let name' = - match name with - | Identifier id -> identifier id - | StringLiteral id -> string_literal id - in - let local' = - match default with - | Some default -> - node "AssignmentPattern" loc [("left", pattern local); ("right", expression default)] - | None -> pattern local - in - node - "ComponentParameter" - loc - [("name", name'); ("local", local'); ("shorthand", bool shorthand)] - and enum_body body = - let open Statement.EnumDeclaration in - let (loc, { Body.members; explicit_type; has_unknown_members; comments }) = body in - let enum_member_name = function - | Identifier id -> identifier id - | StringLiteral sl -> string_literal sl - in - let enum_member = function - | BooleanMember (loc, { InitializedMember.id; init }) -> - node "EnumBooleanMember" loc [("id", enum_member_name id); ("init", boolean_literal init)] - | NumberMember (loc, { InitializedMember.id; init }) -> - node "EnumNumberMember" loc [("id", enum_member_name id); ("init", number_literal init)] - | StringMember (loc, { InitializedMember.id; init }) -> - node "EnumStringMember" loc [("id", enum_member_name id); ("init", string_literal init)] - | BigIntMember (loc, { InitializedMember.id; init }) -> - node "EnumBigIntMember" loc [("id", enum_member_name id); ("init", bigint_literal init)] - | DefaultedMember (loc, { DefaultedMember.id }) -> - node "EnumDefaultedMember" loc [("id", enum_member_name id)] - in - let explicit_type_str = - match explicit_type with - | Some (_, et) -> string (Flow_ast_utils.string_of_enum_explicit_type et) - | None -> null - in - node - ?comments:(format_internal_comments comments) - "EnumBody" - loc - [ - ("members", array_of_list enum_member members); - ("explicitType", explicit_type_str); - ("hasUnknownMembers", bool (has_unknown_members <> None)); - ] - and enum_declaration (loc, { Statement.EnumDeclaration.id; body; const_; comments }) = - let props = [("id", identifier id); ("body", enum_body body)] in - let props = - if const_ then - ("const", bool true) :: props - else - props - in - node ?comments "EnumDeclaration" loc props - and interface_declaration (loc, { Statement.Interface.id; tparams; body; extends; comments }) = - node - ?comments - "InterfaceDeclaration" - loc - [ - ("id", identifier id); - ("typeParameters", option type_parameter_declaration tparams); - ("body", object_type ~include_inexact:false body); - ("extends", array_of_list interface_extends extends); - ] - and interface_extends (loc, { Type.Generic.id; targs; comments }) = - let id = - match id with - | Type.Generic.Identifier.Unqualified id -> identifier id - | Type.Generic.Identifier.Qualified q -> generic_type_qualified_identifier q - | Type.Generic.Identifier.ImportTypeAnnot it -> import_type it - in - node ?comments "InterfaceExtends" loc [("id", id); ("typeParameters", option type_args targs)] - and pattern = - Pattern.( - function - | (loc, Object { Object.properties; annot; optional; comments }) -> - node - ?comments:(format_internal_comments comments) - "ObjectPattern" - loc - [ - ("properties", array_of_list object_pattern_property properties); - ("typeAnnotation", hint type_annotation annot); - ("optional", bool optional); - ] - | (loc, Array { Array.elements; annot; optional; comments }) -> - node - ?comments:(format_internal_comments comments) - "ArrayPattern" - loc - [ - ("elements", array_of_list array_pattern_element elements); - ("typeAnnotation", hint type_annotation annot); - ("optional", bool optional); - ] - | (loc, Identifier pattern_id) -> pattern_identifier loc pattern_id - | (_loc, Expression expr) -> expression expr - ) - and function_param (loc, param) = - let open Ast.Function.Param in - match param with - | RegularParam { argument; default } -> - (match default with - | Some default -> - node "AssignmentPattern" loc [("left", pattern argument); ("right", expression default)] - | None -> pattern argument) - | ParamProperty prop -> class_property_helper "ParameterProperty" loc prop - and this_param (loc, { Function.ThisParam.annot; comments }) = - node - ?comments - "Identifier" - loc - [("name", string "this"); ("typeAnnotation", type_annotation annot)] - and function_params = - let open Ast.Function.Params in - function - | ( _, - { - params; - rest = Some (rest_loc, { Function.RestParam.argument; comments }); - comments = _; - this_; - } - ) -> - let rest = node ?comments "RestElement" rest_loc [("argument", pattern argument)] in - let rev_params = List.rev_map function_param params in - let params = List.rev (rest :: rev_params) in - let params = - match this_ with - | Some this -> this_param this :: params - | None -> params - in - array params - | (_, { params; rest = None; this_; comments = _ }) -> - let params = List.map function_param params in - let params = - match this_ with - | Some this -> this_param this :: params - | None -> params - in - array params - and rest_element loc { Pattern.RestElement.argument; comments } = - node ?comments "RestElement" loc [("argument", pattern argument)] - and array_pattern_element = - let open Pattern.Array in - function - | Hole _ -> null - | Element (loc, { Element.argument; default = Some default }) -> - node "AssignmentPattern" loc [("left", pattern argument); ("right", expression default)] - | Element (_loc, { Element.argument; default = None }) -> pattern argument - | RestElement (loc, el) -> rest_element loc el - and function_return_type = function - | Ast.Function.ReturnAnnot.Missing _ -> null - | Ast.Function.ReturnAnnot.TypeGuard (loc, g) -> type_guard_annotation (loc, g) - | Ast.Function.ReturnAnnot.Available t -> type_annotation t - and object_property = - let open Expression.Object in - function - | Property (loc, prop) -> - Property.( - let (key, value, kind, method_, shorthand, comments) = - match prop with - | Init { key; value; shorthand } -> - (key, expression value, "init", false, shorthand, None) - | Method { key; value = (loc, func) } -> - (key, function_expression (loc, func), "init", true, false, None) - | Get { key; value = (loc, func); comments } -> - (key, function_expression (loc, func), "get", false, false, comments) - | Set { key; value = (loc, func); comments } -> - (key, function_expression (loc, func), "set", false, false, comments) - in - let (key, computed, comments) = property_key ~comments key in - node - ?comments - "Property" - loc - [ - ("key", key); - ("value", value); - ("kind", string kind); - ("method", bool method_); - ("shorthand", bool shorthand); - ("computed", bool computed); - ] - ) - | SpreadProperty (loc, { SpreadProperty.argument; comments }) -> - node ?comments "SpreadElement" loc [("argument", expression argument)] - and object_pattern_property = - let open Pattern.Object in - function - | Property (loc, { Property.key; pattern = patt; default; shorthand }) -> - let (key, computed, comments) = - match key with - | Property.StringLiteral lit -> (string_literal lit, false, None) - | Property.NumberLiteral lit -> (number_literal lit, false, None) - | Property.BigIntLiteral lit -> (bigint_literal lit, false, None) - | Property.Identifier id -> (identifier id, false, None) - | Property.Computed (_, { ComputedKey.expression = expr; comments }) -> - (expression expr, true, comments) - in - let value = - match default with - | Some default -> - let loc = Loc.btwn (fst patt) (fst default) in - node "AssignmentPattern" loc [("left", pattern patt); ("right", expression default)] - | None -> pattern patt - in - node - ?comments - "Property" - loc - [ - ("key", key); - ("value", value); - ("kind", string "init"); - ("method", bool false); - ("shorthand", bool shorthand); - ("computed", bool computed); - ] - | RestElement (loc, el) -> rest_element loc el - and spread_element ~in_optional_chain (loc, { Expression.SpreadElement.argument; comments }) = - node ?comments "SpreadElement" loc [("argument", expression ~in_optional_chain argument)] - and expression_or_spread ~in_optional_chain = - let open Expression in - function - | Expression expr -> expression ~in_optional_chain expr - | Spread spread -> spread_element ~in_optional_chain spread - and array_element = - let open Expression.Array in - function - | Hole _ -> null - | Expression expr -> expression expr - | Spread spread -> spread_element ~in_optional_chain:false spread - and number_literal (loc, { NumberLiteral.value; raw; comments }) = - node ?comments "Literal" loc [("value", number value); ("raw", string raw)] - and bigint_literal (loc, ({ BigIntLiteral.raw; value = _; comments } as bigint)) = - let bigint = Flow_ast_utils.string_of_bigint bigint in - node ?comments "Literal" loc [("value", null); ("bigint", string bigint); ("raw", string raw)] - and string_literal (loc, { StringLiteral.value; raw; comments }) = - node ?comments "Literal" loc [("value", string value); ("raw", string raw)] - and boolean_literal (loc, { BooleanLiteral.value; comments }) = - let raw = - if value then - "true" - else - "false" - in - node ?comments "Literal" loc [("value", bool value); ("raw", string raw)] - and regexp_literal (loc, { RegExpLiteral.pattern; flags; raw; comments; _ }) = - let value = regexp loc pattern flags in - let regex = obj [("pattern", string pattern); ("flags", string flags)] in - node ?comments "Literal" loc [("value", value); ("raw", string raw); ("regex", regex)] - and null_literal (loc, comments) = - node ?comments "Literal" loc [("value", null); ("raw", string "null")] - and module_ref_literal (loc, { ModuleRefLiteral.value; raw; comments; _ }) = - string_literal (loc, { StringLiteral.value; raw; comments }) - and template_literal (loc, { Expression.TemplateLiteral.quasis; expressions; comments }) = - node - ?comments - "TemplateLiteral" - loc - [ - ("quasis", array_of_list template_element quasis); - ("expressions", array_of_list expression expressions); - ] - and template_element - ( loc, - { - Expression.TemplateLiteral.Element.value = - { Expression.TemplateLiteral.Element.raw; cooked }; - tail; - } - ) = - let value = obj [("raw", string raw); ("cooked", string cooked)] in - node "TemplateElement" loc [("value", value); ("tail", bool tail)] - and tagged_template (loc, { Expression.TaggedTemplate.tag; targs; quasi; comments }) = - node - ?comments - "TaggedTemplateExpression" - loc - [ - ("tag", expression tag); - ("typeArguments", option call_type_args targs); - ("quasi", template_literal quasi); - ] - and variable_declaration (loc, { Statement.VariableDeclaration.kind; declarations; comments }) = - let kind = Flow_ast_utils.string_of_variable_kind kind in - node - ?comments - "VariableDeclaration" - loc - [("declarations", array_of_list variable_declarator declarations); ("kind", string kind)] - and variable_declarator (loc, { Statement.VariableDeclaration.Declarator.id; init }) = - node "VariableDeclarator" loc [("id", pattern id); ("init", option expression init)] - and variance (loc, { Variance.kind; comments }) = - let open Variance in - let kind_str = - match kind with - | Plus -> "plus" - | Minus -> "minus" - | Readonly -> "readonly" - | Writeonly -> "writeonly" - | In -> "in" - | Out -> "out" - | InOut -> "in-out" - in - node ?comments "Variance" loc [("kind", string kind_str)] - and _type (loc, t) = - Type.( - match t with - | Any comments -> any_type loc comments - | Mixed comments -> mixed_type loc comments - | Empty comments -> empty_type loc comments - | Void comments -> void_type loc comments - | Null comments -> null_type loc comments - | Symbol comments -> symbol_type loc comments - | Number comments -> number_type loc comments - | BigInt comments -> bigint_type loc comments - | String comments -> string_type loc comments - | Boolean { raw = _; comments } -> boolean_type loc comments - | Nullable t -> nullable_type loc t - | Function fn -> function_type (loc, fn) - | Component c -> component_type (loc, c) - | Object o -> object_type ~include_inexact:true (loc, o) - | Interface i -> interface_type (loc, i) - | Array t -> array_type loc t - | Conditional t -> conditional_type loc t - | Infer t -> infer_type loc t - | Generic g -> generic_type (loc, g) - | IndexedAccess ia -> indexed_access (loc, ia) - | OptionalIndexedAccess ia -> optional_indexed_access (loc, ia) - | Union t -> union_type (loc, t) - | Intersection t -> intersection_type (loc, t) - | Typeof t -> typeof_type (loc, t) - | Keyof t -> keyof_type (loc, t) - | Renders renders -> render_type loc renders - | ReadOnly t -> read_only_type (loc, t) - | Tuple t -> tuple_type (loc, t) - | StringLiteral s -> string_literal_type (loc, s) - | NumberLiteral n -> number_literal_type (loc, n) - | BigIntLiteral n -> bigint_literal_type (loc, n) - | BooleanLiteral b -> boolean_literal_type (loc, b) - | TemplateLiteral t -> template_literal_type (loc, t) - | Exists comments -> exists_type loc comments - | Unknown comments -> unknown_type loc comments - | Never comments -> never_type loc comments - | Undefined comments -> undefined_type loc comments - | UniqueSymbol comments -> unique_symbol_type loc comments - | ConstructorType ct -> constructor_type (loc, ct) - ) - and any_type loc comments = node ?comments "AnyTypeAnnotation" loc [] - and mixed_type loc comments = node ?comments "MixedTypeAnnotation" loc [] - and empty_type loc comments = node ?comments "EmptyTypeAnnotation" loc [] - and void_type loc comments = node ?comments "VoidTypeAnnotation" loc [] - and null_type loc comments = node ?comments "NullLiteralTypeAnnotation" loc [] - and symbol_type loc comments = node ?comments "SymbolTypeAnnotation" loc [] - and number_type loc comments = node ?comments "NumberTypeAnnotation" loc [] - and bigint_type loc comments = node ?comments "BigIntTypeAnnotation" loc [] - and string_type loc comments = node ?comments "StringTypeAnnotation" loc [] - and boolean_type loc comments = node ?comments "BooleanTypeAnnotation" loc [] - and nullable_type loc { Type.Nullable.argument; comments } = - node ?comments "NullableTypeAnnotation" loc [("typeAnnotation", _type argument)] - and unknown_type loc comments = node ?comments "UnknownTypeAnnotation" loc [] - and never_type loc comments = node ?comments "NeverTypeAnnotation" loc [] - and undefined_type loc comments = node ?comments "UndefinedTypeAnnotation" loc [] - and unique_symbol_type loc comments = - node - ?comments - "TypeOperator" - loc - [("operator", string "unique"); ("typeAnnotation", node "SymbolTypeAnnotation" loc [])] - and return_annotation = function - | Ast.Type.Function.Missing _ -> null - | Ast.Type.Function.Available t -> _type t - | Ast.Type.Function.TypeGuard g -> type_guard g - and type_guard (loc, { Ast.Type.TypeGuard.kind; guard = (x, t); comments }) = - let kind = - let open Ast.Type.TypeGuard in - match kind with - | Default -> null - | Asserts -> string "asserts" - | Implies -> string "implies" - in - node - ?comments:(format_internal_comments comments) - "TypePredicate" - loc - [("parameterName", identifier x); ("typeAnnotation", option _type t); ("kind", kind)] - and function_type - ( loc, - { - Type.Function.params = - (_, { Type.Function.Params.this_; params; rest; comments = params_comments }); - return; - tparams; - effect_; - comments = func_comments; - } - ) = - let comments = - Flow_ast_utils.merge_comments - ~inner:(format_internal_comments params_comments) - ~outer:func_comments - in - let name = - if effect_ = Function.Hook then - "HookTypeAnnotation" - else - "FunctionTypeAnnotation" - in - node - ?comments - name - loc - ([ - ("params", array_of_list function_type_param params); - ("returnType", return_annotation return); - ("rest", option function_type_rest rest); - ("typeParameters", option type_parameter_declaration tparams); - ] - @ - if effect_ = Function.Hook then - [] - else - [("this", option function_type_this_constraint this_)] - ) - and constructor_type - ( loc, - { - Type.ConstructorType.abstract_; - func = - { - Type.Function.params = - (_, { Type.Function.Params.this_ = _; params; rest; comments = params_comments }); - return; - tparams; - effect_ = _; - comments = func_comments; - }; - } - ) = - let comments = - Flow_ast_utils.merge_comments - ~inner:(format_internal_comments params_comments) - ~outer:func_comments - in - node - ?comments - "ConstructorTypeAnnotation" - loc - [ - ("abstract", bool abstract_); - ("params", array_of_list function_type_param params); - ("returnType", return_annotation return); - ("rest", option function_type_rest rest); - ("typeParameters", option type_parameter_declaration tparams); - ] - and function_type_param ?comments (loc, param) = - let open Type.Function.Param in - match param with - | Anonymous annot -> - node - ?comments - "FunctionTypeParam" - loc - [("name", null); ("typeAnnotation", _type annot); ("optional", bool false)] - | Labeled { name; annot; optional } -> - node - ?comments - "FunctionTypeParam" - loc - [("name", identifier name); ("typeAnnotation", _type annot); ("optional", bool optional)] - | Destructuring patt -> pattern patt - and function_type_rest (_loc, { Type.Function.RestParam.argument; comments }) = - (* TODO: add a node for the rest param itself, including the `...`, - like we do with RestElement on normal functions. This should be - coordinated with Babel, ast-types, etc. so keeping the status quo for - now. Here's an example: *) - (* node "FunctionTypeRestParam" loc [ - "argument", function_type_param argument; - ] *) - function_type_param ?comments argument - and function_type_this_constraint (loc, { Type.Function.ThisParam.annot = (_, annot); comments }) - = - node - ?comments - "FunctionTypeParam" - loc - [ - ("name", option identifier None); ("typeAnnotation", _type annot); ("optional", bool false); - ] - and object_type ~include_inexact (loc, { Type.Object.properties; exact; inexact; comments }) = - Type.Object.( - let (props, ixs, calls, slots) = - List.fold_left - (fun (props, ixs, calls, slots) -> function - | Property p -> - let prop = object_type_property p in - (prop :: props, ixs, calls, slots) - | SpreadProperty p -> - let prop = object_type_spread_property p in - (prop :: props, ixs, calls, slots) - | Indexer i -> - let ix = object_type_indexer i in - (props, ix :: ixs, calls, slots) - | CallProperty c -> - let call = object_type_call_property c in - (props, ixs, call :: calls, slots) - | InternalSlot s -> - let slot = object_type_internal_slot s in - (props, ixs, calls, slot :: slots) - | MappedType m -> - let mapped_type = object_type_mapped_type m in - (mapped_type :: props, ixs, calls, slots) - | PrivateField pf -> - let prop = object_type_private_field pf in - (prop :: props, ixs, calls, slots)) - ([], [], [], []) - properties - in - let fields = - [ - ("exact", bool exact); - ("properties", array (List.rev props)); - ("indexers", array (List.rev ixs)); - ("callProperties", array (List.rev calls)); - ("internalSlots", array (List.rev slots)); - ] - in - let fields = - if include_inexact then - ("inexact", bool inexact) :: fields - else - fields - in - node ?comments:(format_internal_comments comments) "ObjectTypeAnnotation" loc fields - ) - and object_type_property - ( loc, - { - Type.Object.Property.key; - value; - optional; - static; - proto; - variance = variance_; - _method; - abstract; - override; - ts_accessibility; - init = init_; - comments; - } - ) = - let (key, computed, comments) = property_key ~comments key in - let (value, kind) = - match value with - | Type.Object.Property.Init (Some value) -> (_type value, "init") - | Type.Object.Property.Init None -> (null, "init") - | Type.Object.Property.Get (loc, f) -> (function_type (loc, f), "get") - | Type.Object.Property.Set (loc, f) -> (function_type (loc, f), "set") - in - node - ?comments - "ObjectTypeProperty" - loc - ([ - ("key", key); - ("value", value); - ("method", bool _method); - ("optional", bool optional); - ("static", bool static); - ("proto", bool proto); - ("abstract", bool abstract); - ("variance", option variance variance_); - ("kind", string kind); - ("init", option expression init_); - ] - @ ( if computed then - [("computed", bool computed)] - else - [] - ) - @ ( if override then - [("override", bool override)] - else - [] - ) - @ - match ts_accessibility_to_string ts_accessibility with - | Some v -> [("tsAccessibility", string v)] - | None -> [] - ) - and object_type_spread_property (loc, { Type.Object.SpreadProperty.argument; comments }) = - node ?comments "ObjectTypeSpreadProperty" loc [("argument", _type argument)] - and object_type_indexer - ( loc, - { Type.Object.Indexer.id; key; value; static; variance = variance_; optional; comments } - ) = - node - ?comments - "ObjectTypeIndexer" - loc - ([ - ("id", option identifier id); - ("key", _type key); - ("value", _type value); - ("static", bool static); - ("variance", option variance variance_); - ] - @ - if optional then - [("optional", bool optional)] - else - [] - ) - and object_type_call_property (loc, { Type.Object.CallProperty.value; static; comments }) = - node - ?comments - "ObjectTypeCallProperty" - loc - [("value", function_type value); ("static", bool static)] - and object_type_mapped_type - ( mt_loc, - { - Type.Object.MappedType.key_tparam; - prop_type; - source_type; - name_type; - variance = variance_; - variance_op; - comments; - optional; - } - ) = - let optional_flag flag = - Type.Object.MappedType.( - match flag with - | PlusOptional -> string "PlusOptional" - | MinusOptional -> string "MinusOptional" - | Optional -> string "Optional" - | NoOptionalFlag -> null - ) - in - let variance_op = - match variance_op with - | Some Type.Object.MappedType.Add -> string "+" - | Some Type.Object.MappedType.Remove -> string "-" - | None -> null - in - node - ?comments - "ObjectTypeMappedTypeProperty" - mt_loc - [ - ("keyTparam", type_param key_tparam); - ("propType", _type prop_type); - ("sourceType", _type source_type); - ("nameType", option _type name_type); - ("variance", option variance variance_); - ("varianceOp", variance_op); - ("optional", optional_flag optional); - ] - and object_type_internal_slot - (loc, { Type.Object.InternalSlot.id; optional; static; _method; value; comments }) = - node - ?comments - "ObjectTypeInternalSlot" - loc - [ - ("id", identifier id); - ("optional", bool optional); - ("static", bool static); - ("method", bool _method); - ("value", _type value); - ] - and object_type_private_field (loc, { Type.Object.PrivateField.key; comments }) = - node ?comments "ObjectTypePrivateField" loc [("key", private_identifier key)] - and interface_type (loc, { Type.Interface.extends; body; comments }) = - node - ?comments - "InterfaceTypeAnnotation" - loc - [ - ("extends", array_of_list interface_extends extends); - ("body", object_type ~include_inexact:false body); - ] - and array_type loc { Type.Array.argument; comments } = - node ?comments "ArrayTypeAnnotation" loc [("elementType", _type argument)] - and conditional_type - loc { Type.Conditional.check_type; extends_type; true_type; false_type; comments } = - node - ?comments - "ConditionalTypeAnnotation" - loc - [ - ("checkType", _type check_type); - ("extendsType", _type extends_type); - ("trueType", _type true_type); - ("falseType", _type false_type); - ] - and infer_type loc { Type.Infer.tparam; comments } = - node ?comments "InferTypeAnnotation" loc [("typeParameter", type_param tparam)] - and import_type (loc, { Type.Generic.Identifier.argument; comments }) = - node ?comments "ImportType" loc [("argument", string_literal argument)] - and generic_type_qualified_identifier (loc, { Type.Generic.Identifier.id; qualification }) = - let qualification = - match qualification with - | Type.Generic.Identifier.Unqualified id -> identifier id - | Type.Generic.Identifier.Qualified q -> generic_type_qualified_identifier q - | Type.Generic.Identifier.ImportTypeAnnot it -> import_type it - in - node "QualifiedTypeIdentifier" loc [("qualification", qualification); ("id", identifier id)] - and generic_type (loc, { Type.Generic.id; targs; comments }) = - (* Mirror upstream Hermes' mapGenericTypeAnnotation: collapse the - no-targs `this` identifier case to a ThisTypeAnnotation leaf node. - OCaml's parser produces `Type.Generic { id: Unqualified "this"; - targs: None }` for both `type T = this` and `(this) => void` / - `m(): this`. *) - match (targs, id) with - | (None, Type.Generic.Identifier.Unqualified (_, { Identifier.name = "this"; _ })) -> - node ?comments "ThisTypeAnnotation" loc [] - | _ -> - let id = - match id with - | Type.Generic.Identifier.Unqualified id -> identifier id - | Type.Generic.Identifier.Qualified q -> generic_type_qualified_identifier q - | Type.Generic.Identifier.ImportTypeAnnot it -> import_type it - in - node - ?comments - "GenericTypeAnnotation" - loc - [("id", id); ("typeParameters", option type_args targs)] - and indexed_access_properties { Type.IndexedAccess._object; index; comments = _ } = - [("objectType", _type _object); ("indexType", _type index)] - and indexed_access (loc, ({ Type.IndexedAccess.comments; _ } as ia)) = - node ?comments "IndexedAccessType" loc (indexed_access_properties ia) - and optional_indexed_access - ( loc, - { - Type.OptionalIndexedAccess.indexed_access = - { Type.IndexedAccess.comments; _ } as indexed_access; - optional; - } - ) = - node - ?comments - "OptionalIndexedAccessType" - loc - (indexed_access_properties indexed_access @ [("optional", bool optional)]) - and union_type (loc, { Type.Union.types = (t0, t1, ts); comments }) = - node ?comments "UnionTypeAnnotation" loc [("types", array_of_list _type (t0 :: t1 :: ts))] - and intersection_type (loc, { Type.Intersection.types = (t0, t1, ts); comments }) = - node - ?comments - "IntersectionTypeAnnotation" - loc - [("types", array_of_list _type (t0 :: t1 :: ts))] - and typeof_type (loc, { Type.Typeof.argument; targs; comments }) = - let targs_field = - match targs with - | None -> [] - | Some targs -> [("typeArguments", type_args targs)] - in - node ?comments "TypeofTypeAnnotation" loc (("argument", typeof_expr argument) :: targs_field) - and typeof_expr id = - match id with - | Type.Typeof.Target.Unqualified id -> identifier id - | Type.Typeof.Target.Qualified q -> typeof_qualifier q - | Type.Typeof.Target.Import it -> import_type it - and typeof_qualifier (loc, { Type.Typeof.Target.id; qualification }) = - let qualification = typeof_expr qualification in - node "QualifiedTypeofIdentifier" loc [("qualification", qualification); ("id", identifier id)] - and keyof_type (loc, { Type.Keyof.argument; comments }) = - node ?comments "KeyofTypeAnnotation" loc [("argument", _type argument)] - and renders_annotation = function - | Ast.Type.AvailableRenders (loc, v) -> render_type loc v - | Ast.Type.MissingRenders _ -> null - and render_type loc { Type.Renders.operator_loc = _; comments; variant; argument } = - let operator = - match variant with - | Type.Renders.Normal -> "renders" - | Type.Renders.Maybe -> "renders?" - | Type.Renders.Star -> "renders*" - in - flow_type_operator loc comments operator argument - and flow_type_operator loc comments operator operand = - node - ?comments - "TypeOperator" - loc - [("operator", string operator); ("typeAnnotation", _type operand)] - and read_only_type (loc, { Type.ReadOnly.argument; comments }) = - flow_type_operator loc comments "readonly" argument - and tuple_type (loc, { Type.Tuple.elements; inexact; comments }) = - node - ?comments - "TupleTypeAnnotation" - loc - [ - ( "elementTypes", - array_of_list - (function - | (loc, Type.Tuple.UnlabeledElement { Type.Tuple.UnlabeledElement.annot; optional }) - -> - if optional then - node - "TupleTypeElement" - loc - [("elementType", _type annot); ("optional", bool true)] - else - _type annot - | (loc, Type.Tuple.LabeledElement e) -> tuple_labeled_element loc e - | (loc, Type.Tuple.SpreadElement e) -> tuple_spread_element loc e) - elements - ); - ("inexact", bool inexact); - ] - and tuple_labeled_element - ?comments loc { Type.Tuple.LabeledElement.name; annot; variance = variance_; optional } = - node - ?comments - "TupleTypeLabeledElement" - loc - [ - ("label", identifier name); - ("elementType", _type annot); - ("variance", option variance variance_); - ("optional", bool optional); - ] - and tuple_spread_element ?comments loc { Type.Tuple.SpreadElement.name; annot } = - node - ?comments - "TupleTypeSpreadElement" - loc - [("label", option identifier name); ("typeAnnotation", _type annot)] - and string_literal_type (loc, { Ast.StringLiteral.value; raw; comments }) = - node - ?comments - "StringLiteralTypeAnnotation" - loc - [("value", string value); ("raw", string raw)] - and number_literal_type (loc, { Ast.NumberLiteral.value; raw; comments }) = - node - ?comments - "NumberLiteralTypeAnnotation" - loc - [("value", number value); ("raw", string raw)] - and bigint_literal_type (loc, { Ast.BigIntLiteral.raw; comments; _ }) = - node ?comments "BigIntLiteralTypeAnnotation" loc [("value", null); ("raw", string raw)] - and boolean_literal_type (loc, { Ast.BooleanLiteral.value; comments }) = - node - ?comments - "BooleanLiteralTypeAnnotation" - loc - [ - ("value", bool value); - ( "raw", - string - ( if value then - "true" - else - "false" - ) - ); - ] - and template_literal_type (loc, { Ast.Type.TemplateLiteral.quasis; types; comments }) = - node - ?comments - "TemplateLiteralTypeAnnotation" - loc - [ - ("quasis", array_of_list template_element_type quasis); - ("types", array_of_list _type types); - ] - and template_element_type - ( loc, - { - Ast.Type.TemplateLiteral.Element.value = - { Ast.Type.TemplateLiteral.Element.raw; cooked }; - tail; - } - ) = - let value = obj [("raw", string raw); ("cooked", string cooked)] in - node "TemplateElement" loc [("value", value); ("tail", bool tail)] - and exists_type loc comments = node ?comments "ExistsTypeAnnotation" loc [] - and type_annotation (loc, ty) = node "TypeAnnotation" loc [("typeAnnotation", _type ty)] - and type_guard_annotation (loc, (loc1, guard)) = - node "TypeAnnotation" loc [("typeAnnotation", type_guard (loc1, guard))] - and type_parameter_declaration (loc, { Type.TypeParams.params; comments }) = - node - ?comments:(format_internal_comments comments) - "TypeParameterDeclaration" - loc - [("params", array_of_list type_param params)] - and type_param - ( loc, - { - Type.TypeParam.name = (_, { Identifier.name; comments }); - bound; - bound_kind; - variance = tp_var; - default; - const; - } - ) = - node - ?comments - "TypeParameter" - loc - ([ - (* we track the location of the name, but don't expose it here for - backwards-compatibility. TODO: change this? *) - ("name", string name); - (* Hermes' deserializeTypeParameter reads `bound` as a plain type - node, NOT a TypeAnnotation-wrapped node. Emit the inner annotation - directly rather than going through `type_annotation` (which writes - a TypeAnnotation header). When the bound is missing, write null. *) - ("bound", hint (fun (_loc, ty) -> _type ty) bound); - ("const", bool (Option.is_some const)); - ("variance", option variance tp_var); - ("default", option _type default); - ] - @ - match bound_kind with - | Type.TypeParam.Colon -> [] - | Type.TypeParam.Extends -> [("usesExtendsBound", bool true)] - ) - and type_args (loc, { Type.TypeArgs.arguments; comments }) = - node - ?comments:(format_internal_comments comments) - "TypeParameterInstantiation" - loc - [("params", array_of_list _type arguments)] - and call_type_args (loc, { Expression.CallTypeArgs.arguments; comments }) = - node - ?comments:(format_internal_comments comments) - "TypeParameterInstantiation" - loc - [("params", array_of_list call_type_arg arguments)] - and call_type_arg x = - match x with - | Expression.CallTypeArg.Explicit t -> _type t - | Expression.CallTypeArg.Implicit (loc, { Expression.CallTypeArg.Implicit.comments }) -> - generic_type - ( loc, - { - Type.Generic.id = - Type.Generic.Identifier.Unqualified (Flow_ast_utils.ident_of_source (loc, "_")); - targs = None; - comments; - } - ) - and jsx_element - (loc, { JSX.opening_element; closing_element; children = (_loc, children); comments }) = - node - ?comments - "JSXElement" - loc - [ - ("openingElement", jsx_opening opening_element); - ("closingElement", option jsx_closing closing_element); - ("children", array_of_list jsx_child children); - ] - and jsx_fragment - ( loc, - { - JSX.frag_opening_element; - frag_closing_element; - frag_children = (_loc, frag_children); - frag_comments; - } - ) = - node - ?comments:frag_comments - "JSXFragment" - loc - [ - ("openingFragment", jsx_opening_fragment frag_opening_element); - ("children", array_of_list jsx_child frag_children); - ("closingFragment", jsx_closing_fragment frag_closing_element); - ] - and jsx_opening (loc, { JSX.Opening.name; targs; attributes; self_closing }) = - node - "JSXOpeningElement" - loc - ([ - ("name", jsx_name name); - ("attributes", array_of_list jsx_opening_attribute attributes); - ("selfClosing", bool self_closing); - ] - @ - match targs with - | Some targs -> [("typeArguments", call_type_args targs)] - | None -> [] - ) - and jsx_opening_fragment loc = node "JSXOpeningFragment" loc [] - and jsx_opening_attribute = - JSX.Opening.( - function - | Attribute attribute -> jsx_attribute attribute - | SpreadAttribute attribute -> jsx_spread_attribute attribute - ) - and jsx_closing (loc, { JSX.Closing.name }) = - node "JSXClosingElement" loc [("name", jsx_name name)] - and jsx_closing_fragment loc = node "JSXClosingFragment" loc [] - and jsx_child = - JSX.( - function - | (loc, Element element) -> jsx_element (loc, element) - | (loc, Fragment fragment) -> jsx_fragment (loc, fragment) - | (loc, ExpressionContainer expr) -> jsx_expression_container (loc, expr) - | (loc, SpreadChild spread) -> jsx_spread_child (loc, spread) - | (loc, Text str) -> jsx_text (loc, str) - ) - and jsx_name = - JSX.( - function - | Identifier id -> jsx_identifier id - | NamespacedName namespaced_name -> jsx_namespaced_name namespaced_name - | MemberExpression member -> jsx_member_expression member - ) - and jsx_attribute (loc, { JSX.Attribute.name; value }) = - let name = - match name with - | JSX.Attribute.Identifier id -> jsx_identifier id - | JSX.Attribute.NamespacedName namespaced_name -> jsx_namespaced_name namespaced_name - in - node "JSXAttribute" loc [("name", name); ("value", option jsx_attribute_value value)] - and jsx_attribute_value = - JSX.Attribute.( - function - | StringLiteral (loc, value) -> string_literal (loc, value) - | ExpressionContainer (loc, expr) -> jsx_expression_container (loc, expr) - ) - and jsx_spread_attribute (loc, { JSX.SpreadAttribute.argument; comments }) = - node ?comments "JSXSpreadAttribute" loc [("argument", expression argument)] - and jsx_expression_container (loc, { JSX.ExpressionContainer.expression = expr; comments }) = - let expression = - match expr with - | JSX.ExpressionContainer.Expression expr -> expression expr - | JSX.ExpressionContainer.EmptyExpression -> - let empty_loc = - let open Loc in - { - loc with - start = { loc.start with column = loc.start.column + 1 }; - _end = { loc._end with column = loc._end.column - 1 }; - } - in - - node "JSXEmptyExpression" empty_loc [] - in - node - ?comments:(format_internal_comments comments) - "JSXExpressionContainer" - loc - [("expression", expression)] - and jsx_spread_child (loc, { JSX.SpreadChild.expression = expr; comments }) = - node ?comments "JSXSpreadChild" loc [("expression", expression expr)] - and jsx_text (loc, { JSX.Text.value; raw }) = - node "JSXText" loc [("value", string value); ("raw", string raw)] - and jsx_member_expression (loc, { JSX.MemberExpression._object; property }) = - let _object = - match _object with - | JSX.MemberExpression.Identifier id -> jsx_identifier id - | JSX.MemberExpression.MemberExpression member -> jsx_member_expression member - in - node "JSXMemberExpression" loc [("object", _object); ("property", jsx_identifier property)] - and jsx_namespaced_name (loc, { JSX.NamespacedName.namespace; name }) = - node - "JSXNamespacedName" - loc - [("namespace", jsx_identifier namespace); ("name", jsx_identifier name)] - and jsx_identifier (loc, { JSX.Identifier.name; comments }) = - node ?comments "JSXIdentifier" loc [("name", string name)] - and export_specifier - ( loc, - { - Statement.ExportNamedDeclaration.ExportSpecifier.exported; - local; - export_kind; - from_remote = _; - imported_name_def_loc = _; - } - ) = - let exported = - match exported with - | Some exported -> identifier exported - | None -> identifier local - in - node - "ExportSpecifier" - loc - [ - ("local", identifier local); - ("exported", exported); - ("exportKind", string (string_of_export_kind export_kind)); - ] - and import_default_specifier - { Statement.ImportDeclaration.identifier = id; remote_default_name_def_loc = _ } = - node "ImportDefaultSpecifier" (fst id) [("local", identifier id)] - and import_namespace_specifier (loc, id) = - node "ImportNamespaceSpecifier" loc [("local", identifier id)] - and import_named_specifier local_id remote_id kind kind_loc = - let start_loc = - match kind_loc with - | Some kl -> kl - | None -> fst remote_id - in - let span_loc = - match local_id with - | Some local_id -> Loc.btwn start_loc (fst local_id) - | None -> Loc.btwn start_loc (fst remote_id) - in - let local_id = - match local_id with - | Some id -> id - | None -> remote_id - in - node - "ImportSpecifier" - span_loc - [ - ("imported", identifier remote_id); - ("local", identifier local_id); - ( "importKind", - match kind with - | Some Statement.ImportDeclaration.ImportType -> string "type" - | Some Statement.ImportDeclaration.ImportTypeof -> string "typeof" - | Some Statement.ImportDeclaration.ImportValue - | None -> - null - ); - ] - and import_attribute { Statement.ImportDeclaration.loc; key; value } = - let key_json = - match key with - | Statement.ImportDeclaration.Identifier id -> identifier id - | Statement.ImportDeclaration.StringLiteral (loc, lit) -> string_literal (loc, lit) - in - let value_json = string_literal value in - node "ImportAttribute" loc [("key", key_json); ("value", value_json)] - and comment_list comments = array_of_list comment comments - and comment (loc, c) = - Comment.( - let (_type, value) = - match c with - | { kind = Line; text = s; _ } -> ("Line", s) - | { kind = Block; text = s; _ } -> ("Block", s) - in - node _type loc [("value", string value)] - ) - and predicate (loc, { Ast.Type.Predicate.kind; comments }) = - let open Ast.Type.Predicate in - let (_type, value) = - match kind with - | Declared e -> ("DeclaredPredicate", [("value", expression e)]) - | Inferred -> ("InferredPredicate", []) - in - node ?comments _type loc value - and call_node_properties - ~in_optional_chain ?wrap_callee { Expression.Call.callee; targs; arguments; comments = _ } = - let callee = - match wrap_callee with - | None -> expression ~in_optional_chain callee - | Some wrap -> wrap (expression ~in_optional_chain callee) - in - [ - ("callee", callee); - ("typeArguments", option call_type_args targs); - ("arguments", arg_list ~in_optional_chain arguments); - ] - and member_node_properties - ~in_optional_chain ?wrap_receiver { Expression.Member._object; property; comments = _ } = - let (property, computed) = - match property with - | Expression.Member.PropertyIdentifier id -> (identifier id, false) - | Expression.Member.PropertyPrivateName name -> (private_identifier name, false) - | Expression.Member.PropertyExpression expr -> (expression ~in_optional_chain expr, true) - in - let _object = - match wrap_receiver with - | None -> expression ~in_optional_chain _object - | Some wrap -> wrap (expression ~in_optional_chain _object) - in - [("object", _object); ("property", property); ("computed", bool computed)] - in - { program; expression } - - let program offset_table = (make_functions offset_table).program - - let expression offset_table = (make_functions offset_table).expression -end diff --git a/compiler/flow_parser/parser/jsdoc.ml b/compiler/flow_parser/parser/jsdoc.ml deleted file mode 100644 index 3ef373e5e8..0000000000 --- a/compiler/flow_parser/parser/jsdoc.ml +++ /dev/null @@ -1,308 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module Sedlexing = Flow_sedlexing - -module Param = struct - type optionality = - | NotOptional - | Optional - | OptionalWithDefault of string - [@@deriving show, eq] - - type info = { - description: string option; - optional: optionality; - } - [@@deriving show, eq] - - type path = - | Name - | Element of path - | Member of path * string - [@@deriving show, eq] - - type t = (path * info) list [@@deriving show, eq] -end - -module Params = struct - type t = (string * Param.t) list [@@deriving show, eq] -end - -module Unrecognized_tags = struct - type t = (string * string option) list [@@deriving show, eq] -end - -type t = { - description: string option; - params: Params.t; - deprecated: string option; - unrecognized_tags: Unrecognized_tags.t; -} - -(*************) -(* accessors *) -(*************) - -let description { description; _ } = description - -let params { params; _ } = params - -let deprecated { deprecated; _ } = deprecated - -let unrecognized_tags { unrecognized_tags; _ } = unrecognized_tags - -(***********) -(* parsing *) -(***********) - -module Parser = struct - (* regexps copied from Flow_lexer since sedlex doesn't let us import them *) - - let whitespace = - [%sedlex.regexp? - ( 0x0009 | 0x000B | 0x000C | 0x0020 | 0x00A0 | 0xfeff | 0x1680 - | 0x2000 .. 0x200a - | 0x202f | 0x205f | 0x3000 )] - - let line_terminator_sequence = [%sedlex.regexp? '\n' | '\r' | "\r\n" | 0x2028 | 0x2029] - - let identifier = [%sedlex.regexp? Plus (Compl (white_space | '[' | '.' | ']' | '=' | '{'))] - - (* Helpers *) - - let empty = { description = None; params = []; deprecated = None; unrecognized_tags = [] } - - let trim_end s = - let is_space = function - | ' ' - | '\012' - | '\n' - | '\r' - | '\t' -> - true - | _ -> false - in - let len = String.length s in - let j = ref (len - 1) in - while !j >= 0 && is_space (String.get s !j) do - decr j - done; - if !j = len - 1 then - s - else if !j >= 0 then - String.sub s 0 (!j + 1) - else - "" - - let trimmed_string_of_buffer buffer = buffer |> Buffer.contents |> trim_end - - let description_of_desc_buf desc_buf = - match trimmed_string_of_buffer desc_buf with - | "" -> None - | s -> Some s - - (* like Base.List.Assoc.add, but maintains ordering differently: - * - if k is already in the list, keeps it in that position and updates the value - * - if k isn't in the list, adds it to the end *) - let rec add_assoc ~equal k v = function - | [] -> [(k, v)] - | (k', v') :: xs -> - if equal k' k then - (k, v) :: xs - else - (k', v') :: add_assoc ~equal k v xs - - let add_param jsdoc name path description optional = - let old_param_infos = - match Base.List.Assoc.find ~equal:String.equal jsdoc.params name with - | None -> [] - | Some param_infos -> param_infos - in - let new_param_infos = - add_assoc ~equal:Param.equal_path path { Param.description; optional } old_param_infos - in - { jsdoc with params = add_assoc ~equal:String.equal name new_param_infos jsdoc.params } - - let add_unrecognized_tag jsdoc name description = - let { unrecognized_tags; _ } = jsdoc in - { jsdoc with unrecognized_tags = unrecognized_tags @ [(name, description)] } - - (* Parsing functions *) - - (* - `description`, `description_or_tag`, and `description_startline` are - helpers for parsing descriptions: a description is a possibly-multiline - string terminated by EOF or a new tag. The beginning of each line could - contain whitespace and asterisks, which are stripped out when parsing. - *) - let rec description desc_buf lexbuf = - match%sedlex lexbuf with - | line_terminator_sequence -> - Buffer.add_string desc_buf (Sedlexing.Utf8.lexeme lexbuf); - description_startline desc_buf lexbuf - | any -> - Buffer.add_string desc_buf (Sedlexing.Utf8.lexeme lexbuf); - description desc_buf lexbuf - | _ (* eof *) -> description_of_desc_buf desc_buf - - and description_or_tag desc_buf lexbuf = - let rec skip_and_count_significant_whitespace acc = - match%sedlex lexbuf with - | whitespace -> skip_and_count_significant_whitespace (acc + 1) - | '@' -> None - | _ -> Some acc - in - match skip_and_count_significant_whitespace 0 with - | None -> description_of_desc_buf desc_buf - | Some count -> - for _i = 1 to count do - Buffer.add_char desc_buf ' ' - done; - description desc_buf lexbuf - - and description_startline desc_buf lexbuf = - match%sedlex lexbuf with - | '*' -> description_or_tag desc_buf lexbuf - | whitespace -> description_startline desc_buf lexbuf - | _ -> description_or_tag desc_buf lexbuf - - let rec param_path ?(path = Param.Name) lexbuf = - match%sedlex lexbuf with - | "[]" -> param_path ~path:(Param.Element path) lexbuf - | ('.', identifier) -> - let member = Sedlexing.Utf8.sub_lexeme lexbuf 1 (Sedlexing.lexeme_length lexbuf - 1) in - param_path ~path:(Param.Member (path, member)) lexbuf - | _ -> path - - let rec skip_tag jsdoc lexbuf = - match%sedlex lexbuf with - | Plus (Compl '@') -> skip_tag jsdoc lexbuf - | '@' -> tag jsdoc lexbuf - | _ (* eof *) -> jsdoc - - and param_tag_description jsdoc name path optional lexbuf = - let desc_buf = Buffer.create 127 in - let description = description desc_buf lexbuf in - let jsdoc = add_param jsdoc name path description optional in - tag jsdoc lexbuf - - and param_tag_pre_description jsdoc name path optional lexbuf = - match%sedlex lexbuf with - | ' ' -> param_tag_pre_description jsdoc name path optional lexbuf - | '-' -> param_tag_description jsdoc name path optional lexbuf - | _ -> param_tag_description jsdoc name path optional lexbuf - - and param_tag_optional_default jsdoc name path def_buf lexbuf = - match%sedlex lexbuf with - | ']' -> - let default = Buffer.contents def_buf in - param_tag_pre_description jsdoc name path (Param.OptionalWithDefault default) lexbuf - | Plus (Compl ']') -> - Buffer.add_string def_buf (Sedlexing.Utf8.lexeme lexbuf); - param_tag_optional_default jsdoc name path def_buf lexbuf - | _ -> - let default = Buffer.contents def_buf in - param_tag_pre_description jsdoc name path (Param.OptionalWithDefault default) lexbuf - - and param_tag_optional jsdoc lexbuf = - match%sedlex lexbuf with - | identifier -> - let name = Sedlexing.Utf8.lexeme lexbuf in - let path = param_path lexbuf in - (match%sedlex lexbuf with - | ']' -> param_tag_pre_description jsdoc name path Param.Optional lexbuf - | '=' -> - let def_buf = Buffer.create 127 in - param_tag_optional_default jsdoc name path def_buf lexbuf - | _ -> param_tag_pre_description jsdoc name path Param.Optional lexbuf) - | _ -> skip_tag jsdoc lexbuf - - (* ignore jsdoc type annotation *) - and param_tag_type jsdoc lexbuf = - match%sedlex lexbuf with - | '}' -> param_tag jsdoc lexbuf - | Plus (Compl '}') -> param_tag_type jsdoc lexbuf - | _ (* eof *) -> jsdoc - - and param_tag jsdoc lexbuf = - match%sedlex lexbuf with - | ' ' -> param_tag jsdoc lexbuf - | '{' -> param_tag_type jsdoc lexbuf - | '[' -> param_tag_optional jsdoc lexbuf - | identifier -> - let name = Sedlexing.Utf8.lexeme lexbuf in - let path = param_path lexbuf in - param_tag_pre_description jsdoc name path Param.NotOptional lexbuf - | _ -> skip_tag jsdoc lexbuf - - and description_tag jsdoc lexbuf = - let desc_buf = Buffer.create 127 in - let description = description desc_buf lexbuf in - let jsdoc = { jsdoc with description } in - tag jsdoc lexbuf - - and deprecated_tag jsdoc lexbuf = - let deprecated_tag_buf = Buffer.create 127 in - let deprecated = Some (Base.Option.value ~default:"" (description deprecated_tag_buf lexbuf)) in - { jsdoc with deprecated } - - and unrecognized_tag jsdoc name lexbuf = - let desc_buf = Buffer.create 127 in - let description = description desc_buf lexbuf in - let jsdoc = add_unrecognized_tag jsdoc name description in - tag jsdoc lexbuf - - and tag jsdoc lexbuf = - match%sedlex lexbuf with - | "param" - | "arg" - | "argument" -> - param_tag jsdoc lexbuf - | "description" - | "desc" -> - description_tag jsdoc lexbuf - | "deprecated" -> deprecated_tag jsdoc lexbuf - | identifier -> - let name = Sedlexing.Utf8.lexeme lexbuf in - unrecognized_tag jsdoc name lexbuf - | _ -> skip_tag jsdoc lexbuf - - let initial lexbuf = - match%sedlex lexbuf with - | ('*', Compl '*') -> - Sedlexing.rollback lexbuf; - let desc_buf = Buffer.create 127 in - let description = description_startline desc_buf lexbuf in - let jsdoc = { empty with description } in - Some (tag jsdoc lexbuf) - | _ -> None -end - -let parse str = - let lexbuf = Sedlexing.Utf8.from_string str in - Parser.initial lexbuf - -(* find and parse the last jsdoc-containing comment in the list if exists *) -let of_comments = - let open Flow_ast in - let of_comment = function - | (l, Comment.{ kind = Block; text; _ }) -> - (match parse text with - | Some d -> Some (l, d) - | None -> None) - | (_, Comment.{ kind = Line; _ }) -> None - in - let rec of_comment_list = function - | [] -> None - | c :: cs -> - (match of_comment_list cs with - | Some _ as j -> j - | None -> of_comment c) - in - let of_syntax Syntax.{ leading; _ } = of_comment_list leading in - Base.Option.bind ~f:of_syntax diff --git a/compiler/flow_parser/parser/jsdoc.mli b/compiler/flow_parser/parser/jsdoc.mli deleted file mode 100644 index f17a6081c7..0000000000 --- a/compiler/flow_parser/parser/jsdoc.mli +++ /dev/null @@ -1,58 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module Param : sig - type optionality = - | NotOptional - | Optional - | OptionalWithDefault of string - [@@deriving show, eq] - - type info = { - description: string option; - optional: optionality; - } - [@@deriving show, eq] - - type path = - | Name - | Element of path - | Member of path * string - [@@deriving show, eq] - - type t = (path * info) list [@@deriving show, eq] -end - -module Params : sig - type t = (string * Param.t) list [@@deriving show, eq] -end - -module Unrecognized_tags : sig - type t = (string * string option) list [@@deriving show, eq] -end - -type t - -(*************) -(* accessors *) -(*************) - -val description : t -> string option - -val params : t -> Params.t - -val deprecated : t -> string option - -val unrecognized_tags : t -> Unrecognized_tags.t - -(***********) -(* parsing *) -(***********) - -val parse : string -> t option - -val of_comments : ('M, 'T) Flow_ast.Syntax.t option -> ('M * t) option diff --git a/compiler/flow_parser/parser/offset_utils.ml b/compiler/flow_parser/parser/offset_utils.ml deleted file mode 100644 index aaf64def1e..0000000000 --- a/compiler/flow_parser/parser/offset_utils.ml +++ /dev/null @@ -1,172 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(* table from 0-based line number and 0-based column number to the offset at that point *) -type t = int array array - -type offset_kind = - | Utf8 - | JavaScript - -(* Classify each codepoint. We care about how many bytes each codepoint takes, in order to - compute offsets in terms of bytes instead of codepoints. We also care about various kinds of - newlines. To reduce memory, it is important that this is a basic variant with no parameters - (so, don't make it `Chars of int`). *) -type kind = - (* Char has a codepoint greater than or equal to 0x0 but less than 0x80 *) - | Chars_0x0 - (* Char has a codepoint greater than or equal to 0x80 but less than 0x800 *) - | Chars_0x80 - | Chars_0x800 - | Chars_0x10000 - | Malformed - | Cr - | Nl - | Ls - -(* Gives the size in bytes of the character's UTF-8 encoding *) -let utf8_size_of_kind = function - | Chars_0x0 -> 1 - | Chars_0x80 -> 2 - | Chars_0x800 -> 3 - | Chars_0x10000 -> 4 - | Malformed -> 1 - | Cr -> 1 - | Nl -> 1 - | Ls -> 3 - -(* Gives the size in code units (16-bit blocks) of the character's UTF-16 encoding *) -let js_size_of_kind = function - | Chars_0x0 - | Chars_0x80 - | Chars_0x800 -> - 1 - | Chars_0x10000 -> 2 - | Malformed -> 1 - | Cr -> 1 - | Nl -> 1 - | Ls -> 1 - -let make = - (* Using Wtf8 allows us to properly track multi-byte characters, so that we increment the column - * by 1 for a multi-byte character, but increment the offset by the number of bytes in the - * character. It also keeps us from incrementing the line number if a multi-byte character happens - * to include e.g. the codepoint for '\n' as a second-fourth byte. *) - let fold_codepoints acc _offset chr = - let kind = - match chr with - | Wtf8.Point code -> - if code == 0x2028 || code == 0x2029 then - Ls - else if code == 0xA then - Nl - else if code == 0xD then - Cr - else if code >= 0x10000 then - Chars_0x10000 - else if code >= 0x800 then - Chars_0x800 - else if code >= 0x80 then - Chars_0x80 - else - Chars_0x0 - | Wtf8.Malformed -> Malformed - in - kind :: acc - in - (* Traverses a `kind list`, breaking it up into an `int array array`, where each `int array` - contains the offsets at each character (aka codepoint) of a line. *) - let rec build_table size_of_kind (offset, rev_line, acc) = function - | [] -> Array.of_list (List.rev acc) - | Cr :: Nl :: rest -> - (* https://www.ecma-international.org/ecma-262/5.1/#sec-7.3 says that "\r\n" should be treated - like a single line terminator, even though both '\r' and '\n' are line terminators in their - own right. *) - let line = Array.of_list (List.rev (offset :: rev_line)) in - build_table size_of_kind (offset + 2, [], line :: acc) rest - | ((Cr | Nl | Ls) as kind) :: rest -> - let line = Array.of_list (List.rev (offset :: rev_line)) in - build_table size_of_kind (offset + size_of_kind kind, [], line :: acc) rest - | ((Chars_0x0 | Chars_0x80 | Chars_0x800 | Chars_0x10000 | Malformed) as kind) :: rest -> - build_table size_of_kind (offset + size_of_kind kind, offset :: rev_line, acc) rest - in - fun ~kind text -> - let rev_kinds = Wtf8.fold_wtf_8 fold_codepoints [] text in - (* Add a phantom line at the end of the file. Since end positions are reported exclusively, it - * is possible for the lexer to output an end position with a line number one higher than the - * last line, to indicate something such as "the entire last line." For this purpose, we can - * return the offset that is one higher than the last legitimate offset, since it could only be - * correctly used as an exclusive index. *) - let rev_kinds = Nl :: rev_kinds in - let size_of_kind = - match kind with - | Utf8 -> utf8_size_of_kind - | JavaScript -> js_size_of_kind - in - build_table size_of_kind (0, [], []) (List.rev rev_kinds) - -exception Offset_lookup_failed of Loc.position * string - -let lookup arr i pos context_string = - try arr.(i) with - | Invalid_argument _ -> - let msg = - Printf.sprintf - "Failure while looking up %s. Index: %d. Length: %d." - context_string - i - (Array.length arr) - in - raise (Offset_lookup_failed (pos, msg)) - -let offset table pos = - Loc.( - (* Special-case `Loc.none` so we don't try to look up line -1. *) - if pos.line = 0 && pos.column = 0 then - (* Loc.none sets the offset as 0, so that's what we'll return here. *) - 0 - else - (* lines are 1-indexed, columns are zero-indexed *) - let line_table = lookup table (pos.line - 1) pos "line" in - lookup line_table pos.column pos "column" - ) - -let debug_string table = - let buf = Buffer.create 4096 in - Array.iteri - (fun line_num line -> - Printf.bprintf buf "%6d: " line_num; - Array.iter (fun offset -> Printf.bprintf buf "%8d " offset) line; - Buffer.add_char buf '\n') - table; - Buffer.contents buf - -let line_lengths table = - Array.fold_left - (fun (prev_line_end, lengths_rev) line -> - let line_end = line.(Array.length line - 1) in - (line_end, (line_end - prev_line_end) :: lengths_rev)) - (-1, []) - table - |> snd - |> List.rev - -let contains_multibyte_character table = - let exception FoundMultibyte in - try - Array.iter - (fun line -> - Array.iteri - (fun i offset -> - if i > 0 then - let offset_before = line.(i - 1) in - if offset - offset_before > 1 then raise FoundMultibyte) - line) - table; - false - with - | FoundMultibyte -> true diff --git a/compiler/flow_parser/parser/offset_utils.mli b/compiler/flow_parser/parser/offset_utils.mli deleted file mode 100644 index a5fc4bc4c9..0000000000 --- a/compiler/flow_parser/parser/offset_utils.mli +++ /dev/null @@ -1,56 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(* Note on character encodings: - * - * Throughout Flow, we assume that program text uses a UTF-8 encoding. OCaml strings are just a - * sequence of bytes, so any handling of multi-byte characters needs to be done explicitly. - * - * Column numbers in `Loc.position`s are based on the number of characters into a line the position - * appears, not the number of bytes. Single-byte and multi-byte characters are treated the same for - * the purposes of counting columns. - * - * However, offsets are most useful (at least when working with OCaml's string representation) when - * they represent the number of bytes into the text a given position is. - * - * In contrast, JavaScript strings must behave as if they have a UTF-16 encoding, and each element - * is a single 16-bit entry. So, each character occupies either one or two elements of a JavaScript - * string. Esprima, for example, returns ranges based on index into a JS string. - * - * Clients can choose between byte offsets and UTF-16 code unit offsets when building the offset - * table. - * - * For example, with the Utf8 offset kind selected, this utility would consider the smiley emoji - * (code point 0x1f603) to have width 4 (because its UTF-8 encoding is 4 8-bit elements), but with - * the JavaScript offset kind selected, it (and Esprima) would consider it to have width 2 (because - * its UTF-16 encoding is 2 16-bit elements). - *) - -(* A structure that allows for quick computation of offsets when given a Loc.position *) -type t - -type offset_kind = - | Utf8 - | JavaScript - -(* Create a table for offsets in the given file. Takes O(n) time and returns an object that takes - * O(n) space, where `n` is the size of the given program text. *) -val make : kind:offset_kind -> string (* program text *) -> t - -exception Offset_lookup_failed of Loc.position * string - -(* Returns the offset for the given location. This is the offset in bytes (not characters!) into the - * file where the given position can be found. Constant time operation. Raises - * `Offset_lookup_failed` if the given position does not exist in the file contents which were used - * to construct the table. *) -val offset : t -> Loc.position -> int - -val debug_string : t -> string - -val line_lengths : t -> int list - -val contains_multibyte_character : t -> bool diff --git a/compiler/flow_parser/parser/relativeLoc.ml b/compiler/flow_parser/parser/relativeLoc.ml deleted file mode 100644 index 3c0f5625fb..0000000000 --- a/compiler/flow_parser/parser/relativeLoc.ml +++ /dev/null @@ -1,35 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -type t = - | Same_line of { - start: Loc.position; - column_offset: int; - } - | Diff_line of { - start: Loc.position; - line_offset: int; - column: int; - } - -let of_loc ({ Loc.start = base_pos; _end = pos; _ } : Loc.t) = - let line_offset = pos.Loc.line - base_pos.Loc.line in - if line_offset = 0 then - Same_line { start = base_pos; column_offset = pos.Loc.column - base_pos.Loc.column } - else - Diff_line { start = base_pos; line_offset; column = pos.Loc.column } - -let to_loc relative_loc source : Loc.t = - match relative_loc with - | Same_line { start; column_offset } -> - { - Loc.start; - _end = { Loc.line = start.Loc.line; column = start.Loc.column + column_offset }; - source; - } - | Diff_line { start; line_offset; column } -> - { Loc.start; _end = { Loc.line = start.Loc.line + line_offset; column }; source } diff --git a/compiler/flow_parser/parser/relativeLoc.mli b/compiler/flow_parser/parser/relativeLoc.mli deleted file mode 100644 index acca0fe881..0000000000 --- a/compiler/flow_parser/parser/relativeLoc.mli +++ /dev/null @@ -1,27 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -(* - * When we store data to the shared heap, we first marshal it using OCaml's marshaller, then we - * compress it. OCaml's marshaling algorithm uses a more compact representation for smaller - * integers, so it is advantageous to use small integers rather than large ones when serializing to - * the shared heap. - * - * To that end, this utility converts locations so that the end position is stored relative to the - * start position, rather than storing it in absolute terms. The intuition is that the end location - * will always be closer to (or as close as) the start position than to the start of the file, so - * the numbers stored will be smaller and therefore have a more compact representation, on average. - * - * This does not change the in-memory size of the location. It does, however make it smaller to - * serialize. - * *) - -type t - -val of_loc : Loc.t -> t - -val to_loc : t -> File_key.t option -> Loc.t diff --git a/compiler/flow_parser/parser/token_translator.ml b/compiler/flow_parser/parser/token_translator.ml deleted file mode 100644 index 80e359db64..0000000000 --- a/compiler/flow_parser/parser/token_translator.ml +++ /dev/null @@ -1,66 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module Translate (Impl : Translator_intf.S) : sig - type t - - val token : Offset_utils.t -> Parser_env.token_sink_result -> t - - val token_list : Offset_utils.t -> Parser_env.token_sink_result list -> t -end -with type t = Impl.t = struct - type t = Impl.t - - let token offset_table { Parser_env.token_loc; token; token_context } = - Loc.( - Impl.obj - [ - ("type", Impl.string (Token.token_to_string token)); - ( "context", - Impl.string - Parser_env.Lex_mode.( - match token_context with - | NORMAL -> "normal" - | TYPE -> "type" - | JSX_TAG -> "jsxTag" - | JSX_CHILD -> "jsxChild" - | REGEXP -> "regexp" - ) - ); - ( "loc", - Impl.obj - [ - ( "start", - Impl.obj - [ - ("line", Impl.number (float token_loc.start.line)); - ("column", Impl.number (float token_loc.start.column)); - ] - ); - ( "end", - Impl.obj - [ - ("line", Impl.number (float token_loc._end.line)); - ("column", Impl.number (float token_loc._end.column)); - ] - ); - ] - ); - ( "range", - Impl.array - [ - Impl.number (float (Offset_utils.offset offset_table token_loc.start)); - Impl.number (float (Offset_utils.offset offset_table token_loc._end)); - ] - ); - ("value", Impl.string (Token.value_of_token token)); - ] - ) - - let token_list offset_table tokens = - Impl.array (List.rev_map (token offset_table) tokens |> List.rev) -end diff --git a/compiler/flow_parser/parser/translator_intf.ml b/compiler/flow_parser/parser/translator_intf.ml deleted file mode 100644 index a58d8a6986..0000000000 --- a/compiler/flow_parser/parser/translator_intf.ml +++ /dev/null @@ -1,26 +0,0 @@ -(* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - *) - -module type S = sig - type t - - val string : string -> t - - val bool : bool -> t - - val obj : (string * t) list -> t - - val array : t list -> t - - val number : float -> t - - val int : int -> t - - val null : t - - val regexp : Loc.t -> string -> string -> t -end