From 4a2f0220dc851a503c0ac1d7be6ae4b7b15a93fc Mon Sep 17 00:00:00 2001 From: Sacha Ayoun Date: Tue, 4 May 2021 19:31:03 +0200 Subject: [PATCH] Migrate to ppxlib >= 0.18.0 (#5) migrate to ppxlib >= 0.18.0 --- .github/workflows/main.yml | 29 + .gitignore | 1 + dune-project | 3 +- ppx_gen_rec.opam | 3 +- src/dune | 2 +- src/ppx_gen_rec.ml | 78 +- test/dune | 14 + test/flow_ast.ml | 1865 ++++++++++++++++++++++++++++++++++++ test/foo.ml | 18 + test/tests.expected | 2 + 10 files changed, 1981 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 test/dune create mode 100644 test/flow_ast.ml create mode 100644 test/foo.ml create mode 100644 test/tests.expected diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..3b96a5e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,29 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v2 + - uses: avsm/setup-ocaml@v1 + - run: opam install . -y --deps-only --with-test + - name: Running tests + run: opam exec dune test diff --git a/.gitignore b/.gitignore index 9012564..5cf6cbe 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ _build/ *.byte *.install *.swp +_opam diff --git a/dune-project b/dune-project index d816d52..b1d125b 100644 --- a/dune-project +++ b/dune-project @@ -1,2 +1,3 @@ -(lang dune 1.0) +(lang dune 2.0) + (name ppx_gen_rec) diff --git a/ppx_gen_rec.opam b/ppx_gen_rec.opam index dd868e4..d4a47df 100644 --- a/ppx_gen_rec.opam +++ b/ppx_gen_rec.opam @@ -7,7 +7,8 @@ bug-reports: "https://github.com/flowtype/ocaml-ppx_gen_rec/issues" depends: [ "ocaml" "dune" {build} - "ocaml-migrate-parsetree" {>= "1.1.0"} + "ppxlib" {>= "0.18.0"} + "ppx_deriving" {with-test} ] build: ["dune" "build" "-p" name "-j" jobs] dev-repo: "git+https://github.com/flowtype/ocaml-ppx_gen_rec.git" diff --git a/src/dune b/src/dune index 0e2e09e..b7b49e6 100644 --- a/src/dune +++ b/src/dune @@ -2,5 +2,5 @@ (name ppx_gen_rec) (public_name ppx_gen_rec) (kind ppx_rewriter) - (libraries compiler-libs.common ocaml-migrate-parsetree) + (libraries ppxlib) (preprocess no_preprocessing)) diff --git a/src/ppx_gen_rec.ml b/src/ppx_gen_rec.ml index 3f5687f..7303eef 100644 --- a/src/ppx_gen_rec.ml +++ b/src/ppx_gen_rec.ml @@ -4,11 +4,8 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. *) - -open Migrate_parsetree -open OCaml_405.Ast -open Parsetree -open Ast_mapper + +open Ppxlib let raise_errorf = Location.raise_errorf @@ -17,8 +14,8 @@ let rec module_expr_desc_of_type_desc = function Pmod_ident ident | Pmty_signature items -> Pmod_structure (structure_of_signature items) - | Pmty_functor (loc, a, b) -> - Pmod_functor (loc, a, module_expr_of_type b) + | Pmty_functor (a, b) -> + Pmod_functor (a, module_expr_of_type b) | Pmty_with (_module_type, _with_constraints) -> raise_errorf "ppx_gen_rec: Pmty_with not supported yet" | Pmty_typeof _module_expr -> @@ -43,9 +40,18 @@ and module_binding_of_declaration { pmd_name; pmd_type; pmd_attributes; pmd_loc; pmb_loc = pmd_loc; } +and open_declaration_of_open_description desc = + let ident_loc = desc.popen_expr in + let module_expr = { + pmod_attributes=[]; + pmod_loc=ident_loc.loc; + pmod_desc=Pmod_ident ident_loc + } in + { desc with popen_expr = module_expr } + and structure_item_desc_of_signature_item_desc = function - | Psig_value _value_description -> - raise_errorf "ppx_gen_rec: Psig_value not supported yet" + | Psig_value {pval_loc; _} -> + raise_errorf ~loc:pval_loc "ppx_gen_rec: Psig_value not supported yet" | Psig_type (rec_flag, decls) -> Pstr_type (rec_flag, decls) | Psig_typext type_extension -> @@ -59,7 +65,7 @@ and structure_item_desc_of_signature_item_desc = function | Psig_modtype module_type_declaration -> Pstr_modtype module_type_declaration | Psig_open desc -> - Pstr_open desc + Pstr_open (open_declaration_of_open_description desc) | Psig_include _include_description -> raise_errorf "ppx_gen_rec: Psig_include not supported yet" | Psig_class _class_descriptions -> @@ -70,6 +76,10 @@ and structure_item_desc_of_signature_item_desc = function Pstr_attribute attr | Psig_extension (ext, attrs) -> Pstr_extension (ext, attrs) + | Psig_typesubst _ -> + raise_errorf "ppx_gen_rec: Psig_typesubst not supported yet" + | Psig_modsubst _ -> + raise_errorf "ppx_gen_rec: Psig_modsubst not supported yet" and structure_item_of_signature_item { psig_desc; psig_loc; } = { @@ -80,7 +90,11 @@ and structure_item_of_signature_item { psig_desc; psig_loc; } = and structure_of_signature signature_items = List.map structure_item_of_signature_item signature_items -let module_binding mapper = function +let mapper = + object + inherit Ast_traverse.map as super + + method! module_binding = function | { pmb_name = {txt = name; _}; pmb_expr = ({ pmod_desc = Pmod_constraint ( @@ -90,7 +104,7 @@ let module_binding mapper = function _ } as expr); _ - } as binding when name = ident -> + } as binding when name = Some ident -> { binding with pmb_expr = { expr with pmod_desc = Pmod_constraint ( { m with pmod_desc = Pmod_structure (structure_of_signature signature_items) }, @@ -99,24 +113,26 @@ let module_binding mapper = function } } | other -> - default_mapper.module_binding mapper other - -let gen_rec_mapper = { default_mapper with module_binding } - -let structure_item mapper = function - | { pstr_desc = Pstr_extension (({txt = "gen"; _}, PStr [{ - pstr_desc = Pstr_recmodule decls; - pstr_loc; - }]), _); - pstr_loc = _; - } -> - let decls = List.map (gen_rec_mapper.module_binding gen_rec_mapper) decls in - { pstr_desc = Pstr_recmodule decls; pstr_loc } - | other -> - default_mapper.structure_item mapper other - -let gen_rec_mapper = { default_mapper with structure_item } + super # module_binding other +end + +let expand_struct_item = function + | PStr [{ + pstr_desc = Pstr_recmodule decls; + pstr_loc; + }] -> let decls = List.map (mapper # module_binding) decls in + { pstr_desc = Pstr_recmodule decls; pstr_loc } + | _ -> failwith "%gen can only be used with rec modules" + + +let extensions = [ + Extension.declare + "gen" + Extension.Context.structure_item + Ast_pattern.__ + (fun ~loc:_ ~path:_ x -> expand_struct_item x) +] let () = - Driver.register ~name:"ppx_gen_rec" ~position:~-10 Versions.ocaml_405 - (fun _config _cookies -> gen_rec_mapper) + Driver.register_transformation "ppx_gen_rec" + ~extensions diff --git a/test/dune b/test/dune new file mode 100644 index 0000000..c30cfe5 --- /dev/null +++ b/test/dune @@ -0,0 +1,14 @@ +(executable + (name foo) + (preprocess + (pps ppx_gen_rec ppx_deriving.std))) + +(rule + (with-stdout-to + tests.output + (run ./foo.exe))) + +(rule + (alias runtest) + (action + (diff tests.expected tests.output))) diff --git a/test/flow_ast.ml b/test/flow_ast.ml new file mode 100644 index 0000000..cdb74a0 --- /dev/null +++ b/test/flow_ast.ml @@ -0,0 +1,1865 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + (* + * An Ocaml implementation of the SpiderMonkey Parser API + * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + *) + + module%gen rec Syntax : sig + type ('M, 'internal) t = { + leading: 'M Comment.t list; + trailing: 'M Comment.t list; + internal: 'internal; + } + [@@deriving show] + end = + Syntax + + and Identifier : sig + type ('M, 'T) t = 'T * 'M t' + + and 'M t' = { + name: string; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + Identifier + + and PrivateName : sig + type 'M t = 'M * 'M t' + + and 'M t' = { + id: ('M, 'M) Identifier.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + PrivateName + + and Literal : sig + module RegExp : sig + type t = { + pattern: string; + flags: string; + } + [@@deriving show] + end + + (* Literals also carry along their raw value *) + type 'M t = { + value: value; + raw: string; + comments: ('M, unit) Syntax.t option; + } + + and value = + | String of string + | Boolean of bool + | Null + | Number of float + | BigInt of float + | RegExp of RegExp.t + [@@deriving show] + end = + Literal + + and StringLiteral : sig + type 'M t = { + value: string; + raw: string; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + StringLiteral + + and NumberLiteral : sig + type 'M t = { + value: float; + raw: string; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + NumberLiteral + + and BigIntLiteral : sig + type 'M t = { + approx_value: float; + (* Warning! Might lose precision! *) + bigint: string; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + BigIntLiteral + + and BooleanLiteral : sig + type 'M t = { + value: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + BooleanLiteral + + and Variance : sig + type 'M t = 'M * 'M t' + + and kind = + | Plus + | Minus + + and 'M t' = { + kind: kind; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + Variance + + and ComputedKey : sig + type ('M, 'T) t = 'M * ('M, 'T) ComputedKey.t' + + and ('M, 'T) t' = { + expression: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + ComputedKey + + and Type : sig + module Function : sig + module Param : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + name: ('M, 'T) Identifier.t option; + annot: ('M, 'T) Type.t; + optional: bool; + } + [@@deriving show] + end + + module RestParam : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Param.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module ThisParam : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + annot: ('M, 'T) Type.annotation; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Params : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + this_: ('M, 'T) ThisParam.t option; + params: ('M, 'T) Param.t list; + rest: ('M, 'T) RestParam.t option; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + tparams: ('M, 'T) Type.TypeParams.t option; + params: ('M, 'T) Params.t; + return: ('M, 'T) Type.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Generic : sig + module Identifier : sig + type ('M, 'T) t = + | Unqualified of ('M, 'T) Identifier.t + | Qualified of ('M, 'T) qualified + + and ('M, 'T) qualified = 'M * ('M, 'T) qualified' + + and ('M, 'T) qualified' = { + qualification: ('M, 'T) t; + id: ('M, 'T) Identifier.t; + } + [@@deriving show] + end + + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + targs: ('M, 'T) Type.TypeArgs.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Object : sig + module Property : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + key: ('M, 'T) Expression.Object.Property.key; + value: ('M, 'T) value; + optional: bool; + static: bool; + proto: bool; + _method: bool; + variance: 'M Variance.t option; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) value = + | Init of ('M, 'T) Type.t + | Get of ('M * ('M, 'T) Function.t) + | Set of ('M * ('M, 'T) Function.t) + [@@deriving show] + end + + module SpreadProperty : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Type.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Indexer : sig + type ('M, 'T) t' = { + id: ('M, 'M) Identifier.t option; + key: ('M, 'T) Type.t; + value: ('M, 'T) Type.t; + static: bool; + variance: 'M Variance.t option; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) t = 'M * ('M, 'T) t' [@@deriving show] + end + + module CallProperty : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + value: 'M * ('M, 'T) Function.t; + static: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module InternalSlot : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + id: ('M, 'M) Identifier.t; + value: ('M, 'T) Type.t; + optional: bool; + static: bool; + _method: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + exact: bool; + (* Inexact indicates the presence of ... in the object. It is more + * easily understood if exact is read as "explicitly exact" and "inexact" + * is read as "explicitly inexact". + * + * This confusion will go away when we get rid of the exact flag in favor + * of inexact as part of the work to make object types exact by default. + * *) + inexact: bool; + properties: ('M, 'T) property list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + + and ('M, 'T) property = + | Property of ('M, 'T) Property.t + | SpreadProperty of ('M, 'T) SpreadProperty.t + | Indexer of ('M, 'T) Indexer.t + | CallProperty of ('M, 'T) CallProperty.t + | InternalSlot of ('M, 'T) InternalSlot.t + [@@deriving show] + end + + module Interface : sig + type ('M, 'T) t = { + body: 'M * ('M, 'T) Object.t; + extends: ('M * ('M, 'T) Generic.t) list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Nullable : sig + type ('M, 'T) t = { + argument: ('M, 'T) Type.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Typeof : sig + type ('M, 'T) t = { + argument: ('M, 'T) Type.t; + (* TODO T64309494 *) + internal: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Tuple : sig + type ('M, 'T) t = { + types: ('M, 'T) Type.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Array : sig + type ('M, 'T) t = { + argument: ('M, 'T) Type.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Union : sig + type ('M, 'T) t = { + types: ('M, 'T) Type.t * ('M, 'T) Type.t * ('M, 'T) Type.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Intersection : sig + type ('M, 'T) t = { + types: ('M, 'T) Type.t * ('M, 'T) Type.t * ('M, 'T) Type.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = 'T * ('M, 'T) t' + + (* Yes, we could add a little complexity here to show that Any and Void + * should never be declared nullable, but that check can happen later *) + and ('M, 'T) t' = + | Any of ('M, unit) Syntax.t option + | Mixed of ('M, unit) Syntax.t option + | Empty of ('M, unit) Syntax.t option + | Void of ('M, unit) Syntax.t option + | Null of ('M, unit) Syntax.t option + | Number of ('M, unit) Syntax.t option + | BigInt of ('M, unit) Syntax.t option + | String of ('M, unit) Syntax.t option + | Boolean of ('M, unit) Syntax.t option + | Symbol of ('M, unit) Syntax.t option + | Exists of ('M, unit) Syntax.t option + | Nullable of ('M, 'T) Nullable.t + | Function of ('M, 'T) Function.t + | Object of ('M, 'T) Object.t + | Interface of ('M, 'T) Interface.t + | Array of ('M, 'T) Array.t + | Generic of ('M, 'T) Generic.t + | Union of ('M, 'T) Union.t + | Intersection of ('M, 'T) Intersection.t + | Typeof of ('M, 'T) Typeof.t + | Tuple of ('M, 'T) Tuple.t + | StringLiteral of 'M StringLiteral.t + | NumberLiteral of 'M NumberLiteral.t + | BigIntLiteral of 'M BigIntLiteral.t + | BooleanLiteral of 'M BooleanLiteral.t + + (* Type.annotation is a concrete syntax node with a location that starts at + * the colon and ends after the type. For example, "var a: number", the + * identifier a would have a property annot which contains a + * Type.annotation with a location from column 6-14 *) + and ('M, 'T) annotation = 'M * ('M, 'T) t + + and ('M, 'T) annotation_or_hint = + | Missing of 'T + | Available of ('M, 'T) Type.annotation + [@@deriving show] + + module TypeParam : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + name: ('M, 'M) Identifier.t; + bound: ('M, 'T) Type.annotation_or_hint; + variance: 'M Variance.t option; + default: ('M, 'T) Type.t option; + } + [@@deriving show] + end + + module TypeParams : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + params: ('M, 'T) TypeParam.t list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module TypeArgs : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + arguments: ('M, 'T) Type.t list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module Predicate : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + kind: ('M, 'T) kind; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) kind = + | Declared of ('M, 'T) Expression.t + | Inferred + [@@deriving show] + end + end = + Type + + and Statement : sig + module Block : sig + type ('M, 'T) t = { + body: ('M, 'T) Statement.t list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module If : sig + module Alternate : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + body: ('M, 'T) Statement.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + test: ('M, 'T) Expression.t; + consequent: ('M, 'T) Statement.t; + alternate: ('M, 'T) Alternate.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Labeled : sig + type ('M, 'T) t = { + label: ('M, 'M) Identifier.t; + body: ('M, 'T) Statement.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Break : sig + type 'M t = { + label: ('M, 'M) Identifier.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Continue : sig + type 'M t = { + label: ('M, 'M) Identifier.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Debugger : sig + type 'M t = { comments: ('M, unit) Syntax.t option } [@@deriving show] + end + + module With : sig + type ('M, 'T) t = { + _object: ('M, 'T) Expression.t; + body: ('M, 'T) Statement.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module TypeAlias : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + tparams: ('M, 'T) Type.TypeParams.t option; + right: ('M, 'T) Type.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module OpaqueType : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + tparams: ('M, 'T) Type.TypeParams.t option; + impltype: ('M, 'T) Type.t option; + supertype: ('M, 'T) Type.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Switch : sig + module Case : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + test: ('M, 'T) Expression.t option; + consequent: ('M, 'T) Statement.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + discriminant: ('M, 'T) Expression.t; + cases: ('M, 'T) Case.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Return : sig + type ('M, 'T) t = { + argument: ('M, 'T) Expression.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Throw : sig + type ('M, 'T) t = { + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Try : sig + module CatchClause : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + param: ('M, 'T) Pattern.t option; + body: 'M * ('M, 'T) Block.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + block: 'M * ('M, 'T) Block.t; + handler: ('M, 'T) CatchClause.t option; + finalizer: ('M * ('M, 'T) Block.t) option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module VariableDeclaration : sig + module Declarator : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + id: ('M, 'T) Pattern.t; + init: ('M, 'T) Expression.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + declarations: ('M, 'T) Declarator.t list; + kind: kind; + comments: ('M, unit) Syntax.t option; + } + + and kind = + | Var + | Let + | Const + [@@deriving show] + end + + module While : sig + type ('M, 'T) t = { + test: ('M, 'T) Expression.t; + body: ('M, 'T) Statement.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DoWhile : sig + type ('M, 'T) t = { + body: ('M, 'T) Statement.t; + test: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module For : sig + type ('M, 'T) t = { + init: ('M, 'T) init option; + test: ('M, 'T) Expression.t option; + update: ('M, 'T) Expression.t option; + body: ('M, 'T) Statement.t; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) init = + | InitDeclaration of ('M * ('M, 'T) VariableDeclaration.t) + | InitExpression of ('M, 'T) Expression.t + [@@deriving show] + end + + module ForIn : sig + type ('M, 'T) t = { + left: ('M, 'T) left; + right: ('M, 'T) Expression.t; + body: ('M, 'T) Statement.t; + each: bool; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) left = + | LeftDeclaration of ('M * ('M, 'T) VariableDeclaration.t) + | LeftPattern of ('M, 'T) Pattern.t + [@@deriving show] + end + + module ForOf : sig + type ('M, 'T) t = { + left: ('M, 'T) left; + right: ('M, 'T) Expression.t; + body: ('M, 'T) Statement.t; + await: bool; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) left = + | LeftDeclaration of ('M * ('M, 'T) VariableDeclaration.t) + | LeftPattern of ('M, 'T) Pattern.t + [@@deriving show] + end + + module EnumDeclaration : sig + module DefaultedMember : sig + type 'M t = 'M * 'M t' + + and 'M t' = { id: ('M, 'M) Identifier.t } [@@deriving show] + end + + module InitializedMember : sig + type ('I, 'M) t = 'M * ('I, 'M) t' + + and ('I, 'M) t' = { + id: ('M, 'M) Identifier.t; + init: 'M * 'I; + } + [@@deriving show] + end + + module BooleanBody : sig + type 'M t = { + members: ('M BooleanLiteral.t, 'M) InitializedMember.t list; + explicit_type: bool; + has_unknown_members: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module NumberBody : sig + type 'M t = { + members: ('M NumberLiteral.t, 'M) InitializedMember.t list; + explicit_type: bool; + has_unknown_members: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module StringBody : sig + type 'M t = { + members: ('M StringLiteral.t, 'M) members; + explicit_type: bool; + has_unknown_members: bool; + comments: ('M, unit) Syntax.t option; + } + + and ('I, 'M) members = + | Defaulted of 'M DefaultedMember.t list + | Initialized of ('I, 'M) InitializedMember.t list + [@@deriving show] + end + + module SymbolBody : sig + type 'M t = { + members: 'M DefaultedMember.t list; + has_unknown_members: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + body: 'M body; + comments: ('M, unit) Syntax.t option; + } + + and 'M body = 'M * 'M body' + + and 'M body' = + | BooleanBody of 'M BooleanBody.t + | NumberBody of 'M NumberBody.t + | StringBody of 'M StringBody.t + | SymbolBody of 'M SymbolBody.t + [@@deriving show] + end + + module Interface : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + tparams: ('M, 'T) Type.TypeParams.t option; + extends: ('M * ('M, 'T) Type.Generic.t) list; + body: 'M * ('M, 'T) Type.Object.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DeclareClass : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + tparams: ('M, 'T) Type.TypeParams.t option; + body: 'M * ('M, 'T) Type.Object.t; + extends: ('M * ('M, 'T) Type.Generic.t) option; + mixins: ('M * ('M, 'T) Type.Generic.t) list; + implements: ('M, 'T) Class.Implements.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DeclareVariable : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + annot: ('M, 'T) Type.annotation_or_hint; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DeclareFunction : sig + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t; + annot: ('M, 'T) Type.annotation; + predicate: ('M, 'T) Type.Predicate.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DeclareModule : sig + type ('M, 'T) id = + | Identifier of ('M, 'T) Identifier.t + | Literal of ('T * 'M StringLiteral.t) + + and 'M module_kind = + | CommonJS of 'M + | ES of 'M + + and ('M, 'T) t = { + id: ('M, 'T) id; + body: 'M * ('M, 'T) Block.t; + kind: 'M module_kind; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module DeclareModuleExports : sig + type ('M, 'T) t = { + annot: ('M, 'T) Type.annotation; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module ExportNamedDeclaration : sig + module ExportSpecifier : sig + type 'M t = 'M * 'M t' + + and 'M t' = { + local: ('M, 'M) Identifier.t; + exported: ('M, 'M) Identifier.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + declaration: ('M, 'T) Statement.t option; + specifiers: 'M specifier option; + source: ('M * 'M StringLiteral.t) option; + export_kind: Statement.export_kind; + comments: ('M, unit) Syntax.t option; + } + + and 'M specifier = + | ExportSpecifiers of 'M ExportSpecifier.t list + | ExportBatchSpecifier of 'M * ('M, 'M) Identifier.t option + [@@deriving show] + end + + module ExportDefaultDeclaration : sig + type ('M, 'T) t = { + default: 'M; + declaration: ('M, 'T) declaration; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) declaration = + | Declaration of ('M, 'T) Statement.t + | Expression of ('M, 'T) Expression.t + [@@deriving show] + end + + module DeclareExportDeclaration : sig + type ('M, 'T) declaration = + (* declare export var *) + | Variable of ('M * ('M, 'T) DeclareVariable.t) + (* declare export function *) + | Function of ('M * ('M, 'T) DeclareFunction.t) + (* declare export class *) + | Class of ('M * ('M, 'T) DeclareClass.t) + (* declare export default [type] + * this corresponds to things like + * export default 1+1; *) + | DefaultType of ('M, 'T) Type.t + (* declare export type *) + | NamedType of ('M * ('M, 'T) TypeAlias.t) + (* declare export opaque type *) + | NamedOpaqueType of ('M * ('M, 'T) OpaqueType.t) + (* declare export interface *) + | Interface of ('M * ('M, 'T) Interface.t) + + and ('M, 'T) t = { + default: 'M option; + declaration: ('M, 'T) declaration option; + specifiers: 'M ExportNamedDeclaration.specifier option; + source: ('M * 'M StringLiteral.t) option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module ImportDeclaration : sig + type import_kind = + | ImportType + | ImportTypeof + | ImportValue + + and ('M, 'T) specifier = + | ImportNamedSpecifiers of ('M, 'T) named_specifier list + | ImportNamespaceSpecifier of ('M * ('M, 'T) Identifier.t) + + and ('M, 'T) named_specifier = { + kind: import_kind option; + local: ('M, 'T) Identifier.t option; + remote: ('M, 'T) Identifier.t; + } + + and ('M, 'T) t = { + import_kind: import_kind; + source: 'M * 'M StringLiteral.t; + default: ('M, 'T) Identifier.t option; + specifiers: ('M, 'T) specifier option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Expression : sig + type ('M, 'T) t = { + expression: ('M, 'T) Expression.t; + directive: string option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Empty : sig + type 'M t = { comments: ('M, unit) Syntax.t option } [@@deriving show] + end + + type export_kind = + | ExportType + | ExportValue + + and ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = + | Block of ('M, 'T) Block.t + | Break of 'M Break.t + | ClassDeclaration of ('M, 'T) Class.t + | Continue of 'M Continue.t + | Debugger of 'M Debugger.t + | DeclareClass of ('M, 'T) DeclareClass.t + | DeclareExportDeclaration of ('M, 'T) DeclareExportDeclaration.t + | DeclareFunction of ('M, 'T) DeclareFunction.t + | DeclareInterface of ('M, 'T) Interface.t + | DeclareModule of ('M, 'T) DeclareModule.t + | DeclareModuleExports of ('M, 'T) DeclareModuleExports.t + | DeclareTypeAlias of ('M, 'T) TypeAlias.t + | DeclareOpaqueType of ('M, 'T) OpaqueType.t + | DeclareVariable of ('M, 'T) DeclareVariable.t + | DoWhile of ('M, 'T) DoWhile.t + | Empty of 'M Empty.t + | EnumDeclaration of ('M, 'T) EnumDeclaration.t + | ExportDefaultDeclaration of ('M, 'T) ExportDefaultDeclaration.t + | ExportNamedDeclaration of ('M, 'T) ExportNamedDeclaration.t + | Expression of ('M, 'T) Expression.t + | For of ('M, 'T) For.t + | ForIn of ('M, 'T) ForIn.t + | ForOf of ('M, 'T) ForOf.t + | FunctionDeclaration of ('M, 'T) Function.t + | If of ('M, 'T) If.t + | ImportDeclaration of ('M, 'T) ImportDeclaration.t + | InterfaceDeclaration of ('M, 'T) Interface.t + | Labeled of ('M, 'T) Labeled.t + | Return of ('M, 'T) Return.t + | Switch of ('M, 'T) Switch.t + | Throw of ('M, 'T) Throw.t + | Try of ('M, 'T) Try.t + | TypeAlias of ('M, 'T) TypeAlias.t + | OpaqueType of ('M, 'T) OpaqueType.t + | VariableDeclaration of ('M, 'T) VariableDeclaration.t + | While of ('M, 'T) While.t + | With of ('M, 'T) With.t + [@@deriving show] + end = + Statement + + and Expression : sig + module CallTypeArg : sig + module Implicit : sig + type ('M, 'T) t = 'T * 'M t' + + and 'M t' = { comments: ('M, unit) Syntax.t option } [@@deriving show] + end + + type ('M, 'T) t = + | Explicit of ('M, 'T) Type.t + | Implicit of ('M, 'T) Implicit.t + [@@deriving show] + end + + module CallTypeArgs : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + arguments: ('M, 'T) CallTypeArg.t list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module SpreadElement : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Array : sig + type ('M, 'T) element = + | Expression of ('M, 'T) Expression.t + | Spread of ('M, 'T) SpreadElement.t + | Hole of 'M + [@@deriving show] + + type ('M, 'T) t = { + elements: ('M, 'T) element list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module TemplateLiteral : sig + module Element : sig + type value = { + raw: string; + cooked: string; + } + + and 'M t = 'M * t' + + and t' = { + value: value; + tail: bool; + } + [@@deriving show] + end + + type ('M, 'T) t = { + quasis: 'M Element.t list; + expressions: ('M, 'T) Expression.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module TaggedTemplate : sig + type ('M, 'T) t = { + tag: ('M, 'T) Expression.t; + quasi: 'M * ('M, 'T) TemplateLiteral.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Object : sig + module Property : sig + type ('M, 'T) key = + | Literal of ('T * 'M Literal.t) + | Identifier of ('M, 'T) Identifier.t + | PrivateName of 'M PrivateName.t + | Computed of ('M, 'T) ComputedKey.t + + and ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = + | Init of { + key: ('M, 'T) key; + value: ('M, 'T) Expression.t; + shorthand: bool; + } + | Method of { + key: ('M, 'T) key; + value: 'M * ('M, 'T) Function.t; + } + | Get of { + key: ('M, 'T) key; + value: 'M * ('M, 'T) Function.t; + comments: ('M, unit) Syntax.t option; + } + | Set of { + key: ('M, 'T) key; + value: 'M * ('M, 'T) Function.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module SpreadProperty : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) property = + | Property of ('M, 'T) Property.t + | SpreadProperty of ('M, 'T) SpreadProperty.t + + and ('M, 'T) t = { + properties: ('M, 'T) property list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module Sequence : sig + type ('M, 'T) t = { + expressions: ('M, 'T) Expression.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Unary : sig + type operator = + | Minus + | Plus + | Not + | BitNot + | Typeof + | Void + | Delete + | Await + + and ('M, 'T) t = { + operator: operator; + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Binary : sig + type operator = + | Equal + | NotEqual + | StrictEqual + | StrictNotEqual + | LessThan + | LessThanEqual + | GreaterThan + | GreaterThanEqual + | LShift + | RShift + | RShift3 + | Plus + | Minus + | Mult + | Exp + | Div + | Mod + | BitOr + | Xor + | BitAnd + | In + | Instanceof + + and ('M, 'T) t = { + operator: operator; + left: ('M, 'T) Expression.t; + right: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Assignment : sig + type operator = + | PlusAssign + | MinusAssign + | MultAssign + | ExpAssign + | DivAssign + | ModAssign + | LShiftAssign + | RShiftAssign + | RShift3Assign + | BitOrAssign + | BitXorAssign + | BitAndAssign + + and ('M, 'T) t = { + operator: operator option; + left: ('M, 'T) Pattern.t; + right: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Update : sig + type operator = + | Increment + | Decrement + + and ('M, 'T) t = { + operator: operator; + argument: ('M, 'T) Expression.t; + prefix: bool; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Logical : sig + type operator = + | Or + | And + | NullishCoalesce + + and ('M, 'T) t = { + operator: operator; + left: ('M, 'T) Expression.t; + right: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Conditional : sig + type ('M, 'T) t = { + test: ('M, 'T) Expression.t; + consequent: ('M, 'T) Expression.t; + alternate: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) expression_or_spread = + | Expression of ('M, 'T) Expression.t + | Spread of ('M, 'T) SpreadElement.t + [@@deriving show] + + module ArgList : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + arguments: ('M, 'T) expression_or_spread list; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module New : sig + type ('M, 'T) t = { + callee: ('M, 'T) Expression.t; + targs: ('M, 'T) Expression.CallTypeArgs.t option; + arguments: ('M, 'T) ArgList.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Call : sig + type ('M, 'T) t = { + callee: ('M, 'T) Expression.t; + targs: ('M, 'T) Expression.CallTypeArgs.t option; + arguments: ('M, 'T) ArgList.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module OptionalCall : sig + type ('M, 'T) t = { + call: ('M, 'T) Call.t; + optional: bool; + } + [@@deriving show] + end + + module Member : sig + type ('M, 'T) property = + | PropertyIdentifier of ('M, 'T) Identifier.t + | PropertyPrivateName of 'M PrivateName.t + | PropertyExpression of ('M, 'T) Expression.t + + and ('M, 'T) t = { + _object: ('M, 'T) Expression.t; + property: ('M, 'T) property; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module OptionalMember : sig + type ('M, 'T) t = { + member: ('M, 'T) Member.t; + optional: bool; + } + [@@deriving show] + end + + module Yield : sig + type ('M, 'T) t = { + argument: ('M, 'T) Expression.t option; + comments: ('M, unit) Syntax.t option; + delegate: bool; + } + [@@deriving show] + end + + module Comprehension : sig + module Block : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + left: ('M, 'T) Pattern.t; + right: ('M, 'T) Expression.t; + each: bool; + } + [@@deriving show] + end + + type ('M, 'T) t = { + blocks: ('M, 'T) Block.t list; + filter: ('M, 'T) Expression.t option; + } + [@@deriving show] + end + + module Generator : sig + type ('M, 'T) t = { + blocks: ('M, 'T) Comprehension.Block.t list; + filter: ('M, 'T) Expression.t option; + } + [@@deriving show] + end + + module TypeCast : sig + type ('M, 'T) t = { + expression: ('M, 'T) Expression.t; + annot: ('M, 'T) Type.annotation; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module MetaProperty : sig + type 'M t = { + meta: ('M, 'M) Identifier.t; + property: ('M, 'M) Identifier.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module This : sig + type 'M t = { comments: ('M, unit) Syntax.t option } [@@deriving show] + end + + module Super : sig + type 'M t = { comments: ('M, unit) Syntax.t option } [@@deriving show] + end + + module Import : sig + type ('M, 'T) t = { + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = 'T * ('M, 'T) t' + + and ('M, 'T) t' = + | Array of ('M, 'T) Array.t + | ArrowFunction of ('M, 'T) Function.t + | Assignment of ('M, 'T) Assignment.t + | Binary of ('M, 'T) Binary.t + | Call of ('M, 'T) Call.t + | Class of ('M, 'T) Class.t + | Comprehension of ('M, 'T) Comprehension.t + | Conditional of ('M, 'T) Conditional.t + | Function of ('M, 'T) Function.t + | Generator of ('M, 'T) Generator.t + | Identifier of ('M, 'T) Identifier.t + | Import of ('M, 'T) Import.t + | JSXElement of ('M, 'T) JSX.element + | JSXFragment of ('M, 'T) JSX.fragment + | Literal of 'M Literal.t + | Logical of ('M, 'T) Logical.t + | Member of ('M, 'T) Member.t + | MetaProperty of 'M MetaProperty.t + | New of ('M, 'T) New.t + | Object of ('M, 'T) Object.t + | OptionalCall of ('M, 'T) OptionalCall.t + | OptionalMember of ('M, 'T) OptionalMember.t + | Sequence of ('M, 'T) Sequence.t + | Super of 'M Super.t + | TaggedTemplate of ('M, 'T) TaggedTemplate.t + | TemplateLiteral of ('M, 'T) TemplateLiteral.t + | This of 'M This.t + | TypeCast of ('M, 'T) TypeCast.t + | Unary of ('M, 'T) Unary.t + | Update of ('M, 'T) Update.t + | Yield of ('M, 'T) Yield.t + [@@deriving show] + end = + Expression + + and JSX : sig + module Identifier : sig + type ('M, 'T) t = 'T * 'M t' + + and 'M t' = { + name: string; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module NamespacedName : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + namespace: ('M, 'T) Identifier.t; + name: ('M, 'T) Identifier.t; + } + [@@deriving show] + end + + module ExpressionContainer : sig + type ('M, 'T) t = { + expression: ('M, 'T) expression; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + + and ('M, 'T) expression = + | Expression of ('M, 'T) Expression.t + | EmptyExpression + [@@deriving show] + end + + module Text : sig + type t = { + value: string; + raw: string; + } + [@@deriving show] + end + + module Attribute : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) name = + | Identifier of ('M, 'T) Identifier.t + | NamespacedName of ('M, 'T) NamespacedName.t + + and ('M, 'T) value = + | Literal of 'T * 'M Literal.t + | ExpressionContainer of 'T * ('M, 'T) ExpressionContainer.t + + and ('M, 'T) t' = { + name: ('M, 'T) name; + value: ('M, 'T) value option; + } + [@@deriving show] + end + + module SpreadAttribute : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module MemberExpression : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) _object = + | Identifier of ('M, 'T) Identifier.t + | MemberExpression of ('M, 'T) t + + and ('M, 'T) t' = { + _object: ('M, 'T) _object; + property: ('M, 'T) Identifier.t; + } + [@@deriving show] + end + + type ('M, 'T) name = + | Identifier of ('M, 'T) Identifier.t + | NamespacedName of ('M, 'T) NamespacedName.t + | MemberExpression of ('M, 'T) MemberExpression.t + [@@deriving show] + + module Opening : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) attribute = + | Attribute of ('M, 'T) Attribute.t + | SpreadAttribute of ('M, 'T) SpreadAttribute.t + + and ('M, 'T) t' = { + name: ('M, 'T) name; + self_closing: bool; + attributes: ('M, 'T) attribute list; + } + [@@deriving show] + end + + module Closing : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { name: ('M, 'T) name } [@@deriving show] + end + + module SpreadChild : sig + type ('M, 'T) t = { + expression: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) child = 'M * ('M, 'T) child' + + and ('M, 'T) child' = + | Element of ('M, 'T) element + | Fragment of ('M, 'T) fragment + | ExpressionContainer of ('M, 'T) ExpressionContainer.t + | SpreadChild of ('M, 'T) SpreadChild.t + | Text of Text.t + + and ('M, 'T) element = { + opening_element: ('M, 'T) Opening.t; + closing_element: ('M, 'T) Closing.t option; + children: 'M * ('M, 'T) child list; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) fragment = { + frag_opening_element: 'M; + frag_closing_element: 'M; + frag_children: 'M * ('M, 'T) child list; + frag_comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + JSX + + and Pattern : sig + module RestElement : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Pattern.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Object : sig + module Property : sig + type ('M, 'T) key = + | Literal of ('M * 'M Literal.t) + | Identifier of ('M, 'T) Identifier.t + | Computed of ('M, 'T) ComputedKey.t + + and ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + key: ('M, 'T) key; + pattern: ('M, 'T) Pattern.t; + default: ('M, 'T) Expression.t option; + shorthand: bool; + } + [@@deriving show] + end + + type ('M, 'T) property = + | Property of ('M, 'T) Property.t + | RestElement of ('M, 'T) RestElement.t + + and ('M, 'T) t = { + properties: ('M, 'T) property list; + annot: ('M, 'T) Type.annotation_or_hint; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module Array : sig + module Element : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Pattern.t; + default: ('M, 'T) Expression.t option; + } + [@@deriving show] + end + + type ('M, 'T) element = + | Element of ('M, 'T) Element.t + | RestElement of ('M, 'T) RestElement.t + | Hole of 'M + + and ('M, 'T) t = { + elements: ('M, 'T) element list; + annot: ('M, 'T) Type.annotation_or_hint; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + module Identifier : sig + type ('M, 'T) t = { + name: ('M, 'T) Identifier.t; + annot: ('M, 'T) Type.annotation_or_hint; + optional: bool; + } + [@@deriving show] + end + + type ('M, 'T) t = 'T * ('M, 'T) t' + + and ('M, 'T) t' = + | Object of ('M, 'T) Object.t + | Array of ('M, 'T) Array.t + | Identifier of ('M, 'T) Identifier.t + | Expression of ('M, 'T) Expression.t + [@@deriving show] + end = + Pattern + + and Comment : sig + type 'M t = 'M * t' + + and kind = + | Block + | Line + + and t' = { + kind: kind; + text: string; + on_newline: bool; + } + [@@deriving show] + end = + Comment + + and Class : sig + module Method : sig + type ('M, 'T) t = 'T * ('M, 'T) t' + + and kind = + | Constructor + | Method + | Get + | Set + + and ('M, 'T) t' = { + kind: kind; + key: ('M, 'T) Expression.Object.Property.key; + value: 'M * ('M, 'T) Function.t; + static: bool; + decorators: ('M, 'T) Class.Decorator.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Property : sig + type ('M, 'T) t = 'T * ('M, 'T) t' + + and ('M, 'T) t' = { + key: ('M, 'T) Expression.Object.Property.key; + value: ('M, 'T) value; + annot: ('M, 'T) Type.annotation_or_hint; + static: bool; + variance: 'M Variance.t option; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) value = + | Declared + | Uninitialized + | Initialized of ('M, 'T) Expression.t + [@@deriving show] + end + + module PrivateField : sig + type ('M, 'T) t = 'T * ('M, 'T) t' + + and ('M, 'T) t' = { + key: 'M PrivateName.t; + value: ('M, 'T) Class.Property.value; + annot: ('M, 'T) Type.annotation_or_hint; + static: bool; + variance: 'M Variance.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Extends : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + expr: ('M, 'T) Expression.t; + targs: ('M, 'T) Type.TypeArgs.t option; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Implements : sig + module Interface : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + id: ('M, 'T) Identifier.t; + targs: ('M, 'T) Type.TypeArgs.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + interfaces: ('M, 'T) Interface.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Body : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + body: ('M, 'T) element list; + comments: ('M, unit) Syntax.t option; + } + + and ('M, 'T) element = + | Method of ('M, 'T) Method.t + | Property of ('M, 'T) Property.t + | PrivateField of ('M, 'T) PrivateField.t + [@@deriving show] + end + + module Decorator : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + expression: ('M, 'T) Expression.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t option; + body: ('M, 'T) Class.Body.t; + tparams: ('M, 'T) Type.TypeParams.t option; + extends: ('M, 'T) Extends.t option; + implements: ('M, 'T) Implements.t option; + class_decorators: ('M, 'T) Decorator.t list; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end = + Class + + and Function : sig + module RestParam : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Pattern.t; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Param : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + argument: ('M, 'T) Pattern.t; + default: ('M, 'T) Expression.t option; + } + [@@deriving show] + end + + module ThisParam : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + annot: ('M, 'T) Type.annotation; + comments: ('M, unit) Syntax.t option; + } + [@@deriving show] + end + + module Params : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + this_: ('M, 'T) ThisParam.t option; + params: ('M, 'T) Param.t list; + rest: ('M, 'T) RestParam.t option; + comments: ('M, 'M Comment.t list) Syntax.t option; + } + [@@deriving show] + end + + type ('M, 'T) t = { + id: ('M, 'T) Identifier.t option; + params: ('M, 'T) Params.t; + body: ('M, 'T) body; + async: bool; + generator: bool; + predicate: ('M, 'T) Type.Predicate.t option; + return: ('M, 'T) Type.annotation_or_hint; + tparams: ('M, 'T) Type.TypeParams.t option; + comments: ('M, unit) Syntax.t option; + (* Location of the signature portion of a function, e.g. + * function foo(): void {} + * ^^^^^^^^^^^^^^^^^^^^ + *) + sig_loc: 'M; + } + + and ('M, 'T) body = + | BodyBlock of ('M * ('M, 'T) Statement.Block.t) + | BodyExpression of ('M, 'T) Expression.t + [@@deriving show] + end = + Function + + and Program : sig + type ('M, 'T) t = 'M * ('M, 'T) t' + + and ('M, 'T) t' = { + statements: ('M, 'T) Statement.t list; + comments: ('M, unit) Syntax.t option; + all_comments: 'M Comment.t list; + } + [@@deriving show] + end = + Program + \ No newline at end of file diff --git a/test/foo.ml b/test/foo.ml new file mode 100644 index 0000000..34bcf51 --- /dev/null +++ b/test/foo.ml @@ -0,0 +1,18 @@ + +module%gen rec Foo : sig + type t = string [@@deriving show] +end = Foo + +let foo : Foo.t = "foo" + +let () = print_endline (Foo.show foo) + + +let () = + let empty_program = Flow_ast.Program.{ + statements = []; + comments = None; + all_comments = []; + } in + let nop = fun _ _ -> () in + print_endline (Flow_ast.Program.show nop nop (None, empty_program)) \ No newline at end of file diff --git a/test/tests.expected b/test/tests.expected new file mode 100644 index 0000000..41a88f9 --- /dev/null +++ b/test/tests.expected @@ -0,0 +1,2 @@ +"foo" +(, { Flow_ast.Program.statements = []; comments = None; all_comments = [] })