2 * Copyright (c) 2016, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
10 module OcamlPrintf
= Printf
13 open Full_fidelity_schema
15 let full_fidelity_path_prefix = "hphp/hack/src/parser/"
18 [ "as"; "break"; "const"; "continue"; "crate"; "else"; "enum"; "extern";
19 "false"; "fn"; "for"; "if"; "impl"; "in"; "let"; "loop"; "match"; "mod";
20 "move"; "mut"; "pub"; "ref"; "return"; "self"; "Self"; "static"; "struct";
21 "super"; "trait"; "true"; "type"; "unsafe"; "use"; "where"; "while";
22 "async"; "await"; "dyn" ]
23 [@@ocamlformat
"disable"]
25 let escape_rust_keyword field_name
=
26 if List.mem
rust_keywords field_name ~equal
:String.equal
then
27 sprintf
"%s_" field_name
36 let make_header comment_style
(header_comment
: string) : string =
37 let (open_char
, close_char
) =
38 match comment_style
with
39 | CStyle
-> ("/*", '
/'
)
40 | MLStyle
-> ("(", '
)'
)
44 * Copyright (c) 2016, Facebook, Inc.
45 * All rights reserved.
47 * This source code is licensed under the MIT license found in the
48 * LICENSE file in the \"hack\" directory of this source tree. An additional
53 * THIS FILE IS @%s; DO NOT EDIT IT
54 * To regenerate this file, run
56 * buck run //hphp/hack/src:generate_full_fidelity
62 (* Any file containing '@' followed by the word 'generated' is considered a
63 * generated file in Phabricator. Cheeky trick to avoid making this script
64 * being seen as generated. *)
70 (string -> string -> string, unit, string, string -> string) format4
72 let all_tokens = given_text_tokens
@ variable_text_tokens
@ no_text_tokens
74 let align_fmt : 'a
. ('a
-> string) -> 'a list
-> valign
=
76 let folder acc x
= max acc
(String.length
(f x
)) in
77 let width = List.fold_left ~f
:folder ~init
:0 xs
in
78 Scanf.format_from_string
(sprintf
"%%-%ds" width) "%-1s"
80 let kind_name_fmt = align_fmt (fun x
-> x
.kind_name
) schema
82 let type_name_fmt = align_fmt (fun x
-> x
.type_name
) schema
84 let trivia_kind_fmt = align_fmt (fun x
-> x
.trivia_kind
) trivia_kinds
86 let token_kind_fmt = align_fmt (fun x
-> x
.token_kind
) all_tokens
88 let omit_syntax_record =
93 "closure_type_specifier";
94 "function_declaration";
95 "function_declaration_header";
98 "methodish_declaration";
101 (fun x
-> not
(SSet.mem x
.type_name
names))
103 module GenerateFFSyntaxType
= struct
104 let to_parse_tree x
=
105 if omit_syntax_record x
then
108 let field_width = 50 - String.length x
.prefix
in
109 let fmt = sprintf
"%s_%%-%ds: t\n" x
.prefix
field_width in
110 let mapper (f
, _
) = sprintf
(Scanf.format_from_string
fmt "%-1s") f
in
111 let fields = map_and_concat_separated
" ; " mapper x
.fields in
112 sprintf
" and %s =\n { %s }\n" x
.type_name
fields
115 let field_width = 50 - String.length x
.prefix
in
116 let fmt = sprintf
"%s_%%-%ds: t\n" x
.prefix
field_width in
117 let mapper (f
, _
) = sprintf
(Scanf.format_from_string
fmt "%-1s") f
in
118 let fields = map_and_concat_separated
" ; " mapper x
.fields in
120 (" | " ^^
kind_name_fmt ^^
" of\n { %s }\n")
124 let to_aggregate_type x
=
125 let aggregated_types = aggregation_of x
in
126 let (prefix
, trim
) = aggregate_type_pfx_trim x
in
127 let compact = Str.global_replace
(Str.regexp trim
) "" in
128 let valign = align_fmt (fun x
-> compact x
.kind_name
) aggregated_types in
129 let type_name = aggregate_type_name x
in
130 let make_constructor ty
=
132 ("%s" ^^
valign ^^
" of %s")
134 (compact ty
.kind_name
)
137 let type_body = List.map ~f
:make_constructor aggregated_types in
141 (String.concat ~sep
:"\n | " type_body)
143 let full_fidelity_syntax_template : string =
147 * This module contains the type describing the structure of a syntax tree.
149 * The structure of the syntax tree is described by the collection of recursive
150 * types that makes up the bulk of this file. The type `t` is the type of a node
151 * in the syntax tree; each node has associated with it an arbitrary value of
152 * type `SyntaxValue.t`, and syntax node proper, which has structure given by
155 * Note that every child in the syntax tree is of type `t`, except for the
156 * `Token.t` type. This should be the *only* child of a type other than `t`.
157 * We are explicitly NOT attempting to impose a type structure on the parse
158 * tree beyond what is already implied by the types here. For example,
159 * we are not attempting to put into the type system here the restriction that
160 * the children of a binary operator must be expressions. The reason for this
161 * is because we are potentially parsing code as it is being typed, and we
162 * do not want to restrict our ability to make good error recovery by imposing
163 * a restriction that will only be valid in correct program text.
165 * That said, it would of course be ideal if the only children of a compound
166 * statement were statements, and so on. But those invariants should be
167 * imposed by the design of the parser, not by the type system of the syntax
170 * We want to be able to use different kinds of tokens, with different
171 * performance characteristics. Moreover, we want to associate arbitrary values
172 * with the syntax nodes, so that we can construct syntax trees with various
173 * properties -- trees that only know their widths and are thereby cheap to
174 * serialize, trees that have full position data for each node, trees where the
175 * tokens know their text and can therefore be edited, trees that have name
176 * annotations or type annotations, and so on.
178 * We wish to associate arbitrary values with the syntax nodes so that we can
179 * construct syntax trees with various properties -- trees that only know
180 * their widths and are thereby cheap to serialize, trees that have full
181 * position data for each node, trees where the tokens know their text and
182 * can therefore be edited, trees that have name annotations or type
183 * annotations, and so on.
185 * Therefore this module is functorized by the types for token and value to be
186 * associated with the node."
190 module type TokenType = sig
191 module Trivia : Lexable_trivia_sig.LexableTrivia_S
192 type t [@@deriving show, eq, sexp_of]
193 val kind: t -> Full_fidelity_token_kind.t
194 val to_json: t -> Hh_json.json
195 val leading : t -> Trivia.t list
198 module type SyntaxValueType = sig
199 type t [@@deriving show, eq, sexp_of]
200 val to_json: t -> Hh_json.json
203 (* This functor describe the shape of a parse tree that has a particular kind of
204 * token in the leaves, and a particular kind of value associated with each
207 module MakeSyntaxType(Token : TokenType)(SyntaxValue : SyntaxValueType) = struct
208 type value = SyntaxValue.t [@@deriving show, eq, sexp_of]
209 type t = { syntax : syntax ; value : value } [@@deriving show, eq, sexp_of]
210 PARSE_TREE and syntax =
213 | SyntaxList of t list
220 let full_fidelity_syntax_type =
221 Full_fidelity_schema.make_template_file
224 { pattern
= "PARSE_TREE"; func
= to_parse_tree };
225 { pattern
= "SYNTAX"; func
= to_syntax };
227 ~aggregate_transformations
:
230 aggregate_pattern
= "AGGREGATE_TYPES";
231 aggregate_func
= to_aggregate_type;
234 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_syntax_type.ml")
235 ~template
:full_fidelity_syntax_template
239 module GenerateFFRustSyntaxImplByRef
= struct
242 " SyntaxVariant::%s {..} => SyntaxKind::%s,\n"
247 make_header CStyle
""
249 use crate::{syntax_kind::SyntaxKind, lexable_token::LexableToken};
250 use super::{syntax::Syntax, syntax_variant_generated::SyntaxVariant};
252 impl<T: LexableToken, V> Syntax<'_, T, V> {
253 pub fn kind(&self) -> SyntaxKind {
254 match &self.children {
255 SyntaxVariant::Missing => SyntaxKind::Missing,
256 SyntaxVariant::Token (t) => SyntaxKind::Token(t.kind()),
257 SyntaxVariant::SyntaxList (_) => SyntaxKind::SyntaxList,
263 let full_fidelity_syntax =
264 Full_fidelity_schema.make_template_file
265 ~transformations
:[{ pattern
= "TO_KIND"; func
= to_kind }]
267 (full_fidelity_path_prefix ^
"syntax_by_ref/syntax_impl_generated.rs")
272 module GenerateSyntaxSerialize
= struct
274 let get_field x
= escape_rust_keyword (fst x
) in
275 let serialize_fields =
276 map_and_concat_separated
280 "ss.serialize_field(\"%s_%s\", &self.with(%s))?;"
286 let fields = map_and_concat_separated
"," get_field x
.fields in
288 "SyntaxVariant::%s (%sChildren{%s} ) => {
289 let mut ss = s.serialize_struct(\"\", %d)?;
290 ss.serialize_field(\"kind\", \"%s\")?;
297 (1 + List.length x
.fields)
302 make_header CStyle
""
304 use super::{serialize::WithContext, syntax::Syntax, syntax_variant_generated::*};
305 use serde::{ser::SerializeStruct, Serialize, Serializer};
307 impl<'a, T, V> Serialize for WithContext<'a, Syntax<'a, T, V>>
310 WithContext<'a, T>: Serialize,
312 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
313 match self.1.children {
314 SyntaxVariant::Missing => {
315 let mut ss = s.serialize_struct(\"\", 1)?;
316 ss.serialize_field(\"kind\", \"missing\")?;
319 SyntaxVariant::Token(ref t) => {
320 let mut ss = s.serialize_struct(\"\", 2)?;
321 ss.serialize_field(\"kind\", \"token\")?;
322 ss.serialize_field(\"token\", &self.with(t))?;
325 SyntaxVariant::SyntaxList(l) => {
326 let mut ss = s.serialize_struct(\"\", 2)?;
327 ss.serialize_field(\"kind\", \"list\")?;
328 ss.serialize_field(\"elements\", &self.with(l))?;
338 Full_fidelity_schema.make_template_file
339 ~transformations
:[{ pattern
= "MATCH_ARMS"; func
= match_arm }]
341 (full_fidelity_path_prefix
342 ^
"syntax_by_ref/syntax_serialize_generated.rs")
347 module GenerateFFRustSyntaxVariantByRef
= struct
348 let to_syntax_variant_children x
=
350 sprintf
" pub %s: Syntax<'a, T, V>," (escape_rust_keyword f
)
352 let fields = map_and_concat_separated
"\n" mapper x
.fields in
354 "#[derive(Debug, Clone)]\npub struct %sChildren<'a, T, V> {\n%s\n}\n\n"
358 let to_syntax_variant x
=
359 sprintf
" %s(&'a %sChildren<'a, T, V>),\n" x
.kind_name x
.kind_name
361 let full_fidelity_syntax_template =
362 make_header CStyle
""
366 syntax_children_iterator::SyntaxChildrenIterator,
369 #[derive(Debug, Clone)]
370 pub enum SyntaxVariant<'a, T, V> {
373 SyntaxList(&'a [Syntax<'a, T, V>]),
378 impl<'a, T, V> SyntaxVariant<'a, T, V> {
379 pub fn iter_children(&'a self) -> SyntaxChildrenIterator<'a, T, V> {
380 SyntaxChildrenIterator {
389 let full_fidelity_syntax =
390 Full_fidelity_schema.make_template_file
393 { pattern
= "SYNTAX_VARIANT"; func
= to_syntax_variant };
394 { pattern
= "SYNTAX_CHILDREN"; func
= to_syntax_variant_children };
397 (full_fidelity_path_prefix ^
"syntax_by_ref/syntax_variant_generated.rs")
398 ~
template:full_fidelity_syntax_template
402 module GenerateSyntaxChildrenIterator
= struct
403 let to_iter_children x
=
406 let res = sprintf
"%d => Some(&x.%s)," !index (escape_rust_keyword f
) in
407 let () = incr
index in
411 map_and_concat_separated
"\n " mapper x
.fields
415 get_index(%d).and_then(|index| { match index {
422 (List.length x
.fields)
425 let full_fidelity_syntax_template =
426 make_header CStyle
""
429 syntax_children_iterator::*,
430 syntax_variant_generated::*,
434 impl<'a, T, V> SyntaxChildrenIterator<'a, T, V> {
435 pub fn next_impl(&mut self, direction : bool) -> Option<&'a Syntax<'a, T, V>> {
436 use SyntaxVariant::*;
437 let get_index = |len| {
438 let back_index_plus_1 = len - self.index_back;
439 if back_index_plus_1 <= self.index {
445 Some (back_index_plus_1 - 1)
448 let res = match self.syntax {
451 SyntaxList(elems) => {
452 get_index(elems.len()).and_then(|x| elems.get(x))
458 self.index = self.index + 1
460 self.index_back = self.index_back + 1
468 let full_fidelity_syntax =
469 Full_fidelity_schema.make_template_file
470 ~transformations
:[{ pattern
= "ITER_CHILDREN"; func
= to_iter_children }]
472 (full_fidelity_path_prefix
473 ^
"syntax_by_ref/syntax_children_iterator_generated.rs")
474 ~
template:full_fidelity_syntax_template
478 module GenerateSyntaxTypeImpl
= struct
479 let to_syntax_constructors x
=
480 let mapper (f
, _
) = sprintf
"%s: Self" (escape_rust_keyword f
) in
481 let args = map_and_concat_separated
", " mapper x
.fields in
482 let mapper (f
, _
) = sprintf
"%s" (escape_rust_keyword f
) in
483 let fields = map_and_concat_separated
",\n " mapper x
.fields in
485 " fn make_%s(ctx: &C, %s) -> Self {
486 let syntax = SyntaxVariant::%s(ctx.get_arena().alloc(%sChildren {
489 let value = V::from_values(syntax.iter_children().map(|child| &child.value));
490 Self::make(syntax, value)
498 let full_fidelity_syntax_template =
499 make_header CStyle
""
503 syntax::*, syntax_variant_generated::*,
506 lexable_token::LexableToken,
507 syntax::{SyntaxType, SyntaxValueType},
510 impl<'a, C, T, V> SyntaxType<C> for Syntax<'a, T, V>
512 T: LexableToken + Copy,
513 V: SyntaxValueType<T>,
516 SYNTAX_CONSTRUCTORS }
519 let full_fidelity_syntax =
520 Full_fidelity_schema.make_template_file
522 [{ pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors }]
524 (full_fidelity_path_prefix
525 ^
"syntax_by_ref/syntax_type_impl_generated.rs")
526 ~
template:full_fidelity_syntax_template
530 module GenerateFFRustSyntax
= struct
531 let from_children x
=
532 let mapper prefix
(f
, _
) =
533 sprintf
"%s_%s : (Box::new(ts.pop().unwrap()))" prefix f
536 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
539 "SyntaxKind::%s => SyntaxVariant::%s {
548 " SyntaxVariant::%s {..} => SyntaxKind::%s,\n"
553 let mapper prefix
(f
, _
) = sprintf
"&*%s_%s" prefix f
in
555 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
557 let mapper prefix
(f
, _
) = sprintf
"ref %s_%s" prefix f
in
559 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
569 let to_iter_children x
=
571 let mapper prefix
(f
, _
) =
572 let res = sprintf
"%d => Some(&x.%s_%s)," !index prefix f
in
573 let () = incr
index in
577 map_and_concat_separated
584 get_index(%d).and_then(|index| { match index {
591 (List.length x
.fields)
594 let syntax_as_slice x
=
595 (* SAFETY: We have `#[repr(C)]` on all the children structs, and all their
596 fields are of type Syntax. So a child struct with 3 fields should have
597 the same layout as the array `[Syntax; 3]`, and it should be valid to
598 take a slice of length 3 from a pointer to its first field. *)
600 " SyntaxVariant::%s(x) => unsafe { std::slice::from_raw_parts(&x.%s_%s, %d) },\n"
603 (fst
(List.hd_exn x
.fields))
604 (List.length x
.fields)
606 let syntax_as_slice_mut x
=
607 (* SAFETY: As above in `syntax_as_slice` *)
609 " SyntaxVariant::%s(x) => unsafe { std::slice::from_raw_parts_mut(&mut x.%s_%s, %d) },\n"
612 (fst
(List.hd_exn x
.fields))
613 (List.length x
.fields)
615 let fold_over_owned x
=
616 let fold_mapper prefix
(f
, _
) =
617 sprintf
"let acc = f(%s_%s, acc)" prefix f
620 map_and_concat_separated
622 (fold_mapper x
.prefix
)
625 let destructure_mapper prefix
(f
, _
) = sprintf
"%s_%s" prefix f
in
626 let destructure_fields =
627 map_and_concat_separated
", " (destructure_mapper x
.prefix
) x
.fields
630 " SyntaxVariant::%s(x) => {
631 let %sChildren { %s } = *x;
640 let to_syntax_variant x
=
641 sprintf
" %s(Box<%sChildren<T, V>>),\n" x
.kind_name x
.kind_name
643 let to_syntax_variant_children x
=
644 let mapper prefix
(f
, _
) =
645 sprintf
" pub %s_%s: Syntax<T, V>," prefix f
647 let fields = map_and_concat_separated
"\n" (mapper x
.prefix
) x
.fields in
648 (* NB: The `#[repr(C)]` here is required for the `from_raw_parts` and
649 `from_raw_parts_mut` above (in `syntax_as_slice` and
650 `syntax_as_slice_mut`) to be valid. *)
652 "#[derive(Debug, Clone)]\n#[repr(C)]\npub struct %sChildren<T, V> {\n%s\n}\n\n"
656 let to_syntax_constructors x
=
657 let mapper prefix
(f
, _
) = sprintf
"%s_%s: Self" prefix f
in
658 let args = map_and_concat_separated
", " (mapper x
.prefix
) x
.fields in
659 let mapper prefix
(f
, _
) = sprintf
"%s_%s" prefix f
in
661 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
664 " fn make_%s(_: &C, %s) -> Self {
665 let syntax = SyntaxVariant::%s(Box::new(%sChildren {
668 let value = V::from_values(syntax.iter_children().map(|child| &child.value));
669 Self::make(syntax, value)
677 let to_syntax_from_children x
=
679 sprintf
"%s_%s: ts.pop().unwrap(),\n " x
.prefix f
681 let fields = map_and_concat
mapper (List.rev x
.fields) in
683 " (SyntaxKind::%s, %d) => SyntaxVariant::%s(Box::new(%sChildren {
687 (List.length x
.fields)
692 let full_fidelity_syntax_template =
693 make_header CStyle
""
695 use crate::lexable_token::LexableToken;
696 use crate::syntax::*;
697 use crate::syntax_kind::SyntaxKind;
699 impl<T, V, C> SyntaxType<C> for Syntax<T, V>
702 V: SyntaxValueType<T>,
704 SYNTAX_CONSTRUCTORS }
706 impl<T, V> Syntax<T, V>
710 pub fn fold_over_children_owned<U>(
711 f: &dyn Fn(Self, U) -> U,
713 syntax: SyntaxVariant<T, V>,
716 SyntaxVariant::Missing => acc,
717 SyntaxVariant::Token (_) => acc,
718 SyntaxVariant::SyntaxList(elems) => {
725 FOLD_OVER_CHILDREN_OWNED
729 pub fn kind(&self) -> SyntaxKind {
731 SyntaxVariant::Missing => SyntaxKind::Missing,
732 SyntaxVariant::Token (t) => SyntaxKind::Token(t.kind()),
733 SyntaxVariant::SyntaxList (_) => SyntaxKind::SyntaxList,
737 pub fn from_children(kind : SyntaxKind, mut ts : Vec<Self>) -> SyntaxVariant<T, V> {
738 match (kind, ts.len()) {
739 (SyntaxKind::Missing, 0) => SyntaxVariant::Missing,
740 (SyntaxKind::SyntaxList, _) => SyntaxVariant::SyntaxList(ts),
741 SYNTAX_FROM_CHILDREN _ => panic!(\"from_children called with wrong number of children\"),
745 pub fn children(&self) -> &[Self] {
747 SyntaxVariant::Missing => &[],
748 SyntaxVariant::Token(..) => &[],
749 SyntaxVariant::SyntaxList(l) => l.as_slice(),
753 pub fn children_mut(&mut self) -> &mut [Self] {
754 match &mut self.syntax {
755 SyntaxVariant::Missing => &mut [],
756 SyntaxVariant::Token(..) => &mut [],
757 SyntaxVariant::SyntaxList(l) => l.as_mut_slice(),
758 SYNTAX_AS_SLICE_MUT }
763 #[derive(Debug, Clone)]
764 pub enum SyntaxVariant<T, V> {
767 SyntaxList(Vec<Syntax<T, V>>),
770 impl<'a, T, V> SyntaxChildrenIterator<'a, T, V> {
771 pub fn next_impl(&mut self, direction : bool) -> Option<&'a Syntax<T, V>> {
772 use SyntaxVariant::*;
773 let get_index = |len| {
774 let back_index_plus_1 = len - self.index_back;
775 if back_index_plus_1 <= self.index {
781 Some (back_index_plus_1 - 1)
784 let res = match &self.syntax {
787 SyntaxList(elems) => {
788 get_index(elems.len()).and_then(|x| elems.get(x))
794 self.index = self.index + 1
796 self.index_back = self.index_back + 1
804 let full_fidelity_syntax =
805 Full_fidelity_schema.make_template_file
808 { pattern
= "SYNTAX_VARIANT"; func
= to_syntax_variant };
809 { pattern
= "SYNTAX_CHILDREN"; func
= to_syntax_variant_children };
810 { pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors };
811 { pattern
= "ITER_CHILDREN"; func
= to_iter_children };
812 { pattern
= "FOLD_OVER_CHILDREN_OWNED"; func
= fold_over_owned };
813 { pattern
= "TO_KIND"; func
= to_kind };
814 { pattern
= "SYNTAX_FROM_CHILDREN"; func
= to_syntax_from_children };
815 { pattern
= "SYNTAX_AS_SLICE"; func
= syntax_as_slice };
816 { pattern
= "SYNTAX_AS_SLICE_MUT"; func
= syntax_as_slice_mut };
818 ~filename
:(full_fidelity_path_prefix ^
"syntax_generated.rs")
819 ~
template:full_fidelity_syntax_template
823 (* GenerateFFRustSyntax *)
825 module GenerateFFRustSyntaxType
= struct
828 " SyntaxVariant::%s {..} => SyntaxKind::%s,\n"
833 let mapper prefix
(f
, _
) = sprintf
"&*%s_%s" prefix f
in
835 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
837 let mapper prefix
(f
, _
) = sprintf
"ref %s_%s" prefix f
in
839 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
849 let into_children x
=
850 let mapper prefix
(f
, _
) = sprintf
"x.%s_%s" prefix f
in
852 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
855 " SyntaxVariant::%s (x) => { vec!(
862 let mapper prefix
(f
, _
) = sprintf
"let acc = f(&x.%s_%s, acc)" prefix f
in
864 map_and_concat_separated
";\n " (mapper x
.prefix
) x
.fields
867 " SyntaxVariant::%s(x) => {
874 let to_syntax_constructors x
=
875 let mapper prefix
(f
, _
) = sprintf
"%s_%s: Self" prefix f
in
876 let args = map_and_concat_separated
", " (mapper x
.prefix
) x
.fields in
877 sprintf
" fn make_%s(ctx: &C, %s) -> Self;\n" x
.type_name args
879 let full_fidelity_syntax_template =
880 make_header CStyle
""
882 use crate::syntax::*;
884 pub trait SyntaxType<C>: SyntaxTypeBase<C>
890 let full_fidelity_syntax =
891 Full_fidelity_schema.make_template_file
893 [{ pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors }]
894 ~filename
:(full_fidelity_path_prefix ^
"syntax_type.rs")
895 ~
template:full_fidelity_syntax_template
899 (* GenerateFFRustSyntaxType *)
901 module GenerateFFSyntaxSig
= struct
902 let to_constructor_methods x
=
903 let mapper1 (_f
, _
) = " t ->" in
904 let fields1 = map_and_concat
mapper1 x
.fields in
905 sprintf
" val make_%s :%s t\n" x
.type_name fields1
907 let to_type_tests x
= sprintf
" val is_%s : t -> bool\n" x
.type_name
910 let field_width = 50 - String.length x
.prefix
in
911 let fmt = sprintf
"%s_%%-%ds: t\n" x
.prefix
field_width in
912 let mapper (f
, _
) = sprintf
(Scanf.format_from_string
fmt "%-1s") f
in
913 let fields = map_and_concat_separated
" ; " mapper x
.fields in
915 (" | " ^^
kind_name_fmt ^^
" of\n { %s }\n")
919 let full_fidelity_syntax_template : string =
923 * This module contains a signature which can be used to describe the public
924 * surface area of a constructable syntax tree.
928 module TriviaKind = Full_fidelity_trivia_kind
929 module TokenKind = Full_fidelity_token_kind
931 module type Syntax_S = sig
932 module Token : Lexable_token_sig.LexableToken_S
933 type value [@@deriving show, eq, sexp_of]
934 type t = { syntax : syntax ; value : value } [@@deriving show, eq, sexp_of]
938 | SyntaxList of t list
943 Full_fidelity_source_text.t ->
944 Full_fidelity_parser_env.t ->
945 unit * t * Full_fidelity_syntax_error.t list * Rust_pointer.t option
946 val rust_parser_errors :
947 Full_fidelity_source_text.t ->
949 ParserOptions.ffi_t ->
950 Full_fidelity_syntax_error.t list
951 val has_leading_trivia : TriviaKind.t -> Token.t -> bool
952 val to_json : ?with_value:bool -> ?ignore_missing:bool -> t -> Hh_json.json
953 val extract_text : t -> string option
954 val is_in_body : t -> int -> bool
955 val syntax_node_to_list : t -> t list
957 val full_width : t -> int
958 val trailing_width : t -> int
959 val leading_width : t -> int
960 val leading_token : t -> Token.t option
961 val children : t -> t list
962 val syntax : t -> syntax
963 val kind : t -> Full_fidelity_syntax_kind.t
964 val value : t -> value
965 val make_token : Token.t -> t
966 val get_token : t -> Token.t option
967 val all_tokens : t -> Token.t list
968 val make_missing : Full_fidelity_source_text.t -> int -> t
969 val make_list : Full_fidelity_source_text.t -> int -> t list -> t
970 val is_namespace_prefix : t -> bool
971 val syntax_list_fold : init:'a -> f:('a -> t -> 'a) -> t -> 'a
974 val position : Relative_path.t -> t -> Pos.t option
975 val offset : t -> int option
976 val is_missing : t -> bool
977 val is_list : t -> bool
980 val is_specific_token : TokenKind.t -> t -> bool
981 val is_loop_statement : t -> bool
982 val is_external : t -> bool
983 val is_name : t -> bool
984 val is_construct : t -> bool
985 val is_static : t -> bool
986 val is_private : t -> bool
987 val is_public : t -> bool
988 val is_protected : t -> bool
989 val is_abstract : t -> bool
990 val is_final : t -> bool
991 val is_async : t -> bool
992 val is_void : t -> bool
993 val is_left_brace : t -> bool
994 val is_ellipsis : t -> bool
995 val is_comma : t -> bool
996 val is_ampersand : t -> bool
997 val is_inout : t -> bool
1003 let full_fidelity_syntax_sig =
1004 Full_fidelity_schema.make_template_file
1007 { pattern
= "SYNTAX"; func
= to_syntax };
1008 { pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods };
1009 { pattern
= "TYPE_TESTS"; func
= to_type_tests };
1011 ~filename
:(full_fidelity_path_prefix ^
"syntax_sig.ml")
1012 ~
template:full_fidelity_syntax_template
1016 (* GenerateFFSyntaxSig *)
1018 module GenerateFFSmartConstructors
= struct
1019 let full_fidelity_smart_constructors_template : string =
1023 * This module contains a signature which can be used to describe smart
1028 module ParserEnv = Full_fidelity_parser_env
1030 module type SmartConstructors_S = sig
1031 module Token : Lexable_token_sig.LexableToken_S
1033 type t (* state *) [@@deriving show, sexp_of]
1035 type r (* smart constructor return type *) [@@deriving show]
1038 Full_fidelity_source_text.t ->
1040 t * r * Full_fidelity_syntax_error.t list * Rust_pointer.t option
1042 val initial_state : ParserEnv.t -> t
1046 let full_fidelity_smart_constructors =
1047 Full_fidelity_schema.make_template_file
1050 (full_fidelity_path_prefix ^
"smart_constructors/smartConstructors.ml")
1051 ~
template:full_fidelity_smart_constructors_template
1055 (* GenerateFFSmartConstructors *)
1057 module GenerateFFRustSmartConstructors
= struct
1058 let to_make_methods x
=
1060 List.mapi x
.fields ~f
:(fun i _
->
1061 "arg" ^ string_of_int i ^
": Self::Output")
1063 let stack = String.concat ~sep
:", " fields in
1064 sprintf
" fn make_%s(&mut self, %s) -> Self::Output;\n" x
.type_name stack
1066 let full_fidelity_smart_constructors_template : string =
1067 make_header CStyle
""
1069 use parser_core_types::token_factory::TokenFactory;
1070 use parser_core_types::lexable_token::LexableToken;
1072 pub type Token<S> = <<S as SmartConstructors>::Factory as TokenFactory>::Token;
1073 pub type Trivia<S> = <Token<S> as LexableToken>::Trivia;
1075 pub trait SmartConstructors: Clone {
1076 type Factory: TokenFactory;
1080 fn state_mut(&mut self) -> &mut Self::State;
1081 fn into_state(self) -> Self::State;
1082 fn token_factory_mut(&mut self) -> &mut Self::Factory;
1084 fn make_missing(&mut self, offset : usize) -> Self::Output;
1085 fn make_token(&mut self, arg0: Token<Self>) -> Self::Output;
1086 fn make_list(&mut self, arg0: Vec<Self::Output>, offset: usize) -> Self::Output;
1088 fn begin_enumerator(&mut self) {}
1089 fn begin_enum_class_enumerator(&mut self) {}
1090 fn begin_constant_declarator(&mut self) {}
1096 let full_fidelity_smart_constructors =
1097 Full_fidelity_schema.make_template_file
1098 ~transformations
:[{ pattern
= "MAKE_METHODS"; func
= to_make_methods }]
1099 ~filename
:(full_fidelity_path_prefix ^
"smart_constructors_generated.rs")
1100 ~
template:full_fidelity_smart_constructors_template
1104 (* GenerateFFRustSmartConstructors *)
1106 module GenerateFFRustPositionedSmartConstructors
= struct
1107 let to_constructor_methods x
=
1109 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1111 let args = String.concat ~sep
:", " args in
1112 let fwd_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1113 let fwd_args = String.concat ~sep
:", " fwd_args in
1115 " fn make_%s(&mut self, %s) -> Self::Output {
1116 <Self as SyntaxSmartConstructors<S, TF, St>>::make_%s(self, %s)
1123 let positioned_smart_constructors_template : string =
1124 make_header CStyle
""
1128 use parser_core_types::{
1130 lexable_token::LexableToken,
1131 token_factory::TokenFactory,
1133 use smart_constructors::SmartConstructors;
1134 use syntax_smart_constructors::{SyntaxSmartConstructors, StateType};
1137 pub struct PositionedSmartConstructors<S, TF, St: StateType<S>> {
1140 phantom_s: std::marker::PhantomData<S>,
1143 impl<S, TF, St: StateType<S>> PositionedSmartConstructors<S, TF, St> {
1144 pub fn new(state: St, token_factory: TF) -> Self {
1145 Self { state, token_factory, phantom_s: std::marker::PhantomData }
1149 impl<S, TF, St> SyntaxSmartConstructors<S, TF, St> for PositionedSmartConstructors<S, TF, St>
1151 TF: TokenFactory<Token = S::Token>,
1153 S: SyntaxType<St> + Clone,
1154 S::Token: LexableToken,
1157 impl<S, TF, St> SmartConstructors for PositionedSmartConstructors<S, TF, St>
1159 TF: TokenFactory<Token = S::Token>,
1160 S::Token: LexableToken,
1161 S: SyntaxType<St> + Clone,
1168 fn state_mut(&mut self) -> &mut St {
1172 fn into_state(self) -> St {
1176 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1177 &mut self.token_factory
1180 fn make_missing(&mut self, offset: usize) -> Self::Output {
1181 <Self as SyntaxSmartConstructors<S, TF, St>>::make_missing(self, offset)
1184 fn make_token(&mut self, offset: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1185 <Self as SyntaxSmartConstructors<S, TF, St>>::make_token(self, offset)
1188 fn make_list(&mut self, lst: Vec<Self::Output>, offset: usize) -> Self::Output {
1189 <Self as SyntaxSmartConstructors<S, TF, St>>::make_list(self, lst, offset)
1191 CONSTRUCTOR_METHODS}
1194 let positioned_smart_constructors =
1195 Full_fidelity_schema.make_template_file
1197 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1198 ~filename
:(full_fidelity_path_prefix ^
"positioned_smart_constructors.rs")
1199 ~
template:positioned_smart_constructors_template
1203 module GenerateFFSyntaxSmartConstructors
= struct
1204 let full_fidelity_syntax_smart_constructors_template : string =
1208 * This module contains smart constructors implementation that can be used to
1214 module type SC_S = SmartConstructors.SmartConstructors_S
1216 module ParserEnv = Full_fidelity_parser_env
1218 module type State_S = sig
1219 type r [@@deriving show]
1221 type t [@@deriving show, sexp_of]
1223 val initial : ParserEnv.t -> t
1225 val next : t -> r list -> t
1228 module type RustParser_S = sig
1234 Full_fidelity_source_text.t ->
1236 t * r * Full_fidelity_syntax_error.t list * Rust_pointer.t option
1239 module WithSyntax (Syntax : Syntax_sig.Syntax_S) = struct
1240 module WithState (State : State_S with type r = Syntax.t) = struct
1241 module WithRustParser
1242 (RustParser : RustParser_S with type t = State.t with type r = Syntax.t) =
1244 module Token = Syntax.Token
1246 type t = State.t [@@deriving show, sexp_of]
1248 type r = Syntax.t [@@deriving show]
1250 let rust_parse = RustParser.rust_parse
1252 let initial_state = State.initial
1256 include WithState (struct
1257 type r = Syntax.t [@@deriving show]
1259 type t = unit [@@deriving show, sexp_of]
1266 include WithRustParser (struct
1271 let rust_parse = Syntax.rust_parse
1276 let full_fidelity_syntax_smart_constructors =
1277 Full_fidelity_schema.make_template_file
1280 (full_fidelity_path_prefix
1281 ^
"smart_constructors/syntaxSmartConstructors.ml")
1282 ~
template:full_fidelity_syntax_smart_constructors_template
1286 (* GenerateFFSyntaxSmartConstructors *)
1288 module GenerateFFRustSyntaxSmartConstructors
= struct
1289 let to_constructor_methods x
=
1291 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d : Self::Output" i
)
1293 let params = String.concat ~sep
:", " params in
1294 let args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1295 let args = String.concat ~sep
:", " args in
1296 let next_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"&arg%d" i
) in
1297 let next_args = String.concat ~sep
:", " next_args in
1299 " fn make_%s(&mut self, %s) -> Self::Output {
1300 self.state_mut().next(&[%s]);
1301 Self::Output::make_%s(self.state_mut(), %s)
1309 let full_fidelity_syntax_smart_constructors_template : string =
1310 make_header CStyle
""
1312 use parser_core_types::{
1314 token_factory::TokenFactory,
1316 use smart_constructors::{NoState, SmartConstructors};
1317 use crate::StateType;
1319 pub trait SyntaxSmartConstructors<S: SyntaxType<St>, TF: TokenFactory<Token = S::Token>, St = NoState>:
1320 SmartConstructors<State = St, Output=S, Factory = TF>
1324 fn make_missing(&mut self, offset: usize) -> Self::Output {
1325 let r = Self::Output::make_missing(self.state_mut(), offset);
1326 self.state_mut().next(&[]);
1330 fn make_token(&mut self, arg: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1331 let r = Self::Output::make_token(self.state_mut(), arg);
1332 self.state_mut().next(&[]);
1336 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1337 if items.is_empty() {
1338 <Self as SyntaxSmartConstructors<S, TF, St>>::make_missing(self, offset)
1340 let item_refs: Vec<_> = items.iter().collect();
1341 self.state_mut().next(&item_refs);
1342 Self::Output::make_list(self.state_mut(), items, offset)
1346 CONSTRUCTOR_METHODS}
1349 let full_fidelity_syntax_smart_constructors =
1350 Full_fidelity_schema.make_template_file
1352 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1354 (full_fidelity_path_prefix ^
"syntax_smart_constructors_generated.rs")
1355 ~
template:full_fidelity_syntax_smart_constructors_template
1359 (* GenerateFFRustSyntaxSmartConstructors *)
1361 module GenerateFFRustDeclModeSmartConstructors
= struct
1362 let to_constructor_methods x
=
1364 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1366 let args = String.concat ~sep
:", " args in
1367 let fwd_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1368 let fwd_args = String.concat ~sep
:", " fwd_args in
1370 " fn make_%s(&mut self, %s) -> Self::Output {
1371 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_%s(self, %s)
1378 let decl_mode_smart_constructors_template : string =
1379 make_header CStyle
""
1381 use parser_core_types::{
1382 lexable_token::LexableToken, syntax::SyntaxValueType, syntax_by_ref::syntax::Syntax,
1383 token_factory::TokenFactory,
1385 use smart_constructors::SmartConstructors;
1386 use syntax_smart_constructors::SyntaxSmartConstructors;
1389 impl<'s, 'a, Token, Value, TF> SmartConstructors
1390 for DeclModeSmartConstructors<'s, 'a, Syntax<'a, Token, Value>, Token, Value, TF>
1392 TF: TokenFactory<Token = SyntaxToken<'s, 'a, Token, Value>>,
1393 Token: LexableToken + Copy,
1394 Value: SyntaxValueType<Token> + Clone,
1396 type State = State<'s, 'a, Syntax<'a, Token, Value>>;
1398 type Output = Syntax<'a, Token, Value>;
1400 fn state_mut(&mut self) -> &mut State<'s, 'a, Syntax<'a, Token, Value>> {
1404 fn into_state(self) -> State<'s, 'a, Syntax<'a, Token, Value>> {
1408 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1409 &mut self.token_factory
1412 fn make_missing(&mut self, o: usize) -> Self::Output {
1413 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_missing(self, o)
1416 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1417 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_token(self, token)
1420 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1421 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_list(self, items, offset)
1424 CONSTRUCTOR_METHODS}
1427 let decl_mode_smart_constructors =
1428 Full_fidelity_schema.make_template_file
1430 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1432 (full_fidelity_path_prefix ^
"decl_mode_smart_constructors_generated.rs")
1433 ~
template:decl_mode_smart_constructors_template
1437 (* GenerateFFRustDeclModeSmartConstructors *)
1439 module GenerateRustFlattenSmartConstructors
= struct
1440 let to_constructor_methods x
=
1442 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1444 let args = String.concat ~sep
:", " args in
1446 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"Self::is_zero(&arg%d)" i
)
1448 let if_cond = String.concat ~sep
:" && " if_cond in
1449 let flatten_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1450 let flatten_args = String.concat ~sep
:", " flatten_args in
1452 " fn make_%s(&mut self, %s) -> Self::Output {
1454 Self::zero(SyntaxKind::%s)
1456 self.flatten(SyntaxKind::%s, vec!(%s))
1466 let flatten_smart_constructors_template : string =
1467 make_header CStyle
""
1469 use smart_constructors::SmartConstructors;
1470 use parser_core_types::{
1471 lexable_token::LexableToken,
1472 syntax_kind::SyntaxKind,
1473 token_factory::TokenFactory,
1476 pub trait FlattenSmartConstructors: SmartConstructors
1478 fn is_zero(s: &Self::Output) -> bool;
1479 fn zero(kind: SyntaxKind) -> Self::Output;
1480 fn flatten(&self, kind: SyntaxKind, lst: Vec<Self::Output>) -> Self::Output;
1482 fn make_missing(&mut self, _: usize) -> Self::Output {
1483 Self::zero(SyntaxKind::Missing)
1486 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1487 Self::zero(SyntaxKind::Token(token.kind()))
1490 fn make_list(&mut self, _: Vec<Self::Output>, _: usize) -> Self::Output {
1491 Self::zero(SyntaxKind::SyntaxList)
1494 fn begin_enumerator(&mut self) {}
1496 fn begin_enum_class_enumerator(&mut self) {}
1498 fn begin_constant_declarator(&mut self) {}
1500 CONSTRUCTOR_METHODS}
1503 let flatten_smart_constructors =
1504 Full_fidelity_schema.make_template_file
1506 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1507 ~filename
:(full_fidelity_path_prefix ^
"flatten_smart_constructors.rs")
1508 ~
template:flatten_smart_constructors_template
1512 (* GenerateRustFlattenSmartConstructors *)
1514 module GenerateRustDirectDeclSmartConstructors
= struct
1515 let to_constructor_methods x
=
1517 List.map x
.fields ~f
:(fun (name
, _
) ->
1518 sprintf
"%s: Self::Output" (escape_rust_keyword name
))
1520 let args = String.concat ~sep
:", " args in
1522 List.map x
.fields ~f
:(fun (name
, _
) -> escape_rust_keyword name
)
1524 let fwd_args = String.concat ~sep
:", " fwd_args in
1526 " fn make_%s(&mut self, %s) -> Self::Output {
1527 <Self as FlattenSmartConstructors>::make_%s(self, %s)
1534 let direct_decl_smart_constructors_template : string =
1535 make_header CStyle
""
1537 use flatten_smart_constructors::*;
1538 use parser_core_types::compact_token::CompactToken;
1539 use parser_core_types::token_factory::SimpleTokenFactoryImpl;
1540 use smart_constructors::SmartConstructors;
1542 use crate::{DirectDeclSmartConstructors, Node, SourceTextAllocator};
1544 impl<'a, 'o, 't, S: SourceTextAllocator<'t, 'a>> SmartConstructors for DirectDeclSmartConstructors<'a, 'o, 't, S> {
1546 type Factory = SimpleTokenFactoryImpl<CompactToken>;
1547 type Output = Node<'a>;
1549 fn state_mut(&mut self) -> &mut Self {
1553 fn into_state(self) -> Self {
1557 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1558 &mut self.token_factory
1561 fn make_missing(&mut self, offset: usize) -> Self::Output {
1562 <Self as FlattenSmartConstructors>::make_missing(self, offset)
1565 fn make_token(&mut self, token: CompactToken) -> Self::Output {
1566 <Self as FlattenSmartConstructors>::make_token(self, token)
1569 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1570 <Self as FlattenSmartConstructors>::make_list(self, items, offset)
1573 fn begin_enumerator(&mut self) {
1574 <Self as FlattenSmartConstructors>::begin_enumerator(self)
1577 fn begin_enum_class_enumerator(&mut self) {
1578 <Self as FlattenSmartConstructors>::begin_enum_class_enumerator(self)
1581 fn begin_constant_declarator(&mut self) {
1582 <Self as FlattenSmartConstructors>::begin_constant_declarator(self)
1587 CONSTRUCTOR_METHODS}
1590 let direct_decl_smart_constructors =
1591 Full_fidelity_schema.make_template_file
1593 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1595 (full_fidelity_path_prefix
1596 ^
"../decl/direct_decl_smart_constructors_generated.rs")
1597 ~
template:direct_decl_smart_constructors_template
1601 (* GenerateRustDirectDeclSmartConstructors *)
1603 module GenerateRustPairSmartConstructors
= struct
1604 let to_constructor_methods x
=
1606 List.map x
.fields ~f
:(fun (name
, _
) ->
1607 sprintf
"%s: Self::Output" (escape_rust_keyword name
))
1609 let args = String.concat ~sep
:", " args in
1611 List.map x
.fields ~f
:(fun (name
, _
) -> escape_rust_keyword name
)
1614 List.map
fwd_args ~f
:(fun name
-> name ^
"." ^ idx
)
1615 |> String.concat ~sep
:", "
1618 " fn make_%s(&mut self, %s) -> Self::Output {
1619 Node(self.0.make_%s(%s), self.1.make_%s(%s))
1628 let pair_smart_constructors_template : string =
1629 make_header CStyle
""
1632 use parser_core_types::token_factory::TokenFactory;
1633 use smart_constructors::{NodeType, SmartConstructors};
1635 use crate::{PairTokenFactory, Node};
1638 pub struct PairSmartConstructors<SC0, SC1>(pub SC0, pub SC1, PairTokenFactory<SC0::Factory, SC1::Factory>)
1640 SC0: SmartConstructors,
1641 SC0::Output: NodeType,
1642 SC1: SmartConstructors,
1643 SC1::Output: NodeType;
1645 impl<SC0, SC1> PairSmartConstructors<SC0, SC1>
1647 SC0: SmartConstructors,
1648 SC0::Output: NodeType,
1649 SC1: SmartConstructors,
1650 SC1::Output: NodeType,
1652 pub fn new(mut sc0: SC0, mut sc1: SC1) -> Self {
1653 let tf0 = sc0.token_factory_mut().clone();
1654 let tf1 = sc1.token_factory_mut().clone();
1655 let tf = PairTokenFactory::new(tf0, tf1);
1660 impl<SC0, SC1> SmartConstructors for PairSmartConstructors<SC0, SC1>
1662 SC0: SmartConstructors,
1663 SC0::Output: NodeType,
1664 SC1: SmartConstructors,
1665 SC1::Output: NodeType,
1668 type Factory = PairTokenFactory<SC0::Factory, SC1::Factory>;
1669 type Output = Node<SC0::Output, SC1::Output>;
1671 fn state_mut(&mut self) -> &mut Self {
1675 fn into_state(self) -> Self {
1679 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1683 fn make_missing(&mut self, offset: usize) -> Self::Output {
1684 Node(self.0.make_missing(offset), self.1.make_missing(offset))
1687 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1688 Node(self.0.make_token(token.0), self.1.make_token(token.1))
1691 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1692 let (items0, items1) = items.into_iter().map(|n| (n.0, n.1)).unzip();
1693 Node(self.0.make_list(items0, offset), self.1.make_list(items1, offset))
1696 CONSTRUCTOR_METHODS}
1699 let pair_smart_constructors =
1700 Full_fidelity_schema.make_template_file
1702 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1704 (full_fidelity_path_prefix ^
"pair_smart_constructors_generated.rs")
1705 ~
template:pair_smart_constructors_template
1709 (* GenerateRustPairSmartConstructors *)
1711 module GenerateFFSmartConstructorsWrappers
= struct
1712 let full_fidelity_smart_constructors_wrappers_template : string =
1716 * This module contains smart constructors implementation that can be used to
1721 module type SC_S = SmartConstructors.SmartConstructors_S
1723 module SK = Full_fidelity_syntax_kind
1725 module type SyntaxKind_S = sig
1728 type original_sc_r [@@deriving show]
1731 module SyntaxKind (SC : SC_S) :
1733 with module Token = SC.Token
1734 and type original_sc_r = SC.r
1735 and type t = SC.t = struct
1736 module Token = SC.Token
1738 type original_sc_r = SC.r [@@deriving show]
1740 type t = SC.t [@@deriving show, sexp_of]
1742 type r = SK.t * SC.r [@@deriving show]
1744 let compose : SK.t -> t * SC.r -> t * r =
1745 (fun kind (state, res) -> (state, (kind, res)))
1747 let rust_parse text env =
1748 let (state, res, errors, pointer) = SC.rust_parse text env in
1749 let (state, res) = compose SK.Script (state, res) in
1750 (state, res, errors, pointer)
1752 let initial_state = SC.initial_state
1756 let full_fidelity_smart_constructors_wrappers =
1757 Full_fidelity_schema.make_template_file
1760 (full_fidelity_path_prefix
1761 ^
"smart_constructors/smartConstructorsWrappers.ml")
1762 ~
template:full_fidelity_smart_constructors_wrappers_template
1766 (* GenerateFFSmartConstructorsWrappers *)
1768 module GenerateFFRustSmartConstructorsWrappers
= struct
1769 let to_constructor_methods x
=
1771 List.mapi x
.fields ~f
:(fun i _
->
1772 "arg" ^ string_of_int i ^
" : Self::Output")
1774 let params = String.concat ~sep
:", " params in
1775 let args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1776 let raw_args = map_and_concat_separated
", " (fun x
-> x ^
".1") args in
1778 " fn make_%s(&mut self, %s) -> Self::Output {
1779 compose(SyntaxKind::%s, self.s.make_%s(%s))
1787 let full_fidelity_smart_constructors_wrappers_template : string =
1788 make_header CStyle
""
1790 // This module contains smart constructors implementation that can be used to
1794 use parser_core_types::{
1795 lexable_token::LexableToken,
1796 syntax_kind::SyntaxKind,
1797 token_factory::TokenFactory,
1799 use crate::SmartConstructors;
1802 pub struct WithKind<S> {
1806 impl<S> WithKind<S> {
1807 pub fn new(s: S) -> Self {
1812 impl<S, St> SmartConstructors for WithKind<S>
1813 where S: SmartConstructors<State = St>,
1815 type Factory = S::Factory;
1817 type Output = (SyntaxKind, S::Output);
1819 fn state_mut(&mut self) -> &mut St {
1823 fn into_state(self) -> St {
1827 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1828 self.s.token_factory_mut()
1832 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1833 compose(SyntaxKind::Token(token.kind()), self.s.make_token(token))
1836 fn make_missing(&mut self, p: usize) -> Self::Output {
1837 compose(SyntaxKind::Missing, self.s.make_missing(p))
1840 fn make_list(&mut self, items: Vec<Self::Output>, p: usize) -> Self::Output {
1841 let kind = if items.is_empty() {
1844 SyntaxKind::SyntaxList
1846 compose(kind, self.s.make_list(items.into_iter().map(|x| x.1).collect(), p))
1853 fn compose<R>(kind: SyntaxKind, r: R) -> (SyntaxKind, R) {
1858 let full_fidelity_smart_constructors_wrappers =
1859 Full_fidelity_schema.make_template_file
1861 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1862 ~filename
:(full_fidelity_path_prefix ^
"smart_constructors_wrappers.rs")
1863 ~
template:full_fidelity_smart_constructors_wrappers_template
1867 (* GenerateFFRustSmartConstructorsWrappers *)
1869 module GenerateFFSyntax
= struct
1872 (" | " ^^
kind_name_fmt ^^
" _ -> SyntaxKind.%s\n")
1876 let to_type_tests x
=
1878 (" let is_" ^^
type_name_fmt ^^
" = has_kind SyntaxKind.%s\n")
1883 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1884 let fields = map_and_concat
mapper x
.fields in
1886 " | %s {\n%s } -> [\n%s ]\n"
1891 let to_fold_from_syntax x
=
1892 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1893 let fields = map_and_concat
mapper x
.fields in
1894 let mapper2 (f
, _
) =
1895 sprintf
" let acc = f acc %s_%s in\n" x
.prefix f
1897 let fields2 = map_and_concat
mapper2 x
.fields in
1899 " | %s {\n%s } ->\n%s acc\n"
1904 let to_children_names x
=
1905 let mapper1 (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1906 let mapper2 (f
, _
) = sprintf
" \"%s_%s\";\n" x
.prefix f
in
1907 let fields1 = map_and_concat
mapper1 x
.fields in
1908 let fields2 = map_and_concat
mapper2 x
.fields in
1910 " | %s {\n%s } -> [\n%s ]\n"
1915 let to_syntax_from_children x
=
1916 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1917 let fields = map_and_concat
mapper x
.fields in
1919 " | (SyntaxKind.%s, [
1929 let to_constructor_methods x
=
1930 let mapper1 (f
, _
) = sprintf
" %s_%s\n" x
.prefix f
in
1931 let fields1 = map_and_concat
mapper1 x
.fields in
1932 let mapper2 (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1933 let fields2 = map_and_concat
mapper2 x
.fields in
1939 let value = ValueBuilder.value_from_syntax syntax in
1948 let to_from_methods x
=
1949 if omit_syntax_record x
then
1952 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1953 let fields = map_and_concat
mapper x
.fields in
1964 let to_get_methods x
=
1965 if omit_syntax_record x
then
1968 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1969 let fields = map_and_concat
mapper x
.fields in
1973 | %s {\n%s } -> {\n%s }
1974 | _ -> failwith \"get_%s: not a %s\"
1983 let full_fidelity_syntax_template =
1987 * With these factory methods, nodes can be built up from their child nodes. A
1988 * factory method must not just know all the children and the kind of node it is
1989 * constructing; it also must know how to construct the value that this node is
1990 * going to be tagged with. For that reason, an optional functor is provided.
1991 * This functor requires that methods be provided to construct the values
1992 * associated with a token or with any arbitrary node, given its children. If
1993 * this functor is used then the resulting module contains factory methods.
1995 * This module also provides some useful helper functions, like an iterator,
1996 * a rewriting visitor, and so on."
2000 open Full_fidelity_syntax_type
2002 module SyntaxKind = Full_fidelity_syntax_kind
2003 module TokenKind = Full_fidelity_token_kind
2004 module Operator = Full_fidelity_operator
2005 [@@@warning \"-27\"] (* unused variable *)
2007 module WithToken(Token: TokenType) = struct
2008 module WithSyntaxValue(SyntaxValue: SyntaxValueType) = struct
2010 include MakeSyntaxType(Token)(SyntaxValue)
2012 let make syntax value =
2021 let syntax_node_to_list node =
2022 match syntax node with
2027 let to_kind syntax =
2029 | Missing -> SyntaxKind.Missing
2030 | Token t -> SyntaxKind.Token (Token.kind t)
2031 | SyntaxList _ -> SyntaxKind.SyntaxList
2035 to_kind (syntax node)
2037 let has_kind syntax_kind node =
2038 SyntaxKind.equal (kind node) syntax_kind
2040 let is_missing node =
2041 match kind node with
2042 | SyntaxKind.Missing -> true
2046 match kind node with
2047 | SyntaxKind.SyntaxList -> true
2052 let is_loop_statement node =
2053 is_for_statement node ||
2054 is_foreach_statement node ||
2055 is_while_statement node ||
2056 is_do_statement node
2058 let is_separable_prefix node =
2059 match syntax node with
2061 TokenKind.(match Token.kind t with
2062 | PlusPlus | MinusMinus -> false
2066 let is_specific_token kind node =
2067 match syntax node with
2068 | Token t -> TokenKind.equal (Token.kind t) kind
2071 let is_namespace_prefix node =
2072 match syntax node with
2073 | QualifiedName e ->
2074 begin match List.last (syntax_node_to_list e.qualified_name_parts) with
2077 begin match syntax p with
2078 | ListItem p -> not (is_missing p.list_separator)
2084 let has_leading_trivia kind token =
2085 List.exists (Token.leading token)
2087 Full_fidelity_trivia_kind.equal (Token.Trivia.kind trivia) kind)
2090 is_specific_token TokenKind.Semicolon e || is_missing e
2092 let is_name = is_specific_token TokenKind.Name
2093 let is_construct = is_specific_token TokenKind.Construct
2094 let is_static = is_specific_token TokenKind.Static
2095 let is_private = is_specific_token TokenKind.Private
2096 let is_public = is_specific_token TokenKind.Public
2097 let is_protected = is_specific_token TokenKind.Protected
2098 let is_abstract = is_specific_token TokenKind.Abstract
2099 let is_final = is_specific_token TokenKind.Final
2100 let is_async = is_specific_token TokenKind.Async
2101 let is_void = is_specific_token TokenKind.Void
2102 let is_left_brace = is_specific_token TokenKind.LeftBrace
2103 let is_ellipsis = is_specific_token TokenKind.DotDotDot
2104 let is_comma = is_specific_token TokenKind.Comma
2105 let is_ampersand = is_specific_token TokenKind.Ampersand
2106 let is_inout = is_specific_token TokenKind.Inout
2108 let syntax_list_fold ~init ~f node =
2109 match syntax node with
2113 ~f:(fun init li -> match syntax li with
2114 | ListItem { list_item; _; }-> f init list_item
2121 let fold_over_children f acc syntax =
2125 | SyntaxList items ->
2126 List.fold_left ~f ~init:acc items
2129 (* The order that the children are returned in should match the order
2130 that they appear in the source text *)
2131 let children_from_syntax s =
2139 children_from_syntax node.syntax
2141 let children_names node =
2142 match node.syntax with
2145 | SyntaxList _ -> []
2148 let rec to_json_ ?(with_value = false) ?(ignore_missing = false) node =
2150 let ch = match node.syntax with
2151 | Token t -> [ \"token\", Token.to_json t ]
2152 | SyntaxList x -> [ (\"elements\",
2153 JSON_Array (List.filter_map ~f:(to_json_ ~with_value ~ignore_missing) x)) ]
2155 let rec aux acc c n =
2158 | ((hc :: tc), (hn :: tn)) ->
2159 let result = (to_json_ ~with_value ~ignore_missing) hc in
2161 | Some r -> aux ((hn, r):: acc) tc tn
2162 | None -> aux acc tc tn)
2163 | _ -> failwith \"mismatch between children and names\" in
2164 List.rev (aux [] (children node) (children_names node)) in
2165 let k = (\"kind\", JSON_String (SyntaxKind.to_string (kind node))) in
2166 let v = if with_value then
2167 (\"value\", SyntaxValue.to_json node.value) :: ch
2169 if ignore_missing && (List.is_empty ch) then None else Some(JSON_Object (k :: v))
2171 let to_json ?(with_value = false) ?(ignore_missing = false) node =
2172 match to_json_ ~with_value ~ignore_missing node with
2174 | None -> Hh_json.JSON_Object([])
2176 let binary_operator_kind b =
2179 let kind = Token.kind token in
2180 if Operator.is_trailing_operator_token kind then
2181 Some (Operator.trailing_from_token kind)
2186 let get_token node =
2187 match (syntax node) with
2188 | Token token -> Some token
2191 let leading_token node =
2196 let token = get_token h in
2197 if Option.is_none token then
2198 let result = aux (children h) in
2199 if Option.is_none result then aux t else result
2204 let trailing_token node =
2209 let token = get_token h in
2210 if Option.is_none token then
2211 let result = aux (List.rev (children h)) in
2212 if Option.is_none result then aux t else result
2217 let syntax_from_children kind ts =
2219 SYNTAX_FROM_CHILDREN | (SyntaxKind.Missing, []) -> Missing
2220 | (SyntaxKind.SyntaxList, items) -> SyntaxList items
2222 \"syntax_from_children called with wrong number of children\"
2224 let all_tokens node =
2225 let rec aux acc nodes =
2231 | Token token -> aux (token :: acc) t
2232 | _ -> aux (aux acc (children h)) t
2234 List.rev (aux [] [node])
2236 module type ValueBuilderType = sig
2237 val value_from_children:
2238 Full_fidelity_source_text.t ->
2240 Full_fidelity_syntax_kind.t ->
2243 val value_from_token: Token.t -> SyntaxValue.t
2244 val value_from_syntax: syntax -> SyntaxValue.t
2247 module WithValueBuilder(ValueBuilder: ValueBuilderType) = struct
2248 let from_children text offset kind ts =
2249 let syntax = syntax_from_children kind ts in
2250 let value = ValueBuilder.value_from_children text offset kind ts in
2253 let make_token token =
2254 let syntax = Token token in
2255 let value = ValueBuilder.value_from_token token in
2258 let make_missing text offset =
2259 from_children text offset SyntaxKind.Missing []
2261 (* An empty list is represented by Missing; everything else is a
2262 SyntaxList, even if the list has only one item. *)
2263 let make_list text offset items =
2265 | [] -> make_missing text offset
2266 | _ -> from_children text offset SyntaxKind.SyntaxList items
2279 let full_fidelity_syntax =
2280 Full_fidelity_schema.make_template_file
2283 { pattern
= "TO_KIND"; func
= to_to_kind };
2284 { pattern
= "TYPE_TESTS"; func
= to_type_tests };
2285 { pattern
= "CHILDREN"; func
= to_children };
2286 { pattern
= "FOLD_FROM_SYNTAX"; func
= to_fold_from_syntax };
2287 { pattern
= "CHILDREN_NAMES"; func
= to_children_names };
2288 { pattern
= "SYNTAX_FROM_CHILDREN"; func
= to_syntax_from_children };
2289 { pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods };
2290 { pattern
= "FROM_METHODS"; func
= to_from_methods };
2291 { pattern
= "GET_METHODS"; func
= to_get_methods };
2293 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_syntax.ml")
2294 ~
template:full_fidelity_syntax_template
2298 module GenerateFFTriviaKind
= struct
2299 let to_trivia { trivia_kind
; trivia_text
= _
} =
2300 sprintf
" | %s\n" trivia_kind
2302 let to_to_string { trivia_kind
; trivia_text
} =
2304 (" | " ^^
trivia_kind_fmt ^^
" -> \"%s\"\n")
2308 let full_fidelity_trivia_kind_template =
2309 make_header MLStyle
""
2314 [@@deriving show, enum, eq, sexp_of]
2316 let to_string kind =
2320 let full_fidelity_trivia_kind =
2321 Full_fidelity_schema.make_template_file
2322 ~trivia_transformations
:
2324 { trivia_pattern
= "TRIVIA"; trivia_func
= map_and_concat
to_trivia };
2326 trivia_pattern
= "TO_STRING";
2327 trivia_func
= map_and_concat
to_to_string;
2330 ~filename
:(full_fidelity_path_prefix ^
"/full_fidelity_trivia_kind.ml")
2331 ~
template:full_fidelity_trivia_kind_template
2335 (* GenerateFFSyntaxKind *)
2337 module GenerateFFRustTriviaKind
= struct
2338 let ocaml_tag = ref (-1)
2340 let to_trivia { trivia_kind
; trivia_text
= _
} =
2342 sprintf
" %s = %d,\n" trivia_kind
!ocaml_tag
2344 let to_to_string { trivia_kind
; trivia_text
} =
2345 sprintf
" TriviaKind::%s => \"%s\",\n" trivia_kind trivia_text
2347 let full_fidelity_trivia_kind_template =
2348 make_header CStyle
""
2351 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2353 #[derive(Debug, Copy, Clone, FromOcamlRep, ToOcamlRep, PartialEq)]
2355 pub enum TriviaKind {
2359 pub fn to_string(&self) -> &str {
2364 pub const fn ocaml_tag(self) -> u8 {
2370 let full_fidelity_trivia_kind =
2371 Full_fidelity_schema.make_template_file
2372 ~trivia_transformations
:
2374 { trivia_pattern
= "TRIVIA"; trivia_func
= map_and_concat
to_trivia };
2376 trivia_pattern
= "TO_STRING";
2377 trivia_func
= map_and_concat
to_to_string;
2380 ~filename
:(full_fidelity_path_prefix ^
"trivia_kind.rs")
2381 ~
template:full_fidelity_trivia_kind_template
2385 (* GenerateFFRustTriviaKind *)
2387 module GenerateFFSyntaxKind
= struct
2388 let to_tokens x
= sprintf
" | %s\n" x
.kind_name
2390 let to_to_string x
=
2392 (" | " ^^
kind_name_fmt ^^
" -> \"%s\"\n")
2396 let full_fidelity_syntax_kind_template =
2397 make_header MLStyle
""
2401 | Token of Full_fidelity_token_kind.t
2405 [@@deriving show, eq]
2407 let to_string kind =
2409 | Token _ -> \"token\"
2410 | Missing -> \"missing\"
2411 | SyntaxList -> \"list\"
2414 let full_fidelity_syntax_kind =
2415 Full_fidelity_schema.make_template_file
2418 { pattern
= "TOKENS"; func
= to_tokens };
2419 { pattern
= "TO_STRING"; func
= to_to_string };
2421 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_syntax_kind.ml")
2422 ~
template:full_fidelity_syntax_kind_template
2426 (* GenerateFFTriviaKind *)
2428 module GenerateFFRustSyntaxKind
= struct
2429 let to_tokens x
= sprintf
" %s,\n" x
.kind_name
2431 let to_to_string x
=
2433 (" SyntaxKind::" ^^
kind_name_fmt ^^
" => \"%s\",\n")
2439 let to_ocaml_tag x
=
2441 sprintf
" SyntaxKind::%s => %d,\n" x
.kind_name
!tag
2443 let full_fidelity_syntax_kind_template =
2444 make_header CStyle
""
2447 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2449 use crate::token_kind::TokenKind;
2451 #[derive(Debug, Copy, Clone, FromOcamlRep, ToOcamlRep, PartialEq)]
2452 pub enum SyntaxKind {
2460 pub fn to_string(&self) -> &str {
2462 SyntaxKind::SyntaxList => \"list\",
2463 SyntaxKind::Missing => \"missing\",
2464 SyntaxKind::Token(_) => \"token\",
2468 pub fn ocaml_tag(self) -> u8 {
2470 SyntaxKind::Missing => 0,
2471 SyntaxKind::Token(_) => 0,
2472 SyntaxKind::SyntaxList => 1,
2478 let full_fidelity_syntax_kind =
2479 Full_fidelity_schema.make_template_file
2482 { pattern
= "TOKENS"; func
= to_tokens };
2483 { pattern
= "TO_STRING"; func
= to_to_string };
2484 { pattern
= "OCAML_TAG"; func
= to_ocaml_tag };
2486 ~filename
:(full_fidelity_path_prefix ^
"syntax_kind.rs")
2487 ~
template:full_fidelity_syntax_kind_template
2491 (* GenerateFFRustSyntaxKind *)
2493 module GenerateFFTokenKind
= struct
2494 let given_text_width =
2495 let folder acc x
= max
acc (String.length x
.token_text
) in
2496 List.fold_left ~f
:folder ~init
:0 given_text_tokens
2498 let to_kind_declaration x
= sprintf
" | %s\n" x
.token_kind
2500 let add_guard_or_pad :
2501 cond
:bool * string -> ?else_cond
:bool * string -> string -> string =
2502 fun ~cond
:(cond
, guard
) ?else_cond guards
->
2503 let pad str
= String.make (String.length str
) ' '
in
2504 let is_only_spaces str
= String.equal str
(pad str
) in
2505 let make_same_length str1 str2
=
2507 try String.make n ' '
with
2508 | Invalid_argument _
-> ""
2510 let (len1
, len2
) = (String.length str1
, String.length str2
) in
2511 let str1 = str1 ^
blanks (len2
- len1
) in
2512 let str2 = str2 ^
blanks (len1
- len2
) in
2515 let (else_cond
, else_guard
) =
2516 match else_cond
with
2517 | Some
(cond
, guard
) -> (cond
, guard
)
2518 | None
-> (false, "")
2521 if cond
|| else_cond
then
2522 if is_only_spaces guards
then
2529 let (guard
, else_guard
) = make_same_length guard else_guard
in
2533 else if else_cond
then
2538 guards ^
prefix ^
guard ^
" "
2540 let to_from_string x
=
2541 let token_text = escape_token_text x
.token_text in
2542 let spacer_width = given_text_width - String.length
token_text in
2543 let spacer = String.make spacer_width ' '
in
2545 add_guard_or_pad "" ~cond
:(x
.allowed_as_identifier
, "not only_reserved")
2547 sprintf
" | \"%s\"%s %s-> Some %s\n" token_text spacer guards x
.token_kind
2549 let to_to_string x
=
2550 let token_text = escape_token_text x
.token_text in
2551 sprintf
(" | " ^^
token_kind_fmt ^^
" -> \"%s\"\n") x
.token_kind
token_text
2553 let to_is_variable_text x
= sprintf
" | %s -> true\n" x
.token_kind
2555 let full_fidelity_token_kind_template =
2556 make_header MLStyle
""
2560 (* No text tokens *)
2561 KIND_DECLARATIONS_NO_TEXT (* Given text tokens *)
2562 KIND_DECLARATIONS_GIVEN_TEXT (* Variable text tokens *)
2563 KIND_DECLARATIONS_VARIABLE_TEXT
2564 [@@deriving show, eq, sexp_of]
2566 let from_string keyword ~only_reserved =
2568 | \"true\" when not only_reserved -> Some BooleanLiteral
2569 | \"false\" when not only_reserved -> Some BooleanLiteral
2570 FROM_STRING_GIVEN_TEXT | _ -> None
2572 let to_string kind =
2574 (* No text tokens *)
2575 TO_STRING_NO_TEXT (* Given text tokens *)
2576 TO_STRING_GIVEN_TEXT (* Variable text tokens *)
2577 TO_STRING_VARIABLE_TEXT
2579 let is_variable_text kind =
2581 IS_VARIABLE_TEXT_VARIABLE_TEXT | _ -> false
2584 let full_fidelity_token_kind =
2585 Full_fidelity_schema.make_template_file
2586 ~token_no_text_transformations
:
2589 token_pattern
= "KIND_DECLARATIONS_NO_TEXT";
2590 token_func
= map_and_concat
to_kind_declaration;
2593 token_pattern
= "TO_STRING_NO_TEXT";
2594 token_func
= map_and_concat
to_to_string;
2597 ~token_given_text_transformations
:
2600 token_pattern
= "KIND_DECLARATIONS_GIVEN_TEXT";
2601 token_func
= map_and_concat
to_kind_declaration;
2604 token_pattern
= "FROM_STRING_GIVEN_TEXT";
2605 token_func
= map_and_concat
to_from_string;
2608 token_pattern
= "TO_STRING_GIVEN_TEXT";
2609 token_func
= map_and_concat
to_to_string;
2612 ~token_variable_text_transformations
:
2615 token_pattern
= "KIND_DECLARATIONS_VARIABLE_TEXT";
2616 token_func
= map_and_concat
to_kind_declaration;
2619 token_pattern
= "TO_STRING_VARIABLE_TEXT";
2620 token_func
= map_and_concat
to_to_string;
2623 token_pattern
= "IS_VARIABLE_TEXT_VARIABLE_TEXT";
2624 token_func
= map_and_concat
to_is_variable_text;
2627 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_token_kind.ml")
2628 ~
template:full_fidelity_token_kind_template
2632 (* GenerateFFTokenKind *)
2634 module GenerateFFRustTokenKind
= struct
2636 match x
.token_kind with
2637 | "Self" -> "SelfToken"
2640 let to_from_string x
=
2641 let token_text = escape_token_text x
.token_text in
2643 if x
.allowed_as_identifier
then
2649 if String.equal
guard "" then
2655 " b\"%s\"%s => Some(TokenKind::%s),\n"
2660 let rust_tag = ref (-1)
2662 let to_kind_declaration x
=
2664 sprintf
" %s = %d,\n" (token_kind x
) !rust_tag
2666 let token_text x
= escape_token_text x
.token_text
2668 let to_to_string x
=
2670 " TokenKind::%s => \"%s\",\n"
2674 let ocaml_tag = ref (-1)
2676 let to_ocaml_tag x
=
2678 sprintf
" TokenKind::%s => %d,\n" (token_kind x
) !ocaml_tag
2680 let from_u8_tag = ref (-1)
2682 let to_try_from_u8 x
=
2685 " %d => Some(TokenKind::%s),\n"
2691 if String.equal
(token_kind x
) "Backslash" then
2694 String.length
(token_text x
)
2698 " TokenKind::%s => Some(unsafe { NonZeroUsize::new_unchecked(%d) }),\n"
2702 let full_fidelity_rust_token_kind_template =
2703 make_header CStyle
""
2706 use std::num::NonZeroUsize;
2708 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2710 #[allow(non_camel_case_types)] // allow Include_once and Require_once
2711 #[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd, FromOcamlRep, ToOcamlRep)]
2713 pub enum TokenKind {
2715 KIND_DECLARATIONS_NO_TEXT // Given text tokens
2716 KIND_DECLARATIONS_GIVEN_TEXT // Variable text tokens
2717 KIND_DECLARATIONS_VARIABLE_TEXT}
2720 pub fn to_string(self) -> &'static str {
2723 TO_STRING_NO_TEXT // Given text tokens
2724 TO_STRING_GIVEN_TEXT // Variable text tokes
2725 TO_STRING_VARIABLE_TEXT }
2730 only_reserved: bool,
2733 b\"true\" if !only_reserved => Some(TokenKind::BooleanLiteral),
2734 b\"false\" if !only_reserved => Some(TokenKind::BooleanLiteral),
2735 FROM_STRING_GIVEN_TEXT _ => None,
2739 pub fn ocaml_tag(self) -> u8 {
2741 OCAML_TAG_NO_TEXTOCAML_TAG_GIVEN_TEXTOCAML_TAG_VARIABLE_TEXT }
2744 pub fn try_from_u8(tag: u8) -> Option<Self> {
2746 FROM_U8_NO_TEXTFROM_U8_GIVEN_TEXTFROM_U8_VARIABLE_TEXT _ => None,
2750 pub fn fixed_width(self) -> Option<NonZeroUsize> {
2752 WIDTH_GIVEN_TEXT _ => None,
2758 let full_fidelity_token_kind =
2759 Full_fidelity_schema.make_template_file
2760 ~token_no_text_transformations
:
2763 token_pattern
= "KIND_DECLARATIONS_NO_TEXT";
2764 token_func
= map_and_concat
to_kind_declaration;
2767 token_pattern
= "TO_STRING_NO_TEXT";
2768 token_func
= map_and_concat
to_to_string;
2771 token_pattern
= "OCAML_TAG_NO_TEXT";
2772 token_func
= map_and_concat
to_ocaml_tag;
2775 token_pattern
= "FROM_U8_NO_TEXT";
2776 token_func
= map_and_concat
to_try_from_u8;
2779 ~token_given_text_transformations
:
2782 token_pattern
= "KIND_DECLARATIONS_GIVEN_TEXT";
2783 token_func
= map_and_concat
to_kind_declaration;
2786 token_pattern
= "FROM_STRING_GIVEN_TEXT";
2787 token_func
= map_and_concat
to_from_string;
2790 token_pattern
= "TO_STRING_GIVEN_TEXT";
2791 token_func
= map_and_concat
to_to_string;
2794 token_pattern
= "OCAML_TAG_GIVEN_TEXT";
2795 token_func
= map_and_concat
to_ocaml_tag;
2798 token_pattern
= "FROM_U8_GIVEN_TEXT";
2799 token_func
= map_and_concat
to_try_from_u8;
2802 token_pattern
= "WIDTH_GIVEN_TEXT";
2803 token_func
= map_and_concat
to_width;
2806 ~token_variable_text_transformations
:
2809 token_pattern
= "KIND_DECLARATIONS_VARIABLE_TEXT";
2810 token_func
= map_and_concat
to_kind_declaration;
2813 token_pattern
= "TO_STRING_VARIABLE_TEXT";
2814 token_func
= map_and_concat
to_to_string;
2817 token_pattern
= "OCAML_TAG_VARIABLE_TEXT";
2818 token_func
= map_and_concat
to_ocaml_tag;
2821 token_pattern
= "FROM_U8_VARIABLE_TEXT";
2822 token_func
= map_and_concat
to_try_from_u8;
2825 ~filename
:(full_fidelity_path_prefix ^
"token_kind.rs")
2826 ~
template:full_fidelity_rust_token_kind_template
2830 (* GenerateFFTRustTokenKind *)
2832 module GenerateFFOperatorRust
= struct
2834 make_header CStyle
""
2837 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2839 #[derive(FromOcamlRep, ToOcamlRep)]
2844 let full_fidelity_operators =
2845 Full_fidelity_schema.make_template_file
2846 ~operator_transformations
:
2849 operator_pattern
= "OPERATORS";
2851 map_and_concat
(fun op
-> sprintf
" %sOperator,\n" op
.name
);
2854 ~filename
:(full_fidelity_path_prefix ^
"operator_generated.rs")
2859 (* GenerateFFOperatorRust *)
2861 module GenerateFFOperator
= struct
2863 make_header MLStyle
""
2865 module type Sig = sig
2867 OPERATOR_DECL_SIGend
2869 module Impl : Sig = struct
2871 OPERATOR_DECL_IMPLend
2874 let op_pattern prefix op
= sprintf
"%s| %sOperator\n" prefix op
.name
2876 let transform pattern
=
2878 operator_pattern
= pattern
;
2879 operator_func
= map_and_concat
(op_pattern " ");
2882 let full_fidelity_operator =
2883 Full_fidelity_schema.make_template_file
2884 ~operator_transformations
:
2885 [transform "OPERATOR_DECL_SIG"; transform "OPERATOR_DECL_IMPL"]
2887 (full_fidelity_path_prefix ^
"full_fidelity_operator_generated.ml")
2892 module GenerateSchemaVersion
= struct
2894 make_header CStyle
""
2897 pub const VERSION: &str = \"%s\";
2899 Full_fidelity_schema.full_fidelity_schema_version_number
2902 Full_fidelity_schema.make_template_file
2904 "hphp/hack/src/parser/schema/full_fidelity_schema_version_number.rs"
2911 GenerateFFOperatorRust.full_fidelity_operators;
2912 GenerateFFOperator.full_fidelity_operator;
2913 GenerateFFSyntaxType.full_fidelity_syntax_type;
2914 GenerateFFSyntaxSig.full_fidelity_syntax_sig;
2915 GenerateFFTriviaKind.full_fidelity_trivia_kind;
2916 GenerateFFRustTriviaKind.full_fidelity_trivia_kind;
2917 GenerateFFSyntax.full_fidelity_syntax;
2918 GenerateFFRustSyntax.full_fidelity_syntax;
2919 GenerateFFRustSyntaxType.full_fidelity_syntax;
2920 GenerateFFSyntaxKind.full_fidelity_syntax_kind;
2921 GenerateFFRustSyntaxKind.full_fidelity_syntax_kind;
2922 GenerateFFTokenKind.full_fidelity_token_kind;
2923 GenerateFFRustTokenKind.full_fidelity_token_kind;
2924 GenerateFFJSONSchema.full_fidelity_json_schema
;
2925 GenerateFFSmartConstructors.full_fidelity_smart_constructors;
2926 GenerateFFRustSmartConstructors.full_fidelity_smart_constructors;
2927 GenerateFFRustPositionedSmartConstructors.positioned_smart_constructors;
2928 GenerateFFSyntaxSmartConstructors.full_fidelity_syntax_smart_constructors;
2929 GenerateFFRustSyntaxSmartConstructors
2930 .full_fidelity_syntax_smart_constructors;
2931 GenerateFFRustDeclModeSmartConstructors.decl_mode_smart_constructors;
2932 GenerateRustFlattenSmartConstructors.flatten_smart_constructors;
2933 GenerateRustDirectDeclSmartConstructors.direct_decl_smart_constructors;
2934 GenerateRustPairSmartConstructors.pair_smart_constructors;
2935 GenerateFFSmartConstructorsWrappers
2936 .full_fidelity_smart_constructors_wrappers;
2937 GenerateFFRustSmartConstructorsWrappers
2938 .full_fidelity_smart_constructors_wrappers;
2939 GenerateFFRustSyntaxVariantByRef.full_fidelity_syntax;
2940 GenerateSyntaxTypeImpl.full_fidelity_syntax;
2941 GenerateSyntaxChildrenIterator.full_fidelity_syntax;
2942 GenerateFFRustSyntaxImplByRef.full_fidelity_syntax;
2943 GenerateSyntaxSerialize.gen;
2944 GenerateSchemaVersion.gen;