├── .gitignore ├── .ocamlformat ├── LICENSE ├── Makefile ├── README.md ├── docs-assets └── rebind-vscode.gif ├── dune-project ├── rebind.opam ├── src ├── js │ ├── dune │ ├── rebind_js.ml │ ├── rebind_js.mli │ └── test │ │ ├── dune │ │ └── run.t ├── native │ ├── dune │ ├── rebind.ml │ └── test │ │ ├── dune │ │ └── run.t └── shared │ ├── ast_utils.ml │ ├── dune │ ├── handle_expression.ml │ ├── handle_literal.ml │ ├── handle_plain_statement.ml │ ├── ir_transformer.ml │ ├── shared.ml │ ├── shared_types.ml │ └── utils.ml └── vendor ├── collections ├── dune ├── iMap.ml ├── iSet.ml ├── immQueue.ml ├── immQueue.mli ├── intKey.ml ├── priorityQueue.ml ├── reordered_argument_collections.ml ├── sMap.ml ├── sSet.ml ├── stringKey.ml ├── third-party │ ├── LICENSE │ ├── flow_map.ml │ └── flow_set.ml ├── union_find.ml ├── wrappedMap.ml ├── wrappedMap.mli └── wrappedMap_sig.ml ├── parser ├── Makefile ├── README.md ├── comment_attachment.ml ├── comment_utils.ml ├── declaration_parser.ml ├── dune ├── enum_common.ml ├── enum_parser.ml ├── estree_translator.ml ├── expression_parser.ml ├── file_key.ml ├── flow_ast.ml ├── flow_ast_mapper.ml ├── flow_ast_utils.ml ├── flow_ast_utils.mli ├── flow_lexer.ml ├── flow_lexer.mli ├── js_id.ml ├── js_id.mli ├── js_id_unicode.ml ├── jsdoc.ml ├── jsdoc.mli ├── jsx_parser.ml ├── lex_env.ml ├── lex_result.ml ├── loc.ml ├── loc.mli ├── object_parser.ml ├── offset_utils.ml ├── offset_utils.mli ├── parse_error.ml ├── parse_error_utils.ml ├── parser_common.ml ├── parser_env.ml ├── parser_env.mli ├── parser_flow.ml ├── pattern_cover.ml ├── pattern_parser.ml ├── relativeLoc.ml ├── relativeLoc.mli ├── statement_parser.ml ├── token.ml ├── token_translator.ml ├── translator_intf.ml └── type_parser.ml ├── sedlex-ppx ├── Changes.md ├── LICENSE ├── dune ├── flow_sedlex.ml ├── flow_sedlex.mli ├── ppx_sedlex.ml ├── sedlex_cset.ml └── sedlex_cset.mli └── sedlex ├── Changes.md ├── LICENSE ├── dune ├── flow_sedlexing.ml └── flow_sedlexing.mli /.gitignore: -------------------------------------------------------------------------------- 1 | *TAGS 2 | _build 3 | /_obuild 4 | /.ocp 5 | /lib/INDEX 6 | .DS_STORE 7 | docs/_site/ 8 | _site/ 9 | bin 10 | npm-debug.log 11 | /node_modules/ 12 | /tests/*/*.err 13 | *.swp 14 | *.swo 15 | flow.odocl 16 | flow.docdir 17 | *~ 18 | /hack/utils/get_build_id.gen.c 19 | /flowlib.rc 20 | .DS_Store 21 | .merlin 22 | .bsb.lock 23 | lib/bs/ 24 | *.bs.js 25 | _opam 26 | .vscode 27 | -------------------------------------------------------------------------------- /.ocamlformat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/rebind/53797e3d6fb7f73842691311d4065dcd97095e92/.ocamlformat -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Javier Chávarri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | project_name = rebind 2 | 3 | DUNE = opam exec -- dune 4 | 5 | .DEFAULT_GOAL := help 6 | 7 | .PHONY: help 8 | help: ## Print this help message 9 | @echo "List of available make commands"; 10 | @echo ""; 11 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'; 12 | @echo ""; 13 | 14 | .PHONY: create-switch 15 | create-switch: ## Create opam switch 16 | opam switch create . 5.1.0~rc3 -y --deps-only 17 | 18 | .PHONY: init 19 | init: create-switch install ## Configure everything to develop this repository in local 20 | 21 | .PHONY: install 22 | install: ## Install development dependencies 23 | opam update 24 | opam install -y . --deps-only --with-test 25 | 26 | .PHONY: build 27 | build: ## Build the project 28 | $(DUNE) build 29 | 30 | .PHONY: clean 31 | clean: ## Clean build artifacts and other generated files 32 | $(DUNE) clean 33 | 34 | .PHONY: format 35 | format: ## Format the codebase with ocamlformat 36 | $(DUNE) build @fmt --auto-promote 37 | 38 | .PHONY: format-check 39 | format-check: ## Checks if format is correct 40 | $(DUNE) build @fmt 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :on: Rebind 2 | 3 | Experimental automated generation of Reason/BuckleScript bindings from JavaScript code. 4 | 5 | ## Status 6 | 7 | Rebind is in very early stages. While a few BuckleScript attributes have some minimal support (`[@mel.obj]`, `[@mel.send]`, `[@mel.module]`, ...), the range of JavaScript expressions that are not covered is still quite large (see table below). 8 | 9 | ## Why 10 | 11 | This JavaScript code: 12 | 13 | ```javascript 14 | const nano = require("nano")("http://localhost:5984"); 15 | nano.db.create("foo", (err, body, headers) => { 16 | console.log(err); 17 | }); 18 | ``` 19 | 20 | Requires roughly the following bindings in Reason to be generated: 21 | 22 | ```reason 23 | type nano; 24 | type err; 25 | type body; 26 | type headers; 27 | type db; 28 | type create; 29 | [@mel.module] external nano : string => nano = ""; 30 | [@mel.get] external db : nano => db = ""; 31 | [@mel.send] 32 | external create : (db, string, (err, body, headers) => unit) => create = ""; 33 | ``` 34 | 35 | The process of creating bindings is a core part of introducing Reason / BuckleScript into existing JavaScript applications. However, this binding creation is a non-trivial process, and it might become a time consuming activity over time. Plus, it requires remembering the different BuckleScript attributes for each case, which, at least in my experience, has been challenging. 36 | 37 | Rebind is an attempt to help easing this process by parsing JavaScript code, and generating as many bindings as possible based on the available syntactic information. 38 | 39 | Over time, Rebind might become a way of coding "best practices" when it comes to write bindings, depending on the community consensus for each particular case. 40 | 41 | Potentially, at some point in the future, Rebind could be integrated with editor extensions, allowing for easier migration of JavaScript apps to Reason / BuckleScript: 42 | 43 | ![Potential VSCode integration](./docs-assets/rebind-vscode.gif) 44 | 45 | ## Install 46 | 47 | 1. From your terminal: 48 | ```bash 49 | git clone https://github.com/jchavarri/rebind 50 | npm install -g . 51 | ``` 52 | 1. Rebind needs `refmt` to output the Reason/OCaml code, so you will have to follow the instructions from the [official Reason docs](https://reasonml.github.io/docs/en/global-installation.html) to get it installed. 53 | 54 | ## Running 55 | 56 | From the terminal: 57 | 58 | `rebind yourFile.js | refmt --parse binary --print re` 59 | 60 | Rebind also supports passing some input JavaScript in stdin, like so: 61 | 62 | `echo "var t = {a:2}" | rebind` 63 | 64 | --- 65 | 66 | ## How does it work 67 | 68 | Rebind analyzes the JavaScript syntax tree from a given piece of JavaScript code and tries to generate an OCaml syntax tree that defines bindings to the expressions the JavaScript code contains. 69 | 70 | This derivation can be very accurate at times, (whenever many literals are used) but in general it will be a best effort approach. If your code uses a lot of variables which value is defined outside the code being analyzed, Rebind will "fill the gaps" using opaque types. 71 | 72 | For example, this JavaScript code: 73 | 74 | ```javascript 75 | const result = something.awesome("test"); 76 | ``` 77 | 78 | ```reason 79 | type something; 80 | type awesome; 81 | [@mel.module] external something : something = ""; 82 | [@mel.send] external awesome : (something, string) => awesome = ""; 83 | ``` 84 | 85 | As you can see, `something` is inferred to be an external module, and a companion opaque type is created for it. 86 | 87 | ## Expressions supported 88 | 89 | **Legend** 90 | - :egg: no support yet / unclear 91 | - :hatching_chick: some basic support 92 | - :chicken: full support 93 | 94 | Expression Name | Binding(s) generated | Status 95 | ------------ | ------------- | ------------- 96 | Function | None, it iterates over params to get identifiers | :hatching_chick: 97 | ArrowFunction | None, it iterates over params to get identifiers | :hatching_chick: 98 | Identifier | `[@mel.module]` | :hatching_chick: 99 | Literal | None, return types for bindings to be used | :hatching_chick: 100 | Call | `[@mel.module]` or `[@mel.send]` | :hatching_chick: 101 | Member | `[@mel.get]` | :hatching_chick: 102 | Object | `[@mel.obj]` | :hatching_chick: 103 | This | - | :egg: 104 | Super | - | :egg: 105 | Array | - | :egg: 106 | Sequence | - | :egg: 107 | Unary | - | :egg: 108 | Binary | - | :egg: 109 | Assignment | - | :egg: 110 | Update | - | :egg: 111 | Logical | - | :egg: 112 | Conditional | - | :egg: 113 | New | - | :egg: 114 | Yield | - | :egg: 115 | Comprehension | - | :egg: 116 | Generator | - | :egg: 117 | TemplateLiteral | - | :egg: 118 | TaggedTemplate | - | :egg: 119 | JSXElement | - | :egg: 120 | Class | - | :egg: 121 | TypeCast | - | :egg: 122 | MetaProperty | - | :egg: 123 | 124 | 125 | ## Frequently asked questions 126 | 127 | #### Does this support JSX / other fancy syntax features? 128 | 129 | Probably not. See the table above. 130 | 131 | #### Can I use this with VSCode or my editor of choice? 132 | 133 | Not yet, but there are proof of concepts like shown in the GIF above that are being explored, and it could be possible at some point in the future. 134 | 135 | #### Can I use it from Node / the browser? 136 | 137 | Not yet, but it should be possible. It "just" needs to be compiled together with `refmt`, as both tools need to share the binary representation of OCaml / Reason syntax tree. 138 | 139 | #### How can I contribute? 140 | 141 | * Report bugs 142 | * Provide examples of JavaScript code + bindings that you'd like to see generated (you can do so by creating a PR with a failing test) 143 | * Open discussion issues to debate what kind of bindings we could generate from some of the expressions from the table above 144 | 145 | ## Acknowledgements / preliminary work 146 | 147 | #### Jeason 148 | 149 | Rebind is more than influenced by Jeason. It was originally a fork of that project, but at some point it became more and more obvious that the original vision of Jeason is much more ambitious, and those differences made hard to conciliate both projects at the technical level. Rebind wouldn't be possible without Jeason and the work @chenglou did. :sparkles: 150 | 151 | #### Flow 152 | 153 | As Jeason, Rebind contains a vendored version of the Flow parser, which allows to generate the JavaScript syntax tree. 154 | 155 | #### JavaScript to ReasonML transpiler 156 | 157 | Another influence for this project has been the [JavaScript to ReasonML Transpiler](https://github.com/emnh/js-to-reasonml-transpiler) by Eivind Magnus Hvidevold, that takes a different approach by running the JavaScript code at runtime and getting the type information there. This allows to get much better accuracy than Rebind, at the cost of a heavier footprint due to these runtime constraints. 158 | -------------------------------------------------------------------------------- /docs-assets/rebind-vscode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/rebind/53797e3d6fb7f73842691311d4065dcd97095e92/docs-assets/rebind-vscode.gif -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.8) 2 | 3 | (cram enable) 4 | 5 | (using melange 0.1) 6 | 7 | (name rebind) 8 | -------------------------------------------------------------------------------- /rebind.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | synopsis: "Rebind" 3 | description: "Experimental automated generation of Melange bindings from JavaScript code" 4 | maintainer: ["jchavarri"] 5 | authors: ["jchavarri"] 6 | license: "MIT" 7 | homepage: "https://github.com/jchavarri/rebind" 8 | bug-reports: "https://github.com/jchavarri/rebind/issues" 9 | depends: [ 10 | "ocaml" 11 | "dune" {>= "3.9"} 12 | "reason" {>= "3.10.0"} 13 | "js_of_ocaml" 14 | "ocamlformat" 15 | "ppx_deriving" # flow 16 | "ppx_gen_rec" # flow 17 | "ppxlib" # flow 18 | "base" {>= "v0.14.1"} # flow 19 | "wtf8" # flow 20 | "melange" {>= "1.0.0" & with-test} 21 | "ocaml-lsp-server" {with-test} # todo: use with-dev-setup once 2.2 is out 22 | "dot-merlin-reader" {with-test} 23 | "odoc" {with-doc} 24 | ] 25 | build: [ 26 | ["dune" "subst"] {dev} 27 | [ 28 | "dune" 29 | "build" 30 | "-p" 31 | name 32 | "-j" 33 | jobs 34 | "@install" 35 | "@runtest" {with-test} 36 | "@doc" {with-doc} 37 | ] 38 | ] 39 | dev-repo: "git+https://github.com/jchavarri/rebind.git" 40 | pin-depends: [ 41 | ["melange.dev" "git+https://github.com/melange-re/melange.git#e114ad55d185badeb32b3c766c9ab547495eac1b"] 42 | ["reason.3.10.0" "git+https://github.com/reasonml/reason.git#972261dab3b651ff8ab9b8b9fcc32940595073dc"] 43 | ] 44 | -------------------------------------------------------------------------------- /src/js/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name rebind_js) 3 | (public_name rebind_js) 4 | (modes byte js) 5 | (libraries js_of_ocaml-compiler.runtime reason shared)) 6 | 7 | (install 8 | (section bin) 9 | (package rebind) 10 | (files 11 | (rebind_js.bc.js as rebind.js))) 12 | -------------------------------------------------------------------------------- /src/js/rebind_js.ml: -------------------------------------------------------------------------------- 1 | module Js = Jsoo_runtime.Js 2 | 3 | let export (field : Js.t) v = Js.set (Js.pure_js_expr "globalThis") field v 4 | 5 | module Reason = struct 6 | module Js = Jsoo_runtime.Js 7 | module RE = Reason_toolchain.RE 8 | 9 | let printWith ~f structureAndComments = 10 | Js.string (Format.asprintf "%a" f structureAndComments) 11 | 12 | let printRE = printWith ~f:RE.print_implementation_with_comments 13 | end 14 | 15 | let () = 16 | export (Js.string "rebind") 17 | (Js.obj 18 | [| 19 | ( "generateML", 20 | Js.wrap_meth_callback (fun _ js_code -> 21 | let result = 22 | Pprintast.string_of_structure 23 | (Shared.get_bindings None js_code) 24 | in 25 | Js.(obj [| ("code", Js.string result) |])) ); 26 | ( "generateRE", 27 | Js.wrap_meth_callback (fun _ js_code -> 28 | let result = Shared.get_bindings None js_code in 29 | let reason = 30 | Reason.printRE 31 | (Ppxlib.Selected_ast.Of_ocaml.copy_structure result, []) 32 | in 33 | Js.(obj [| ("code", (reason : Js.t)) |])) ); 34 | |]) 35 | -------------------------------------------------------------------------------- /src/js/rebind_js.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchavarri/rebind/53797e3d6fb7f73842691311d4065dcd97095e92/src/js/rebind_js.mli -------------------------------------------------------------------------------- /src/js/test/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (deps ../rebind_js.bc.js %{bin:rebind_js})) 3 | -------------------------------------------------------------------------------- /src/js/test/run.t: -------------------------------------------------------------------------------- 1 | Prepare an input file to test some snippets to exercise common functionality 2 | 3 | $ cat > input.js <<\EOF 4 | > require(process.env.DUNE_SOURCEROOT + '/_build/default/src/js/rebind_js.bc.js'); 5 | > console.log(rebind.generateML("const nano = Nano(\"test\", 4);")); 6 | > EOF 7 | 8 | $ node input.js 9 | { code: 'type nano\nexternal nano : string -> float -> nano = "Nano"' } 10 | -------------------------------------------------------------------------------- /src/native/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name rebind) 3 | (public_name rebind) 4 | (libraries ocamlformat-lib shared unix)) 5 | -------------------------------------------------------------------------------- /src/native/rebind.ml: -------------------------------------------------------------------------------- 1 | let cat filename = 2 | let ic = open_in_bin filename in 3 | let len = in_channel_length ic in 4 | let buf = Buffer.create len in 5 | Buffer.add_channel buf ic len; 6 | let content = Buffer.contents buf in 7 | close_in ic; 8 | content 9 | 10 | let read_stdin () = 11 | let out = ref (input_line stdin) in 12 | if String.length !out > 0 then 13 | try 14 | while true do 15 | let line = input_line stdin in 16 | out := String.concat "" [ !out; line ] 17 | done; 18 | "" 19 | with End_of_file -> !out 20 | else !out 21 | 22 | let processContent () = 23 | let file, content = 24 | if Array.length Sys.argv <> 2 && not (Unix.isatty Unix.stdin) then 25 | ("stdin", read_stdin ()) 26 | else 27 | let file = Sys.argv.(1) in 28 | let content = cat file in 29 | (file, content) 30 | in 31 | let result = 32 | Pprintast.string_of_structure 33 | (Shared.get_bindings (Some (File_key.SourceFile file)) content) 34 | in 35 | let formatted = 36 | let open Ocamlformat_lib in 37 | match 38 | Translation_unit.parse_and_format Syntax.Use_file Conf.default 39 | ~input_name:"_none_" ~source:result 40 | with 41 | | Ok formatted -> formatted 42 | | Error _e -> failwith "ocamlformat error" 43 | in 44 | print_endline formatted 45 | 46 | let () = 47 | if Array.length Sys.argv <> 2 && Unix.isatty Unix.stdin then 48 | print_endline "Missing input: Add a file path or use stdin" 49 | else processContent () 50 | -------------------------------------------------------------------------------- /src/native/test/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (deps %{bin:melc} %{bin:rebind})) 3 | -------------------------------------------------------------------------------- /src/shared/ast_utils.ml: -------------------------------------------------------------------------------- 1 | open Asttypes 2 | open Longident 3 | 4 | let strip_chars charsToStrip s = 5 | let len = String.length s in 6 | let res = Bytes.create len in 7 | let rec aux i j = 8 | if i >= len then Bytes.sub res 0 j 9 | else if Bytes.contains charsToStrip s.[i] then aux (succ i) j 10 | else ( 11 | Bytes.set res j s.[i]; 12 | aux (succ i) (succ j)) 13 | in 14 | Bytes.to_string (aux 0 0) 15 | 16 | let correct_labelled_arg name = 17 | let corrected_name = 18 | match name with 19 | | "" -> "_" 20 | | _ -> 21 | let first_char = name.[0] in 22 | if Char.uppercase_ascii first_char = first_char then "_" ^ name 23 | else name 24 | in 25 | let process_reserved_words name = 26 | match name with 27 | | "object" -> "_object" 28 | | "type" -> "_type" 29 | | "done" -> "_done" 30 | | "then" -> "_then" 31 | | n -> n 32 | in 33 | process_reserved_words corrected_name 34 | 35 | (* helpers *) 36 | (* TODO: turn foo_bar into foo_bar_ *) 37 | let correct_identifier ident = 38 | let rec strip_leading_underscores s = 39 | if String.length s = 0 then s 40 | else if s.[0] = '_' then 41 | strip_leading_underscores (String.sub s 1 (String.length s - 1)) 42 | else s 43 | in 44 | (* ocaml/reason identifiers need to be lower-cased (uppercase reserved for variants constructors, modules, etc.)*) 45 | if ident = "" then ident 46 | else 47 | (* foo => foo 48 | Foo => foo 49 | _foo => foo 50 | _foo_bar => foo_bar_ *) 51 | let correctedName = 52 | strip_leading_underscores ident |> strip_chars (Bytes.of_string ".-") 53 | in 54 | (* correct other cases where the js name is a reserved ocaml/reason keyword *) 55 | let correctedName = 56 | match String.contains correctedName '_' with 57 | | true -> correctedName ^ "_" 58 | | false -> correctedName 59 | in 60 | let correctedName = String.uncapitalize_ascii correctedName in 61 | let process_reserved_words name = 62 | match name with 63 | | "object" -> "object_" 64 | | "type" -> "type_" 65 | | "done" -> "done_" 66 | | "then" -> "then_" 67 | | n -> n 68 | in 69 | process_reserved_words correctedName 70 | 71 | let ast_helper_str_lident a = 72 | match a with 73 | | [] -> raise (Invalid_argument "identifier is empty.") 74 | | _ -> 75 | let inner = Lident (List.hd a) in 76 | let res = 77 | List.tl a |> List.fold_left (fun acc curr -> Ldot (acc, curr)) inner 78 | in 79 | { loc = Ast_helper.default_loc.contents; txt = res } 80 | -------------------------------------------------------------------------------- /src/shared/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name shared) 3 | (libraries flow_parser compiler-libs)) 4 | -------------------------------------------------------------------------------- /src/shared/handle_expression.ml: -------------------------------------------------------------------------------- 1 | open Parser_flow.Ast.Expression 2 | open Shared_types 3 | 4 | type callable_expr = CallExpr | NewExpr 5 | 6 | let get_state (state, _lastType) = state 7 | 8 | let maybe_add_identifier ?customType state name = 9 | let lastType, output_types = 10 | match Utils.try_find_id name state.identifiers with 11 | | Some existingType -> (existingType, state.output_types) 12 | | None -> 13 | ( Utils.get_with_default customType (Abstract name), 14 | name :: state.output_types ) 15 | in 16 | ( { 17 | state with 18 | output_types; 19 | identifiers = Identifiers.add name lastType state.identifiers; 20 | }, 21 | lastType ) 22 | 23 | let maybe_add_external state externalAttr name inputTypes = 24 | let state, lastType = maybe_add_identifier state name in 25 | let name = 26 | match externalAttr with 27 | | ObjectCreation -> 28 | String.concat "" [ "make"; String.capitalize_ascii name ] 29 | | _ -> name 30 | in 31 | (* Add the potential `make*` identifier *) 32 | let state = 33 | { state with identifiers = Identifiers.add name lastType state.identifiers } 34 | in 35 | (* TODO: Try to match params with existing externals *) 36 | let existingExternal = 37 | Utils.try_find_in_list (fun e -> e.name = name) state.output_externals 38 | in 39 | match existingExternal with 40 | | Some _ -> (state, lastType) 41 | | None -> 42 | let external_statement = 43 | { attr = externalAttr; name; types = inputTypes @ [ lastType ] } 44 | in 45 | ( { 46 | state with 47 | output_externals = external_statement :: state.output_externals; 48 | }, 49 | lastType ) 50 | 51 | let rec handle_callable_expr exprType callee (_, arguments) state = 52 | let callee_loc, callee_exp = callee in 53 | let callee_name = 54 | match callee_exp with 55 | | Identifier (_, { name; comments = _ }) -> name 56 | | Member 57 | { 58 | _object; 59 | property = Member.PropertyIdentifier (_, { name; comments = _ }); 60 | comments = _; 61 | } -> 62 | name 63 | | _ -> "" 64 | in 65 | let state, right_side_types = 66 | arguments.ArgList.arguments 67 | |> List.fold_left 68 | (fun (accState, accTypes) argument -> 69 | match argument with 70 | | Expression e -> 71 | let accState, lastType = h accState e in 72 | (accState, accTypes @ [ lastType ]) 73 | | Spread _ -> failwith "Call.argument.Spread") 74 | ({ state with parent_context_name = callee_name ^ "Param" }, []) 75 | in 76 | match callee_exp with 77 | (* Maybe this shouldn't be nested here, and the recursion should continue... *) 78 | | Identifier (_, { name; comments = _ }) -> ( 79 | match (name, right_side_types) with 80 | | "require", String requireType :: [] -> ( 81 | (* Discard the input types of this expression -they'll be just the string inside `require`-, 82 | and pick the ones passed from above in the state *) 83 | match List.length state.right_side_types > 0 with 84 | | true -> 85 | maybe_add_external state Module requireType state.right_side_types 86 | | false -> 87 | maybe_add_identifier ~customType:(Module requireType) state 88 | requireType) 89 | | _ -> ( 90 | match (exprType, Utils.try_find_id name state.identifiers) with 91 | | NewExpr, Some (Module n) -> 92 | maybe_add_external state ModuleAndNew n right_side_types 93 | | NewExpr, Some (ModuleProperty (moduleName, local, remote)) -> 94 | maybe_add_external state 95 | (ScopedModuleAndNew (moduleName, remote)) 96 | local right_side_types 97 | | NewExpr, _ -> maybe_add_external state NewAttr name right_side_types 98 | | _, Some (Module n) -> 99 | maybe_add_external state Module n right_side_types 100 | | _, Some (ModuleProperty (moduleName, local, remote)) -> 101 | maybe_add_external state 102 | (ScopedModule (moduleName, remote)) 103 | local right_side_types 104 | | _, _ -> maybe_add_external state Val name right_side_types)) 105 | | Member { _object; property; comments = _ } -> ( 106 | let objectState, objectLastType = h state _object in 107 | match property with 108 | | Member.PropertyIdentifier (_, { name; comments = _ }) -> 109 | maybe_add_external objectState Send name 110 | ([ objectLastType ] @ right_side_types) 111 | | PropertyExpression _ -> failwith "Member.PropertyExpression" 112 | | PropertyPrivateName _ -> failwith "Member.PropertyPrivateName") 113 | | _ -> h { state with right_side_types } (callee_loc, callee_exp) 114 | 115 | and h state (_, expression) = 116 | match expression with 117 | | Function f | ArrowFunction f -> 118 | let _loc, params = f.params in 119 | let funName = 120 | match f.id with 121 | | Some (_loc, { name; comments = _ }) -> name 122 | | None -> "Callback" 123 | in 124 | let state, types = 125 | params.params 126 | |> List.fold_left 127 | (fun (accState, accTypes) 128 | ((_loc, p) : ('a, 'b) Flow_ast.Function.Param.t) -> 129 | match snd p.argument with 130 | | Parser_flow.Ast.Pattern.Identifier 131 | { name = _loc, idName; annot = _; optional = _ } -> 132 | let accState, lastType = 133 | maybe_add_identifier accState idName.name 134 | in 135 | (accState, accTypes @ [ lastType ]) 136 | | Object _ | Array _ | Expression _ -> 137 | failwith "Unsupported pattern in Function or ArrowFunction") 138 | (state, []) 139 | in 140 | (maybe_add_identifier state funName |> get_state, Fun (funName, types)) 141 | | Identifier (_, { name; comments = _ }) -> ( 142 | match Utils.try_find_id name state.identifiers with 143 | | Some (Module n) -> maybe_add_external state Module n [] 144 | | Some (ModuleProperty (moduleName, local, remote)) -> 145 | maybe_add_external state (ScopedModule (moduleName, remote)) local [] 146 | | _ -> maybe_add_identifier state name) 147 | | Call { callee; arguments; targs = _; comments = _ } -> 148 | handle_callable_expr CallExpr callee arguments state 149 | | New { callee; arguments; targs = _; comments = _ } -> ( 150 | match arguments with 151 | | Some arguments -> handle_callable_expr NewExpr callee arguments state 152 | | None -> failwith "New with arguments None") 153 | (* I know this duplication is ugly but yolo *) 154 | | Member { _object; property; comments = _ } -> ( 155 | let objectState, objectLastType = 156 | match _object with 157 | | _, Identifier (_, { name; comments = _ }) -> ( 158 | match Utils.try_find_id name state.identifiers with 159 | | Some (Module n) -> maybe_add_external state Module n [] 160 | | Some (ModuleProperty (moduleName, local, remote)) -> 161 | maybe_add_external state 162 | (ScopedModule (moduleName, remote)) 163 | local [] 164 | | _ -> maybe_add_external state Val name []) 165 | | _ -> h state _object 166 | in 167 | match property with 168 | | Member.PropertyIdentifier (_, { name; comments = _ }) -> 169 | maybe_add_external objectState Get name [ objectLastType ] 170 | | PropertyExpression _ -> failwith "Member.PropertyExpression" 171 | | PropertyPrivateName _ -> failwith "Member.PropertyPrivateName") 172 | | Object obj -> 173 | let originalContextName = state.parent_context_name in 174 | let state, objTypes = 175 | obj.properties 176 | |> List.fold_left 177 | (fun (accState, accTypes) property -> 178 | let propertyKey, propertyValue = 179 | match property with 180 | | Object.Property (_loc, property) -> ( 181 | match property with 182 | | Init { key; value; shorthand = _ } -> (key, value) 183 | | Method _ -> 184 | failwith "Object property using unsupported Method" 185 | | Get _ -> failwith "Object property using unsupported Get" 186 | | Set _ -> failwith "Object property using unsupported Set" 187 | ) 188 | | SpreadProperty _ -> 189 | failwith "Spread properties are unsupported" 190 | in 191 | let propertyName = 192 | match propertyKey with 193 | | Identifier (_loc, { name; comments = _ }) -> 194 | Ast_utils.correct_labelled_arg name 195 | | Computed _ | StringLiteral _ | NumberLiteral _ 196 | | BigIntLiteral _ | PrivateName _ -> 197 | failwith "Computed properties in objects are unsupported" 198 | in 199 | let propState, propType = 200 | h 201 | { accState with parent_context_name = propertyName } 202 | propertyValue 203 | in 204 | let namedType = Named (propertyName, propType) in 205 | (propState, namedType :: accTypes)) 206 | (state, []) 207 | in 208 | maybe_add_external state ObjectCreation originalContextName 209 | (objTypes @ [ Unit ]) 210 | | MetaProperty { meta = _, meta; property = _, property; comments = _ } -> 211 | let state, lastType = maybe_add_external state Val meta.name [] in 212 | maybe_add_external state Get property.name [ lastType ] 213 | | StringLiteral { value; raw = _; comments = _ } -> 214 | Handle_literal.h state (String value) 215 | | NumberLiteral { value; raw = _; comments = _ } -> 216 | Handle_literal.h state (Number value) 217 | | Import _ -> (state, Unit) 218 | | Array _ | Sequence _ | Unary _ | Binary _ | Assignment _ | Update _ 219 | | Logical _ | Conditional _ | Yield _ | TemplateLiteral _ | TaggedTemplate _ 220 | | JSXElement _ | Class _ | TypeCast _ | JSXFragment _ | BooleanLiteral _ 221 | | NullLiteral _ | BigIntLiteral _ | RegExpLiteral _ | ModuleRefLiteral _ 222 | | OptionalCall _ | OptionalMember _ | Super _ | This _ | TSTypeCast _ -> 223 | (state, Unit) 224 | -------------------------------------------------------------------------------- /src/shared/handle_literal.ml: -------------------------------------------------------------------------------- 1 | type literal = String of string | Number of float 2 | 3 | let h (state : Shared_types.state) literal = 4 | match literal with 5 | | String v -> (state, Shared_types.String v) 6 | | Number _ -> (state, Float) 7 | -------------------------------------------------------------------------------- /src/shared/handle_plain_statement.ml: -------------------------------------------------------------------------------- 1 | open Parser_flow.Ast.Statement 2 | 3 | let h (state : Shared_types.state) 4 | ((_, statement) : (Loc.t, Loc.t) Flow_ast.Statement.t) = 5 | (* Reset the expression related state *) 6 | let state = { state with right_side_types = [] } in 7 | match statement with 8 | | VariableDeclaration 9 | { VariableDeclaration.declarations; kind = _; comments = _ } -> ( 10 | let _, { VariableDeclaration.Declarator.id = _loc, id; init } = 11 | List.hd declarations 12 | in 13 | match (init, id) with 14 | | ( Some e, 15 | Identifier 16 | { name = _, { name; comments = _ }; annot = _; optional = _ } ) -> 17 | let state, lastType = 18 | Handle_expression.h { state with parent_context_name = name } e 19 | in 20 | { 21 | state with 22 | identifiers = 23 | Shared_types.Identifiers.add name lastType state.identifiers; 24 | } 25 | | _, _ -> state) 26 | | Expression { expression; directive = _; comments = _ } -> 27 | let state, _lastType = Handle_expression.h state expression in 28 | state 29 | | ImportDeclaration 30 | { 31 | import_kind; 32 | source = _loc, { raw = _; value = source; comments = _ }; 33 | specifiers; 34 | default; 35 | comments = _; 36 | } -> ( 37 | let state = 38 | match default with 39 | | Some 40 | { identifier = _loc, identifier; remote_default_name_def_loc = _ } 41 | -> 42 | let state, _lastType = 43 | Handle_expression.maybe_add_identifier 44 | ~customType: 45 | (ModuleProperty (source, identifier.name, "default")) 46 | state identifier.name 47 | in 48 | state 49 | | None -> state 50 | in 51 | match specifiers with 52 | | None -> state 53 | | Some specifier -> ( 54 | match (import_kind, source) with 55 | | ImportValue, name -> ( 56 | match specifier with 57 | | ImportNamespaceSpecifier (_loc, (_anotherLoc, specifierName)) -> 58 | let state, _lastType = 59 | Handle_expression.maybe_add_identifier 60 | ~customType:(Module name) state specifierName.name 61 | in 62 | state 63 | | ImportNamedSpecifiers specifiers -> 64 | specifiers 65 | |> List.fold_left 66 | (fun state 67 | Parser_flow.Ast.Statement.ImportDeclaration. 68 | { 69 | local; 70 | remote; 71 | kind = _; 72 | remote_name_def_loc = _; 73 | } -> 74 | let _loc, localName = 75 | Utils.get_with_default local remote 76 | in 77 | let _loc, remoteName = remote in 78 | let state, _lastType = 79 | Handle_expression.maybe_add_identifier 80 | ~customType: 81 | (ModuleProperty 82 | (name, localName.name, remoteName.name)) 83 | state localName.name 84 | in 85 | state) 86 | state) 87 | | ( ImportType, 88 | _ (* ImportType and ImportTypeof are flow imports (I think) *) ) 89 | | ImportTypeof, _ -> 90 | state)) 91 | | Return _ | If _ | Block _ | FunctionDeclaration _ | ClassDeclaration _ 92 | | ExportDefaultDeclaration _ | ExportNamedDeclaration _ | Labeled _ | Break _ 93 | | Continue _ | With _ | TypeAlias _ | Switch _ | Throw _ | Try _ | While _ 94 | | DoWhile _ | For _ | ForIn _ | ForOf _ | InterfaceDeclaration _ 95 | | DeclareVariable _ | DeclareFunction _ | DeclareClass _ | DeclareModule _ 96 | | DeclareModuleExports _ | DeclareExportDeclaration _ | ComponentDeclaration _ 97 | | Debugger _ | DeclareComponent _ | DeclareEnum _ | DeclareInterface _ 98 | | DeclareTypeAlias _ | DeclareOpaqueType _ | Empty _ | EnumDeclaration _ 99 | | OpaqueType _ -> 100 | state 101 | -------------------------------------------------------------------------------- /src/shared/ir_transformer.ml: -------------------------------------------------------------------------------- 1 | open Ast_helper 2 | open Parsetree 3 | open Shared_types 4 | module OrigToSafeMap = Map.Make (String) 5 | 6 | let find_with_default x xs = 7 | try Shared_types.Identifiers.find x xs with Not_found -> x 8 | 9 | module SafeToOrigMap = Map.Make (String) 10 | 11 | let external_type_to_string t = 12 | match t with 13 | | String _ -> "string" 14 | | Float -> "float" 15 | | Abstract a -> a 16 | | Unit -> "unit" 17 | | Fun (_, _) -> 18 | failwith 19 | "Fun type should be resolved before calling external_type_to_string" 20 | | Module n -> n 21 | | ModuleProperty (_name, local, _remote) -> local 22 | | Named (_, _) -> 23 | failwith 24 | "Named type should be resolved before calling external_type_to_string" 25 | 26 | let type_constr externalType safeIds = 27 | { 28 | ptyp_desc = 29 | Ptyp_constr 30 | ( Ast_utils.ast_helper_str_lident 31 | [ find_with_default (external_type_to_string externalType) safeIds ], 32 | [] ); 33 | ptyp_loc = default_loc.contents; 34 | ptyp_attributes = []; 35 | ptyp_loc_stack = []; 36 | } 37 | 38 | let type_arrow a b label = 39 | { 40 | ptyp_desc = Ptyp_arrow (label, a, b); 41 | ptyp_loc = default_loc.contents; 42 | ptyp_attributes = []; 43 | ptyp_loc_stack = []; 44 | } 45 | 46 | let type_from_external_types typesList safeIds = 47 | let rec root_type list = 48 | let rec process l acc = 49 | match (l, acc) with 50 | | [], Some t -> t 51 | | Fun (name, l) :: xl, Some a -> 52 | let funTypes = l @ [ Abstract (find_with_default name safeIds) ] in 53 | process xl (Some (type_arrow (root_type funTypes) a Nolabel)) 54 | | Named (name, type_) :: xl, Some a -> 55 | process xl 56 | (Some 57 | (type_arrow (root_type [ type_ ]) a 58 | (Labelled (find_with_default name safeIds)))) 59 | | ( a :: xl, 60 | Some 61 | { 62 | ptyp_loc; 63 | ptyp_attributes; 64 | ptyp_desc = Ptyp_constr (bLoc, bList); 65 | ptyp_loc_stack = _; 66 | } ) -> 67 | process xl 68 | (Some 69 | (type_arrow (type_constr a safeIds) 70 | { 71 | ptyp_loc; 72 | ptyp_attributes; 73 | ptyp_desc = Ptyp_constr (bLoc, bList); 74 | ptyp_loc_stack = []; 75 | } 76 | Nolabel)) 77 | | a :: xl, None -> process xl (Some (type_constr a safeIds)) 78 | | ( a :: xl, 79 | Some 80 | { 81 | ptyp_loc; 82 | ptyp_attributes; 83 | ptyp_desc = Ptyp_arrow (bLabel, bType1, bType2); 84 | ptyp_loc_stack = _; 85 | } ) -> 86 | process xl 87 | (Some 88 | (type_arrow (type_constr a safeIds) 89 | { 90 | ptyp_loc; 91 | ptyp_attributes; 92 | ptyp_desc = Ptyp_arrow (bLabel, bType1, bType2); 93 | ptyp_loc_stack = []; 94 | } 95 | Nolabel)) 96 | | [], None -> failwith "empty list passed to descFromTypes" 97 | | _, _ -> failwith "impossible" 98 | in 99 | process (List.rev list) None 100 | in 101 | root_type typesList 102 | 103 | let external_with_attribute originalName types safeIds attr = 104 | let newName = OrigToSafeMap.find originalName safeIds in 105 | let outputAttrs, valueDescription = 106 | match attr with 107 | | Module -> ([ ("mel.module", None) ], originalName) 108 | | Send -> ([ ("mel.send", None) ], originalName) 109 | | Get -> ([ ("mel.get", None) ], originalName) 110 | | ObjectCreation -> ([ ("mel.obj", None) ], "") 111 | | Val -> ([], originalName) 112 | | NewAttr -> ([ ("mel.new", None) ], originalName) 113 | | ModuleAndNew -> ([ ("mel.new", None); ("mel.module", None) ], originalName) 114 | | ScopedModuleAndNew (name, scopeProperty) -> 115 | ([ ("mel.new", None); ("mel.module", Some name) ], scopeProperty) 116 | | ScopedModule (name, scopeProperty) -> 117 | ([ ("mel.module", Some name) ], scopeProperty) 118 | in 119 | let attrs = 120 | (outputAttrs 121 | |> List.map (fun (outputAttr, constant) -> 122 | let constExpr = 123 | (match constant with 124 | | Some c -> 125 | [ 126 | { 127 | pstr_desc = 128 | Pstr_eval 129 | ( { 130 | pexp_desc = 131 | Pexp_constant 132 | (Pconst_string (c, Location.none, None)); 133 | pexp_loc = default_loc.contents; 134 | pexp_attributes = []; 135 | pexp_loc_stack = []; 136 | }, 137 | [] ); 138 | pstr_loc = default_loc.contents; 139 | }; 140 | ] 141 | | None -> [] 142 | : Parsetree.structure_item list) 143 | in 144 | { 145 | attr_loc = default_loc.contents; 146 | attr_name = { txt = outputAttr; loc = Location.none }; 147 | attr_payload = PStr constExpr; 148 | }) 149 | : Parsetree.attributes) 150 | in 151 | let t = 152 | ({ 153 | pval_name = { loc = default_loc.contents; txt = newName }; 154 | pval_prim = [ valueDescription ]; 155 | pval_loc = default_loc.contents; 156 | pval_type = type_from_external_types types safeIds; 157 | pval_attributes = attrs; 158 | } 159 | : Parsetree.value_description) 160 | in 161 | Str.primitive ~loc:Location.none t 162 | 163 | let rec generate_safe_id ?(postFix = None) name safeToOrig = 164 | let strPostFix = 165 | match postFix with Some n -> string_of_int n | None -> "" 166 | in 167 | let safeName = Ast_utils.correct_identifier name ^ strPostFix in 168 | match (postFix, Utils.try_find_id safeName safeToOrig) with 169 | | Some n, Some _safeName -> 170 | generate_safe_id ~postFix:(Some (n + 1)) name safeToOrig 171 | | None, Some _existingId -> generate_safe_id ~postFix:(Some 2) name safeToOrig 172 | | _, None -> safeName 173 | 174 | let safe_identifiers identifiers = 175 | let origToSafe, _safeToOrig = 176 | Identifiers.fold 177 | (fun name _externalType (origToSafe, safeToOrig) -> 178 | match Utils.try_find_id name origToSafe with 179 | | Some _existingId -> (origToSafe, safeToOrig) 180 | | None -> 181 | let safeId = generate_safe_id name safeToOrig in 182 | ( OrigToSafeMap.add name safeId origToSafe, 183 | SafeToOrigMap.add safeId name safeToOrig )) 184 | identifiers 185 | (OrigToSafeMap.empty, SafeToOrigMap.empty) 186 | in 187 | origToSafe 188 | 189 | let transform state = 190 | let { 191 | identifiers; 192 | output_types; 193 | output_externals; 194 | right_side_types = _; 195 | parent_context_name = _; 196 | } = 197 | state 198 | in 199 | let safeIds = safe_identifiers identifiers in 200 | (List.rev output_types 201 | |> List.map (fun outputType -> 202 | Str.type_ ~loc:Location.none Recursive 203 | [ 204 | Type.mk ~loc:Location.none ~kind:Ptype_abstract ~priv:Public 205 | { 206 | loc = default_loc.contents; 207 | txt = OrigToSafeMap.find outputType safeIds; 208 | }; 209 | ])) 210 | @ (List.rev output_externals 211 | |> List.map (fun structureItem -> 212 | external_with_attribute structureItem.name structureItem.types 213 | safeIds structureItem.attr)) 214 | -------------------------------------------------------------------------------- /src/shared/shared.ml: -------------------------------------------------------------------------------- 1 | let init_state = 2 | let open Shared_types in 3 | { 4 | right_side_types = []; 5 | output_types = []; 6 | output_externals = []; 7 | identifiers = Identifiers.empty; 8 | parent_context_name = ""; 9 | } 10 | 11 | let get_output statements = 12 | statements 13 | |> List.fold_left 14 | (fun acc_state statement -> Handle_plain_statement.h acc_state statement) 15 | init_state 16 | |> Ir_transformer.transform 17 | 18 | let get_bindings file content = 19 | let parse_options = 20 | let open Parser_env in 21 | Some 22 | { 23 | components = true; 24 | enums = true; 25 | (* 26 | * Always parse ES proposal syntax. The user-facing config option to 27 | * ignore/warn/enable them is handled during inference so that a clean error 28 | * can be surfaced (rather than a more cryptic parse error). 29 | *) 30 | esproposal_decorators = true; 31 | types = false; 32 | use_strict = false; 33 | module_ref_prefix = None; 34 | module_ref_prefix_LEGACY_INTEROP = None; 35 | } 36 | in 37 | 38 | let (_, ast), _parse_errors = 39 | Parser_flow.program_file ~fail:false ~parse_options content file 40 | in 41 | (* if parse_errors <> [] then 42 | let converted = 43 | List.fold_left 44 | (fun acc parse_error -> 45 | Flow_errors_utils.ConcreteLocPrintableErrorSet.add 46 | (error_of_parse_error file parse_error) 47 | acc) 48 | Flow_errors_utils.ConcreteLocPrintableErrorSet.empty parse_errors 49 | in 50 | Error converted 51 | else Ok *) 52 | get_output ast.statements 53 | -------------------------------------------------------------------------------- /src/shared/shared_types.ml: -------------------------------------------------------------------------------- 1 | type external_base_type = 2 | | String of string 3 | | Float 4 | | Abstract of string 5 | | Unit 6 | | Named of string * external_base_type 7 | | Fun of string * external_base_type list 8 | | Module of string 9 | (* Just a helper to identify somehow expressions like require('something') *) 10 | | ModuleProperty of 11 | string * string * string (* (moduleName, localName, remoteName) *) 12 | 13 | type external_statement_attr = 14 | | Module 15 | | Get 16 | | Send 17 | | ObjectCreation 18 | | Val 19 | | NewAttr 20 | (* Adding a suffix to `New` to avoid conflicts with Flow's SpiderMonkey types *) 21 | | ModuleAndNew 22 | | ScopedModule of string * string (* (moduleName, scopedProperty) *) 23 | | ScopedModuleAndNew of string * string (* (moduleName, scopedProperty) *) 24 | 25 | type external_statement = { 26 | attr : external_statement_attr; 27 | name : string; 28 | types : external_base_type list; 29 | } 30 | 31 | module Identifiers = Map.Make (String) 32 | 33 | type state = { 34 | identifiers : external_base_type Identifiers.t; 35 | right_side_types : external_base_type list; 36 | (* The carried types in an expression *) 37 | output_types : string list; 38 | output_externals : external_statement list; 39 | parent_context_name : string; 40 | } 41 | -------------------------------------------------------------------------------- /src/shared/utils.ml: -------------------------------------------------------------------------------- 1 | let get_with_default opt def = match opt with Some c -> c | None -> def 2 | 3 | let try_find_id x xs = 4 | try Some (Shared_types.Identifiers.find x xs) with Not_found -> None 5 | 6 | let try_find_in_list f xs = try Some (List.find f xs) with Not_found -> None 7 | -------------------------------------------------------------------------------- /vendor/collections/dune: -------------------------------------------------------------------------------- 1 | (include_subdirs unqualified) 2 | 3 | (library 4 | (name collections) 5 | (wrapped false) 6 | (libraries base)) 7 | -------------------------------------------------------------------------------- /vendor/collections/iMap.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | include WrappedMap.Make (IntKey) 9 | 10 | let pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit = 11 | (fun pp_data -> make_pp IntKey.pp pp_data) 12 | 13 | let show pp_data x = Format.asprintf "%a" (pp pp_data) x 14 | -------------------------------------------------------------------------------- /vendor/collections/iSet.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | include Flow_set.Make (IntKey) 9 | 10 | let pp = make_pp IntKey.pp 11 | 12 | let show iset = Format.asprintf "%a" pp iset 13 | 14 | let to_string = show 15 | -------------------------------------------------------------------------------- /vendor/collections/immQueue.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type 'a t = { 9 | incoming: 'a list; 10 | outgoing: 'a list; 11 | length: int; 12 | } 13 | 14 | let empty = { incoming = []; outgoing = []; length = 0 } 15 | 16 | let length t = t.length 17 | 18 | let is_empty t = length t = 0 19 | 20 | let push t x = { t with incoming = x :: t.incoming; length = t.length + 1 } 21 | 22 | let prepare_for_read t = 23 | match t.outgoing with 24 | | [] -> { t with incoming = []; outgoing = List.rev t.incoming } 25 | | _ -> t 26 | 27 | let pop t = 28 | let t = prepare_for_read t in 29 | match t.outgoing with 30 | | [] -> (None, t) 31 | | hd :: tl -> (Some hd, { t with outgoing = tl; length = t.length - 1 }) 32 | 33 | let peek t = 34 | let t = prepare_for_read t in 35 | match t.outgoing with 36 | | [] -> (None, t) 37 | | hd :: _ -> (Some hd, t) 38 | 39 | let exists t ~f = List.exists f t.outgoing || List.exists f t.incoming 40 | 41 | let iter t ~f = 42 | List.iter f t.outgoing; 43 | List.iter f (List.rev t.incoming) 44 | 45 | let from_list x = { incoming = []; outgoing = x; length = List.length x } 46 | 47 | let to_list x = x.outgoing @ List.rev x.incoming 48 | 49 | let concat t = 50 | { 51 | incoming = []; 52 | outgoing = Base.List.concat_map ~f:to_list t; 53 | length = List.map (fun u -> u.length) t |> List.fold_left ( + ) 0; 54 | } 55 | -------------------------------------------------------------------------------- /vendor/collections/immQueue.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* 9 | * Immutable queue implementation. Modeled loosely after the mutable stdlib 10 | * Queue. push, pop, etc. are amortized O(1). 11 | *) 12 | 13 | type 'a t 14 | 15 | val empty : 'a t 16 | 17 | val push : 'a t -> 'a -> 'a t 18 | 19 | val pop : 'a t -> 'a option * 'a t 20 | 21 | val peek : 'a t -> 'a option * 'a t 22 | 23 | val is_empty : 'a t -> bool 24 | 25 | val length : 'a t -> int 26 | 27 | val exists : 'a t -> f:('a -> bool) -> bool 28 | 29 | val iter : 'a t -> f:('a -> unit) -> unit 30 | 31 | (* from_list: the head of the list is the first one to be popped *) 32 | val from_list : 'a list -> 'a t 33 | 34 | (* to_list: the head of the list is the first one to be popped *) 35 | val to_list : 'a t -> 'a list 36 | 37 | val concat : 'a t list -> 'a t 38 | -------------------------------------------------------------------------------- /vendor/collections/intKey.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = int 9 | 10 | let compare = ( - ) 11 | 12 | let pp = Format.pp_print_int 13 | -------------------------------------------------------------------------------- /vendor/collections/priorityQueue.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Make (Ord : Set.OrderedType) = struct 9 | type elt = Ord.t 10 | 11 | type t = { 12 | mutable __queue: elt option array; 13 | mutable size: int; 14 | } 15 | 16 | let rec make_empty n = { __queue = Array.make n None; size = 0 } 17 | 18 | and is_empty t = t.size = 0 19 | 20 | and pop t = 21 | if t.size = 0 then failwith "Popping from an empty priority queue"; 22 | let v = t.__queue.(0) in 23 | t.size <- t.size - 1; 24 | 25 | if t.size <> 0 then ( 26 | let last = t.__queue.(t.size) in 27 | t.__queue.(t.size) <- None; 28 | __bubble_down t.__queue t.size last 0 29 | ); 30 | 31 | match v with 32 | | None -> failwith "Attempting to return a null value" 33 | | Some v -> v 34 | 35 | and push t element = 36 | if Array.length t.__queue = t.size then ( 37 | let new_queue = Array.make ((Array.length t.__queue * 2) + 1) None in 38 | Array.blit t.__queue 0 new_queue 0 (Array.length t.__queue); 39 | t.__queue <- new_queue 40 | ); 41 | 42 | t.__queue.(t.size) <- Some element; 43 | __bubble_up t.__queue t.size; 44 | t.size <- t.size + 1; 45 | () 46 | 47 | and __swap arr i j = 48 | let tmp = arr.(i) in 49 | arr.(i) <- arr.(j); 50 | arr.(j) <- tmp 51 | 52 | and __bubble_up arr index = 53 | if index = 0 then (); 54 | let pindex = (index - 1) / 2 in 55 | match (arr.(index), arr.(pindex)) with 56 | | (None, _) 57 | | (_, None) -> 58 | failwith "Unexpected null index found when calling __bubble_up" 59 | | (Some e, Some p) -> 60 | if Ord.compare e p < 0 then ( 61 | __swap arr index pindex; 62 | __bubble_up arr pindex 63 | ) 64 | 65 | and __bubble_down arr size value index = 66 | let right_child_index = (index * 2) + 2 in 67 | let left_child_index = right_child_index - 1 in 68 | if right_child_index < size then 69 | match (arr.(right_child_index), arr.(left_child_index), value) with 70 | | (None, _, _) 71 | | (_, None, _) 72 | | (_, _, None) -> 73 | failwith "Unexpected null index found when calling __bubble_down" 74 | | (Some r, Some l, Some v) -> 75 | let (smaller_child, smaller_child_index) = 76 | if Ord.compare r l < 0 then 77 | (r, right_child_index) 78 | else 79 | (l, left_child_index) 80 | in 81 | if Ord.compare v smaller_child <= 0 then 82 | arr.(index) <- value 83 | else ( 84 | arr.(index) <- arr.(smaller_child_index); 85 | __bubble_down arr size value smaller_child_index 86 | ) 87 | else if left_child_index < size then 88 | match (arr.(left_child_index), value) with 89 | | (None, _) 90 | | (_, None) -> 91 | failwith "Unexpected null index found when calling __bubble_down" 92 | | (Some l, Some v) -> 93 | if Ord.compare v l <= 0 then 94 | arr.(index) <- value 95 | else ( 96 | arr.(index) <- arr.(left_child_index); 97 | arr.(left_child_index) <- value 98 | ) 99 | else 100 | arr.(index) <- value 101 | end 102 | -------------------------------------------------------------------------------- /vendor/collections/reordered_argument_collections.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Reordered_argument_map (S : WrappedMap.S) = struct 9 | include S 10 | 11 | let add m ~key ~data = add key data m 12 | 13 | let filter m ~f = filter f m 14 | 15 | let fold m ~init ~f = fold f m init 16 | 17 | let find_opt m k = find_opt k m 18 | 19 | let find m k = find k m 20 | 21 | let iter m ~f = iter f m 22 | 23 | let map m ~f = map f m 24 | 25 | let mapi m ~f = mapi f m 26 | 27 | let mem m v = mem v m 28 | 29 | let remove m v = remove v m 30 | 31 | let exists m ~f = exists f m 32 | 33 | let merge m1 m2 ~f = merge f m1 m2 34 | 35 | let filter m ~f = filter m ~f 36 | 37 | let partition m ~f = partition f m 38 | end 39 | 40 | module Reordered_argument_set (S : Flow_set.S) = struct 41 | include S 42 | 43 | let add s v = add v s 44 | 45 | let filter s ~f = filter f s 46 | 47 | let fold s ~init ~f = fold f s init 48 | 49 | let iter s ~f = iter f s 50 | 51 | let mem s v = mem v s 52 | 53 | let remove s v = remove v s 54 | 55 | let exists s ~f = exists f s 56 | 57 | let of_list l = List.fold_left add S.empty l 58 | 59 | let make_pp pp fmt x = 60 | Format.fprintf fmt "@[{"; 61 | let elts = elements x in 62 | (match elts with 63 | | [] -> () 64 | | _ -> Format.fprintf fmt " "); 65 | ignore 66 | (List.fold_left 67 | (fun sep elt -> 68 | if sep then Format.fprintf fmt ";@ "; 69 | let () = pp fmt elt in 70 | true) 71 | false 72 | elts 73 | ); 74 | (match elts with 75 | | [] -> () 76 | | _ -> Format.fprintf fmt " "); 77 | Format.fprintf fmt "}@]" 78 | end 79 | 80 | module SSet = struct 81 | include Reordered_argument_set (SSet) 82 | 83 | let pp = SSet.pp 84 | 85 | let show = SSet.show 86 | end 87 | 88 | module SMap = struct 89 | include Reordered_argument_map (SMap) 90 | 91 | let pp = SMap.pp 92 | 93 | let show = SMap.show 94 | end 95 | -------------------------------------------------------------------------------- /vendor/collections/sMap.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | include WrappedMap.Make (StringKey) 9 | 10 | let pp : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit = 11 | (fun pp_data -> make_pp StringKey.pp pp_data) 12 | 13 | let show pp_data x = Format.asprintf "%a" (pp pp_data) x 14 | -------------------------------------------------------------------------------- /vendor/collections/sSet.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | include Flow_set.Make (StringKey) 9 | 10 | let pp = make_pp StringKey.pp 11 | 12 | let show sset = Format.asprintf "%a" pp sset 13 | 14 | let to_string = show 15 | -------------------------------------------------------------------------------- /vendor/collections/stringKey.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = string 9 | 10 | let compare (x : t) (y : t) = String.compare x y 11 | 12 | let to_string x = x 13 | 14 | let pp fmt x = Format.fprintf fmt "%S" x 15 | -------------------------------------------------------------------------------- /vendor/collections/union_find.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type ident = int 9 | 10 | exception Tvar_not_found of ident 11 | 12 | module Make (Constraints : sig 13 | type t 14 | end) = 15 | struct 16 | (** A root structure carries the actual non-trivial state of a tvar, and 17 | consists of: 18 | 19 | - rank, which is a quantity roughly corresponding to the longest chain of 20 | gotos pointing to the tvar. It's an implementation detail of the unification 21 | algorithm that simply has to do with efficiently finding the root of a tree. 22 | We merge a tree with another tree by converting the root with the lower rank 23 | to a goto node, and making it point to the root with the higher rank. See 24 | http://en.wikipedia.org/wiki/Disjoint-set_data_structure for more details on 25 | this data structure and supported operations. 26 | 27 | - constraints, which carry type information that narrows down the possible 28 | solutions of the tvar (see below). *) 29 | type root = { 30 | mutable rank: int; 31 | mutable constraints: Constraints.t; 32 | } 33 | 34 | (** Type variables are unknowns, and we are ultimately interested in constraints 35 | on their solutions for type inference. 36 | 37 | Type variables form nodes in a "union-find" forest: each tree denotes a set 38 | of type variables that are considered by the type system to be equivalent. 39 | 40 | There are two kinds of nodes: Goto nodes and Root nodes. 41 | 42 | - All Goto nodes of a tree point, directly or indirectly, to the Root node 43 | of the tree. 44 | - A Root node holds the actual non-trivial state of a tvar, represented by a 45 | root structure (see below). *) 46 | type node_ = 47 | | Goto of { mutable parent: ident } 48 | | Root of root 49 | 50 | type node = node_ ref 51 | 52 | type graph = node IMap.t 53 | 54 | let create_root constraints = ref (Root { rank = 0; constraints }) 55 | 56 | let create_goto parent = ref (Goto { parent }) 57 | 58 | (* Find the root of a type variable, potentially traversing a chain of type 59 | variables, while short-circuiting all the type variables in the chain to the 60 | root during traversal to speed up future traversals. *) 61 | let rec find_root graph id = 62 | match IMap.find_opt id graph with 63 | | None -> raise (Tvar_not_found id) 64 | | Some node -> 65 | (match !node with 66 | | Root root -> (id, node, root) 67 | | Goto goto -> 68 | let ((root_id, _, _) as root) = find_root graph goto.parent in 69 | goto.parent <- root_id; 70 | root) 71 | 72 | let find_root_id graph id = 73 | let (root_id, _, _) = find_root graph id in 74 | root_id 75 | 76 | (* Find the constraints of a type variable in the graph. 77 | 78 | Recall that type variables are either roots or goto nodes. (See 79 | Constraint for details.) If the type variable is a root, the 80 | constraints are stored with the type variable. Otherwise, the type variable 81 | is a goto node, and it points to another type variable: a linked list of such 82 | type variables must be traversed until a root is reached. *) 83 | let find_constraints graph id = 84 | let (root_id, _, root) = find_root graph id in 85 | (root_id, root.constraints) 86 | 87 | let find_graph graph id = 88 | let (_, constraints) = find_constraints graph id in 89 | constraints 90 | end 91 | -------------------------------------------------------------------------------- /vendor/collections/wrappedMap.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module type S = WrappedMap_sig.S 9 | 10 | module Make (Ord : Map.OrderedType) : S with type key = Ord.t = struct 11 | include Flow_map.Make (Ord) 12 | 13 | let union ?combine x y = 14 | let combine = 15 | match combine with 16 | | None -> (fun _ fst _ -> Some fst) 17 | | Some f -> f 18 | in 19 | union combine x y 20 | 21 | let rec fold_left_env env l ~init ~f = 22 | match l with 23 | | [] -> (env, init) 24 | | x :: xs -> 25 | let (env, init) = f env init x in 26 | fold_left_env env xs ~init ~f 27 | 28 | let merge_env env s1 s2 ~combine = 29 | let (env, map) = 30 | fold_left_env 31 | env 32 | ~init:empty 33 | ~f:(fun env map (key, v2) -> 34 | let v1opt = find_opt key s1 in 35 | let (env, vopt) = combine env key v1opt (Some v2) in 36 | let map = 37 | match vopt with 38 | | None -> map 39 | | Some v -> add key v map 40 | in 41 | (env, map)) 42 | (bindings s2) 43 | in 44 | fold_left_env 45 | env 46 | ~init:map 47 | ~f:(fun env map (key, v1) -> 48 | let v2opt = find_opt key s2 in 49 | match v2opt with 50 | | None -> 51 | let (env, vopt) = combine env key (Some v1) None in 52 | let map = 53 | match vopt with 54 | | None -> map 55 | | Some v -> add key v map 56 | in 57 | (env, map) 58 | | Some _ -> (env, map)) 59 | (bindings s1) 60 | 61 | let union_env env s1 s2 ~combine = 62 | let f env key o1 o2 = 63 | match (o1, o2) with 64 | | (None, None) -> (env, None) 65 | | (Some v, None) 66 | | (None, Some v) -> 67 | (env, Some v) 68 | | (Some v1, Some v2) -> combine env key v1 v2 69 | in 70 | merge_env env s1 s2 ~combine:f 71 | 72 | let values m = fold (fun _ v acc -> v :: acc) m [] 73 | 74 | let fold_env env f m init = fold (fun key v (env, acc) -> f env key v acc) m (env, init) 75 | 76 | let elements m = fold (fun k v acc -> (k, v) :: acc) m [] 77 | 78 | let map_env f env m = 79 | fold_env 80 | env 81 | (fun env key v map -> 82 | let (env, v) = f env key v in 83 | (env, add key v map)) 84 | m 85 | empty 86 | 87 | let of_list elts = 88 | List.fold_left 89 | begin 90 | (fun acc (key, value) -> add key value acc) 91 | end 92 | empty 93 | elts 94 | 95 | let of_function domain f = 96 | List.fold_left 97 | begin 98 | (fun acc key -> add key (f key) acc) 99 | end 100 | empty 101 | domain 102 | 103 | let add ?combine key new_value map = 104 | match combine with 105 | | None -> add key new_value map 106 | | Some combine -> 107 | adjust 108 | key 109 | (fun opt -> 110 | match opt with 111 | | None -> new_value 112 | | Some old_value -> combine old_value new_value) 113 | map 114 | 115 | let ident_map f coll = 116 | let changed = ref false in 117 | let new_map = 118 | map 119 | (fun x -> 120 | let new_item = f x in 121 | if new_item != x then changed := true; 122 | new_item) 123 | coll 124 | in 125 | if !changed then 126 | new_map 127 | else 128 | coll 129 | 130 | let for_all2 ~f m1 m2 = 131 | let key_bool_map = merge (fun k v1opt v2opt -> Some (f k v1opt v2opt)) m1 m2 in 132 | for_all (fun _k b -> b) key_bool_map 133 | 134 | let make_pp pp_key pp_data fmt x = 135 | Format.fprintf fmt "@[{"; 136 | let bindings = bindings x in 137 | (match bindings with 138 | | [] -> () 139 | | _ -> Format.fprintf fmt " "); 140 | ignore 141 | (List.fold_left 142 | (fun sep (key, data) -> 143 | if sep then Format.fprintf fmt ";@ "; 144 | Format.fprintf fmt "@["; 145 | pp_key fmt key; 146 | Format.fprintf fmt " ->@ "; 147 | pp_data fmt data; 148 | Format.fprintf fmt "@]"; 149 | true) 150 | false 151 | bindings 152 | ); 153 | (match bindings with 154 | | [] -> () 155 | | _ -> Format.fprintf fmt " "); 156 | Format.fprintf fmt "}@]" 157 | end 158 | -------------------------------------------------------------------------------- /vendor/collections/wrappedMap.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module type S = WrappedMap_sig.S 9 | 10 | module Make (Ord : Map.OrderedType) : S with type key = Ord.t 11 | -------------------------------------------------------------------------------- /vendor/collections/wrappedMap_sig.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module type S = sig 9 | include Flow_map.S 10 | 11 | val add : ?combine:('a -> 'a -> 'a) -> key -> 'a -> 'a t -> 'a t 12 | 13 | val union : ?combine:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t 14 | 15 | val union_env : 16 | 'a -> 'b t -> 'b t -> combine:('a -> key -> 'b -> 'b -> 'a * 'b option) -> 'a * 'b t 17 | 18 | val merge_env : 19 | 'a -> 20 | 'b t -> 21 | 'c t -> 22 | combine:('a -> key -> 'b option -> 'c option -> 'a * 'd option) -> 23 | 'a * 'd t 24 | 25 | val keys : 'a t -> key list 26 | 27 | val ordered_keys : 'a t -> key list 28 | 29 | val values : 'a t -> 'a list 30 | 31 | val fold_env : 'a -> ('a -> key -> 'b -> 'c -> 'a * 'c) -> 'b t -> 'c -> 'a * 'c 32 | 33 | val map_env : ('c -> key -> 'a -> 'c * 'b) -> 'c -> 'a t -> 'c * 'b t 34 | 35 | val of_list : (key * 'a) list -> 'a t 36 | 37 | val of_function : key list -> (key -> 'a) -> 'a t 38 | 39 | val elements : 'a t -> (key * 'a) list 40 | 41 | val ident_map : ('a -> 'a) -> 'a t -> 'a t 42 | 43 | val ident_map_key : ?combine:('a -> 'a -> 'a) -> (key -> key) -> 'a t -> 'a t 44 | 45 | val for_all2 : f:(key -> 'a option -> 'b option -> bool) -> 'a t -> 'b t -> bool 46 | 47 | val make_pp : 48 | (Format.formatter -> key -> unit) -> 49 | (Format.formatter -> 'a -> unit) -> 50 | Format.formatter -> 51 | 'a t -> 52 | unit 53 | 54 | val of_increasing_iterator_unchecked : (unit -> key * 'a) -> int -> 'a t 55 | end 56 | -------------------------------------------------------------------------------- /vendor/parser/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) Meta Platforms, Inc. and affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | DIR:=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 7 | TOP=$(DIR)/../.. 8 | REL_DIR=src/parser 9 | DUNE_OUT="$(TOP)/_build/default/$(REL_DIR)" 10 | 11 | OCAML_PATH=$(shell ocamlc -where) 12 | OCAML_HEADERS=\ 13 | $(sort $(patsubst $(OCAML_PATH)/%,dist/libflowparser/include/%, \ 14 | $(filter $(OCAML_PATH)/%,$(shell \ 15 | $(CC) -I $(OCAML_PATH) -MM -MT deps libflowparser.h \ 16 | )))) 17 | 18 | all: 19 | 20 | clean: 21 | rm -f flow_parser.js 22 | rm -rf dist 23 | 24 | .PHONY: libflowparser.exe.o 25 | libflowparser.exe.o: 26 | dune build --profile opt ./libflowparser.exe.o 27 | 28 | dist/libflowparser/lib/libflowparser.a: libflowparser.exe.o libflowparser.h 29 | @mkdir -p "$(@D)" 30 | if [ ! -e "$@" -o "$(DUNE_OUT)/libflowparser.exe.o" -nt "$@" -o libflowparser.h -nt "$@" ]; then \ 31 | ar rcs "$@" "$(DUNE_OUT)/libflowparser.exe.o"; \ 32 | fi 33 | 34 | $(OCAML_HEADERS): dist/libflowparser/include/%: $(OCAML_PATH)/% 35 | @mkdir -p "$(@D)" 36 | cp "$<" "$@" 37 | 38 | dist/libflowparser/include/flowparser/libflowparser.h: libflowparser.h 39 | @mkdir -p "$(@D)" 40 | cp "$<" "$@" 41 | 42 | dist/libflowparser.zip: \ 43 | $(OCAML_HEADERS) \ 44 | dist/libflowparser/include/flowparser/libflowparser.h \ 45 | dist/libflowparser/lib/libflowparser.a 46 | cd dist && zip -r $(@F) libflowparser 47 | 48 | js: 49 | dune build --no-print-directory --profile opt flow_parser_dot_js.bc.js 50 | @if [ ! -e flow_parser.js -o "$(TOP)/_build/default/$(REL_DIR)/flow_parser_dot_js.bc.js" -nt flow_parser.js ]; then \ 51 | cp "$(TOP)/_build/default/$(REL_DIR)/flow_parser_dot_js.bc.js" flow_parser.js; \ 52 | chmod +w flow_parser.js; \ 53 | fi 54 | 55 | test-js: js 56 | cd $(TOP)/packages/flow-parser; npm test 57 | 58 | test-esprima-ocaml: 59 | dune build @parser_esprima_tests 60 | 61 | test-hardcoded-ocaml: 62 | dune build @parser_flow_tests 63 | 64 | test-ocaml: test-esprima-ocaml test-hardcoded-ocaml 65 | 66 | test: test-js test-ocaml 67 | -------------------------------------------------------------------------------- /vendor/parser/README.md: -------------------------------------------------------------------------------- 1 | # The Flow Parser 2 | 3 | The Flow Parser is a JavaScript parser written in OCaml. It produces an AST that conforms to [SpiderMonkey's Parser API](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API) and that mostly matches what [esprima](http://esprima.org/) produces. The Flow Parser can be compiled to native code or can be compiled to JavaScript using [js_of_ocaml](http://ocsigen.org/js_of_ocaml/). 4 | 5 | ## Building the Flow Parser 6 | 7 | Building the Flow Parser requires OCaml. Compiling to JavaScript requires js_of_ocaml. 8 | 9 | ### Initial set up 10 | 11 | * [Install opam](https://opam.ocaml.org/doc/Install.html) 12 | * `opam install js_of_ocaml.3.9.0` 13 | 14 | ### Building the OCaml Flow Parser library 15 | 16 | make 17 | 18 | ### Compiling the Flow Parser to JavaScript 19 | 20 | make js 21 | 22 | ## Tests 23 | 24 | The Flow Parser's test suite tests the JavaScript version of the parser, so you will need js_of_ocaml installed. The tests and tools also have some node module dependencies, so you will need to run 25 | 26 | ### Initial set up 27 | 28 | * Follow the steps in [Building the Flow Parser](https://github.com/facebook/flow/blob/master/src/parser/README.md#building-the-flow-parser) 29 | * `npm install` 30 | 31 | ### Running the Tests 32 | 33 | make test 34 | -------------------------------------------------------------------------------- /vendor/parser/comment_utils.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* returns all of the comments that start before `loc`, and discards the rest *) 9 | let comments_before_loc loc comments = 10 | let rec helper loc acc = function 11 | | ((c_loc, _) as comment) :: rest when Loc.compare c_loc loc < 0 -> 12 | helper loc (comment :: acc) rest 13 | | _ -> List.rev acc 14 | in 15 | helper loc [] comments 16 | 17 | class ['loc] inline_comments_stripper = 18 | object 19 | inherit ['loc] Flow_ast_mapper.mapper 20 | 21 | method! syntax_opt 22 | : 'internal. 23 | ('loc, 'internal) Flow_ast.Syntax.t option -> ('loc, 'internal) Flow_ast.Syntax.t option = 24 | (fun _ -> None) 25 | end 26 | 27 | let strip_inlined_comments p = (new inline_comments_stripper)#program p 28 | 29 | let strip_inlined_comments_expression expr = (new inline_comments_stripper)#expression expr 30 | 31 | let strip_comments_list 32 | ?(preserve_docblock = false) ((loc, program) : ('loc, 'loc) Flow_ast.Program.t) = 33 | let { Flow_ast.Program.all_comments; _ } = program in 34 | ( loc, 35 | { 36 | program with 37 | Flow_ast.Program.all_comments = 38 | ( if preserve_docblock then 39 | comments_before_loc loc all_comments 40 | else 41 | [] 42 | ); 43 | } 44 | ) 45 | 46 | let strip_all_comments ?(preserve_docblock = false) p = 47 | p |> strip_comments_list ~preserve_docblock |> strip_inlined_comments 48 | -------------------------------------------------------------------------------- /vendor/parser/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name flow_parser) 3 | (wrapped false) 4 | (libraries base wtf8 flow_sedlexing collections) 5 | (preprocess 6 | (pps ppx_gen_rec ppx_deriving.std flow_sedlexing_ppx))) 7 | -------------------------------------------------------------------------------- /vendor/parser/enum_common.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type explicit_type = 9 | | Boolean 10 | | Number 11 | | String 12 | | Symbol 13 | | BigInt 14 | [@@deriving ord] 15 | 16 | let string_of_explicit_type = function 17 | | Boolean -> "boolean" 18 | | Number -> "number" 19 | | String -> "string" 20 | | Symbol -> "symbol" 21 | | BigInt -> "bigint" 22 | -------------------------------------------------------------------------------- /vendor/parser/file_key.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = 9 | | LibFile of string 10 | | SourceFile of string 11 | | JsonFile of string 12 | (* A resource that might get required, like .css, .jpg, etc. We don't parse 13 | these, just check that they exist *) 14 | | ResourceFile of string 15 | [@@deriving show, eq] 16 | 17 | let to_string = function 18 | | LibFile x 19 | | SourceFile x 20 | | JsonFile x 21 | | ResourceFile x -> 22 | x 23 | 24 | let to_path = function 25 | | LibFile x 26 | | SourceFile x 27 | | JsonFile x 28 | | ResourceFile x -> 29 | Ok x 30 | 31 | let compare = 32 | (* libs, then source and json files at the same priority since JSON files are 33 | * basically source files. We don't actually read resource files so they come 34 | * last *) 35 | let order_of_filename = function 36 | | LibFile _ -> 1 37 | | SourceFile _ -> 2 38 | | JsonFile _ -> 2 39 | | ResourceFile _ -> 3 40 | in 41 | fun a b -> 42 | let k = order_of_filename a - order_of_filename b in 43 | if k <> 0 then 44 | k 45 | else 46 | String.compare (to_string a) (to_string b) 47 | 48 | let compare_opt a b = 49 | match (a, b) with 50 | | (Some _, None) -> -1 51 | | (None, Some _) -> 1 52 | | (None, None) -> 0 53 | | (Some a, Some b) -> compare a b 54 | 55 | let is_lib_file = function 56 | | LibFile _ -> true 57 | | SourceFile _ -> false 58 | | JsonFile _ -> false 59 | | ResourceFile _ -> false 60 | 61 | let map f = function 62 | | LibFile filename -> LibFile (f filename) 63 | | SourceFile filename -> SourceFile (f filename) 64 | | JsonFile filename -> JsonFile (f filename) 65 | | ResourceFile filename -> ResourceFile (f filename) 66 | 67 | let exists f = function 68 | | LibFile filename 69 | | SourceFile filename 70 | | JsonFile filename 71 | | ResourceFile filename -> 72 | f filename 73 | 74 | let check_suffix filename suffix = exists (fun fn -> Filename.check_suffix fn suffix) filename 75 | 76 | let chop_suffix filename suffix = map (fun fn -> Filename.chop_suffix fn suffix) filename 77 | 78 | let with_suffix filename suffix = map (fun fn -> fn ^ suffix) filename 79 | -------------------------------------------------------------------------------- /vendor/parser/flow_ast_utils.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | open Flow_ast 9 | 10 | type 'loc binding = 'loc * string 11 | 12 | type 'loc ident = 'loc * string [@@deriving show] 13 | 14 | type 'loc source = 'loc * string [@@deriving show] 15 | 16 | let rec fold_bindings_of_pattern = 17 | Pattern.( 18 | let property f acc = 19 | Object.( 20 | function 21 | | Property (_, { Property.pattern = p; _ }) 22 | | RestElement (_, { RestElement.argument = p; comments = _ }) -> 23 | fold_bindings_of_pattern f acc p 24 | ) 25 | in 26 | let element f acc = 27 | Array.( 28 | function 29 | | Hole _ -> acc 30 | | Element (_, { Element.argument = p; default = _ }) 31 | | RestElement (_, { RestElement.argument = p; comments = _ }) -> 32 | fold_bindings_of_pattern f acc p 33 | ) 34 | in 35 | fun f acc -> function 36 | | (_, Identifier { Identifier.name; _ }) -> f acc name 37 | | (_, Object { Object.properties; _ }) -> List.fold_left (property f) acc properties 38 | | (_, Array { Array.elements; _ }) -> List.fold_left (element f) acc elements 39 | (* This is for assignment and default param destructuring `[a.b=1]=c`, ignore these for now. *) 40 | | (_, Expression _) -> acc 41 | ) 42 | 43 | let fold_bindings_of_variable_declarations f acc declarations = 44 | let open Flow_ast.Statement.VariableDeclaration in 45 | List.fold_left 46 | (fun acc -> function 47 | | (_, { Declarator.id = pattern; _ }) -> 48 | let has_anno = 49 | (* Only the toplevel annotation in a pattern is meaningful *) 50 | let open Flow_ast.Pattern in 51 | match pattern with 52 | | (_, Array { Array.annot = Flow_ast.Type.Available _; _ }) 53 | | (_, Object { Object.annot = Flow_ast.Type.Available _; _ }) 54 | | (_, Identifier { Identifier.annot = Flow_ast.Type.Available _; _ }) -> 55 | true 56 | | _ -> false 57 | in 58 | fold_bindings_of_pattern (f has_anno) acc pattern) 59 | acc 60 | declarations 61 | 62 | let rec pattern_has_binding = 63 | let open Pattern in 64 | let property = 65 | let open Object in 66 | function 67 | | Property (_, { Property.pattern = p; _ }) 68 | | RestElement (_, { RestElement.argument = p; comments = _ }) -> 69 | pattern_has_binding p 70 | in 71 | let element = 72 | let open Array in 73 | function 74 | | Hole _ -> false 75 | | Element (_, { Element.argument = p; default = _ }) 76 | | RestElement (_, { RestElement.argument = p; comments = _ }) -> 77 | pattern_has_binding p 78 | in 79 | function 80 | | (_, Identifier _) -> true 81 | | (_, Object { Object.properties; _ }) -> List.exists property properties 82 | | (_, Array { Array.elements; _ }) -> List.exists element elements 83 | | (_, Expression _) -> false 84 | 85 | let partition_directives statements = 86 | let open Flow_ast.Statement in 87 | let rec helper directives = function 88 | | ((_, Expression { Expression.directive = Some _; _ }) as directive) :: rest -> 89 | helper (directive :: directives) rest 90 | | rest -> (List.rev directives, rest) 91 | in 92 | helper [] statements 93 | 94 | let hoist_function_and_component_declarations stmts = 95 | let open Flow_ast.Statement in 96 | let (func_and_component_decs, other_stmts) = 97 | List.partition 98 | (function 99 | (* function f() {} / component F() {} *) 100 | | (_, (FunctionDeclaration { Flow_ast.Function.id = Some _; _ } | ComponentDeclaration _)) 101 | (* export function f() {} / export component F() {} *) 102 | | ( _, 103 | ExportNamedDeclaration 104 | { 105 | ExportNamedDeclaration.declaration = 106 | Some 107 | ( _, 108 | ( FunctionDeclaration { Flow_ast.Function.id = Some _; _ } 109 | | ComponentDeclaration _ ) 110 | ); 111 | _; 112 | } 113 | ) 114 | (* export default function f() {} / export default component F() {} *) 115 | | ( _, 116 | ExportDefaultDeclaration 117 | { 118 | ExportDefaultDeclaration.declaration = 119 | ExportDefaultDeclaration.Declaration 120 | ( _, 121 | ( FunctionDeclaration { Flow_ast.Function.id = Some _; _ } 122 | | ComponentDeclaration _ ) 123 | ); 124 | _; 125 | } 126 | ) 127 | (* TODO(jmbrown): Hoist declared components *) 128 | (* declare function f(): void; *) 129 | | (_, DeclareFunction _) 130 | (* declare export function f(): void; *) 131 | | ( _, 132 | DeclareExportDeclaration DeclareExportDeclaration.{ declaration = Some (Function _); _ } 133 | ) -> 134 | true 135 | | _ -> false) 136 | stmts 137 | in 138 | func_and_component_decs @ other_stmts 139 | 140 | let negate_raw_lit raw = 141 | let raw_len = String.length raw in 142 | if raw_len > 0 && raw.[0] = '-' then 143 | String.sub raw 1 (raw_len - 1) 144 | else 145 | "-" ^ raw 146 | 147 | let negate_number_literal (value, raw) = (~-.value, negate_raw_lit raw) 148 | 149 | let negate_bigint_literal (value, raw) = 150 | match value with 151 | | None -> (None, raw) 152 | | Some value -> (Some (Int64.neg value), negate_raw_lit raw) 153 | 154 | let is_call_to_invariant callee = 155 | match callee with 156 | | (_, Expression.Identifier (_, { Identifier.name = "invariant"; _ })) -> true 157 | | _ -> false 158 | 159 | let is_call_to_is_array callee = 160 | match callee with 161 | | ( _, 162 | Flow_ast.Expression.Member 163 | { 164 | Flow_ast.Expression.Member._object = 165 | ( _, 166 | Flow_ast.Expression.Identifier 167 | (_, { Flow_ast.Identifier.name = "Array"; comments = _ }) 168 | ); 169 | property = 170 | Flow_ast.Expression.Member.PropertyIdentifier 171 | (_, { Flow_ast.Identifier.name = "isArray"; comments = _ }); 172 | comments = _; 173 | } 174 | ) -> 175 | true 176 | | _ -> false 177 | 178 | let is_call_to_object_dot_freeze callee = 179 | match callee with 180 | | ( _, 181 | Flow_ast.Expression.Member 182 | { 183 | Flow_ast.Expression.Member._object = 184 | ( _, 185 | Flow_ast.Expression.Identifier 186 | (_, { Flow_ast.Identifier.name = "Object"; comments = _ }) 187 | ); 188 | property = 189 | Flow_ast.Expression.Member.PropertyIdentifier 190 | (_, { Flow_ast.Identifier.name = "freeze"; comments = _ }); 191 | comments = _; 192 | } 193 | ) -> 194 | true 195 | | _ -> false 196 | 197 | let is_call_to_object_static_method callee = 198 | match callee with 199 | | ( _, 200 | Flow_ast.Expression.Member 201 | { 202 | Flow_ast.Expression.Member._object = 203 | ( _, 204 | Flow_ast.Expression.Identifier 205 | (_, { Flow_ast.Identifier.name = "Object"; comments = _ }) 206 | ); 207 | property = Flow_ast.Expression.Member.PropertyIdentifier _; 208 | comments = _; 209 | } 210 | ) -> 211 | true 212 | | _ -> false 213 | 214 | let is_super_member_access = function 215 | | { Flow_ast.Expression.Member._object = (_, Flow_ast.Expression.Super _); _ } -> true 216 | | _ -> false 217 | 218 | let loc_of_statement = fst 219 | 220 | let loc_of_expression = fst 221 | 222 | let loc_of_pattern = fst 223 | 224 | let loc_of_ident = fst 225 | 226 | let name_of_ident (_, { Identifier.name; comments = _ }) = name 227 | 228 | let source_of_ident (loc, { Identifier.name; comments = _ }) = (loc, name) 229 | 230 | let ident_of_source ?comments (loc, name) = (loc, { Identifier.name; comments }) 231 | 232 | let mk_comments ?(leading = []) ?(trailing = []) a = { Syntax.leading; trailing; internal = a } 233 | 234 | let mk_comments_opt ?(leading = []) ?(trailing = []) () = 235 | match (leading, trailing) with 236 | | ([], []) -> None 237 | | (_, _) -> Some (mk_comments ~leading ~trailing ()) 238 | 239 | let mk_comments_with_internal_opt ?(leading = []) ?(trailing = []) ~internal () = 240 | match (leading, trailing, internal) with 241 | | ([], [], []) -> None 242 | | _ -> Some (mk_comments ~leading ~trailing internal) 243 | 244 | let merge_comments ~inner ~outer = 245 | let open Syntax in 246 | match (inner, outer) with 247 | | (None, c) 248 | | (c, None) -> 249 | c 250 | | (Some inner, Some outer) -> 251 | mk_comments_opt 252 | ~leading:(outer.leading @ inner.leading) 253 | ~trailing:(inner.trailing @ outer.trailing) 254 | () 255 | 256 | let merge_comments_with_internal ~inner ~outer = 257 | match (inner, outer) with 258 | | (inner, None) -> inner 259 | | (None, Some { Syntax.leading; trailing; _ }) -> 260 | mk_comments_with_internal_opt ~leading ~trailing ~internal:[] () 261 | | ( Some { Syntax.leading = inner_leading; trailing = inner_trailing; internal }, 262 | Some { Syntax.leading = outer_leading; trailing = outer_trailing; _ } 263 | ) -> 264 | mk_comments_with_internal_opt 265 | ~leading:(outer_leading @ inner_leading) 266 | ~trailing:(inner_trailing @ outer_trailing) 267 | ~internal 268 | () 269 | 270 | let split_comments comments = 271 | match comments with 272 | | None -> (None, None) 273 | | Some { Syntax.leading; trailing; _ } -> 274 | (mk_comments_opt ~leading (), mk_comments_opt ~trailing ()) 275 | 276 | let string_of_assignment_operator op = 277 | let open Flow_ast.Expression.Assignment in 278 | match op with 279 | | PlusAssign -> "+=" 280 | | MinusAssign -> "-=" 281 | | MultAssign -> "*=" 282 | | ExpAssign -> "**=" 283 | | DivAssign -> "/=" 284 | | ModAssign -> "%=" 285 | | LShiftAssign -> "<<=" 286 | | RShiftAssign -> ">>=" 287 | | RShift3Assign -> ">>>=" 288 | | BitOrAssign -> "|=" 289 | | BitXorAssign -> "^=" 290 | | BitAndAssign -> "&=" 291 | | NullishAssign -> "??=" 292 | | AndAssign -> "&&=" 293 | | OrAssign -> "||=" 294 | 295 | let string_of_binary_operator op = 296 | let open Flow_ast.Expression.Binary in 297 | match op with 298 | | Equal -> "==" 299 | | NotEqual -> "!=" 300 | | StrictEqual -> "===" 301 | | StrictNotEqual -> "!==" 302 | | LessThan -> "<" 303 | | LessThanEqual -> "<=" 304 | | GreaterThan -> ">" 305 | | GreaterThanEqual -> ">=" 306 | | LShift -> "<<" 307 | | RShift -> ">>" 308 | | RShift3 -> ">>>" 309 | | Plus -> "+" 310 | | Minus -> "-" 311 | | Mult -> "*" 312 | | Exp -> "**" 313 | | Div -> "/" 314 | | Mod -> "%" 315 | | BitOr -> "|" 316 | | Xor -> "^" 317 | | BitAnd -> "&" 318 | | In -> "in" 319 | | Instanceof -> "instanceof" 320 | 321 | module ExpressionSort = struct 322 | type t = 323 | | Array 324 | | ArrowFunction 325 | | Assignment 326 | | Binary 327 | | Call 328 | | Class 329 | | Conditional 330 | | Function 331 | | Identifier 332 | | Import 333 | | JSXElement 334 | | JSXFragment 335 | | Literal 336 | | Logical 337 | | Member 338 | | MetaProperty 339 | | New 340 | | Object 341 | | OptionalCall 342 | | OptionalMember 343 | | Sequence 344 | | Super 345 | | TaggedTemplate 346 | | TemplateLiteral 347 | | This 348 | | TypeCast 349 | | Unary 350 | | Update 351 | | Yield 352 | [@@deriving show] 353 | 354 | let to_string = function 355 | | Array -> "array" 356 | | ArrowFunction -> "arrow function" 357 | | Assignment -> "assignment expression" 358 | | Binary -> "binary expression" 359 | | Call -> "call expression" 360 | | Class -> "class" 361 | | Conditional -> "conditional expression" 362 | | Function -> "function" 363 | | Identifier -> "identifier" 364 | | Import -> "import expression" 365 | | JSXElement -> "JSX element" 366 | | JSXFragment -> "JSX fragment" 367 | | Literal -> "literal" 368 | | Logical -> "logical expression" 369 | | Member -> "member expression" 370 | | MetaProperty -> "metaproperty expression" 371 | | New -> "new expression" 372 | | Object -> "object" 373 | | OptionalCall -> "optional call expression" 374 | | OptionalMember -> "optional member expression" 375 | | Sequence -> "sequence" 376 | | Super -> "`super` reference" 377 | | TaggedTemplate -> "tagged template expression" 378 | | TemplateLiteral -> "template literal" 379 | | This -> "`this` reference" 380 | | TypeCast -> "type cast" 381 | | Unary -> "unary expression" 382 | | Update -> "update expression" 383 | | Yield -> "yield expression" 384 | end 385 | 386 | let loc_of_annotation_or_hint = 387 | let open Flow_ast.Type in 388 | function 389 | | Missing loc 390 | | Available (_, (loc, _)) -> 391 | loc 392 | 393 | let loc_of_return_annot = 394 | let open Flow_ast.Function.ReturnAnnot in 395 | function 396 | | Missing loc 397 | | Available (_, (loc, _)) 398 | | TypeGuard (loc, _) -> 399 | loc 400 | 401 | (* Apply type [t] at the toplevel of expression [exp]. This is straightforward overall 402 | * except for the case of Identifier and Member, where we push the type within the 403 | * identifier and member property type position as well. This is to ensure that 404 | * type-at-pos searcher will detect the updated type. *) 405 | let push_toplevel_type t exp = 406 | let open Flow_ast.Expression in 407 | let push_toplevel_identifier id = 408 | let ((id_loc, _), id) = id in 409 | ((id_loc, t), id) 410 | in 411 | let push_to_member mem = 412 | match mem with 413 | | { Member.property = Member.PropertyIdentifier id; _ } -> 414 | { mem with Member.property = Member.PropertyIdentifier (push_toplevel_identifier id) } 415 | | p -> p 416 | in 417 | let ((loc, _), e) = exp in 418 | let e' = 419 | match e with 420 | | Identifier id -> Identifier (push_toplevel_identifier id) 421 | | Member member -> Member (push_to_member member) 422 | | OptionalMember ({ OptionalMember.member; _ } as omem) -> 423 | OptionalMember { omem with OptionalMember.member = push_to_member member } 424 | | _ -> e 425 | in 426 | ((loc, t), e') 427 | -------------------------------------------------------------------------------- /vendor/parser/flow_ast_utils.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type 'loc binding = 'loc * string 9 | 10 | type 'loc ident = 'loc * string [@@deriving show] 11 | 12 | type 'loc source = 'loc * string [@@deriving show] 13 | 14 | val fold_bindings_of_pattern : 15 | ('a -> ('m, 't) Flow_ast.Identifier.t -> 'a) -> 'a -> ('m, 't) Flow_ast.Pattern.t -> 'a 16 | 17 | val fold_bindings_of_variable_declarations : 18 | (bool -> 'a -> ('m, 't) Flow_ast.Identifier.t -> 'a) -> 19 | 'a -> 20 | ('m, 't) Flow_ast.Statement.VariableDeclaration.Declarator.t list -> 21 | 'a 22 | 23 | val pattern_has_binding : ('m, 't) Flow_ast.Pattern.t -> bool 24 | 25 | val partition_directives : 26 | (Loc.t, Loc.t) Flow_ast.Statement.t list -> 27 | (Loc.t, Loc.t) Flow_ast.Statement.t list * (Loc.t, Loc.t) Flow_ast.Statement.t list 28 | 29 | val hoist_function_and_component_declarations : 30 | ('a, 'b) Flow_ast.Statement.t list -> ('a, 'b) Flow_ast.Statement.t list 31 | 32 | val is_call_to_invariant : ('a, 'b) Flow_ast.Expression.t -> bool 33 | 34 | val is_call_to_is_array : ('a, 'b) Flow_ast.Expression.t -> bool 35 | 36 | val is_call_to_object_dot_freeze : ('a, 'b) Flow_ast.Expression.t -> bool 37 | 38 | val is_call_to_object_static_method : ('a, 'b) Flow_ast.Expression.t -> bool 39 | 40 | val is_super_member_access : ('a, 'b) Flow_ast.Expression.Member.t -> bool 41 | 42 | val negate_number_literal : float * string -> float * string 43 | 44 | val negate_bigint_literal : int64 option * string -> int64 option * string 45 | 46 | val loc_of_expression : ('a, 'a) Flow_ast.Expression.t -> 'a 47 | 48 | val loc_of_statement : ('a, 'a) Flow_ast.Statement.t -> 'a 49 | 50 | val loc_of_pattern : ('a, 'a) Flow_ast.Pattern.t -> 'a 51 | 52 | val loc_of_ident : ('a, 'a) Flow_ast.Identifier.t -> 'a 53 | 54 | val name_of_ident : ('loc, 'a) Flow_ast.Identifier.t -> string 55 | 56 | val source_of_ident : ('a, 'a) Flow_ast.Identifier.t -> 'a source 57 | 58 | val ident_of_source : 59 | ?comments:('a, unit) Flow_ast.Syntax.t -> 'a source -> ('a, 'a) Flow_ast.Identifier.t 60 | 61 | val mk_comments : 62 | ?leading:'loc Flow_ast.Comment.t list -> 63 | ?trailing:'loc Flow_ast.Comment.t list -> 64 | 'a -> 65 | ('loc, 'a) Flow_ast.Syntax.t 66 | 67 | val mk_comments_opt : 68 | ?leading:'loc Flow_ast.Comment.t list -> 69 | ?trailing:'loc Flow_ast.Comment.t list -> 70 | unit -> 71 | ('loc, unit) Flow_ast.Syntax.t option 72 | 73 | val mk_comments_with_internal_opt : 74 | ?leading:'loc Flow_ast.Comment.t list -> 75 | ?trailing:'loc Flow_ast.Comment.t list -> 76 | internal:'loc Flow_ast.Comment.t list -> 77 | unit -> 78 | ('loc, 'loc Flow_ast.Comment.t list) Flow_ast.Syntax.t option 79 | 80 | val merge_comments : 81 | inner:('M, unit) Flow_ast.Syntax.t option -> 82 | outer:('M, unit) Flow_ast.Syntax.t option -> 83 | ('M, unit) Flow_ast.Syntax.t option 84 | 85 | val merge_comments_with_internal : 86 | inner:('M, 'loc Flow_ast.Comment.t list) Flow_ast.Syntax.t option -> 87 | outer:('M, 'a) Flow_ast.Syntax.t option -> 88 | ('M, 'loc Flow_ast.Comment.t list) Flow_ast.Syntax.t option 89 | 90 | val split_comments : 91 | ('loc, unit) Flow_ast.Syntax.t option -> 92 | ('loc, unit) Flow_ast.Syntax.t option * ('loc, unit) Flow_ast.Syntax.t option 93 | 94 | module ExpressionSort : sig 95 | type t = 96 | | Array 97 | | ArrowFunction 98 | | Assignment 99 | | Binary 100 | | Call 101 | | Class 102 | | Conditional 103 | | Function 104 | | Identifier 105 | | Import 106 | | JSXElement 107 | | JSXFragment 108 | | Literal 109 | | Logical 110 | | Member 111 | | MetaProperty 112 | | New 113 | | Object 114 | | OptionalCall 115 | | OptionalMember 116 | | Sequence 117 | | Super 118 | | TaggedTemplate 119 | | TemplateLiteral 120 | | This 121 | | TypeCast 122 | | Unary 123 | | Update 124 | | Yield 125 | [@@deriving show] 126 | 127 | val to_string : t -> string 128 | end 129 | 130 | val string_of_assignment_operator : Flow_ast.Expression.Assignment.operator -> string 131 | 132 | val string_of_binary_operator : Flow_ast.Expression.Binary.operator -> string 133 | 134 | val loc_of_annotation_or_hint : ('loc, 'loc) Flow_ast.Type.annotation_or_hint -> 'loc 135 | 136 | val loc_of_return_annot : ('loc, 'loc) Flow_ast.Function.ReturnAnnot.t -> 'loc 137 | 138 | val push_toplevel_type : 139 | 't -> ('loc, 'loc * 't) Flow_ast.Expression.t -> ('loc, 'loc * 't) Flow_ast.Expression.t 140 | -------------------------------------------------------------------------------- /vendor/parser/flow_lexer.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | val jsx_child : Lex_env.t -> Lex_env.t * Lex_result.t 9 | 10 | val regexp : Lex_env.t -> Lex_env.t * Lex_result.t 11 | 12 | val jsx_tag : Lex_env.t -> Lex_env.t * Lex_result.t 13 | 14 | val template_tail : Lex_env.t -> Lex_env.t * Lex_result.t 15 | 16 | val type_token : Lex_env.t -> Lex_env.t * Lex_result.t 17 | 18 | val token : Lex_env.t -> Lex_env.t * Lex_result.t 19 | 20 | val is_valid_identifier_name : Flow_sedlexing.lexbuf -> bool 21 | -------------------------------------------------------------------------------- /vendor/parser/js_id.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | external ( .!() ) : (int * int) array -> int -> int * int = "%array_unsafe_get" 9 | 10 | let rec search (arr : _ array) (start : int) (finish : int) target = 11 | if start > finish then 12 | false 13 | else 14 | let mid = start + ((finish - start) / 2) in 15 | let (a, b) = arr.!(mid) in 16 | if target < a then 17 | search arr start (mid - 1) target 18 | else if target >= b then 19 | search arr (mid + 1) finish target 20 | else 21 | true 22 | 23 | let is_valid_unicode_id (i : int) = 24 | search Js_id_unicode.id_continue 0 (Array.length Js_id_unicode.id_continue - 1) i 25 | -------------------------------------------------------------------------------- /vendor/parser/js_id.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* This test is applied to non-start unicode points *) 9 | val is_valid_unicode_id : int -> bool 10 | -------------------------------------------------------------------------------- /vendor/parser/js_id_unicode.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* This lists two valid unicode point ranges in tuple format. 9 | see more details in https://mathiasbynens.be/notes/javascript-identifiers-es6 10 | TODO: store it in a flat array 11 | add more docs 12 | *) 13 | [@@@ocamlformat "disable"] 14 | 15 | (* JS has stricter rules with start id *) 16 | let id_start = [|36,37;65,91;95,96;97,123;170,171;181,182;186,187;192,215;216,247;248,706;710,722;736,741;748,749;750,751;880,885;886,888;890,894;895,896;902,903;904,907;908,909;910,930;931,1014;1015,1154;1162,1328;1329,1367;1369,1370;1376,1417;1488,1515;1519,1523;1568,1611;1646,1648;1649,1748;1749,1750;1765,1767;1774,1776;1786,1789;1791,1792;1808,1809;1810,1840;1869,1958;1969,1970;1994,2027;2036,2038;2042,2043;2048,2070;2074,2075;2084,2085;2088,2089;2112,2137;2144,2155;2208,2229;2230,2238;2308,2362;2365,2366;2384,2385;2392,2402;2417,2433;2437,2445;2447,2449;2451,2473;2474,2481;2482,2483;2486,2490;2493,2494;2510,2511;2524,2526;2527,2530;2544,2546;2556,2557;2565,2571;2575,2577;2579,2601;2602,2609;2610,2612;2613,2615;2616,2618;2649,2653;2654,2655;2674,2677;2693,2702;2703,2706;2707,2729;2730,2737;2738,2740;2741,2746;2749,2750;2768,2769;2784,2786;2809,2810;2821,2829;2831,2833;2835,2857;2858,2865;2866,2868;2869,2874;2877,2878;2908,2910;2911,2914;2929,2930;2947,2948;2949,2955;2958,2961;2962,2966;2969,2971;2972,2973;2974,2976;2979,2981;2984,2987;2990,3002;3024,3025;3077,3085;3086,3089;3090,3113;3114,3130;3133,3134;3160,3163;3168,3170;3200,3201;3205,3213;3214,3217;3218,3241;3242,3252;3253,3258;3261,3262;3294,3295;3296,3298;3313,3315;3333,3341;3342,3345;3346,3387;3389,3390;3406,3407;3412,3415;3423,3426;3450,3456;3461,3479;3482,3506;3507,3516;3517,3518;3520,3527;3585,3633;3634,3636;3648,3655;3713,3715;3716,3717;3718,3723;3724,3748;3749,3750;3751,3761;3762,3764;3773,3774;3776,3781;3782,3783;3804,3808;3840,3841;3904,3912;3913,3949;3976,3981;4096,4139;4159,4160;4176,4182;4186,4190;4193,4194;4197,4199;4206,4209;4213,4226;4238,4239;4256,4294;4295,4296;4301,4302;4304,4347;4348,4681;4682,4686;4688,4695;4696,4697;4698,4702;4704,4745;4746,4750;4752,4785;4786,4790;4792,4799;4800,4801;4802,4806;4808,4823;4824,4881;4882,4886;4888,4955;4992,5008;5024,5110;5112,5118;5121,5741;5743,5760;5761,5787;5792,5867;5870,5881;5888,5901;5902,5906;5920,5938;5952,5970;5984,5997;5998,6001;6016,6068;6103,6104;6108,6109;6176,6265;6272,6313;6314,6315;6320,6390;6400,6431;6480,6510;6512,6517;6528,6572;6576,6602;6656,6679;6688,6741;6823,6824;6917,6964;6981,6988;7043,7073;7086,7088;7098,7142;7168,7204;7245,7248;7258,7294;7296,7305;7312,7355;7357,7360;7401,7405;7406,7412;7413,7415;7418,7419;7424,7616;7680,7958;7960,7966;7968,8006;8008,8014;8016,8024;8025,8026;8027,8028;8029,8030;8031,8062;8064,8117;8118,8125;8126,8127;8130,8133;8134,8141;8144,8148;8150,8156;8160,8173;8178,8181;8182,8189;8305,8306;8319,8320;8336,8349;8450,8451;8455,8456;8458,8468;8469,8470;8472,8478;8484,8485;8486,8487;8488,8489;8490,8506;8508,8512;8517,8522;8526,8527;8544,8585;11264,11311;11312,11359;11360,11493;11499,11503;11506,11508;11520,11558;11559,11560;11565,11566;11568,11624;11631,11632;11648,11671;11680,11687;11688,11695;11696,11703;11704,11711;11712,11719;11720,11727;11728,11735;11736,11743;12293,12296;12321,12330;12337,12342;12344,12349;12353,12439;12443,12448;12449,12539;12540,12544;12549,12592;12593,12687;12704,12731;12784,12800;13312,19894;19968,40944;40960,42125;42192,42238;42240,42509;42512,42528;42538,42540;42560,42607;42623,42654;42656,42736;42775,42784;42786,42889;42891,42944;42946,42951;42999,43010;43011,43014;43015,43019;43020,43043;43072,43124;43138,43188;43250,43256;43259,43260;43261,43263;43274,43302;43312,43335;43360,43389;43396,43443;43471,43472;43488,43493;43494,43504;43514,43519;43520,43561;43584,43587;43588,43596;43616,43639;43642,43643;43646,43696;43697,43698;43701,43703;43705,43710;43712,43713;43714,43715;43739,43742;43744,43755;43762,43765;43777,43783;43785,43791;43793,43799;43808,43815;43816,43823;43824,43867;43868,43880;43888,44003;44032,55204;55216,55239;55243,55292;63744,64110;64112,64218;64256,64263;64275,64280;64285,64286;64287,64297;64298,64311;64312,64317;64318,64319;64320,64322;64323,64325;64326,64434;64467,64830;64848,64912;64914,64968;65008,65020;65136,65141;65142,65277;65313,65339;65345,65371;65382,65471;65474,65480;65482,65488;65490,65496;65498,65501;65536,65548;65549,65575;65576,65595;65596,65598;65599,65614;65616,65630;65664,65787;65856,65909;66176,66205;66208,66257;66304,66336;66349,66379;66384,66422;66432,66462;66464,66500;66504,66512;66513,66518;66560,66718;66736,66772;66776,66812;66816,66856;66864,66916;67072,67383;67392,67414;67424,67432;67584,67590;67592,67593;67594,67638;67639,67641;67644,67645;67647,67670;67680,67703;67712,67743;67808,67827;67828,67830;67840,67862;67872,67898;67968,68024;68030,68032;68096,68097;68112,68116;68117,68120;68121,68150;68192,68221;68224,68253;68288,68296;68297,68325;68352,68406;68416,68438;68448,68467;68480,68498;68608,68681;68736,68787;68800,68851;68864,68900;69376,69405;69415,69416;69424,69446;69600,69623;69635,69688;69763,69808;69840,69865;69891,69927;69956,69957;69968,70003;70006,70007;70019,70067;70081,70085;70106,70107;70108,70109;70144,70162;70163,70188;70272,70279;70280,70281;70282,70286;70287,70302;70303,70313;70320,70367;70405,70413;70415,70417;70419,70441;70442,70449;70450,70452;70453,70458;70461,70462;70480,70481;70493,70498;70656,70709;70727,70731;70751,70752;70784,70832;70852,70854;70855,70856;71040,71087;71128,71132;71168,71216;71236,71237;71296,71339;71352,71353;71424,71451;71680,71724;71840,71904;71935,71936;72096,72104;72106,72145;72161,72162;72163,72164;72192,72193;72203,72243;72250,72251;72272,72273;72284,72330;72349,72350;72384,72441;72704,72713;72714,72751;72768,72769;72818,72848;72960,72967;72968,72970;72971,73009;73030,73031;73056,73062;73063,73065;73066,73098;73112,73113;73440,73459;73728,74650;74752,74863;74880,75076;77824,78895;82944,83527;92160,92729;92736,92767;92880,92910;92928,92976;92992,92996;93027,93048;93053,93072;93760,93824;93952,94027;94032,94033;94099,94112;94176,94178;94179,94180;94208,100344;100352,101107;110592,110879;110928,110931;110948,110952;110960,111356;113664,113771;113776,113789;113792,113801;113808,113818;119808,119893;119894,119965;119966,119968;119970,119971;119973,119975;119977,119981;119982,119994;119995,119996;119997,120004;120005,120070;120071,120075;120077,120085;120086,120093;120094,120122;120123,120127;120128,120133;120134,120135;120138,120145;120146,120486;120488,120513;120514,120539;120540,120571;120572,120597;120598,120629;120630,120655;120656,120687;120688,120713;120714,120745;120746,120771;120772,120780;123136,123181;123191,123198;123214,123215;123584,123628;124928,125125;125184,125252;125259,125260;126464,126468;126469,126496;126497,126499;126500,126501;126503,126504;126505,126515;126516,126520;126521,126522;126523,126524;126530,126531;126535,126536;126537,126538;126539,126540;126541,126544;126545,126547;126548,126549;126551,126552;126553,126554;126555,126556;126557,126558;126559,126560;126561,126563;126564,126565;126567,126571;126572,126579;126580,126584;126585,126589;126590,126591;126592,126602;126603,126620;126625,126628;126629,126634;126635,126652;131072,173783;173824,177973;177984,178206;178208,183970;183984,191457;194560,195102|] 17 | 18 | (* The followed ID restriction is relaxed, this one 19 | is used in our customized unicode lexing. 20 | *) 21 | let id_continue = [|36,37;48,58;65,91;95,96;97,123;170,171;181,182;183,184;186,187;192,215;216,247;248,706;710,722;736,741;748,749;750,751;768,885;886,888;890,894;895,896;902,907;908,909;910,930;931,1014;1015,1154;1155,1160;1162,1328;1329,1367;1369,1370;1376,1417;1425,1470;1471,1472;1473,1475;1476,1478;1479,1480;1488,1515;1519,1523;1552,1563;1568,1642;1646,1748;1749,1757;1759,1769;1770,1789;1791,1792;1808,1867;1869,1970;1984,2038;2042,2043;2045,2046;2048,2094;2112,2140;2144,2155;2208,2229;2230,2238;2259,2274;2275,2404;2406,2416;2417,2436;2437,2445;2447,2449;2451,2473;2474,2481;2482,2483;2486,2490;2492,2501;2503,2505;2507,2511;2519,2520;2524,2526;2527,2532;2534,2546;2556,2557;2558,2559;2561,2564;2565,2571;2575,2577;2579,2601;2602,2609;2610,2612;2613,2615;2616,2618;2620,2621;2622,2627;2631,2633;2635,2638;2641,2642;2649,2653;2654,2655;2662,2678;2689,2692;2693,2702;2703,2706;2707,2729;2730,2737;2738,2740;2741,2746;2748,2758;2759,2762;2763,2766;2768,2769;2784,2788;2790,2800;2809,2816;2817,2820;2821,2829;2831,2833;2835,2857;2858,2865;2866,2868;2869,2874;2876,2885;2887,2889;2891,2894;2902,2904;2908,2910;2911,2916;2918,2928;2929,2930;2946,2948;2949,2955;2958,2961;2962,2966;2969,2971;2972,2973;2974,2976;2979,2981;2984,2987;2990,3002;3006,3011;3014,3017;3018,3022;3024,3025;3031,3032;3046,3056;3072,3085;3086,3089;3090,3113;3114,3130;3133,3141;3142,3145;3146,3150;3157,3159;3160,3163;3168,3172;3174,3184;3200,3204;3205,3213;3214,3217;3218,3241;3242,3252;3253,3258;3260,3269;3270,3273;3274,3278;3285,3287;3294,3295;3296,3300;3302,3312;3313,3315;3328,3332;3333,3341;3342,3345;3346,3397;3398,3401;3402,3407;3412,3416;3423,3428;3430,3440;3450,3456;3458,3460;3461,3479;3482,3506;3507,3516;3517,3518;3520,3527;3530,3531;3535,3541;3542,3543;3544,3552;3558,3568;3570,3572;3585,3643;3648,3663;3664,3674;3713,3715;3716,3717;3718,3723;3724,3748;3749,3750;3751,3774;3776,3781;3782,3783;3784,3790;3792,3802;3804,3808;3840,3841;3864,3866;3872,3882;3893,3894;3895,3896;3897,3898;3902,3912;3913,3949;3953,3973;3974,3992;3993,4029;4038,4039;4096,4170;4176,4254;4256,4294;4295,4296;4301,4302;4304,4347;4348,4681;4682,4686;4688,4695;4696,4697;4698,4702;4704,4745;4746,4750;4752,4785;4786,4790;4792,4799;4800,4801;4802,4806;4808,4823;4824,4881;4882,4886;4888,4955;4957,4960;4969,4978;4992,5008;5024,5110;5112,5118;5121,5741;5743,5760;5761,5787;5792,5867;5870,5881;5888,5901;5902,5909;5920,5941;5952,5972;5984,5997;5998,6001;6002,6004;6016,6100;6103,6104;6108,6110;6112,6122;6155,6158;6160,6170;6176,6265;6272,6315;6320,6390;6400,6431;6432,6444;6448,6460;6470,6510;6512,6517;6528,6572;6576,6602;6608,6619;6656,6684;6688,6751;6752,6781;6783,6794;6800,6810;6823,6824;6832,6846;6912,6988;6992,7002;7019,7028;7040,7156;7168,7224;7232,7242;7245,7294;7296,7305;7312,7355;7357,7360;7376,7379;7380,7419;7424,7674;7675,7958;7960,7966;7968,8006;8008,8014;8016,8024;8025,8026;8027,8028;8029,8030;8031,8062;8064,8117;8118,8125;8126,8127;8130,8133;8134,8141;8144,8148;8150,8156;8160,8173;8178,8181;8182,8189;8204,8206;8255,8257;8276,8277;8305,8306;8319,8320;8336,8349;8400,8413;8417,8418;8421,8433;8450,8451;8455,8456;8458,8468;8469,8470;8472,8478;8484,8485;8486,8487;8488,8489;8490,8506;8508,8512;8517,8522;8526,8527;8544,8585;11264,11311;11312,11359;11360,11493;11499,11508;11520,11558;11559,11560;11565,11566;11568,11624;11631,11632;11647,11671;11680,11687;11688,11695;11696,11703;11704,11711;11712,11719;11720,11727;11728,11735;11736,11743;11744,11776;12293,12296;12321,12336;12337,12342;12344,12349;12353,12439;12441,12448;12449,12539;12540,12544;12549,12592;12593,12687;12704,12731;12784,12800;13312,19894;19968,40944;40960,42125;42192,42238;42240,42509;42512,42540;42560,42608;42612,42622;42623,42738;42775,42784;42786,42889;42891,42944;42946,42951;42999,43048;43072,43124;43136,43206;43216,43226;43232,43256;43259,43260;43261,43310;43312,43348;43360,43389;43392,43457;43471,43482;43488,43519;43520,43575;43584,43598;43600,43610;43616,43639;43642,43715;43739,43742;43744,43760;43762,43767;43777,43783;43785,43791;43793,43799;43808,43815;43816,43823;43824,43867;43868,43880;43888,44011;44012,44014;44016,44026;44032,55204;55216,55239;55243,55292;63744,64110;64112,64218;64256,64263;64275,64280;64285,64297;64298,64311;64312,64317;64318,64319;64320,64322;64323,64325;64326,64434;64467,64830;64848,64912;64914,64968;65008,65020;65024,65040;65056,65072;65075,65077;65101,65104;65136,65141;65142,65277;65296,65306;65313,65339;65343,65344;65345,65371;65382,65471;65474,65480;65482,65488;65490,65496;65498,65501;65536,65548;65549,65575;65576,65595;65596,65598;65599,65614;65616,65630;65664,65787;65856,65909;66045,66046;66176,66205;66208,66257;66272,66273;66304,66336;66349,66379;66384,66427;66432,66462;66464,66500;66504,66512;66513,66518;66560,66718;66720,66730;66736,66772;66776,66812;66816,66856;66864,66916;67072,67383;67392,67414;67424,67432;67584,67590;67592,67593;67594,67638;67639,67641;67644,67645;67647,67670;67680,67703;67712,67743;67808,67827;67828,67830;67840,67862;67872,67898;67968,68024;68030,68032;68096,68100;68101,68103;68108,68116;68117,68120;68121,68150;68152,68155;68159,68160;68192,68221;68224,68253;68288,68296;68297,68327;68352,68406;68416,68438;68448,68467;68480,68498;68608,68681;68736,68787;68800,68851;68864,68904;68912,68922;69376,69405;69415,69416;69424,69457;69600,69623;69632,69703;69734,69744;69759,69819;69840,69865;69872,69882;69888,69941;69942,69952;69956,69959;69968,70004;70006,70007;70016,70085;70089,70093;70096,70107;70108,70109;70144,70162;70163,70200;70206,70207;70272,70279;70280,70281;70282,70286;70287,70302;70303,70313;70320,70379;70384,70394;70400,70404;70405,70413;70415,70417;70419,70441;70442,70449;70450,70452;70453,70458;70459,70469;70471,70473;70475,70478;70480,70481;70487,70488;70493,70500;70502,70509;70512,70517;70656,70731;70736,70746;70750,70752;70784,70854;70855,70856;70864,70874;71040,71094;71096,71105;71128,71134;71168,71233;71236,71237;71248,71258;71296,71353;71360,71370;71424,71451;71453,71468;71472,71482;71680,71739;71840,71914;71935,71936;72096,72104;72106,72152;72154,72162;72163,72165;72192,72255;72263,72264;72272,72346;72349,72350;72384,72441;72704,72713;72714,72759;72760,72769;72784,72794;72818,72848;72850,72872;72873,72887;72960,72967;72968,72970;72971,73015;73018,73019;73020,73022;73023,73032;73040,73050;73056,73062;73063,73065;73066,73103;73104,73106;73107,73113;73120,73130;73440,73463;73728,74650;74752,74863;74880,75076;77824,78895;82944,83527;92160,92729;92736,92767;92768,92778;92880,92910;92912,92917;92928,92983;92992,92996;93008,93018;93027,93048;93053,93072;93760,93824;93952,94027;94031,94088;94095,94112;94176,94178;94179,94180;94208,100344;100352,101107;110592,110879;110928,110931;110948,110952;110960,111356;113664,113771;113776,113789;113792,113801;113808,113818;113821,113823;119141,119146;119149,119155;119163,119171;119173,119180;119210,119214;119362,119365;119808,119893;119894,119965;119966,119968;119970,119971;119973,119975;119977,119981;119982,119994;119995,119996;119997,120004;120005,120070;120071,120075;120077,120085;120086,120093;120094,120122;120123,120127;120128,120133;120134,120135;120138,120145;120146,120486;120488,120513;120514,120539;120540,120571;120572,120597;120598,120629;120630,120655;120656,120687;120688,120713;120714,120745;120746,120771;120772,120780;120782,120832;121344,121399;121403,121453;121461,121462;121476,121477;121499,121504;121505,121520;122880,122887;122888,122905;122907,122914;122915,122917;122918,122923;123136,123181;123184,123198;123200,123210;123214,123215;123584,123642;124928,125125;125136,125143;125184,125260;125264,125274;126464,126468;126469,126496;126497,126499;126500,126501;126503,126504;126505,126515;126516,126520;126521,126522;126523,126524;126530,126531;126535,126536;126537,126538;126539,126540;126541,126544;126545,126547;126548,126549;126551,126552;126553,126554;126555,126556;126557,126558;126559,126560;126561,126563;126564,126565;126567,126571;126572,126579;126580,126584;126585,126589;126590,126591;126592,126602;126603,126620;126625,126628;126629,126634;126635,126652;131072,173783;173824,177973;177984,178206;178208,183970;183984,191457;194560,195102;917760,918000|] 22 | -------------------------------------------------------------------------------- /vendor/parser/jsdoc.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Sedlexing = Flow_sedlexing 9 | 10 | module Param = struct 11 | type optionality = 12 | | NotOptional 13 | | Optional 14 | | OptionalWithDefault of string 15 | [@@deriving show, eq] 16 | 17 | type info = { 18 | description: string option; 19 | optional: optionality; 20 | } 21 | [@@deriving show, eq] 22 | 23 | type path = 24 | | Name 25 | | Element of path 26 | | Member of path * string 27 | [@@deriving show, eq] 28 | 29 | type t = (path * info) list [@@deriving show, eq] 30 | end 31 | 32 | module Params = struct 33 | type t = (string * Param.t) list [@@deriving show, eq] 34 | end 35 | 36 | module Unrecognized_tags = struct 37 | type t = (string * string option) list [@@deriving show, eq] 38 | end 39 | 40 | type t = { 41 | description: string option; 42 | params: Params.t; 43 | deprecated: string option; 44 | unrecognized_tags: Unrecognized_tags.t; 45 | } 46 | 47 | (*************) 48 | (* accessors *) 49 | (*************) 50 | 51 | let description { description; _ } = description 52 | 53 | let params { params; _ } = params 54 | 55 | let deprecated { deprecated; _ } = deprecated 56 | 57 | let unrecognized_tags { unrecognized_tags; _ } = unrecognized_tags 58 | 59 | (***********) 60 | (* parsing *) 61 | (***********) 62 | 63 | module Parser = struct 64 | (* regexps copied from Flow_lexer since sedlex doesn't let us import them *) 65 | 66 | let whitespace = 67 | [%sedlex.regexp? 68 | ( 0x0009 | 0x000B | 0x000C | 0x0020 | 0x00A0 | 0xfeff | 0x1680 69 | | 0x2000 .. 0x200a 70 | | 0x202f | 0x205f | 0x3000 )] 71 | 72 | let line_terminator_sequence = [%sedlex.regexp? '\n' | '\r' | "\r\n" | 0x2028 | 0x2029] 73 | 74 | let identifier = [%sedlex.regexp? Plus (Compl (white_space | '[' | '.' | ']' | '=' | '{'))] 75 | 76 | (* Helpers *) 77 | 78 | let empty = { description = None; params = []; deprecated = None; unrecognized_tags = [] } 79 | 80 | let trimmed_string_of_buffer buffer = buffer |> Buffer.contents |> String.trim 81 | 82 | let description_of_desc_buf desc_buf = 83 | match trimmed_string_of_buffer desc_buf with 84 | | "" -> None 85 | | s -> Some s 86 | 87 | (* like Base.List.Assoc.add, but maintains ordering differently: 88 | * - if k is already in the list, keeps it in that position and updates the value 89 | * - if k isn't in the list, adds it to the end *) 90 | let rec add_assoc ~equal k v = function 91 | | [] -> [(k, v)] 92 | | (k', v') :: xs -> 93 | if equal k' k then 94 | (k, v) :: xs 95 | else 96 | (k', v') :: add_assoc ~equal k v xs 97 | 98 | let add_param jsdoc name path description optional = 99 | let old_param_infos = 100 | match Base.List.Assoc.find ~equal:String.equal jsdoc.params name with 101 | | None -> [] 102 | | Some param_infos -> param_infos 103 | in 104 | let new_param_infos = 105 | add_assoc ~equal:Param.equal_path path { Param.description; optional } old_param_infos 106 | in 107 | { jsdoc with params = add_assoc ~equal:String.equal name new_param_infos jsdoc.params } 108 | 109 | let add_unrecognized_tag jsdoc name description = 110 | let { unrecognized_tags; _ } = jsdoc in 111 | { jsdoc with unrecognized_tags = unrecognized_tags @ [(name, description)] } 112 | 113 | (* Parsing functions *) 114 | 115 | (* 116 | `description`, `description_or_tag`, and `description_startline` are 117 | helpers for parsing descriptions: a description is a possibly-multiline 118 | string terminated by EOF or a new tag. The beginning of each line could 119 | contain whitespace and asterisks, which are stripped out when parsing. 120 | *) 121 | let rec description desc_buf lexbuf = 122 | match%sedlex lexbuf with 123 | | line_terminator_sequence -> 124 | Buffer.add_string desc_buf (Sedlexing.Utf8.lexeme lexbuf); 125 | description_startline desc_buf lexbuf 126 | | any -> 127 | Buffer.add_string desc_buf (Sedlexing.Utf8.lexeme lexbuf); 128 | description desc_buf lexbuf 129 | | _ (* eof *) -> description_of_desc_buf desc_buf 130 | 131 | and description_or_tag desc_buf lexbuf = 132 | match%sedlex lexbuf with 133 | | '@' -> description_of_desc_buf desc_buf 134 | | _ -> description desc_buf lexbuf 135 | 136 | and description_startline desc_buf lexbuf = 137 | match%sedlex lexbuf with 138 | | '*' 139 | | whitespace -> 140 | description_startline desc_buf lexbuf 141 | | _ -> description_or_tag desc_buf lexbuf 142 | 143 | let rec param_path ?(path = Param.Name) lexbuf = 144 | match%sedlex lexbuf with 145 | | "[]" -> param_path ~path:(Param.Element path) lexbuf 146 | | ('.', identifier) -> 147 | let member = Sedlexing.Utf8.sub_lexeme lexbuf 1 (Sedlexing.lexeme_length lexbuf - 1) in 148 | param_path ~path:(Param.Member (path, member)) lexbuf 149 | | _ -> path 150 | 151 | let rec skip_tag jsdoc lexbuf = 152 | match%sedlex lexbuf with 153 | | Plus (Compl '@') -> skip_tag jsdoc lexbuf 154 | | '@' -> tag jsdoc lexbuf 155 | | _ (* eof *) -> jsdoc 156 | 157 | and param_tag_description jsdoc name path optional lexbuf = 158 | let desc_buf = Buffer.create 127 in 159 | let description = description desc_buf lexbuf in 160 | let jsdoc = add_param jsdoc name path description optional in 161 | tag jsdoc lexbuf 162 | 163 | and param_tag_pre_description jsdoc name path optional lexbuf = 164 | match%sedlex lexbuf with 165 | | ' ' -> param_tag_pre_description jsdoc name path optional lexbuf 166 | | '-' -> param_tag_description jsdoc name path optional lexbuf 167 | | _ -> param_tag_description jsdoc name path optional lexbuf 168 | 169 | and param_tag_optional_default jsdoc name path def_buf lexbuf = 170 | match%sedlex lexbuf with 171 | | ']' -> 172 | let default = Buffer.contents def_buf in 173 | param_tag_pre_description jsdoc name path (Param.OptionalWithDefault default) lexbuf 174 | | Plus (Compl ']') -> 175 | Buffer.add_string def_buf (Sedlexing.Utf8.lexeme lexbuf); 176 | param_tag_optional_default jsdoc name path def_buf lexbuf 177 | | _ -> 178 | let default = Buffer.contents def_buf in 179 | param_tag_pre_description jsdoc name path (Param.OptionalWithDefault default) lexbuf 180 | 181 | and param_tag_optional jsdoc lexbuf = 182 | match%sedlex lexbuf with 183 | | identifier -> 184 | let name = Sedlexing.Utf8.lexeme lexbuf in 185 | let path = param_path lexbuf in 186 | (match%sedlex lexbuf with 187 | | ']' -> param_tag_pre_description jsdoc name path Param.Optional lexbuf 188 | | '=' -> 189 | let def_buf = Buffer.create 127 in 190 | param_tag_optional_default jsdoc name path def_buf lexbuf 191 | | _ -> param_tag_pre_description jsdoc name path Param.Optional lexbuf) 192 | | _ -> skip_tag jsdoc lexbuf 193 | 194 | (* ignore jsdoc type annotation *) 195 | and param_tag_type jsdoc lexbuf = 196 | match%sedlex lexbuf with 197 | | '}' -> param_tag jsdoc lexbuf 198 | | Plus (Compl '}') -> param_tag_type jsdoc lexbuf 199 | | _ (* eof *) -> jsdoc 200 | 201 | and param_tag jsdoc lexbuf = 202 | match%sedlex lexbuf with 203 | | ' ' -> param_tag jsdoc lexbuf 204 | | '{' -> param_tag_type jsdoc lexbuf 205 | | '[' -> param_tag_optional jsdoc lexbuf 206 | | identifier -> 207 | let name = Sedlexing.Utf8.lexeme lexbuf in 208 | let path = param_path lexbuf in 209 | param_tag_pre_description jsdoc name path Param.NotOptional lexbuf 210 | | _ -> skip_tag jsdoc lexbuf 211 | 212 | and description_tag jsdoc lexbuf = 213 | let desc_buf = Buffer.create 127 in 214 | let description = description desc_buf lexbuf in 215 | let jsdoc = { jsdoc with description } in 216 | tag jsdoc lexbuf 217 | 218 | and deprecated_tag jsdoc lexbuf = 219 | let deprecated_tag_buf = Buffer.create 127 in 220 | let deprecated = Some (Base.Option.value ~default:"" (description deprecated_tag_buf lexbuf)) in 221 | { jsdoc with deprecated } 222 | 223 | and unrecognized_tag jsdoc name lexbuf = 224 | let desc_buf = Buffer.create 127 in 225 | let description = description desc_buf lexbuf in 226 | let jsdoc = add_unrecognized_tag jsdoc name description in 227 | tag jsdoc lexbuf 228 | 229 | and tag jsdoc lexbuf = 230 | match%sedlex lexbuf with 231 | | "param" 232 | | "arg" 233 | | "argument" -> 234 | param_tag jsdoc lexbuf 235 | | "description" 236 | | "desc" -> 237 | description_tag jsdoc lexbuf 238 | | "deprecated" -> deprecated_tag jsdoc lexbuf 239 | | identifier -> 240 | let name = Sedlexing.Utf8.lexeme lexbuf in 241 | unrecognized_tag jsdoc name lexbuf 242 | | _ -> skip_tag jsdoc lexbuf 243 | 244 | let initial lexbuf = 245 | match%sedlex lexbuf with 246 | | ('*', Compl '*') -> 247 | Sedlexing.rollback lexbuf; 248 | let desc_buf = Buffer.create 127 in 249 | let description = description_startline desc_buf lexbuf in 250 | let jsdoc = { empty with description } in 251 | Some (tag jsdoc lexbuf) 252 | | _ -> None 253 | end 254 | 255 | let parse str = 256 | let lexbuf = Sedlexing.Utf8.from_string str in 257 | Parser.initial lexbuf 258 | 259 | (* find and parse the last jsdoc-containing comment in the list if exists *) 260 | let of_comments = 261 | let open Flow_ast in 262 | let of_comment = function 263 | | (_, Comment.{ kind = Block; text; _ }) -> parse text 264 | | (_, Comment.{ kind = Line; _ }) -> None 265 | in 266 | let rec of_comment_list = function 267 | | [] -> None 268 | | c :: cs -> 269 | (match of_comment_list cs with 270 | | Some _ as j -> j 271 | | None -> of_comment c) 272 | in 273 | let of_syntax Syntax.{ leading; _ } = of_comment_list leading in 274 | Base.Option.bind ~f:of_syntax 275 | -------------------------------------------------------------------------------- /vendor/parser/jsdoc.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Param : sig 9 | type optionality = 10 | | NotOptional 11 | | Optional 12 | | OptionalWithDefault of string 13 | [@@deriving show, eq] 14 | 15 | type info = { 16 | description: string option; 17 | optional: optionality; 18 | } 19 | [@@deriving show, eq] 20 | 21 | type path = 22 | | Name 23 | | Element of path 24 | | Member of path * string 25 | [@@deriving show, eq] 26 | 27 | type t = (path * info) list [@@deriving show, eq] 28 | end 29 | 30 | module Params : sig 31 | type t = (string * Param.t) list [@@deriving show, eq] 32 | end 33 | 34 | module Unrecognized_tags : sig 35 | type t = (string * string option) list [@@deriving show, eq] 36 | end 37 | 38 | type t 39 | 40 | (*************) 41 | (* accessors *) 42 | (*************) 43 | 44 | val description : t -> string option 45 | 46 | val params : t -> Params.t 47 | 48 | val deprecated : t -> string option 49 | 50 | val unrecognized_tags : t -> Unrecognized_tags.t 51 | 52 | (***********) 53 | (* parsing *) 54 | (***********) 55 | 56 | val of_comments : ('M, 'T) Flow_ast.Syntax.t option -> t option 57 | -------------------------------------------------------------------------------- /vendor/parser/lex_env.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Sedlexing = Flow_sedlexing 9 | 10 | (* bol = Beginning Of Line *) 11 | type bol = { 12 | line: int; 13 | offset: int; 14 | } 15 | 16 | type lex_state = { lex_errors_acc: (Loc.t * Parse_error.t) list } [@@ocaml.unboxed] 17 | 18 | type t = { 19 | lex_source: File_key.t option; 20 | lex_lb: Sedlexing.lexbuf; 21 | lex_bol: bol; 22 | lex_in_comment_syntax: bool; 23 | lex_enable_comment_syntax: bool; 24 | lex_state: lex_state; 25 | lex_last_loc: Loc.t; 26 | } 27 | 28 | let empty_lex_state = { lex_errors_acc = [] } 29 | 30 | (* The lex_last_loc should initially be set to the beginning of the first line, so that 31 | comments on the first line are reported as not being on a new line. *) 32 | let initial_last_loc = 33 | { Loc.source = None; start = { Loc.line = 1; column = 0 }; _end = { Loc.line = 1; column = 0 } } 34 | 35 | let new_lex_env lex_source lex_lb ~enable_types_in_comments = 36 | { 37 | lex_source; 38 | lex_lb; 39 | lex_bol = { line = 1; offset = 0 }; 40 | lex_in_comment_syntax = false; 41 | lex_enable_comment_syntax = enable_types_in_comments; 42 | lex_state = empty_lex_state; 43 | lex_last_loc = initial_last_loc; 44 | } 45 | 46 | (* copy all the mutable things so that we have a distinct lexing environment 47 | that does not interfere with ordinary lexer operations *) 48 | let clone env = 49 | let lex_lb = Sedlexing.lexbuf_clone env.lex_lb in 50 | { env with lex_lb } 51 | 52 | let lexbuf env = env.lex_lb 53 | 54 | let source env = env.lex_source 55 | 56 | let state env = env.lex_state 57 | 58 | let line env = env.lex_bol.line 59 | 60 | let bol_offset env = env.lex_bol.offset 61 | 62 | let is_in_comment_syntax env = env.lex_in_comment_syntax 63 | 64 | let is_comment_syntax_enabled env = env.lex_enable_comment_syntax 65 | 66 | let in_comment_syntax is_in env = 67 | if is_in <> env.lex_in_comment_syntax then 68 | { env with lex_in_comment_syntax = is_in } 69 | else 70 | env 71 | 72 | (* TODO *) 73 | let debug_string_of_lexbuf _lb = "" 74 | 75 | let debug_string_of_lex_env (env : t) = 76 | let source = 77 | match source env with 78 | | None -> "None" 79 | | Some x -> Printf.sprintf "Some %S" (File_key.to_string x) 80 | in 81 | Printf.sprintf 82 | "{\n lex_source = %s\n lex_lb = %s\n lex_in_comment_syntax = %b\n lex_enable_comment_syntax = %b\n lex_state = {errors = (count = %d)}\n}" 83 | source 84 | (debug_string_of_lexbuf env.lex_lb) 85 | (is_in_comment_syntax env) 86 | (is_comment_syntax_enabled env) 87 | (List.length (state env).lex_errors_acc) 88 | -------------------------------------------------------------------------------- /vendor/parser/lex_result.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = { 9 | lex_token: Token.t; 10 | lex_loc: Loc.t; 11 | lex_errors: (Loc.t * Parse_error.t) list; 12 | lex_comments: Loc.t Flow_ast.Comment.t list; 13 | } 14 | 15 | let token result = result.lex_token 16 | 17 | let loc result = result.lex_loc 18 | 19 | let comments result = result.lex_comments 20 | 21 | let errors result = result.lex_errors 22 | 23 | let debug_string_of_lex_result lex_result = 24 | Printf.sprintf 25 | "{\n lex_token = %s\n lex_value = %S\n lex_errors = (length = %d)\n lex_comments = (length = %d)\n}" 26 | (Token.token_to_string lex_result.lex_token) 27 | (Token.value_of_token lex_result.lex_token) 28 | (List.length lex_result.lex_errors) 29 | (List.length lex_result.lex_comments) 30 | -------------------------------------------------------------------------------- /vendor/parser/loc.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* line numbers are 1-indexed; column numbers are 0-indexed *) 9 | type position = { 10 | line: int; 11 | column: int; 12 | } 13 | [@@deriving eq, show] 14 | 15 | (* start is inclusive; end is exclusive *) 16 | (* If you are modifying this record, go look at ALoc.ml and make sure you understand the 17 | * representation there. *) 18 | type t = { 19 | source: File_key.t option; 20 | start: position; 21 | _end: position; 22 | } 23 | [@@deriving show] 24 | 25 | let none = { source = None; start = { line = 0; column = 0 }; _end = { line = 0; column = 0 } } 26 | 27 | let is_none (x : t) = 28 | x == none 29 | || 30 | match x with 31 | | { source = None; start = { line = 0; column = 0 }; _end = { line = 0; column = 0 } } -> true 32 | | _ -> false 33 | 34 | let is_none_ignore_source (x : t) = 35 | x == none 36 | || 37 | match x with 38 | | { source = _; start = { line = 0; column = 0 }; _end = { line = 0; column = 0 } } -> true 39 | | _ -> false 40 | 41 | let btwn loc1 loc2 = { source = loc1.source; start = loc1.start; _end = loc2._end } 42 | 43 | (* Returns the position immediately before the start of the given loc. If the 44 | given loc is at the beginning of a line, return the position of the first 45 | char on the same line. *) 46 | let char_before loc = 47 | let start = 48 | let { line; column } = loc.start in 49 | let column = 50 | if column > 0 then 51 | column - 1 52 | else 53 | column 54 | in 55 | { line; column } 56 | in 57 | let _end = loc.start in 58 | { loc with start; _end } 59 | 60 | (* Returns the location of the first character in the given loc. Not accurate if the 61 | * first line is a newline character, but is still consistent with loc orderings. *) 62 | let first_char loc = 63 | let start = loc.start in 64 | let _end = { start with column = start.column + 1 } in 65 | { loc with _end } 66 | 67 | let pos_cmp a b = 68 | let k = a.line - b.line in 69 | if k = 0 then 70 | a.column - b.column 71 | else 72 | k 73 | 74 | (** 75 | * If `a` spans (completely contains) `b`, then returns 0. 76 | * If `b` starts before `a` (even if it ends inside), returns < 0. 77 | * If `b` ends after `a` (even if it starts inside), returns > 0. 78 | *) 79 | let span_compare a b = 80 | let k = File_key.compare_opt a.source b.source in 81 | if k = 0 then 82 | let k = pos_cmp a.start b.start in 83 | if k <= 0 then 84 | let k = pos_cmp a._end b._end in 85 | if k >= 0 then 86 | 0 87 | else 88 | -1 89 | else 90 | 1 91 | else 92 | k 93 | 94 | (** [contains loc1 loc2] returns true if [loc1] entirely overlaps [loc2] *) 95 | let contains loc1 loc2 = span_compare loc1 loc2 = 0 96 | 97 | (** [intersects loc1 loc2] returns true if [loc1] intersects [loc2] at all *) 98 | let intersects loc1 loc2 = 99 | File_key.compare_opt loc1.source loc2.source = 0 100 | && not (pos_cmp loc1._end loc2.start < 0 || pos_cmp loc1.start loc2._end > 0) 101 | 102 | (** [lines_intersect loc1 loc2] returns true if [loc1] and [loc2] cover any part of 103 | the same line, even if they don't actually intersect. 104 | 105 | For example, if [loc1] ends and then [loc2] begins later on the same line, 106 | [intersects loc1 loc2] is false, but [lines_intersect loc1 loc2] is true. *) 107 | let lines_intersect loc1 loc2 = 108 | File_key.compare_opt loc1.source loc2.source = 0 109 | && not (loc1._end.line < loc2.start.line || loc1.start.line > loc2._end.line) 110 | 111 | let compare_ignore_source loc1 loc2 = 112 | match pos_cmp loc1.start loc2.start with 113 | | 0 -> pos_cmp loc1._end loc2._end 114 | | k -> k 115 | 116 | let compare loc1 loc2 = 117 | let k = File_key.compare_opt loc1.source loc2.source in 118 | if k = 0 then 119 | compare_ignore_source loc1 loc2 120 | else 121 | k 122 | 123 | let equal loc1 loc2 = compare loc1 loc2 = 0 124 | 125 | (** 126 | * This is mostly useful for debugging purposes. 127 | * Please don't dead-code delete this! 128 | *) 129 | let debug_to_string ?(include_source = false) loc = 130 | let source = 131 | if include_source then 132 | Printf.sprintf 133 | "%S: " 134 | (match loc.source with 135 | | Some src -> File_key.to_string src 136 | | None -> "") 137 | else 138 | "" 139 | in 140 | let pos = 141 | Printf.sprintf 142 | "(%d, %d) to (%d, %d)" 143 | loc.start.line 144 | loc.start.column 145 | loc._end.line 146 | loc._end.column 147 | in 148 | source ^ pos 149 | 150 | let to_string_no_source loc = 151 | let line = loc.start.line in 152 | let start = loc.start.column + 1 in 153 | let end_ = loc._end.column in 154 | if line <= 0 then 155 | "0:0" 156 | else if line = loc._end.line && start = end_ then 157 | Printf.sprintf "%d:%d" line start 158 | else if line != loc._end.line then 159 | Printf.sprintf "%d:%d,%d:%d" line start loc._end.line end_ 160 | else 161 | Printf.sprintf "%d:%d-%d" line start end_ 162 | 163 | let mk_loc ?source (start_line, start_column) (end_line, end_column) = 164 | { 165 | source; 166 | start = { line = start_line; column = start_column }; 167 | _end = { line = end_line; column = end_column }; 168 | } 169 | 170 | let source loc = loc.source 171 | 172 | (** Produces a zero-width Loc.t, where start = end *) 173 | let cursor source line column = { source; start = { line; column }; _end = { line; column } } 174 | 175 | let start_loc loc = { loc with _end = loc.start } 176 | 177 | let end_loc loc = { loc with start = loc._end } 178 | -------------------------------------------------------------------------------- /vendor/parser/loc.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type position = { 9 | line: int; 10 | column: int; 11 | } 12 | [@@deriving eq, show] 13 | 14 | type t = { 15 | source: File_key.t option; 16 | start: position; 17 | _end: position; 18 | } 19 | [@@deriving show] 20 | 21 | val none : t 22 | 23 | val is_none : t -> bool 24 | 25 | val is_none_ignore_source : t -> bool 26 | 27 | val btwn : t -> t -> t 28 | 29 | val char_before : t -> t 30 | 31 | val first_char : t -> t 32 | 33 | (** [contains loc1 loc2] returns true if [loc1] entirely overlaps [loc2] *) 34 | val contains : t -> t -> bool 35 | 36 | (** [intersects loc1 loc2] returns true if [loc1] intersects [loc2] at all *) 37 | val intersects : t -> t -> bool 38 | 39 | (** [lines_intersect loc1 loc2] returns true if [loc1] and [loc2] cover any part of 40 | the same line, even if they don't actually intersect. 41 | 42 | For example, if [loc1] ends and then [loc2] begins later on the same line, 43 | [intersects loc1 loc2] is false, but [lines_intersect loc1 loc2] is true. *) 44 | val lines_intersect : t -> t -> bool 45 | 46 | val pos_cmp : position -> position -> int 47 | 48 | val span_compare : t -> t -> int 49 | 50 | val compare_ignore_source : t -> t -> int 51 | 52 | val compare : t -> t -> int 53 | 54 | val equal : t -> t -> bool 55 | 56 | val debug_to_string : ?include_source:bool -> t -> string 57 | 58 | (* Relatively compact; suitable for use as a unique string identifier *) 59 | val to_string_no_source : t -> string 60 | 61 | val mk_loc : ?source:File_key.t -> int * int -> int * int -> t 62 | 63 | val source : t -> File_key.t option 64 | 65 | (** Produces a zero-width Loc.t, where start = end *) 66 | val cursor : File_key.t option -> int -> int -> t 67 | 68 | (* Produces a location at the start of the input location *) 69 | val start_loc : t -> t 70 | 71 | (* Produces a location at the end of the input location *) 72 | val end_loc : t -> t 73 | -------------------------------------------------------------------------------- /vendor/parser/offset_utils.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* table from 0-based line number and 0-based column number to the offset at that point *) 9 | type t = int array array 10 | 11 | type offset_kind = 12 | | Utf8 13 | | JavaScript 14 | 15 | (* Classify each codepoint. We care about how many bytes each codepoint takes, in order to 16 | compute offsets in terms of bytes instead of codepoints. We also care about various kinds of 17 | newlines. To reduce memory, it is important that this is a basic variant with no parameters 18 | (so, don't make it `Chars of int`). *) 19 | type kind = 20 | (* Char has a codepoint greater than or equal to 0x0 but less than 0x80 *) 21 | | Chars_0x0 22 | (* Char has a codepoint greater than or equal to 0x80 but less than 0x800 *) 23 | | Chars_0x80 24 | | Chars_0x800 25 | | Chars_0x10000 26 | | Malformed 27 | | Cr 28 | | Nl 29 | | Ls 30 | 31 | (* Gives the size in bytes of the character's UTF-8 encoding *) 32 | let utf8_size_of_kind = function 33 | | Chars_0x0 -> 1 34 | | Chars_0x80 -> 2 35 | | Chars_0x800 -> 3 36 | | Chars_0x10000 -> 4 37 | | Malformed -> 1 38 | | Cr -> 1 39 | | Nl -> 1 40 | | Ls -> 3 41 | 42 | (* Gives the size in code units (16-bit blocks) of the character's UTF-16 encoding *) 43 | let js_size_of_kind = function 44 | | Chars_0x0 45 | | Chars_0x80 46 | | Chars_0x800 -> 47 | 1 48 | | Chars_0x10000 -> 2 49 | | Malformed -> 1 50 | | Cr -> 1 51 | | Nl -> 1 52 | | Ls -> 1 53 | 54 | let make = 55 | (* Using Wtf8 allows us to properly track multi-byte characters, so that we increment the column 56 | * by 1 for a multi-byte character, but increment the offset by the number of bytes in the 57 | * character. It also keeps us from incrementing the line number if a multi-byte character happens 58 | * to include e.g. the codepoint for '\n' as a second-fourth byte. *) 59 | let fold_codepoints acc _offset chr = 60 | let kind = 61 | match chr with 62 | | Wtf8.Point code -> 63 | if code == 0x2028 || code == 0x2029 then 64 | Ls 65 | else if code == 0xA then 66 | Nl 67 | else if code == 0xD then 68 | Cr 69 | else if code >= 0x10000 then 70 | Chars_0x10000 71 | else if code >= 0x800 then 72 | Chars_0x800 73 | else if code >= 0x80 then 74 | Chars_0x80 75 | else 76 | Chars_0x0 77 | | Wtf8.Malformed -> Malformed 78 | in 79 | kind :: acc 80 | in 81 | (* Traverses a `kind list`, breaking it up into an `int array array`, where each `int array` 82 | contains the offsets at each character (aka codepoint) of a line. *) 83 | let rec build_table size_of_kind (offset, rev_line, acc) = function 84 | | [] -> Array.of_list (List.rev acc) 85 | | Cr :: Nl :: rest -> 86 | (* https://www.ecma-international.org/ecma-262/5.1/#sec-7.3 says that "\r\n" should be treated 87 | like a single line terminator, even though both '\r' and '\n' are line terminators in their 88 | own right. *) 89 | let line = Array.of_list (List.rev (offset :: rev_line)) in 90 | build_table size_of_kind (offset + 2, [], line :: acc) rest 91 | | ((Cr | Nl | Ls) as kind) :: rest -> 92 | let line = Array.of_list (List.rev (offset :: rev_line)) in 93 | build_table size_of_kind (offset + size_of_kind kind, [], line :: acc) rest 94 | | ((Chars_0x0 | Chars_0x80 | Chars_0x800 | Chars_0x10000 | Malformed) as kind) :: rest -> 95 | build_table size_of_kind (offset + size_of_kind kind, offset :: rev_line, acc) rest 96 | in 97 | fun ~kind text -> 98 | let rev_kinds = Wtf8.fold_wtf_8 fold_codepoints [] text in 99 | (* Add a phantom line at the end of the file. Since end positions are reported exclusively, it 100 | * is possible for the lexer to output an end position with a line number one higher than the 101 | * last line, to indicate something such as "the entire last line." For this purpose, we can 102 | * return the offset that is one higher than the last legitimate offset, since it could only be 103 | * correctly used as an exclusive index. *) 104 | let rev_kinds = Nl :: rev_kinds in 105 | let size_of_kind = 106 | match kind with 107 | | Utf8 -> utf8_size_of_kind 108 | | JavaScript -> js_size_of_kind 109 | in 110 | build_table size_of_kind (0, [], []) (List.rev rev_kinds) 111 | 112 | exception Offset_lookup_failed of Loc.position * string 113 | 114 | let lookup arr i pos context_string = 115 | try arr.(i) with 116 | | Invalid_argument _ -> 117 | let msg = 118 | Printf.sprintf 119 | "Failure while looking up %s. Index: %d. Length: %d." 120 | context_string 121 | i 122 | (Array.length arr) 123 | in 124 | raise (Offset_lookup_failed (pos, msg)) 125 | 126 | let offset table pos = 127 | Loc.( 128 | (* Special-case `Loc.none` so we don't try to look up line -1. *) 129 | if pos.line = 0 && pos.column = 0 then 130 | (* Loc.none sets the offset as 0, so that's what we'll return here. *) 131 | 0 132 | else 133 | (* lines are 1-indexed, columns are zero-indexed *) 134 | let line_table = lookup table (pos.line - 1) pos "line" in 135 | lookup line_table pos.column pos "column" 136 | ) 137 | 138 | let debug_string table = 139 | let buf = Buffer.create 4096 in 140 | Array.iteri 141 | (fun line_num line -> 142 | Printf.bprintf buf "%6d: " line_num; 143 | Array.iter (fun offset -> Printf.bprintf buf "%8d " offset) line; 144 | Buffer.add_char buf '\n') 145 | table; 146 | Buffer.contents buf 147 | 148 | let line_lengths table = 149 | Array.fold_left 150 | (fun (prev_line_end, lengths_rev) line -> 151 | let line_end = line.(Array.length line - 1) in 152 | (line_end, (line_end - prev_line_end) :: lengths_rev)) 153 | (-1, []) 154 | table 155 | |> snd 156 | |> List.rev 157 | 158 | let contains_multibyte_character table = 159 | let exception FoundMultibyte in 160 | try 161 | Array.iter 162 | (fun line -> 163 | Array.iteri 164 | (fun i offset -> 165 | if i > 0 then 166 | let offset_before = line.(i - 1) in 167 | if offset - offset_before > 1 then raise FoundMultibyte) 168 | line) 169 | table; 170 | false 171 | with 172 | | FoundMultibyte -> true 173 | -------------------------------------------------------------------------------- /vendor/parser/offset_utils.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* Note on character encodings: 9 | * 10 | * Throughout Flow, we assume that program text uses a UTF-8 encoding. OCaml strings are just a 11 | * sequence of bytes, so any handling of multi-byte characters needs to be done explicitly. 12 | * 13 | * Column numbers in `Loc.position`s are based on the number of characters into a line the position 14 | * appears, not the number of bytes. Single-byte and multi-byte characters are treated the same for 15 | * the purposes of counting columns. 16 | * 17 | * However, offsets are most useful (at least when working with OCaml's string representation) when 18 | * they represent the number of bytes into the text a given position is. 19 | * 20 | * In contrast, JavaScript strings must behave as if they have a UTF-16 encoding, and each element 21 | * is a single 16-bit entry. So, each character occupies either one or two elements of a JavaScript 22 | * string. Esprima, for example, returns ranges based on index into a JS string. 23 | * 24 | * Clients can choose between byte offsets and UTF-16 code unit offsets when building the offset 25 | * table. 26 | * 27 | * For example, with the Utf8 offset kind selected, this utility would consider the smiley emoji 28 | * (code point 0x1f603) to have width 4 (because its UTF-8 encoding is 4 8-bit elements), but with 29 | * the JavaScript offset kind selected, it (and Esprima) would consider it to have width 2 (because 30 | * its UTF-16 encoding is 2 16-bit elements). 31 | *) 32 | 33 | (* A structure that allows for quick computation of offsets when given a Loc.position *) 34 | type t 35 | 36 | type offset_kind = 37 | | Utf8 38 | | JavaScript 39 | 40 | (* Create a table for offsets in the given file. Takes O(n) time and returns an object that takes 41 | * O(n) space, where `n` is the size of the given program text. *) 42 | val make : kind:offset_kind -> string (* program text *) -> t 43 | 44 | exception Offset_lookup_failed of Loc.position * string 45 | 46 | (* Returns the offset for the given location. This is the offset in bytes (not characters!) into the 47 | * file where the given position can be found. Constant time operation. Raises 48 | * `Offset_lookup_failed` if the given position does not exist in the file contents which were used 49 | * to construct the table. *) 50 | val offset : t -> Loc.position -> int 51 | 52 | val debug_string : t -> string 53 | 54 | val line_lengths : t -> int list 55 | 56 | val contains_multibyte_character : t -> bool 57 | -------------------------------------------------------------------------------- /vendor/parser/parse_error_utils.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | let camelize str = 9 | match String.split_on_char '-' str with 10 | | [] -> str 11 | | [str] -> str 12 | | hd :: rest -> 13 | let parts = hd :: List.map String.capitalize_ascii rest in 14 | String.concat "" parts 15 | -------------------------------------------------------------------------------- /vendor/parser/parser_common.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | open Parser_env 9 | open Flow_ast 10 | 11 | type pattern_errors = { 12 | if_expr: (Loc.t * Parse_error.t) list; 13 | if_patt: (Loc.t * Parse_error.t) list; 14 | } 15 | 16 | type pattern_cover = 17 | | Cover_expr of (Loc.t, Loc.t) Expression.t 18 | | Cover_patt of (Loc.t, Loc.t) Expression.t * pattern_errors 19 | 20 | module type PARSER = sig 21 | val program : env -> (Loc.t, Loc.t) Program.t 22 | 23 | val statement : env -> (Loc.t, Loc.t) Statement.t 24 | 25 | val statement_list_item : 26 | ?decorators:(Loc.t, Loc.t) Class.Decorator.t list -> env -> (Loc.t, Loc.t) Statement.t 27 | 28 | val statement_list : term_fn:(Token.t -> bool) -> env -> (Loc.t, Loc.t) Statement.t list 29 | 30 | val statement_list_with_directives : 31 | term_fn:(Token.t -> bool) -> env -> (Loc.t, Loc.t) Statement.t list * bool 32 | 33 | val module_body : term_fn:(Token.t -> bool) -> env -> (Loc.t, Loc.t) Statement.t list 34 | 35 | val expression : env -> (Loc.t, Loc.t) Expression.t 36 | 37 | val expression_or_pattern : env -> pattern_cover 38 | 39 | val conditional : env -> (Loc.t, Loc.t) Expression.t 40 | 41 | val assignment : env -> (Loc.t, Loc.t) Expression.t 42 | 43 | val left_hand_side : env -> (Loc.t, Loc.t) Expression.t 44 | 45 | val object_initializer : env -> Loc.t * (Loc.t, Loc.t) Expression.Object.t * pattern_errors 46 | 47 | val identifier : ?restricted_error:Parse_error.t -> env -> (Loc.t, Loc.t) Identifier.t 48 | 49 | val identifier_with_type : 50 | env -> ?no_optional:bool -> Parse_error.t -> Loc.t * (Loc.t, Loc.t) Pattern.Identifier.t 51 | 52 | val block_body : env -> Loc.t * (Loc.t, Loc.t) Statement.Block.t 53 | 54 | val function_block_body : 55 | expression:bool -> env -> (Loc.t * (Loc.t, Loc.t) Statement.Block.t) * bool 56 | 57 | val jsx_element_or_fragment : 58 | env -> 59 | Loc.t * [ `Element of (Loc.t, Loc.t) JSX.element | `Fragment of (Loc.t, Loc.t) JSX.fragment ] 60 | 61 | val pattern : env -> Parse_error.t -> (Loc.t, Loc.t) Pattern.t 62 | 63 | val pattern_from_expr : env -> (Loc.t, Loc.t) Expression.t -> (Loc.t, Loc.t) Pattern.t 64 | 65 | val object_key : ?class_body:bool -> env -> Loc.t * (Loc.t, Loc.t) Expression.Object.Property.key 66 | 67 | val class_declaration : env -> (Loc.t, Loc.t) Class.Decorator.t list -> (Loc.t, Loc.t) Statement.t 68 | 69 | val class_expression : env -> (Loc.t, Loc.t) Expression.t 70 | 71 | val is_assignable_lhs : (Loc.t, Loc.t) Expression.t -> bool 72 | 73 | val number : env -> Token.number_type -> string -> float 74 | 75 | val annot : env -> (Loc.t, Loc.t) Type.annotation 76 | 77 | val bigint : env -> Token.bigint_type -> string -> int64 option 78 | end 79 | 80 | let identifier_name_raw env = 81 | let open Token in 82 | let name = 83 | match Peek.token env with 84 | (* obviously, Identifier is a valid IdentifierName *) 85 | | T_IDENTIFIER { value; _ } -> value 86 | (* keywords are also IdentifierNames *) 87 | | T_AWAIT -> "await" 88 | | T_BREAK -> "break" 89 | | T_CASE -> "case" 90 | | T_CATCH -> "catch" 91 | | T_CLASS -> "class" 92 | | T_CONST -> "const" 93 | | T_CONTINUE -> "continue" 94 | | T_DEBUGGER -> "debugger" 95 | | T_DEFAULT -> "default" 96 | | T_DELETE -> "delete" 97 | | T_DO -> "do" 98 | | T_ELSE -> "else" 99 | | T_EXPORT -> "export" 100 | | T_EXTENDS -> "extends" 101 | | T_FINALLY -> "finally" 102 | | T_FOR -> "for" 103 | | T_FUNCTION -> "function" 104 | | T_IF -> "if" 105 | | T_IMPORT -> "import" 106 | | T_IN -> "in" 107 | | T_INSTANCEOF -> "instanceof" 108 | | T_NEW -> "new" 109 | | T_RETURN -> "return" 110 | | T_SUPER -> "super" 111 | | T_SWITCH -> "switch" 112 | | T_THIS -> "this" 113 | | T_THROW -> "throw" 114 | | T_TRY -> "try" 115 | | T_TYPEOF -> "typeof" 116 | | T_VAR -> "var" 117 | | T_VOID -> "void" 118 | | T_WHILE -> "while" 119 | | T_WITH -> "with" 120 | | T_YIELD -> "yield" 121 | (* FutureReservedWord *) 122 | | T_ENUM -> "enum" 123 | | T_LET -> "let" 124 | | T_STATIC -> "static" 125 | | T_INTERFACE -> "interface" 126 | | T_IMPLEMENTS -> "implements" 127 | | T_PACKAGE -> "package" 128 | | T_PRIVATE -> "private" 129 | | T_PROTECTED -> "protected" 130 | | T_PUBLIC -> "public" 131 | (* NullLiteral *) 132 | | T_NULL -> "null" 133 | (* BooleanLiteral *) 134 | | T_TRUE -> "true" 135 | | T_FALSE -> "false" 136 | (* Flow-specific stuff *) 137 | | T_ASSERTS -> "asserts" 138 | | T_IS -> "is" 139 | | T_DECLARE -> "declare" 140 | | T_TYPE -> "type" 141 | | T_OPAQUE -> "opaque" 142 | | T_ANY_TYPE -> "any" 143 | | T_MIXED_TYPE -> "mixed" 144 | | T_EMPTY_TYPE -> "empty" 145 | | T_BOOLEAN_TYPE BOOL -> "bool" 146 | | T_BOOLEAN_TYPE BOOLEAN -> "boolean" 147 | | T_NUMBER_TYPE -> "number" 148 | | T_BIGINT_TYPE -> "bigint" 149 | | T_STRING_TYPE -> "string" 150 | | T_VOID_TYPE -> "void" 151 | | T_SYMBOL_TYPE -> "symbol" 152 | | T_UNKNOWN_TYPE -> "unknown" 153 | | T_NEVER_TYPE -> "never" 154 | | T_UNDEFINED_TYPE -> "undefined" 155 | | T_KEYOF -> "keyof" 156 | | T_READONLY -> "readonly" 157 | (* Contextual stuff *) 158 | | T_OF -> "of" 159 | | T_ASYNC -> "async" 160 | (* punctuators, types, literals, etc are not identifiers *) 161 | | _ -> 162 | error_unexpected ~expected:"an identifier" env; 163 | "" 164 | in 165 | Eat.token env; 166 | name 167 | 168 | (* IdentifierName - https://tc39.github.io/ecma262/#prod-IdentifierName *) 169 | let identifier_name env = 170 | let loc = Peek.loc env in 171 | let leading = Peek.comments env in 172 | let name = identifier_name_raw env in 173 | let trailing = Eat.trailing_comments env in 174 | let comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing () in 175 | (loc, { Identifier.name; comments }) 176 | 177 | (** PrivateIdentifier - https://tc39.es/ecma262/#prod-PrivateIdentifier 178 | 179 | N.B.: whitespace, line terminators, and comments are not allowed 180 | between the # and IdentifierName because PrivateIdentifier is a 181 | CommonToken which is considered a single token. See also 182 | https://tc39.es/ecma262/#prod-InputElementDiv *) 183 | let private_identifier env = 184 | let start_loc = Peek.loc env in 185 | let leading = Peek.comments env in 186 | Expect.token env Token.T_POUND; 187 | let name_loc = Peek.loc env in 188 | let name = identifier_name_raw env in 189 | let trailing = Eat.trailing_comments env in 190 | let comments = Flow_ast_utils.mk_comments_opt ~leading ~trailing () in 191 | let loc = Loc.btwn start_loc name_loc in 192 | if not (Loc.equal_position start_loc.Loc._end name_loc.Loc.start) then 193 | error_at env (loc, Parse_error.WhitespaceInPrivateName); 194 | (loc, { PrivateName.name; comments }) 195 | 196 | (** The operation IsSimpleParamterList 197 | https://tc39.es/ecma262/#sec-static-semantics-issimpleparameterlist *) 198 | let is_simple_parameter_list = 199 | let is_simple_param = function 200 | | (_, { Flow_ast.Function.Param.argument = (_, Pattern.Identifier _); default = None }) -> true 201 | | _ -> false 202 | in 203 | fun (_, { Flow_ast.Function.Params.params; rest; comments = _; this_ = _ }) -> 204 | rest = None && List.for_all is_simple_param params 205 | 206 | (** 207 | * The abstract operation IsLabelledFunction 208 | * 209 | * https://tc39.github.io/ecma262/#sec-islabelledfunction 210 | *) 211 | let rec is_labelled_function = function 212 | | (_, Flow_ast.Statement.Labeled { Flow_ast.Statement.Labeled.body; _ }) -> begin 213 | match body with 214 | | (_, Flow_ast.Statement.FunctionDeclaration _) -> true 215 | | _ -> is_labelled_function body 216 | end 217 | | _ -> false 218 | 219 | (** https://tc39.es/ecma262/#sec-exports-static-semantics-early-errors *) 220 | let assert_identifier_name_is_identifier 221 | ?restricted_error env (loc, { Flow_ast.Identifier.name; comments = _ }) = 222 | match name with 223 | | "let" when no_let env -> 224 | error_at env (loc, Parse_error.Unexpected (Token.quote_token_value name)) 225 | | "await" -> 226 | (* `allow_await` means that `await` is allowed to be a keyword, 227 | which makes it illegal to use as an identifier. 228 | https://tc39.github.io/ecma262/#sec-identifiers-static-semantics-early-errors *) 229 | if allow_await env then error_at env (loc, Parse_error.AwaitAsIdentifierReference) 230 | | "yield" -> 231 | (* `allow_yield` means that `yield` is allowed to be a keyword, 232 | which makes it illegal to use as an identifier. 233 | https://tc39.github.io/ecma262/#sec-identifiers-static-semantics-early-errors *) 234 | if allow_yield env then 235 | error_at env (loc, Parse_error.UnexpectedReserved) 236 | else 237 | strict_error_at env (loc, Parse_error.StrictReservedWord) 238 | | _ when is_strict_reserved name -> strict_error_at env (loc, Parse_error.StrictReservedWord) 239 | | _ when is_reserved name -> error_at env (loc, Parse_error.UnexpectedReserved) 240 | | _ -> begin 241 | match restricted_error with 242 | | Some err when is_restricted name -> strict_error_at env (loc, err) 243 | | _ -> () 244 | end 245 | 246 | let with_loc ?start_loc fn env = 247 | let start_loc = 248 | match start_loc with 249 | | Some x -> x 250 | | None -> Peek.loc env 251 | in 252 | let result = fn env in 253 | let loc = 254 | match last_loc env with 255 | | Some end_loc -> Loc.btwn start_loc end_loc 256 | | None -> start_loc 257 | in 258 | (loc, result) 259 | 260 | let with_loc_opt ?start_loc fn env = 261 | match with_loc ?start_loc fn env with 262 | | (loc, Some x) -> Some (loc, x) 263 | | (_, None) -> None 264 | 265 | let with_loc_extra ?start_loc fn env = 266 | let (loc, (x, extra)) = with_loc ?start_loc fn env in 267 | ((loc, x), extra) 268 | 269 | let is_start_of_type_guard env = 270 | let open Token in 271 | (* Parse the identifier part as normal code, since this can be any name that 272 | * a parameter can be. *) 273 | Eat.push_lex_mode env Lex_mode.NORMAL; 274 | let token_1 = Peek.token env in 275 | Eat.pop_lex_mode env; 276 | let token_2 = Peek.ith_token ~i:1 env in 277 | match (token_1, token_2) with 278 | | (T_IDENTIFIER { raw = "asserts"; _ }, (T_IDENTIFIER _ | T_THIS)) 279 | | ((T_IDENTIFIER _ | T_THIS), (T_IS | T_IDENTIFIER { raw = "is"; _ })) -> 280 | true 281 | | _ -> false 282 | -------------------------------------------------------------------------------- /vendor/parser/parser_env.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* This module provides a layer between the lexer and the parser which includes 9 | * some parser state and some lexer state *) 10 | 11 | module SSet : Flow_set.S with type elt = string 12 | 13 | module Lex_mode : sig 14 | type t = 15 | | NORMAL 16 | | TYPE 17 | | JSX_TAG 18 | | JSX_CHILD 19 | | TEMPLATE 20 | | REGEXP 21 | 22 | val debug_string_of_lex_mode : t -> string 23 | end 24 | 25 | type token_sink_result = { 26 | token_loc: Loc.t; 27 | token: Token.t; 28 | token_context: Lex_mode.t; 29 | } 30 | 31 | type parse_options = { 32 | components: bool; (* enable parsing of Flow component syntax *) 33 | enums: bool; (** enable parsing of Flow enums *) 34 | esproposal_decorators: bool; (** enable parsing of decorators *) 35 | types: bool; (** enable parsing of Flow types *) 36 | use_strict: bool; (** treat the file as strict, without needing a "use strict" directive *) 37 | module_ref_prefix: string option; 38 | module_ref_prefix_LEGACY_INTEROP: string option; 39 | } 40 | 41 | val default_parse_options : parse_options 42 | 43 | type env 44 | 45 | type allowed_super = 46 | | No_super 47 | | Super_prop 48 | | Super_prop_or_call 49 | 50 | (* constructor: *) 51 | val init_env : 52 | ?token_sink:(token_sink_result -> unit) option -> 53 | ?parse_options:parse_options option -> 54 | File_key.t option -> 55 | string -> 56 | env 57 | 58 | (* getters: *) 59 | val in_strict_mode : env -> bool 60 | 61 | val last_loc : env -> Loc.t option 62 | 63 | val last_token : env -> Token.t option 64 | 65 | val in_export : env -> bool 66 | 67 | val in_export_default : env -> bool 68 | 69 | val labels : env -> SSet.t 70 | 71 | val comments : env -> Loc.t Flow_ast.Comment.t list 72 | 73 | val in_loop : env -> bool 74 | 75 | val in_switch : env -> bool 76 | 77 | val in_formal_parameters : env -> bool 78 | 79 | val in_function : env -> bool 80 | 81 | val allow_yield : env -> bool 82 | 83 | val allow_await : env -> bool 84 | 85 | val allow_directive : env -> bool 86 | 87 | val allow_super : env -> allowed_super 88 | 89 | val has_simple_parameters : env -> bool 90 | 91 | val no_in : env -> bool 92 | 93 | val no_call : env -> bool 94 | 95 | val no_let : env -> bool 96 | 97 | val no_anon_function_type : env -> bool 98 | 99 | val no_conditional_type : env -> bool 100 | 101 | val no_new : env -> bool 102 | 103 | val errors : env -> (Loc.t * Parse_error.t) list 104 | 105 | val parse_options : env -> parse_options 106 | 107 | val source : env -> File_key.t option 108 | 109 | val should_parse_types : env -> bool 110 | 111 | (* mutators: *) 112 | val error_at : env -> Loc.t * Parse_error.t -> unit 113 | 114 | val error : env -> Parse_error.t -> unit 115 | 116 | val error_unexpected : ?expected:string -> env -> unit 117 | 118 | val error_on_decorators : env -> (Loc.t * 'a) list -> unit 119 | 120 | val error_nameless_declaration : env -> string -> unit 121 | 122 | val strict_error : env -> Parse_error.t -> unit 123 | 124 | val strict_error_at : env -> Loc.t * Parse_error.t -> unit 125 | 126 | val function_as_statement_error_at : env -> Loc.t -> unit 127 | 128 | val error_list : env -> (Loc.t * Parse_error.t) list -> unit 129 | 130 | val enter_class : env -> unit 131 | 132 | val exit_class : env -> unit 133 | 134 | val add_declared_private : env -> string -> unit 135 | 136 | val add_used_private : env -> string -> Loc.t -> unit 137 | 138 | val consume_comments_until : env -> Loc.position -> unit 139 | 140 | (* functional operations -- these return shallow copies, so future mutations to 141 | * the returned env will also affect the original: *) 142 | val with_strict : bool -> env -> env 143 | 144 | val with_in_formal_parameters : bool -> env -> env 145 | 146 | val with_in_function : bool -> env -> env 147 | 148 | val with_allow_yield : bool -> env -> env 149 | 150 | val with_allow_await : bool -> env -> env 151 | 152 | val with_allow_directive : bool -> env -> env 153 | 154 | val with_allow_super : allowed_super -> env -> env 155 | 156 | val with_no_let : bool -> env -> env 157 | 158 | val with_in_loop : bool -> env -> env 159 | 160 | val with_no_in : bool -> env -> env 161 | 162 | val with_no_anon_function_type : bool -> env -> env 163 | 164 | val with_no_conditional_type : bool -> env -> env 165 | 166 | val with_no_new : bool -> env -> env 167 | 168 | val with_in_switch : bool -> env -> env 169 | 170 | val with_in_export : bool -> env -> env 171 | 172 | val with_in_export_default : bool -> env -> env 173 | 174 | val with_no_call : bool -> env -> env 175 | 176 | val with_error_callback : (env -> Parse_error.t -> unit) -> env -> env 177 | 178 | val without_error_callback : env -> env 179 | 180 | val add_label : env -> string -> env 181 | 182 | val enter_function : env -> async:bool -> generator:bool -> simple_params:bool -> env 183 | 184 | val is_contextually_reserved : string -> bool 185 | 186 | val is_reserved : string -> bool 187 | 188 | val token_is_contextually_reserved : Token.t -> bool 189 | 190 | val token_is_reserved : Token.t -> bool 191 | 192 | val token_is_reserved_type : Token.t -> bool 193 | 194 | val token_is_type_identifier : env -> Token.t -> bool 195 | 196 | val token_is_variance : Token.t -> bool 197 | 198 | val is_strict_reserved : string -> bool 199 | 200 | val token_is_strict_reserved : Token.t -> bool 201 | 202 | val is_restricted : string -> bool 203 | 204 | val is_reserved_type : string -> bool 205 | 206 | module Peek : sig 207 | val token : env -> Token.t 208 | 209 | val loc : env -> Loc.t 210 | 211 | val loc_skip_lookahead : env -> Loc.t 212 | 213 | val errors : env -> (Loc.t * Parse_error.t) list 214 | 215 | val comments : env -> Loc.t Flow_ast.Comment.t list 216 | 217 | val has_eaten_comments : env -> bool 218 | 219 | val is_line_terminator : env -> bool 220 | 221 | val is_implicit_semicolon : env -> bool 222 | 223 | val is_identifier : env -> bool 224 | 225 | val is_type_identifier : env -> bool 226 | 227 | val is_identifier_name : env -> bool 228 | 229 | val is_function : env -> bool 230 | 231 | val is_class : env -> bool 232 | 233 | val is_component : env -> bool 234 | 235 | val is_renders_ident : env -> bool 236 | 237 | val ith_token : i:int -> env -> Token.t 238 | 239 | val ith_loc : i:int -> env -> Loc.t 240 | 241 | val ith_errors : i:int -> env -> (Loc.t * Parse_error.t) list 242 | 243 | val ith_comments : i:int -> env -> Loc.t Flow_ast.Comment.t list 244 | 245 | val ith_is_line_terminator : i:int -> env -> bool 246 | 247 | val ith_is_implicit_semicolon : i:int -> env -> bool 248 | 249 | val ith_is_identifier : i:int -> env -> bool 250 | 251 | val ith_is_identifier_name : i:int -> env -> bool 252 | 253 | val ith_is_type_identifier : i:int -> env -> bool 254 | end 255 | 256 | module Eat : sig 257 | val token : env -> unit 258 | 259 | val maybe : env -> Token.t -> bool 260 | 261 | val push_lex_mode : env -> Lex_mode.t -> unit 262 | 263 | val pop_lex_mode : env -> unit 264 | 265 | val double_pop_lex_mode : env -> unit 266 | 267 | val trailing_comments : env -> Loc.t Flow_ast.Comment.t list 268 | 269 | val comments_until_next_line : env -> Loc.t Flow_ast.Comment.t list 270 | 271 | val program_comments : env -> Loc.t Flow_ast.Comment.t list 272 | end 273 | 274 | module Expect : sig 275 | val get_error : env -> Token.t -> Loc.t * Parse_error.t 276 | 277 | val error : env -> Token.t -> unit 278 | 279 | val token : env -> Token.t -> unit 280 | 281 | val token_opt : env -> Token.t -> unit 282 | 283 | val token_maybe : env -> Token.t -> bool 284 | 285 | val identifier : env -> string -> unit 286 | end 287 | 288 | module Try : sig 289 | type 'a parse_result = 290 | | ParsedSuccessfully of 'a 291 | | FailedToParse 292 | 293 | exception Rollback 294 | 295 | val to_parse : env -> (env -> 'a) -> 'a parse_result 296 | 297 | val or_else : env -> fallback:'a -> (env -> 'a) -> 'a 298 | end 299 | -------------------------------------------------------------------------------- /vendor/parser/pattern_cover.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | open Flow_ast 9 | open Parser_common 10 | open Parser_env 11 | 12 | module type COVER = sig 13 | val as_expression : env -> pattern_cover -> (Loc.t, Loc.t) Expression.t 14 | 15 | val as_pattern : ?err:Parse_error.t -> env -> pattern_cover -> (Loc.t, Loc.t) Pattern.t 16 | 17 | val empty_errors : pattern_errors 18 | 19 | val cons_error : Loc.t * Parse_error.t -> pattern_errors -> pattern_errors 20 | 21 | val rev_append_errors : pattern_errors -> pattern_errors -> pattern_errors 22 | 23 | val rev_errors : pattern_errors -> pattern_errors 24 | end 25 | 26 | module Cover (Parse : PARSER) : COVER = struct 27 | let as_expression env = function 28 | | Cover_expr expr -> expr 29 | | Cover_patt (expr, { if_expr; if_patt = _ }) -> 30 | List.iter (error_at env) if_expr; 31 | expr 32 | 33 | let as_pattern ?(err = Parse_error.InvalidLHSInAssignment) env cover = 34 | let expr = 35 | match cover with 36 | | Cover_expr expr -> expr 37 | | Cover_patt (expr, { if_expr = _; if_patt }) -> 38 | List.iter (error_at env) if_patt; 39 | expr 40 | in 41 | if not (Parse.is_assignable_lhs expr) then error_at env (fst expr, err); 42 | 43 | (match expr with 44 | | (loc, Flow_ast.Expression.Identifier (_, { Flow_ast.Identifier.name; comments = _ })) 45 | when is_restricted name -> 46 | strict_error_at env (loc, Parse_error.StrictLHSAssignment) 47 | | _ -> ()); 48 | 49 | Parse.pattern_from_expr env expr 50 | 51 | let empty_errors = { if_patt = []; if_expr = [] } 52 | 53 | let cons_error err { if_patt; if_expr } = { if_patt = err :: if_patt; if_expr = err :: if_expr } 54 | 55 | let rev_append_errors a b = 56 | { if_patt = List.rev_append a.if_patt b.if_patt; if_expr = List.rev_append a.if_expr b.if_expr } 57 | 58 | let rev_errors a = { if_patt = List.rev a.if_patt; if_expr = List.rev a.if_expr } 59 | end 60 | -------------------------------------------------------------------------------- /vendor/parser/pattern_parser.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Ast = Flow_ast 9 | open Token 10 | open Parser_common 11 | open Parser_env 12 | open Flow_ast 13 | 14 | let missing_annot env = Ast.Type.Missing (Peek.loc_skip_lookahead env) 15 | 16 | module Pattern (Parse : Parser_common.PARSER) (Type : Type_parser.TYPE) = struct 17 | (* Reinterpret various expressions as patterns. 18 | * This is not the correct thing to do and is only used for assignment 19 | * expressions. This should be removed and replaced ASAP. 20 | *) 21 | let rec object_from_expr = 22 | let rec properties env acc = 23 | let open Ast.Expression.Object in 24 | function 25 | | [] -> List.rev acc 26 | | Property (loc, prop) :: remaining -> 27 | let acc = 28 | match prop with 29 | | Property.Init { key; value; shorthand } -> 30 | let open Ast.Expression in 31 | let key = 32 | match key with 33 | | Property.StringLiteral s -> Pattern.Object.Property.StringLiteral s 34 | | Property.NumberLiteral n -> Pattern.Object.Property.NumberLiteral n 35 | | Property.BigIntLiteral b -> Pattern.Object.Property.BigIntLiteral b 36 | | Property.Identifier id -> Pattern.Object.Property.Identifier id 37 | | Property.PrivateName _ -> failwith "Internal Error: Found object private prop" 38 | | Property.Computed key -> Pattern.Object.Property.Computed key 39 | in 40 | let (pattern, default) = 41 | match value with 42 | | (_loc, Assignment { Assignment.operator = None; left; right; comments = _ }) -> 43 | (left, Some right) 44 | | _ -> (from_expr env value, None) 45 | in 46 | Pattern.Object.Property 47 | (loc, { Pattern.Object.Property.key; pattern; default; shorthand }) 48 | :: acc 49 | | Property.Method { key = _; value = (loc, _) } -> 50 | error_at env (loc, Parse_error.MethodInDestructuring); 51 | acc 52 | | Property.Get { key = _; value = (loc, _); comments = _ } 53 | | Property.Set { key = _; value = (loc, _); comments = _ } -> 54 | (* these should never happen *) 55 | error_at env (loc, Parse_error.Unexpected "identifier"); 56 | acc 57 | in 58 | properties env acc remaining 59 | | [SpreadProperty (loc, { SpreadProperty.argument; comments })] -> 60 | let acc = 61 | Pattern.Object.RestElement 62 | (loc, { Pattern.RestElement.argument = from_expr env argument; comments }) 63 | :: acc 64 | in 65 | properties env acc [] 66 | | SpreadProperty (loc, _) :: remaining -> 67 | error_at env (loc, Parse_error.PropertyAfterRestElement); 68 | properties env acc remaining 69 | in 70 | fun env (loc, { Ast.Expression.Object.properties = props; comments }) -> 71 | ( loc, 72 | Pattern.( 73 | Object 74 | { Object.properties = properties env [] props; annot = missing_annot env; comments } 75 | ) 76 | ) 77 | 78 | and array_from_expr = 79 | (* Convert an Expression to a Pattern if it is a valid 80 | DestructuringAssignmentTarget, which must be an Object, Array or 81 | IsValidSimpleAssignmentTarget. 82 | #sec-destructuring-assignment-static-semantics-early-errors *) 83 | let assignment_target env ((loc, _) as expr) = 84 | if Parse.is_assignable_lhs expr then 85 | Some (from_expr env expr) 86 | else ( 87 | error_at env (loc, Parse_error.InvalidLHSInAssignment); 88 | None 89 | ) 90 | in 91 | let rec elements env acc = 92 | let open Ast.Expression in 93 | function 94 | | [] -> List.rev acc 95 | | [Array.Spread (loc, { SpreadElement.argument; comments })] -> 96 | (* AssignmentRestElement is a DestructuringAssignmentTarget, see 97 | #prod-AssignmentRestElement *) 98 | let acc = 99 | match assignment_target env argument with 100 | | Some argument -> 101 | Pattern.Array.RestElement (loc, { Pattern.RestElement.argument; comments }) :: acc 102 | | None -> acc 103 | in 104 | elements env acc [] 105 | | Array.Spread (loc, _) :: remaining -> 106 | error_at env (loc, Parse_error.ElementAfterRestElement); 107 | elements env acc remaining 108 | | Array.Expression (loc, Assignment { Assignment.operator = None; left; right; comments = _ }) 109 | :: remaining -> 110 | (* AssignmentElement is a `DestructuringAssignmentTarget Initializer`, see 111 | #prod-AssignmentElement *) 112 | let acc = 113 | Pattern.Array.Element 114 | (loc, { Pattern.Array.Element.argument = left; default = Some right }) 115 | :: acc 116 | in 117 | elements env acc remaining 118 | | Array.Expression expr :: remaining -> 119 | (* AssignmentElement is a DestructuringAssignmentTarget, see 120 | #prod-AssignmentElement *) 121 | let acc = 122 | match assignment_target env expr with 123 | | Some ((loc, _) as expr) -> 124 | let element = 125 | Pattern.Array.Element (loc, { Pattern.Array.Element.argument = expr; default = None }) 126 | in 127 | element :: acc 128 | | None -> acc 129 | in 130 | elements env acc remaining 131 | | Array.Hole loc :: remaining -> elements env (Pattern.Array.Hole loc :: acc) remaining 132 | in 133 | fun env (loc, { Ast.Expression.Array.elements = elems; comments }) -> 134 | ( loc, 135 | Pattern.Array 136 | { Pattern.Array.elements = elements env [] elems; annot = missing_annot env; comments } 137 | ) 138 | 139 | and from_expr env (loc, expr) = 140 | let open Ast.Expression in 141 | match expr with 142 | | Object obj -> object_from_expr env (loc, obj) 143 | | Array arr -> array_from_expr env (loc, arr) 144 | | Identifier ((id_loc, { Identifier.name = string_val; comments = _ }) as name) -> 145 | (* per #sec-destructuring-assignment-static-semantics-early-errors, 146 | it is a syntax error if IsValidSimpleAssignmentTarget of this 147 | IdentifierReference is false. That happens when `string_val` is 148 | "eval" or "arguments" in strict mode. *) 149 | if in_strict_mode env && is_restricted string_val then 150 | error_at env (id_loc, Parse_error.StrictLHSAssignment) 151 | (* per #prod-IdentifierReference, yield is only a valid 152 | IdentifierReference when [~Yield], and await is only valid 153 | when [~Await]. but per #sec-identifiers-static-semantics-early-errors, 154 | they are already invalid in strict mode, which we should have 155 | already errored about when parsing the expression that we're now 156 | converting into a pattern. *) 157 | else if not (in_strict_mode env) then 158 | if allow_yield env && string_val = "yield" then 159 | error_at env (id_loc, Parse_error.YieldAsIdentifierReference) 160 | else if allow_await env && string_val = "await" then 161 | error_at env (id_loc, Parse_error.AwaitAsIdentifierReference); 162 | ( loc, 163 | Pattern.Identifier { Pattern.Identifier.name; annot = missing_annot env; optional = false } 164 | ) 165 | | expr -> (loc, Pattern.Expression (loc, expr)) 166 | 167 | (* Parse object destructuring pattern *) 168 | let rec object_ restricted_error = 169 | let rest_property env = 170 | let leading = Peek.comments env in 171 | let (loc, argument) = 172 | with_loc 173 | (fun env -> 174 | Expect.token env T_ELLIPSIS; 175 | pattern env restricted_error) 176 | env 177 | in 178 | Pattern.Object.RestElement 179 | ( loc, 180 | { Pattern.RestElement.argument; comments = Flow_ast_utils.mk_comments_opt ~leading () } 181 | ) 182 | in 183 | let property_default env = 184 | match Peek.token env with 185 | | T_ASSIGN -> 186 | Expect.token env T_ASSIGN; 187 | Some (Parse.assignment env) 188 | | _ -> None 189 | in 190 | let rec property env = 191 | if Peek.token env = T_ELLIPSIS then 192 | Some (rest_property env) 193 | else 194 | let start_loc = Peek.loc env in 195 | let raw_key = Parse.object_key env in 196 | match Peek.token env with 197 | | T_COLON -> 198 | Expect.token env T_COLON; 199 | let (loc, (pattern, default)) = 200 | with_loc 201 | ~start_loc 202 | (fun env -> 203 | let pattern = pattern env restricted_error in 204 | let default = property_default env in 205 | (pattern, default)) 206 | env 207 | in 208 | let key = 209 | let open Ast.Expression.Object.Property in 210 | match raw_key with 211 | | (_, StringLiteral lit) -> Pattern.Object.Property.StringLiteral lit 212 | | (_, NumberLiteral lit) -> Pattern.Object.Property.NumberLiteral lit 213 | | (_, BigIntLiteral lit) -> Pattern.Object.Property.BigIntLiteral lit 214 | | (_, Identifier id) -> Pattern.Object.Property.Identifier id 215 | | (_, PrivateName _) -> failwith "Internal Error: Found object private prop" 216 | | (_, Computed key) -> Pattern.Object.Property.Computed key 217 | in 218 | Some Pattern.Object.(Property (loc, Property.{ key; pattern; default; shorthand = false })) 219 | | _ -> 220 | (match raw_key with 221 | | ( _, 222 | Ast.Expression.Object.Property.Identifier 223 | ((id_loc, { Identifier.name = string_val; comments = _ }) as name) 224 | ) -> 225 | (* #sec-identifiers-static-semantics-early-errors *) 226 | if is_reserved string_val then 227 | (* it is a syntax error if `name` is a reserved word other than await or yield *) 228 | error_at env (id_loc, Parse_error.UnexpectedReserved) 229 | else if is_strict_reserved string_val then 230 | (* it is a syntax error if `name` is a strict reserved word, in strict mode *) 231 | strict_error_at env (id_loc, Parse_error.StrictReservedWord); 232 | let (loc, (pattern, default)) = 233 | with_loc 234 | ~start_loc 235 | (fun env -> 236 | let pattern = 237 | ( id_loc, 238 | Pattern.Identifier 239 | { Pattern.Identifier.name; annot = missing_annot env; optional = false } 240 | ) 241 | in 242 | let default = property_default env in 243 | (pattern, default)) 244 | env 245 | in 246 | Some 247 | Pattern.Object.( 248 | Property 249 | ( loc, 250 | { Property.key = Property.Identifier name; pattern; default; shorthand = true } 251 | ) 252 | ) 253 | | _ -> 254 | error_unexpected ~expected:"an identifier" env; 255 | 256 | (* invalid shorthand destructuring *) 257 | None) 258 | (* seen_rest is true when we've seen a rest element. rest_trailing_comma is the location of 259 | * the rest element's trailing command 260 | * Trailing comma: `let { ...rest, } = obj` 261 | * Still invalid, but not a trailing comma: `let { ...rest, x } = obj` *) 262 | and properties env ~seen_rest ~rest_trailing_comma acc = 263 | match Peek.token env with 264 | | T_EOF 265 | | T_RCURLY -> 266 | begin 267 | match rest_trailing_comma with 268 | | Some loc -> error_at env (loc, Parse_error.TrailingCommaAfterRestElement) 269 | | None -> () 270 | end; 271 | List.rev acc 272 | | _ -> 273 | (match property env with 274 | | Some ((Pattern.Object.Property (loc, _) | Pattern.Object.RestElement (loc, _)) as prop) -> 275 | let rest_trailing_comma = 276 | if seen_rest then ( 277 | error_at env (loc, Parse_error.PropertyAfterRestElement); 278 | None 279 | ) else 280 | rest_trailing_comma 281 | in 282 | let (seen_rest, rest_trailing_comma) = 283 | match prop with 284 | | Pattern.Object.RestElement _ -> 285 | ( true, 286 | if Peek.token env = T_COMMA then 287 | Some (Peek.loc env) 288 | else 289 | None 290 | ) 291 | | _ -> (seen_rest, rest_trailing_comma) 292 | in 293 | if Peek.token env <> T_RCURLY then Expect.token env T_COMMA; 294 | properties env ~seen_rest ~rest_trailing_comma (prop :: acc) 295 | | None -> properties env ~seen_rest ~rest_trailing_comma acc) 296 | in 297 | with_loc (fun env -> 298 | let leading = Peek.comments env in 299 | Expect.token env T_LCURLY; 300 | let properties = properties env ~seen_rest:false ~rest_trailing_comma:None [] in 301 | let internal = Peek.comments env in 302 | Expect.token env T_RCURLY; 303 | let trailing = Eat.trailing_comments env in 304 | let annot = 305 | if Peek.token env = T_COLON then 306 | Ast.Type.Available (Type.annotation env) 307 | else 308 | missing_annot env 309 | in 310 | Pattern.Object 311 | { 312 | Pattern.Object.properties; 313 | annot; 314 | comments = Flow_ast_utils.mk_comments_with_internal_opt ~leading ~trailing ~internal (); 315 | } 316 | ) 317 | 318 | (* Parse array destructuring pattern *) 319 | and array_ restricted_error = 320 | let rec elements env acc = 321 | match Peek.token env with 322 | | T_EOF 323 | | T_RBRACKET -> 324 | List.rev acc 325 | | T_COMMA -> 326 | let loc = Peek.loc env in 327 | Expect.token env T_COMMA; 328 | elements env (Pattern.Array.Hole loc :: acc) 329 | | T_ELLIPSIS -> 330 | let leading = Peek.comments env in 331 | let (loc, argument) = 332 | with_loc 333 | (fun env -> 334 | Expect.token env T_ELLIPSIS; 335 | pattern env restricted_error) 336 | env 337 | in 338 | let element = 339 | Pattern.Array.RestElement 340 | ( loc, 341 | { 342 | Pattern.RestElement.argument; 343 | comments = Flow_ast_utils.mk_comments_opt ~leading (); 344 | } 345 | ) 346 | in 347 | (* rest elements are always last, the closing ] should be next. but if not, 348 | error and keep going so we recover gracefully by parsing the rest of the 349 | elements. *) 350 | if Peek.token env <> T_RBRACKET then ( 351 | error_at env (loc, Parse_error.ElementAfterRestElement); 352 | if Peek.token env = T_COMMA then Eat.token env 353 | ); 354 | elements env (element :: acc) 355 | | _ -> 356 | let (loc, (pattern, default)) = 357 | with_loc 358 | (fun env -> 359 | let pattern = pattern env restricted_error in 360 | let default = 361 | match Peek.token env with 362 | | T_ASSIGN -> 363 | Expect.token env T_ASSIGN; 364 | Some (Parse.assignment env) 365 | | _ -> None 366 | in 367 | (pattern, default)) 368 | env 369 | in 370 | let element = Pattern.Array.(Element (loc, { Element.argument = pattern; default })) in 371 | if Peek.token env <> T_RBRACKET then Expect.token env T_COMMA; 372 | elements env (element :: acc) 373 | in 374 | with_loc (fun env -> 375 | let leading = Peek.comments env in 376 | Expect.token env T_LBRACKET; 377 | let elements = elements env [] in 378 | let internal = Peek.comments env in 379 | Expect.token env T_RBRACKET; 380 | let annot = 381 | if Peek.token env = T_COLON then 382 | Ast.Type.Available (Type.annotation env) 383 | else 384 | missing_annot env 385 | in 386 | let trailing = Eat.trailing_comments env in 387 | let comments = 388 | Flow_ast_utils.mk_comments_with_internal_opt ~leading ~trailing ~internal () 389 | in 390 | Pattern.Array { Pattern.Array.elements; annot; comments } 391 | ) 392 | 393 | and pattern env restricted_error = 394 | match Peek.token env with 395 | | T_LCURLY -> object_ restricted_error env 396 | | T_LBRACKET -> array_ restricted_error env 397 | | _ -> 398 | let (loc, id) = Parse.identifier_with_type env restricted_error in 399 | (loc, Pattern.Identifier id) 400 | end 401 | -------------------------------------------------------------------------------- /vendor/parser/relativeLoc.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = 9 | | Same_line of { 10 | start: Loc.position; 11 | column_offset: int; 12 | } 13 | | Diff_line of { 14 | start: Loc.position; 15 | line_offset: int; 16 | column: int; 17 | } 18 | 19 | let of_loc ({ Loc.start = base_pos; _end = pos; _ } : Loc.t) = 20 | let line_offset = pos.Loc.line - base_pos.Loc.line in 21 | if line_offset = 0 then 22 | Same_line { start = base_pos; column_offset = pos.Loc.column - base_pos.Loc.column } 23 | else 24 | Diff_line { start = base_pos; line_offset; column = pos.Loc.column } 25 | 26 | let to_loc relative_loc source : Loc.t = 27 | match relative_loc with 28 | | Same_line { start; column_offset } -> 29 | { 30 | Loc.start; 31 | _end = { Loc.line = start.Loc.line; column = start.Loc.column + column_offset }; 32 | source; 33 | } 34 | | Diff_line { start; line_offset; column } -> 35 | { Loc.start; _end = { Loc.line = start.Loc.line + line_offset; column }; source } 36 | -------------------------------------------------------------------------------- /vendor/parser/relativeLoc.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | (* 9 | * When we store data to the shared heap, we first marshal it using OCaml's marshaller, then we 10 | * compress it. OCaml's marshaling algorithm uses a more compact representation for smaller 11 | * integers, so it is advantageous to use small integers rather than large ones when serializing to 12 | * the shared heap. 13 | * 14 | * To that end, this utility converts locations so that the end position is stored relative to the 15 | * start position, rather than storing it in absolute terms. The intuition is that the end location 16 | * will always be closer to (or as close as) the start position than to the start of the file, so 17 | * the numbers stored will be smaller and therefore have a more compact representation, on average. 18 | * 19 | * This does not change the in-memory size of the location. It does, however make it smaller to 20 | * serialize. 21 | * *) 22 | 23 | type t 24 | 25 | val of_loc : Loc.t -> t 26 | 27 | val to_loc : t -> File_key.t option -> Loc.t 28 | -------------------------------------------------------------------------------- /vendor/parser/token.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | type t = 9 | | T_NUMBER of { 10 | kind: number_type; 11 | raw: string; 12 | } 13 | | T_BIGINT of { 14 | kind: bigint_type; 15 | raw: string; 16 | } 17 | | T_STRING of (Loc.t * string * string * bool) (* loc, value, raw, octal *) 18 | | T_TEMPLATE_PART of (Loc.t * string * string * bool * bool) (* loc, value, raw, head, tail *) 19 | | T_IDENTIFIER of { 20 | loc: Loc.t; 21 | value: string; 22 | raw: string; 23 | } 24 | | T_REGEXP of Loc.t * string * string (* /pattern/flags *) 25 | (* Syntax *) 26 | | T_LCURLY 27 | | T_RCURLY 28 | | T_LCURLYBAR 29 | | T_RCURLYBAR 30 | | T_LPAREN 31 | | T_RPAREN 32 | | T_LBRACKET 33 | | T_RBRACKET 34 | | T_SEMICOLON 35 | | T_COMMA 36 | | T_PERIOD 37 | | T_ARROW 38 | | T_ELLIPSIS 39 | | T_AT 40 | | T_POUND 41 | (* Keywords *) 42 | | T_FUNCTION 43 | | T_IF 44 | | T_IN 45 | | T_INSTANCEOF 46 | | T_RETURN 47 | | T_SWITCH 48 | | T_THIS 49 | | T_THROW 50 | | T_TRY 51 | | T_VAR 52 | | T_WHILE 53 | | T_WITH 54 | | T_CONST 55 | | T_LET 56 | | T_NULL 57 | | T_FALSE 58 | | T_TRUE 59 | | T_BREAK 60 | | T_CASE 61 | | T_CATCH 62 | | T_CONTINUE 63 | | T_DEFAULT 64 | | T_DO 65 | | T_FINALLY 66 | | T_FOR 67 | | T_CLASS 68 | | T_EXTENDS 69 | | T_STATIC 70 | | T_ELSE 71 | | T_NEW 72 | | T_DELETE 73 | | T_TYPEOF 74 | | T_VOID 75 | | T_ENUM 76 | | T_EXPORT 77 | | T_IMPORT 78 | | T_SUPER 79 | | T_IMPLEMENTS 80 | | T_INTERFACE 81 | | T_PACKAGE 82 | | T_PRIVATE 83 | | T_PROTECTED 84 | | T_PUBLIC 85 | | T_YIELD 86 | | T_DEBUGGER 87 | | T_DECLARE 88 | | T_TYPE 89 | | T_OPAQUE 90 | | T_OF 91 | | T_ASYNC 92 | | T_AWAIT 93 | | T_CHECKS 94 | (* Operators *) 95 | | T_RSHIFT3_ASSIGN 96 | | T_RSHIFT_ASSIGN 97 | | T_LSHIFT_ASSIGN 98 | | T_BIT_XOR_ASSIGN 99 | | T_BIT_OR_ASSIGN 100 | | T_BIT_AND_ASSIGN 101 | | T_MOD_ASSIGN 102 | | T_DIV_ASSIGN 103 | | T_MULT_ASSIGN 104 | | T_EXP_ASSIGN 105 | | T_MINUS_ASSIGN 106 | | T_PLUS_ASSIGN 107 | | T_NULLISH_ASSIGN 108 | | T_AND_ASSIGN 109 | | T_OR_ASSIGN 110 | | T_ASSIGN 111 | | T_PLING_PERIOD 112 | | T_PLING_PLING 113 | | T_PLING 114 | | T_COLON 115 | | T_OR 116 | | T_AND 117 | | T_BIT_OR 118 | | T_BIT_XOR 119 | | T_BIT_AND 120 | | T_EQUAL 121 | | T_NOT_EQUAL 122 | | T_STRICT_EQUAL 123 | | T_STRICT_NOT_EQUAL 124 | | T_LESS_THAN_EQUAL 125 | | T_GREATER_THAN_EQUAL 126 | | T_LESS_THAN 127 | | T_GREATER_THAN 128 | | T_LSHIFT 129 | | T_RSHIFT 130 | | T_RSHIFT3 131 | | T_PLUS 132 | | T_MINUS 133 | | T_DIV 134 | | T_MULT 135 | | T_EXP 136 | | T_MOD 137 | | T_NOT 138 | | T_BIT_NOT 139 | | T_INCR 140 | | T_DECR 141 | (* Extra tokens *) 142 | | T_INTERPRETER of Loc.t * string 143 | | T_ERROR of string 144 | | T_EOF 145 | (* JSX *) 146 | | T_JSX_IDENTIFIER of { 147 | raw: string; 148 | loc: Loc.t; 149 | } 150 | | T_JSX_CHILD_TEXT of Loc.t * string * string (* loc, value, raw *) 151 | | T_JSX_QUOTE_TEXT of Loc.t * string * string (* loc, value, raw *) 152 | (* Type primitives *) 153 | | T_ANY_TYPE 154 | | T_MIXED_TYPE 155 | | T_EMPTY_TYPE 156 | | T_BOOLEAN_TYPE of bool_or_boolean 157 | | T_NUMBER_TYPE 158 | | T_BIGINT_TYPE 159 | | T_NUMBER_SINGLETON_TYPE of { 160 | kind: number_type; 161 | value: float; 162 | raw: string; 163 | } 164 | | T_BIGINT_SINGLETON_TYPE of { 165 | kind: bigint_type; 166 | value: int64 option; 167 | raw: string; 168 | } 169 | | T_STRING_TYPE 170 | | T_VOID_TYPE 171 | | T_SYMBOL_TYPE 172 | | T_UNKNOWN_TYPE 173 | | T_NEVER_TYPE 174 | | T_UNDEFINED_TYPE 175 | | T_KEYOF 176 | | T_READONLY 177 | | T_INFER 178 | | T_IS 179 | | T_ASSERTS 180 | 181 | (* `bool` and `boolean` are equivalent annotations, but we need to track 182 | which one was used for when it might be an identifier, as in 183 | `(bool: boolean) => void`. It's lexed as two T_BOOLEAN_TYPEs, then the 184 | first one is converted into an identifier. *) 185 | and bool_or_boolean = 186 | | BOOL 187 | | BOOLEAN 188 | 189 | and number_type = 190 | | BINARY 191 | | LEGACY_OCTAL 192 | | LEGACY_NON_OCTAL (* NonOctalDecimalIntegerLiteral in Annex B *) 193 | | OCTAL 194 | | NORMAL 195 | 196 | and bigint_type = 197 | | BIG_BINARY 198 | | BIG_OCTAL 199 | | BIG_NORMAL 200 | [@@deriving eq] 201 | 202 | (*****************************************************************************) 203 | (* Pretty printer (pretty?) *) 204 | (*****************************************************************************) 205 | let token_to_string = function 206 | | T_NUMBER _ -> "T_NUMBER" 207 | | T_BIGINT _ -> "T_BIGINT" 208 | | T_STRING _ -> "T_STRING" 209 | | T_TEMPLATE_PART _ -> "T_TEMPLATE_PART" 210 | | T_IDENTIFIER _ -> "T_IDENTIFIER" 211 | | T_REGEXP _ -> "T_REGEXP" 212 | | T_FUNCTION -> "T_FUNCTION" 213 | | T_IF -> "T_IF" 214 | | T_IN -> "T_IN" 215 | | T_INSTANCEOF -> "T_INSTANCEOF" 216 | | T_RETURN -> "T_RETURN" 217 | | T_SWITCH -> "T_SWITCH" 218 | | T_THIS -> "T_THIS" 219 | | T_THROW -> "T_THROW" 220 | | T_TRY -> "T_TRY" 221 | | T_VAR -> "T_VAR" 222 | | T_WHILE -> "T_WHILE" 223 | | T_WITH -> "T_WITH" 224 | | T_CONST -> "T_CONST" 225 | | T_LET -> "T_LET" 226 | | T_NULL -> "T_NULL" 227 | | T_FALSE -> "T_FALSE" 228 | | T_TRUE -> "T_TRUE" 229 | | T_BREAK -> "T_BREAK" 230 | | T_CASE -> "T_CASE" 231 | | T_CATCH -> "T_CATCH" 232 | | T_CONTINUE -> "T_CONTINUE" 233 | | T_DEFAULT -> "T_DEFAULT" 234 | | T_DO -> "T_DO" 235 | | T_FINALLY -> "T_FINALLY" 236 | | T_FOR -> "T_FOR" 237 | | T_CLASS -> "T_CLASS" 238 | | T_EXTENDS -> "T_EXTENDS" 239 | | T_STATIC -> "T_STATIC" 240 | | T_ELSE -> "T_ELSE" 241 | | T_NEW -> "T_NEW" 242 | | T_DELETE -> "T_DELETE" 243 | | T_TYPEOF -> "T_TYPEOF" 244 | | T_VOID -> "T_VOID" 245 | | T_ENUM -> "T_ENUM" 246 | | T_EXPORT -> "T_EXPORT" 247 | | T_IMPORT -> "T_IMPORT" 248 | | T_SUPER -> "T_SUPER" 249 | | T_IMPLEMENTS -> "T_IMPLEMENTS" 250 | | T_INTERFACE -> "T_INTERFACE" 251 | | T_PACKAGE -> "T_PACKAGE" 252 | | T_PRIVATE -> "T_PRIVATE" 253 | | T_PROTECTED -> "T_PROTECTED" 254 | | T_PUBLIC -> "T_PUBLIC" 255 | | T_YIELD -> "T_YIELD" 256 | | T_DEBUGGER -> "T_DEBUGGER" 257 | | T_DECLARE -> "T_DECLARE" 258 | | T_TYPE -> "T_TYPE" 259 | | T_OPAQUE -> "T_OPAQUE" 260 | | T_OF -> "T_OF" 261 | | T_ASYNC -> "T_ASYNC" 262 | | T_AWAIT -> "T_AWAIT" 263 | | T_CHECKS -> "T_CHECKS" 264 | | T_LCURLY -> "T_LCURLY" 265 | | T_RCURLY -> "T_RCURLY" 266 | | T_LCURLYBAR -> "T_LCURLYBAR" 267 | | T_RCURLYBAR -> "T_RCURLYBAR" 268 | | T_LPAREN -> "T_LPAREN" 269 | | T_RPAREN -> "T_RPAREN" 270 | | T_LBRACKET -> "T_LBRACKET" 271 | | T_RBRACKET -> "T_RBRACKET" 272 | | T_SEMICOLON -> "T_SEMICOLON" 273 | | T_COMMA -> "T_COMMA" 274 | | T_PERIOD -> "T_PERIOD" 275 | | T_ARROW -> "T_ARROW" 276 | | T_ELLIPSIS -> "T_ELLIPSIS" 277 | | T_AT -> "T_AT" 278 | | T_POUND -> "T_POUND" 279 | | T_RSHIFT3_ASSIGN -> "T_RSHIFT3_ASSIGN" 280 | | T_RSHIFT_ASSIGN -> "T_RSHIFT_ASSIGN" 281 | | T_LSHIFT_ASSIGN -> "T_LSHIFT_ASSIGN" 282 | | T_BIT_XOR_ASSIGN -> "T_BIT_XOR_ASSIGN" 283 | | T_BIT_OR_ASSIGN -> "T_BIT_OR_ASSIGN" 284 | | T_BIT_AND_ASSIGN -> "T_BIT_AND_ASSIGN" 285 | | T_MOD_ASSIGN -> "T_MOD_ASSIGN" 286 | | T_DIV_ASSIGN -> "T_DIV_ASSIGN" 287 | | T_MULT_ASSIGN -> "T_MULT_ASSIGN" 288 | | T_EXP_ASSIGN -> "T_EXP_ASSIGN" 289 | | T_MINUS_ASSIGN -> "T_MINUS_ASSIGN" 290 | | T_PLUS_ASSIGN -> "T_PLUS_ASSIGN" 291 | | T_NULLISH_ASSIGN -> "T_NULLISH_ASSIGN" 292 | | T_AND_ASSIGN -> "T_AND_ASSIGN" 293 | | T_OR_ASSIGN -> "T_OR_ASSIGN" 294 | | T_ASSIGN -> "T_ASSIGN" 295 | | T_PLING_PERIOD -> "T_PLING_PERIOD" 296 | | T_PLING_PLING -> "T_PLING_PLING" 297 | | T_PLING -> "T_PLING" 298 | | T_COLON -> "T_COLON" 299 | | T_OR -> "T_OR" 300 | | T_AND -> "T_AND" 301 | | T_BIT_OR -> "T_BIT_OR" 302 | | T_BIT_XOR -> "T_BIT_XOR" 303 | | T_BIT_AND -> "T_BIT_AND" 304 | | T_EQUAL -> "T_EQUAL" 305 | | T_NOT_EQUAL -> "T_NOT_EQUAL" 306 | | T_STRICT_EQUAL -> "T_STRICT_EQUAL" 307 | | T_STRICT_NOT_EQUAL -> "T_STRICT_NOT_EQUAL" 308 | | T_LESS_THAN_EQUAL -> "T_LESS_THAN_EQUAL" 309 | | T_GREATER_THAN_EQUAL -> "T_GREATER_THAN_EQUAL" 310 | | T_LESS_THAN -> "T_LESS_THAN" 311 | | T_GREATER_THAN -> "T_GREATER_THAN" 312 | | T_LSHIFT -> "T_LSHIFT" 313 | | T_RSHIFT -> "T_RSHIFT" 314 | | T_RSHIFT3 -> "T_RSHIFT3" 315 | | T_PLUS -> "T_PLUS" 316 | | T_MINUS -> "T_MINUS" 317 | | T_DIV -> "T_DIV" 318 | | T_MULT -> "T_MULT" 319 | | T_EXP -> "T_EXP" 320 | | T_MOD -> "T_MOD" 321 | | T_NOT -> "T_NOT" 322 | | T_BIT_NOT -> "T_BIT_NOT" 323 | | T_INCR -> "T_INCR" 324 | | T_DECR -> "T_DECR" 325 | | T_KEYOF -> "T_KEYOF" 326 | | T_READONLY -> "T_READONLY" 327 | | T_INFER -> "T_INFER" 328 | | T_IS -> "T_IS" 329 | | T_ASSERTS -> "T_ASSERTS" 330 | (* Extra tokens *) 331 | | T_INTERPRETER _ -> "T_INTERPRETER" 332 | | T_ERROR _ -> "T_ERROR" 333 | | T_EOF -> "T_EOF" 334 | | T_JSX_IDENTIFIER _ -> "T_JSX_IDENTIFIER" 335 | | T_JSX_CHILD_TEXT _ -> "T_JSX_TEXT" 336 | | T_JSX_QUOTE_TEXT _ -> "T_JSX_TEXT" 337 | (* Type primitives *) 338 | | T_ANY_TYPE -> "T_ANY_TYPE" 339 | | T_MIXED_TYPE -> "T_MIXED_TYPE" 340 | | T_EMPTY_TYPE -> "T_EMPTY_TYPE" 341 | | T_BOOLEAN_TYPE _ -> "T_BOOLEAN_TYPE" 342 | | T_NUMBER_TYPE -> "T_NUMBER_TYPE" 343 | | T_BIGINT_TYPE -> "T_BIGINT_TYPE" 344 | | T_NUMBER_SINGLETON_TYPE _ -> "T_NUMBER_SINGLETON_TYPE" 345 | | T_BIGINT_SINGLETON_TYPE _ -> "T_BIGINT_SINGLETON_TYPE" 346 | | T_STRING_TYPE -> "T_STRING_TYPE" 347 | | T_VOID_TYPE -> "T_VOID_TYPE" 348 | | T_SYMBOL_TYPE -> "T_SYMBOL_TYPE" 349 | | T_UNKNOWN_TYPE -> "T_UNKNOWN_TYPE" 350 | | T_NEVER_TYPE -> "T_NEVER_TYPE" 351 | | T_UNDEFINED_TYPE -> "T_UNDEFINED_TYPE" 352 | 353 | let value_of_token = function 354 | | T_NUMBER { raw; _ } -> raw 355 | | T_BIGINT { raw; _ } -> raw 356 | | T_STRING (_, _, raw, _) -> raw 357 | | T_TEMPLATE_PART (_, _, raw, is_head, is_tail) -> 358 | if is_head && is_tail then 359 | "`" ^ raw ^ "`" 360 | else if is_head then 361 | "`" ^ raw ^ "${" 362 | else if is_tail then 363 | "}" ^ raw ^ "`" 364 | else 365 | "${" ^ raw ^ "}" 366 | | T_IDENTIFIER { raw; _ } -> raw 367 | | T_REGEXP (_, pattern, flags) -> "/" ^ pattern ^ "/" ^ flags 368 | | T_LCURLY -> "{" 369 | | T_RCURLY -> "}" 370 | | T_LCURLYBAR -> "{|" 371 | | T_RCURLYBAR -> "|}" 372 | | T_LPAREN -> "(" 373 | | T_RPAREN -> ")" 374 | | T_LBRACKET -> "[" 375 | | T_RBRACKET -> "]" 376 | | T_SEMICOLON -> ";" 377 | | T_COMMA -> "," 378 | | T_PERIOD -> "." 379 | | T_ARROW -> "=>" 380 | | T_ELLIPSIS -> "..." 381 | | T_AT -> "@" 382 | | T_POUND -> "#" 383 | | T_FUNCTION -> "function" 384 | | T_IF -> "if" 385 | | T_IN -> "in" 386 | | T_INSTANCEOF -> "instanceof" 387 | | T_RETURN -> "return" 388 | | T_SWITCH -> "switch" 389 | | T_THIS -> "this" 390 | | T_THROW -> "throw" 391 | | T_TRY -> "try" 392 | | T_VAR -> "var" 393 | | T_WHILE -> "while" 394 | | T_WITH -> "with" 395 | | T_CONST -> "const" 396 | | T_LET -> "let" 397 | | T_NULL -> "null" 398 | | T_FALSE -> "false" 399 | | T_TRUE -> "true" 400 | | T_BREAK -> "break" 401 | | T_CASE -> "case" 402 | | T_CATCH -> "catch" 403 | | T_CONTINUE -> "continue" 404 | | T_DEFAULT -> "default" 405 | | T_DO -> "do" 406 | | T_FINALLY -> "finally" 407 | | T_FOR -> "for" 408 | | T_CLASS -> "class" 409 | | T_EXTENDS -> "extends" 410 | | T_STATIC -> "static" 411 | | T_ELSE -> "else" 412 | | T_NEW -> "new" 413 | | T_DELETE -> "delete" 414 | | T_TYPEOF -> "typeof" 415 | | T_VOID -> "void" 416 | | T_ENUM -> "enum" 417 | | T_EXPORT -> "export" 418 | | T_IMPORT -> "import" 419 | | T_SUPER -> "super" 420 | | T_IMPLEMENTS -> "implements" 421 | | T_INTERFACE -> "interface" 422 | | T_PACKAGE -> "package" 423 | | T_PRIVATE -> "private" 424 | | T_PROTECTED -> "protected" 425 | | T_PUBLIC -> "public" 426 | | T_YIELD -> "yield" 427 | | T_DEBUGGER -> "debugger" 428 | | T_DECLARE -> "declare" 429 | | T_TYPE -> "type" 430 | | T_OPAQUE -> "opaque" 431 | | T_OF -> "of" 432 | | T_ASYNC -> "async" 433 | | T_AWAIT -> "await" 434 | | T_CHECKS -> "%checks" 435 | | T_RSHIFT3_ASSIGN -> ">>>=" 436 | | T_RSHIFT_ASSIGN -> ">>=" 437 | | T_LSHIFT_ASSIGN -> "<<=" 438 | | T_BIT_XOR_ASSIGN -> "^=" 439 | | T_BIT_OR_ASSIGN -> "|=" 440 | | T_BIT_AND_ASSIGN -> "&=" 441 | | T_MOD_ASSIGN -> "%=" 442 | | T_DIV_ASSIGN -> "/=" 443 | | T_MULT_ASSIGN -> "*=" 444 | | T_EXP_ASSIGN -> "**=" 445 | | T_MINUS_ASSIGN -> "-=" 446 | | T_PLUS_ASSIGN -> "+=" 447 | | T_NULLISH_ASSIGN -> "??=" 448 | | T_AND_ASSIGN -> "&&=" 449 | | T_OR_ASSIGN -> "||=" 450 | | T_ASSIGN -> "=" 451 | | T_PLING_PERIOD -> "?." 452 | | T_PLING_PLING -> "??" 453 | | T_PLING -> "?" 454 | | T_COLON -> ":" 455 | | T_OR -> "||" 456 | | T_AND -> "&&" 457 | | T_BIT_OR -> "|" 458 | | T_BIT_XOR -> "^" 459 | | T_BIT_AND -> "&" 460 | | T_EQUAL -> "==" 461 | | T_NOT_EQUAL -> "!=" 462 | | T_STRICT_EQUAL -> "===" 463 | | T_STRICT_NOT_EQUAL -> "!==" 464 | | T_LESS_THAN_EQUAL -> "<=" 465 | | T_GREATER_THAN_EQUAL -> ">=" 466 | | T_LESS_THAN -> "<" 467 | | T_GREATER_THAN -> ">" 468 | | T_LSHIFT -> "<<" 469 | | T_RSHIFT -> ">>" 470 | | T_RSHIFT3 -> ">>>" 471 | | T_PLUS -> "+" 472 | | T_MINUS -> "-" 473 | | T_DIV -> "/" 474 | | T_MULT -> "*" 475 | | T_EXP -> "**" 476 | | T_MOD -> "%" 477 | | T_NOT -> "!" 478 | | T_BIT_NOT -> "~" 479 | | T_INCR -> "++" 480 | | T_DECR -> "--" 481 | | T_KEYOF -> "keyof" 482 | | T_READONLY -> "readonly" 483 | | T_INFER -> "infer" 484 | | T_IS -> "is" 485 | | T_ASSERTS -> "asserts" 486 | (* Extra tokens *) 487 | | T_INTERPRETER (_, str) -> str 488 | | T_ERROR raw -> raw 489 | | T_EOF -> "" 490 | | T_JSX_IDENTIFIER { raw; _ } -> raw 491 | | T_JSX_CHILD_TEXT (_, _, raw) -> raw 492 | | T_JSX_QUOTE_TEXT (_, _, raw) -> raw 493 | (* Type primitives *) 494 | | T_ANY_TYPE -> "any" 495 | | T_MIXED_TYPE -> "mixed" 496 | | T_EMPTY_TYPE -> "empty" 497 | | T_BOOLEAN_TYPE kind -> begin 498 | match kind with 499 | | BOOL -> "bool" 500 | | BOOLEAN -> "boolean" 501 | end 502 | | T_NUMBER_TYPE -> "number" 503 | | T_BIGINT_TYPE -> "bigint" 504 | | T_NUMBER_SINGLETON_TYPE { raw; _ } -> raw 505 | | T_BIGINT_SINGLETON_TYPE { raw; _ } -> raw 506 | | T_STRING_TYPE -> "string" 507 | | T_VOID_TYPE -> "void" 508 | | T_SYMBOL_TYPE -> "symbol" 509 | | T_UNKNOWN_TYPE -> "unknown" 510 | | T_NEVER_TYPE -> "never" 511 | | T_UNDEFINED_TYPE -> "undefined" 512 | 513 | let quote_token_value value = Printf.sprintf "token `%s`" value 514 | 515 | let explanation_of_token ?(use_article = false) token = 516 | let (value, article) = 517 | match token with 518 | | T_NUMBER_SINGLETON_TYPE _ 519 | | T_NUMBER _ -> 520 | ("number", "a") 521 | | T_BIGINT_SINGLETON_TYPE _ 522 | | T_BIGINT _ -> 523 | ("bigint", "a") 524 | | T_JSX_CHILD_TEXT _ 525 | | T_JSX_QUOTE_TEXT _ 526 | | T_STRING _ -> 527 | ("string", "a") 528 | | T_TEMPLATE_PART _ -> ("template literal part", "a") 529 | | T_JSX_IDENTIFIER _ 530 | | T_IDENTIFIER _ -> 531 | ("identifier", "an") 532 | | T_REGEXP _ -> ("regexp", "a") 533 | | T_EOF -> ("end of input", "the") 534 | | _ -> (quote_token_value (value_of_token token), "the") 535 | in 536 | if use_article then 537 | article ^ " " ^ value 538 | else 539 | value 540 | -------------------------------------------------------------------------------- /vendor/parser/token_translator.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module Translate (Impl : Translator_intf.S) : sig 9 | type t 10 | 11 | val token : Offset_utils.t -> Parser_env.token_sink_result -> t 12 | 13 | val token_list : Offset_utils.t -> Parser_env.token_sink_result list -> t 14 | end 15 | with type t = Impl.t = struct 16 | type t = Impl.t 17 | 18 | let token offset_table { Parser_env.token_loc; token; token_context } = 19 | Loc.( 20 | Impl.obj 21 | [ 22 | ("type", Impl.string (Token.token_to_string token)); 23 | ( "context", 24 | Impl.string 25 | Parser_env.Lex_mode.( 26 | match token_context with 27 | | NORMAL -> "normal" 28 | | TYPE -> "type" 29 | | JSX_TAG -> "jsxTag" 30 | | JSX_CHILD -> "jsxChild" 31 | | TEMPLATE -> "template" 32 | | REGEXP -> "regexp" 33 | ) 34 | ); 35 | ( "loc", 36 | Impl.obj 37 | [ 38 | ( "start", 39 | Impl.obj 40 | [ 41 | ("line", Impl.number (float token_loc.start.line)); 42 | ("column", Impl.number (float token_loc.start.column)); 43 | ] 44 | ); 45 | ( "end", 46 | Impl.obj 47 | [ 48 | ("line", Impl.number (float token_loc._end.line)); 49 | ("column", Impl.number (float token_loc._end.column)); 50 | ] 51 | ); 52 | ] 53 | ); 54 | ( "range", 55 | Impl.array 56 | [ 57 | Impl.number (float (Offset_utils.offset offset_table token_loc.start)); 58 | Impl.number (float (Offset_utils.offset offset_table token_loc._end)); 59 | ] 60 | ); 61 | ("value", Impl.string (Token.value_of_token token)); 62 | ] 63 | ) 64 | 65 | let token_list offset_table tokens = 66 | Impl.array (List.rev_map (token offset_table) tokens |> List.rev) 67 | end 68 | -------------------------------------------------------------------------------- /vendor/parser/translator_intf.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | *) 7 | 8 | module type S = sig 9 | type t 10 | 11 | val string : string -> t 12 | 13 | val bool : bool -> t 14 | 15 | val obj : (string * t) list -> t 16 | 17 | val array : t list -> t 18 | 19 | val number : float -> t 20 | 21 | val int : int -> t 22 | 23 | val null : t 24 | 25 | val regexp : Loc.t -> string -> string -> t 26 | end 27 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/Changes.md: -------------------------------------------------------------------------------- 1 | The Flow_sedlexing_ppx module is forked from the Sedlexing_ppx module, with the 2 | following changes: 3 | 4 | - Delete Unicode generator 5 | - Inlined Unicode module into ppx_sedlex, and only keep the character set we need 6 | - Remove charsets not needed by Flow in sedlex_cset 7 | - Dune build rule tweaks 8 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2005, 2014 by Alain Frisch and LexiFi. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name flow_sedlexing_ppx) 3 | (kind ppx_rewriter) 4 | (libraries ppxlib flow_sedlexing) 5 | (ppx_runtime_libraries flow_sedlexing) 6 | (preprocess 7 | (pps ppxlib.metaquot)) 8 | (flags 9 | (:standard -w -9))) 10 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/flow_sedlex.ml: -------------------------------------------------------------------------------- 1 | (* The package sedlex is released under the terms of an MIT-like license. *) 2 | (* See the attached LICENSE file. *) 3 | (* Copyright 2005, 2013 by Alain Frisch and LexiFi. *) 4 | 5 | module Cset = Sedlex_cset 6 | 7 | (* NFA *) 8 | 9 | type node = { 10 | id : int; 11 | mutable eps : node list; 12 | mutable trans : (Cset.t * node) list; 13 | } 14 | 15 | (* Compilation regexp -> NFA *) 16 | 17 | type regexp = node -> node 18 | 19 | let cur_id = ref 0 20 | let new_node () = 21 | incr cur_id; 22 | { id = !cur_id; eps = []; trans = [] } 23 | 24 | let seq r1 r2 succ = r1 (r2 succ) 25 | 26 | let is_chars final = function 27 | | {eps = []; trans = [c, f]} when f == final -> Some c 28 | | _ -> None 29 | 30 | let chars c succ = 31 | let n = new_node () in 32 | n.trans <- [c,succ]; 33 | n 34 | 35 | let alt r1 r2 succ = 36 | let nr1 = r1 succ and nr2 = r2 succ in 37 | match is_chars succ nr1, is_chars succ nr2 with 38 | | Some c1, Some c2 -> chars (Cset.union c1 c2) succ 39 | | _ -> 40 | let n = new_node () in 41 | n.eps <- [nr1; nr2]; 42 | n 43 | 44 | let rep r succ = 45 | let n = new_node () in 46 | n.eps <- [r n; succ]; 47 | n 48 | 49 | let plus r succ = 50 | let n = new_node () in 51 | let nr = r n in 52 | n.eps <- [nr; succ]; 53 | nr 54 | 55 | let eps succ = succ (* eps for epsilon *) 56 | 57 | let compl r = 58 | let n = new_node () in 59 | match is_chars n (r n) with 60 | | Some c -> 61 | Some (chars (Cset.difference Cset.any c)) 62 | | _ -> 63 | None 64 | 65 | let pair_op f r0 r1 = (* Construct subtract or intersection *) 66 | let n = new_node () in 67 | let to_chars r = is_chars n (r n) in 68 | match to_chars r0, to_chars r1 with 69 | | Some c0, Some c1 -> 70 | Some (chars (f c0 c1)) 71 | | _ -> 72 | None 73 | 74 | let subtract = pair_op Cset.difference 75 | 76 | let intersection = pair_op Cset.intersection 77 | 78 | let compile_re re = 79 | let final = new_node () in 80 | (re final, final) 81 | 82 | (* Determinization *) 83 | 84 | type state = node list 85 | (* A state of the DFA corresponds to a set of nodes in the NFA. *) 86 | 87 | let rec add_node state node = 88 | if List.memq node state then state else add_nodes (node::state) node.eps 89 | and add_nodes state nodes = 90 | List.fold_left add_node state nodes 91 | 92 | 93 | let transition (state : state) = 94 | (* Merge transition with the same target *) 95 | let rec norm = function 96 | | (c1, n1)::((c2, n2)::q as l) -> 97 | if n1 == n2 then norm ((Cset.union c1 c2, n1)::q) 98 | else (c1, n1)::(norm l) 99 | | l -> l in 100 | let t = List.concat (List.map (fun n -> n.trans) state) in 101 | let t = norm (List.sort (fun (_, n1) (_, n2) -> n1.id - n2.id) t) in 102 | 103 | (* Split char sets so as to make them disjoint *) 104 | let split (all, t) (c0, n0) = 105 | let t = 106 | (Cset.difference c0 all, [n0]) :: 107 | List.map (fun (c, ns) -> (Cset.intersection c c0, n0::ns)) t @ 108 | List.map (fun (c, ns) -> (Cset.difference c c0, ns)) t 109 | in 110 | Cset.union all c0, 111 | List.filter (fun (c, _) -> not (Cset.is_empty c)) t 112 | in 113 | 114 | let (_,t) = List.fold_left split (Cset.empty,[]) t in 115 | 116 | (* Epsilon closure of targets *) 117 | let t = List.map (fun (c, ns) -> (c, add_nodes [] ns)) t in 118 | 119 | (* Canonical ordering *) 120 | let t = Array.of_list t in 121 | Array.sort (fun (c1, _) (c2, _) -> compare c1 c2) t; 122 | t 123 | 124 | let compile rs = 125 | let rs = Array.map compile_re rs in 126 | let counter = ref 0 in 127 | let states = Hashtbl.create 31 in 128 | let states_def = Hashtbl.create 31 in 129 | let rec aux state = 130 | try Hashtbl.find states state 131 | with Not_found -> 132 | let i = !counter in 133 | incr counter; 134 | Hashtbl.add states state i; 135 | let trans = transition state in 136 | let trans = Array.map (fun (p, t) -> (p, aux t)) trans in 137 | let finals = Array.map (fun (_, f) -> List.memq f state) rs in 138 | Hashtbl.add states_def i (trans, finals); 139 | i 140 | in 141 | let init = ref [] in 142 | Array.iter (fun (i,_) -> init := add_node !init i) rs; 143 | let i = aux !init in 144 | assert(i = 0); 145 | Array.init !counter (Hashtbl.find states_def) 146 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/flow_sedlex.mli: -------------------------------------------------------------------------------- 1 | (* The package sedlex is released under the terms of an MIT-like license. *) 2 | (* See the attached LICENSE file. *) 3 | (* Copyright 2005, 2013 by Alain Frisch and LexiFi. *) 4 | 5 | type regexp 6 | 7 | val chars: Sedlex_cset.t -> regexp 8 | val seq: regexp -> regexp -> regexp 9 | val alt: regexp -> regexp -> regexp 10 | val rep: regexp -> regexp 11 | val plus: regexp -> regexp 12 | val eps: regexp 13 | 14 | val compl: regexp -> regexp option 15 | (* If the argument is a single [chars] regexp, returns a regexp 16 | which matches the complement set. Otherwise returns [None]. *) 17 | val subtract: regexp -> regexp -> regexp option 18 | (* If each argument is a single [chars] regexp, returns a regexp 19 | which matches the set (arg1 - arg2). Otherwise returns [None]. *) 20 | val intersection: regexp -> regexp -> regexp option 21 | (* If each argument is a single [chars] regexp, returns a regexp 22 | which matches the intersection set. Otherwise returns [None]. *) 23 | 24 | val compile: regexp array -> ((Sedlex_cset.t * int) array * bool array) array 25 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/sedlex_cset.ml: -------------------------------------------------------------------------------- 1 | (* The package sedlex is released under the terms of an MIT-like license. *) 2 | (* See the attached LICENSE file. *) 3 | (* Copyright 2005, 2013 by Alain Frisch and LexiFi. *) 4 | 5 | (* Character sets are represented as lists of intervals. The 6 | intervals must be non-overlapping and not collapsable, and the list 7 | must be ordered in increasing order. *) 8 | 9 | type t = (int * int) list 10 | 11 | let max_code = 0x10ffff (* must be < max_int *) 12 | let min_code = -1 13 | 14 | let empty = [] 15 | let singleton i = [i,i] 16 | let is_empty = function [] -> true | _ -> false 17 | let interval i j = if i <= j then [i,j] else [j,i] 18 | let eof = singleton (-1) 19 | let any = interval 0 max_code 20 | 21 | let rec union c1 c2 = 22 | match c1,c2 with 23 | | [], _ -> c2 24 | | _, [] -> c1 25 | | ((i1, j1) as s1)::r1, (i2, j2)::r2 -> 26 | if (i1 <= i2) then 27 | if j1 + 1 < i2 then s1::(union r1 c2) 28 | else if (j1 < j2) then union r1 ((i1, j2)::r2) 29 | else union c1 r2 30 | else union c2 c1 31 | 32 | let complement c = 33 | let rec aux start = function 34 | | [] -> if start <= max_code then [start,max_code] else [] 35 | | (i, j)::l -> (start, i-1)::(aux (succ j) l) 36 | in 37 | match c with 38 | | (-1,j)::l -> aux (succ j) l 39 | | l -> aux (-1) l 40 | 41 | let intersection c1 c2 = 42 | complement (union (complement c1) (complement c2)) 43 | 44 | let difference c1 c2 = 45 | complement (union (complement c1) c2) 46 | -------------------------------------------------------------------------------- /vendor/sedlex-ppx/sedlex_cset.mli: -------------------------------------------------------------------------------- 1 | (* The package sedlex is released under the terms of an MIT-like license. *) 2 | (* See the attached LICENSE file. *) 3 | (* Copyright 2005, 2013 by Alain Frisch and LexiFi. *) 4 | 5 | (** Representation of sets of unicode code points. *) 6 | 7 | type t = (int * int) list 8 | 9 | val min_code: int 10 | val max_code: int 11 | 12 | val empty: t 13 | val any: t 14 | val union: t -> t -> t 15 | val difference: t -> t -> t 16 | val intersection: t -> t -> t 17 | val is_empty: t -> bool 18 | val eof: t 19 | val singleton: int -> t 20 | val interval: int -> int -> t 21 | -------------------------------------------------------------------------------- /vendor/sedlex/Changes.md: -------------------------------------------------------------------------------- 1 | The Flow_sedlexing module is forked from the Sedlexing module, with the 2 | following changes: 3 | 4 | - Removed encodings we don't need, e.g, Utf16, Latin1 5 | - Removed bookkeeping fields which do not matter when everything is done in memory: 6 | - filename 7 | - finished 8 | - refilled (refill not needed either) 9 | - Changed Uchar.t array to int array 10 | - Added lexbuf_clone for internal usage 11 | - Added 12 | - Utf8.lexeme_to_buffer 13 | - Utf8.lexeme_to_buffer2 14 | - Rewrote utf8 encoding/decoding for performance 15 | -------------------------------------------------------------------------------- /vendor/sedlex/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2005, 2014 by Alain Frisch and LexiFi. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /vendor/sedlex/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name flow_sedlexing) 3 | (wrapped false)) 4 | -------------------------------------------------------------------------------- /vendor/sedlex/flow_sedlexing.ml: -------------------------------------------------------------------------------- 1 | (* The package sedlex is released under the terms of an MIT-like license. *) 2 | (* See the attached LICENSE file. *) 3 | (* Copyright 2005, 2013 by Alain Frisch and LexiFi. *) 4 | external ( .!()<- ) : int array -> int -> int -> unit = "%array_unsafe_set" 5 | external ( .!() ) : int array -> int -> int = "%array_unsafe_get" 6 | external ( .![] ) : string -> int -> char = "%string_unsafe_get" 7 | external ( .![]<- ) : bytes -> int -> char -> unit = "%bytes_unsafe_set" 8 | 9 | exception InvalidCodepoint of int 10 | 11 | exception MalFormed 12 | 13 | (* Absolute position from the beginning of the stream *) 14 | type apos = int 15 | 16 | (* critical states: 17 | [pos] [curr_bol] [curr_line] 18 | The state of [curr_bol] and [curr_line] only changes when we hit a newline 19 | [marked_pos] [marked_bol] [marked_line] 20 | [start_pos] [start_bol] [start_line] 21 | get reset whenever we get a new token 22 | *) 23 | type lexbuf = { 24 | buf: int array; 25 | (* Number of meaningful char in buffer *) 26 | len: int; 27 | (* pos is the index in the buffer *) 28 | mutable pos: int; 29 | (* bol is the index in the input stream but not buffer *) 30 | mutable curr_bol: int; 31 | (* start from 1, if it is 0, we would not track postion info for you *) 32 | mutable curr_line: int; 33 | (* First char we need to keep visible *) 34 | mutable start_pos: int; 35 | mutable start_bol: int; 36 | mutable start_line: int; 37 | mutable marked_pos: int; 38 | mutable marked_bol: int; 39 | mutable marked_line: int; 40 | mutable marked_val: int; 41 | } 42 | 43 | 44 | let lexbuf_clone (x : lexbuf) : lexbuf = 45 | { 46 | buf = x.buf; 47 | len = x.len; 48 | pos = x.pos; 49 | curr_bol = x.curr_bol; 50 | curr_line = x.curr_line; 51 | start_pos = x.start_pos; 52 | start_bol = x.start_bol; 53 | start_line = x.start_line; 54 | marked_pos = x.marked_pos; 55 | marked_bol = x.marked_bol; 56 | marked_line = x.marked_line; 57 | marked_val = x.marked_val; 58 | } 59 | 60 | let empty_lexbuf = 61 | { 62 | buf = [||]; 63 | len = 0; 64 | pos = 0; 65 | curr_bol = 0; 66 | curr_line = 0; 67 | start_pos = 0; 68 | start_bol = 0; 69 | start_line = 0; 70 | marked_pos = 0; 71 | marked_bol = 0; 72 | marked_line = 0; 73 | marked_val = 0; 74 | } 75 | 76 | let from_int_array a = 77 | let len = Array.length a in 78 | { empty_lexbuf with buf = a; len } 79 | 80 | let from_int_sub_array a len = 81 | { empty_lexbuf with buf = a; len } 82 | 83 | let new_line lexbuf = 84 | if lexbuf.curr_line != 0 then lexbuf.curr_line <- lexbuf.curr_line + 1; 85 | lexbuf.curr_bol <- lexbuf.pos 86 | 87 | let next lexbuf : Stdlib.Uchar.t option = 88 | if lexbuf.pos = lexbuf.len then 89 | None 90 | else 91 | let ret = lexbuf.buf.!(lexbuf.pos) in 92 | lexbuf.pos <- lexbuf.pos + 1; 93 | if ret = 10 then new_line lexbuf; 94 | Some (Stdlib.Uchar.unsafe_of_int ret) 95 | 96 | let __private__next_int lexbuf : int = 97 | if lexbuf.pos = lexbuf.len then 98 | -1 99 | else 100 | let ret = lexbuf.buf.!(lexbuf.pos) in 101 | lexbuf.pos <- lexbuf.pos + 1; 102 | if ret = 10 then new_line lexbuf; 103 | ret 104 | 105 | let mark lexbuf i = 106 | lexbuf.marked_pos <- lexbuf.pos; 107 | lexbuf.marked_bol <- lexbuf.curr_bol; 108 | lexbuf.marked_line <- lexbuf.curr_line; 109 | lexbuf.marked_val <- i 110 | 111 | let start lexbuf = 112 | lexbuf.start_pos <- lexbuf.pos; 113 | lexbuf.start_bol <- lexbuf.curr_bol; 114 | lexbuf.start_line <- lexbuf.curr_line; 115 | mark lexbuf (-1) 116 | 117 | let backtrack lexbuf = 118 | lexbuf.pos <- lexbuf.marked_pos; 119 | lexbuf.curr_bol <- lexbuf.marked_bol; 120 | lexbuf.curr_line <- lexbuf.marked_line; 121 | lexbuf.marked_val 122 | 123 | let rollback lexbuf = 124 | lexbuf.pos <- lexbuf.start_pos; 125 | lexbuf.curr_bol <- lexbuf.start_bol; 126 | lexbuf.curr_line <- lexbuf.start_line 127 | 128 | let lexeme_start lexbuf = lexbuf.start_pos 129 | let set_lexeme_start lexbuf pos = lexbuf.start_pos <- pos 130 | let lexeme_end lexbuf = lexbuf.pos 131 | 132 | let loc lexbuf = (lexbuf.start_pos , lexbuf.pos ) 133 | 134 | let lexeme_length lexbuf = lexbuf.pos - lexbuf.start_pos 135 | 136 | let sub_lexeme lexbuf pos len = Array.sub lexbuf.buf (lexbuf.start_pos + pos) len 137 | 138 | let lexeme lexbuf = Array.sub lexbuf.buf lexbuf.start_pos (lexbuf.pos - lexbuf.start_pos) 139 | 140 | let current_code_point lexbuf = lexbuf.buf.(lexbuf.start_pos) 141 | (* Decode UTF-8 encoded [s] into codepoints in [a], returning the length of the 142 | * decoded string. 143 | * 144 | * To call this function safely: 145 | * - ensure that [slen] is not greater than the length of [s] 146 | * - ensure that [a] has enough capacity to hold the decoded value 147 | *) 148 | let unsafe_utf8_of_string (s : string) slen (a : int array) : int = 149 | let spos = ref 0 in 150 | let apos = ref 0 in 151 | while !spos < slen do 152 | let spos_code = s.![!spos] in 153 | (match spos_code with 154 | | '\000' .. '\127' as c -> 155 | (* U+0000 - U+007F: 0xxxxxxx *) 156 | a.!(!apos) <- Char.code c; 157 | incr spos 158 | | '\192' .. '\223' as c -> 159 | (* U+0080 - U+07FF: 110xxxxx 10xxxxxx *) 160 | let n1 = Char.code c in 161 | let n2 = Char.code s.![!spos + 1] in 162 | if n2 lsr 6 != 0b10 then raise MalFormed; 163 | a.!(!apos) <- ((n1 land 0x1f) lsl 6) lor (n2 land 0x3f); 164 | spos := !spos + 2 165 | | '\224' .. '\239' as c -> 166 | (* U+0800 - U+FFFF: 1110xxxx 10xxxxxx 10xxxxxx 167 | U+D800 - U+DFFF are reserved for surrogate halves (RFC 3629) *) 168 | let n1 = Char.code c in 169 | let n2 = Char.code s.![!spos + 1] in 170 | let n3 = Char.code s.![!spos + 2] in 171 | let p = ((n1 land 0x0f) lsl 12) lor ((n2 land 0x3f) lsl 6) lor (n3 land 0x3f) in 172 | if (n2 lsr 6 != 0b10 || n3 lsr 6 != 0b10) || (p >= 0xd800 && p <= 0xdfff) then raise MalFormed; 173 | a.!(!apos) <- p; 174 | spos := !spos + 3 175 | | '\240' .. '\247' as c -> 176 | (* U+10000 - U+1FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 177 | > U+10FFFF are invalid (RFC 3629) *) 178 | let n1 = Char.code c in 179 | let n2 = Char.code s.![!spos + 1] in 180 | let n3 = Char.code s.![!spos + 2] in 181 | let n4 = Char.code s.![!spos + 3] in 182 | if n2 lsr 6 != 0b10 || n3 lsr 6 != 0b10 || n4 lsr 6 != 0b10 then raise MalFormed; 183 | let p = 184 | ((n1 land 0x07) lsl 18) 185 | lor ((n2 land 0x3f) lsl 12) 186 | lor ((n3 land 0x3f) lsl 6) 187 | lor (n4 land 0x3f) 188 | in 189 | if p > 0x10ffff then raise MalFormed; 190 | a.!(!apos) <- p; 191 | spos := !spos + 4 192 | | _ -> raise MalFormed); 193 | incr apos 194 | done; 195 | !apos 196 | 197 | (* Encode the decoded codepoints in [a] as UTF-8 into [b], returning the length 198 | * of the encoded string. 199 | * 200 | * To call this function safely: 201 | * - ensure that [offset + len] is not greater than the length of [a] 202 | * - ensure that [b] has sufficient capacity to hold the encoded value 203 | *) 204 | let unsafe_string_of_utf8 (a : int array) ~(offset : int) ~(len : int) (b : bytes) : int = 205 | let apos = ref offset in 206 | let len = ref len in 207 | let i = ref 0 in 208 | while !len > 0 do 209 | let u = a.!(!apos) in 210 | if u < 0 then 211 | raise MalFormed 212 | else if u <= 0x007F then begin 213 | b.![!i] <- Char.unsafe_chr u; 214 | incr i 215 | end else if u <= 0x07FF then ( 216 | b.![!i] <- Char.unsafe_chr (0xC0 lor (u lsr 6)); 217 | b.![!i + 1] <- Char.unsafe_chr (0x80 lor (u land 0x3F)); 218 | i := !i + 2 219 | ) else if u <= 0xFFFF then ( 220 | b.![!i] <- Char.unsafe_chr (0xE0 lor (u lsr 12)); 221 | b.![!i + 1] <- Char.unsafe_chr (0x80 lor ((u lsr 6) land 0x3F)); 222 | b.![!i + 2] <- Char.unsafe_chr (0x80 lor (u land 0x3F)); 223 | i := !i + 3 224 | ) else if u <= 0x10FFFF then ( 225 | b.![!i] <- Char.unsafe_chr (0xF0 lor (u lsr 18)); 226 | b.![!i + 1] <- Char.unsafe_chr (0x80 lor ((u lsr 12) land 0x3F)); 227 | b.![!i + 2] <- Char.unsafe_chr (0x80 lor ((u lsr 6) land 0x3F)); 228 | b.![!i + 3] <- Char.unsafe_chr (0x80 lor (u land 0x3F)); 229 | i := !i + 4 230 | ) else 231 | raise MalFormed; 232 | incr apos; 233 | decr len 234 | done; 235 | !i 236 | 237 | module Utf8 = struct 238 | let from_string s = 239 | let slen = String.length s in 240 | let a = Array.make slen 0 in 241 | let len = unsafe_utf8_of_string s slen a in 242 | from_int_sub_array a len 243 | 244 | let sub_lexeme lexbuf pos len : string = 245 | let offset = lexbuf.start_pos + pos in 246 | let b = Bytes.create (len * 4) in 247 | let buf = lexbuf.buf in 248 | (* Assertion needed, since we make use of unsafe API below *) 249 | assert (offset + len <= Array.length buf); 250 | let i = unsafe_string_of_utf8 buf ~offset ~len b in 251 | Bytes.sub_string b 0 i 252 | 253 | let lexeme lexbuf : string = 254 | let offset = lexbuf.start_pos in 255 | let len = lexbuf.pos - offset in 256 | let b = Bytes.create (len * 4) in 257 | let buf = lexbuf.buf in 258 | let i = unsafe_string_of_utf8 buf ~offset ~len b in 259 | Bytes.sub_string b 0 i 260 | 261 | let lexeme_to_buffer lexbuf buffer : unit = 262 | let offset = lexbuf.start_pos in 263 | let len = lexbuf.pos - offset in 264 | let b = Bytes.create (len * 4) in 265 | let buf = lexbuf.buf in 266 | let i = unsafe_string_of_utf8 buf ~offset ~len b in 267 | Buffer.add_subbytes buffer b 0 i 268 | 269 | let lexeme_to_buffer2 lexbuf buf1 buf2 : unit = 270 | let offset = lexbuf.start_pos in 271 | let len = lexbuf.pos - offset in 272 | let b = Bytes.create (len * 4) in 273 | let buf = lexbuf.buf in 274 | let i = unsafe_string_of_utf8 buf ~offset ~len b in 275 | Buffer.add_subbytes buf1 b 0 i; 276 | Buffer.add_subbytes buf2 b 0 i 277 | end 278 | 279 | let string_of_utf8 (lexbuf : int array) : string = 280 | let offset = 0 in 281 | let len = Array.length lexbuf in 282 | let b = Bytes.create (len * 4) in 283 | let i = unsafe_string_of_utf8 lexbuf ~offset ~len b in 284 | Bytes.sub_string b 0 i 285 | 286 | let backoff lexbuf npos = 287 | lexbuf.pos <- lexbuf.pos - npos 288 | -------------------------------------------------------------------------------- /vendor/sedlex/flow_sedlexing.mli: -------------------------------------------------------------------------------- 1 | 2 | (** This is a module provides the minimal Sedlexing suppport 3 | It is mostly a subset of Sedlexing with two functions for performance reasons: 4 | - Utf8.lexeme_to_buffer 5 | - Utf8.lexeme_to_buffer2 6 | *) 7 | exception InvalidCodepoint of int 8 | exception MalFormed 9 | type apos = int 10 | type lexbuf 11 | val lexbuf_clone : lexbuf -> lexbuf 12 | 13 | val from_int_array : int array -> lexbuf 14 | val new_line : lexbuf -> unit 15 | val next : lexbuf -> Uchar.t option 16 | 17 | (**/**) 18 | val __private__next_int : lexbuf -> int 19 | (**/**) 20 | 21 | val mark : lexbuf -> int -> unit 22 | val start : lexbuf -> unit 23 | val backtrack : lexbuf -> int 24 | val rollback : lexbuf -> unit 25 | val lexeme_start : lexbuf -> int 26 | val lexeme_end : lexbuf -> int 27 | val loc : lexbuf -> int * int 28 | val lexeme_length : lexbuf -> int 29 | val sub_lexeme : lexbuf -> int -> int -> int array 30 | val lexeme : lexbuf -> int array 31 | module Utf8 : sig 32 | val from_string : string -> lexbuf 33 | val sub_lexeme : lexbuf -> int -> int -> string 34 | val lexeme : lexbuf -> string 35 | 36 | (** This API avoids another allocation *) 37 | val lexeme_to_buffer : lexbuf -> Buffer.t -> unit 38 | val lexeme_to_buffer2 : lexbuf -> Buffer.t -> Buffer.t -> unit 39 | end 40 | 41 | val string_of_utf8 : int array -> string 42 | 43 | (** Two APIs used when we want to do customize lexing 44 | instead of using the regex based engine 45 | *) 46 | val current_code_point : lexbuf -> int 47 | val backoff : lexbuf -> int -> unit 48 | val set_lexeme_start : lexbuf -> int -> unit 49 | --------------------------------------------------------------------------------