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 #[allow(clippy::assign_op_pattern)]
435 #[allow(clippy::let_and_return)]
437 impl<'a, T, V> SyntaxChildrenIterator<'a, T, V> {
438 pub fn next_impl(&mut self, direction : bool) -> Option<&'a Syntax<'a, T, V>> {
439 use SyntaxVariant::*;
440 let get_index = |len| {
441 let back_index_plus_1 = len - self.index_back;
442 if back_index_plus_1 <= self.index {
448 Some (back_index_plus_1 - 1)
451 let res = match self.syntax {
454 SyntaxList(elems) => {
455 get_index(elems.len()).and_then(|x| elems.get(x))
461 self.index = self.index + 1
463 self.index_back = self.index_back + 1
471 let full_fidelity_syntax =
472 Full_fidelity_schema.make_template_file
473 ~transformations
:[{ pattern
= "ITER_CHILDREN"; func
= to_iter_children }]
475 (full_fidelity_path_prefix
476 ^
"syntax_by_ref/syntax_children_iterator_generated.rs")
477 ~
template:full_fidelity_syntax_template
481 module GenerateSyntaxTypeImpl
= struct
482 let to_syntax_constructors x
=
483 let mapper (f
, _
) = sprintf
"%s: Self" (escape_rust_keyword f
) in
484 let args = map_and_concat_separated
", " mapper x
.fields in
485 let mapper (f
, _
) = sprintf
"%s" (escape_rust_keyword f
) in
486 let fields = map_and_concat_separated
",\n " mapper x
.fields in
488 " fn make_%s(ctx: &C, %s) -> Self {
489 let syntax = SyntaxVariant::%s(ctx.get_arena().alloc(%sChildren {
492 let value = V::from_values(syntax.iter_children().map(|child| &child.value));
493 Self::make(syntax, value)
501 let full_fidelity_syntax_template =
502 make_header CStyle
""
506 syntax::*, syntax_variant_generated::*,
509 lexable_token::LexableToken,
510 syntax::{SyntaxType, SyntaxValueType},
513 #[allow(clippy::assign_op_pattern)]
514 #[allow(clippy::let_and_return)]
516 impl<'a, C, T, V> SyntaxType<C> for Syntax<'a, T, V>
518 T: LexableToken + Copy,
519 V: SyntaxValueType<T>,
522 SYNTAX_CONSTRUCTORS }
525 let full_fidelity_syntax =
526 Full_fidelity_schema.make_template_file
528 [{ pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors }]
530 (full_fidelity_path_prefix
531 ^
"syntax_by_ref/syntax_type_impl_generated.rs")
532 ~
template:full_fidelity_syntax_template
536 module GenerateFFRustSyntax
= struct
537 let from_children x
=
538 let mapper prefix
(f
, _
) =
539 sprintf
"%s_%s : (Box::new(ts.pop().unwrap()))" prefix f
542 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
545 "SyntaxKind::%s => SyntaxVariant::%s {
554 " SyntaxVariant::%s {..} => SyntaxKind::%s,\n"
559 let mapper prefix
(f
, _
) = sprintf
"&*%s_%s" prefix f
in
561 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
563 let mapper prefix
(f
, _
) = sprintf
"ref %s_%s" prefix f
in
565 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
575 let to_iter_children x
=
577 let mapper prefix
(f
, _
) =
578 let res = sprintf
"%d => Some(&x.%s_%s)," !index prefix f
in
579 let () = incr
index in
583 map_and_concat_separated
590 get_index(%d).and_then(|index| { match index {
597 (List.length x
.fields)
600 let syntax_as_slice x
=
601 (* SAFETY: We have `#[repr(C)]` on all the children structs, and all their
602 fields are of type Syntax. So a child struct with 3 fields should have
603 the same layout as the array `[Syntax; 3]`, and it should be valid to
604 take a slice of length 3 from a pointer to its first field. *)
606 " SyntaxVariant::%s(x) => unsafe { std::slice::from_raw_parts(&x.%s_%s, %d) },\n"
609 (fst
(List.hd_exn x
.fields))
610 (List.length x
.fields)
612 let syntax_as_slice_mut x
=
613 (* SAFETY: As above in `syntax_as_slice` *)
615 " SyntaxVariant::%s(x) => unsafe { std::slice::from_raw_parts_mut(&mut x.%s_%s, %d) },\n"
618 (fst
(List.hd_exn x
.fields))
619 (List.length x
.fields)
621 let fold_over_owned x
=
622 let fold_mapper prefix
(f
, _
) =
623 sprintf
"let acc = f(%s_%s, acc)" prefix f
626 map_and_concat_separated
628 (fold_mapper x
.prefix
)
631 let destructure_mapper prefix
(f
, _
) = sprintf
"%s_%s" prefix f
in
632 let destructure_fields =
633 map_and_concat_separated
", " (destructure_mapper x
.prefix
) x
.fields
636 " SyntaxVariant::%s(x) => {
637 let %sChildren { %s } = *x;
646 let to_syntax_variant x
=
647 sprintf
" %s(Box<%sChildren<T, V>>),\n" x
.kind_name x
.kind_name
649 let to_syntax_variant_children x
=
650 let mapper prefix
(f
, _
) =
651 sprintf
" pub %s_%s: Syntax<T, V>," prefix f
653 let fields = map_and_concat_separated
"\n" (mapper x
.prefix
) x
.fields in
654 (* NB: The `#[repr(C)]` here is required for the `from_raw_parts` and
655 `from_raw_parts_mut` above (in `syntax_as_slice` and
656 `syntax_as_slice_mut`) to be valid. *)
658 "#[derive(Debug, Clone)]\n#[repr(C)]\npub struct %sChildren<T, V> {\n%s\n}\n\n"
662 let to_syntax_constructors x
=
663 let mapper prefix
(f
, _
) = sprintf
"%s_%s: Self" prefix f
in
664 let args = map_and_concat_separated
", " (mapper x
.prefix
) x
.fields in
665 let mapper prefix
(f
, _
) = sprintf
"%s_%s" prefix f
in
667 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
670 " fn make_%s(_: &C, %s) -> Self {
671 let syntax = SyntaxVariant::%s(Box::new(%sChildren {
674 let value = V::from_values(syntax.iter_children().map(|child| &child.value));
675 Self::make(syntax, value)
683 let to_syntax_from_children x
=
685 sprintf
"%s_%s: ts.pop().unwrap(),\n " x
.prefix f
687 let fields = map_and_concat
mapper (List.rev x
.fields) in
689 " (SyntaxKind::%s, %d) => SyntaxVariant::%s(Box::new(%sChildren {
693 (List.length x
.fields)
698 let full_fidelity_syntax_template =
699 make_header CStyle
""
701 use crate::lexable_token::LexableToken;
702 use crate::syntax::*;
703 use crate::syntax_kind::SyntaxKind;
705 #[allow(clippy::assign_op_pattern)]
706 #[allow(clippy::let_and_return)]
708 impl<T, V, C> SyntaxType<C> for Syntax<T, V>
711 V: SyntaxValueType<T>,
713 SYNTAX_CONSTRUCTORS }
715 #[allow(clippy::assign_op_pattern)]
716 #[allow(clippy::let_and_return)]
718 impl<T, V> Syntax<T, V>
722 pub fn fold_over_children_owned<U>(
723 f: &dyn Fn(Self, U) -> U,
725 syntax: SyntaxVariant<T, V>,
728 SyntaxVariant::Missing => acc,
729 SyntaxVariant::Token (_) => acc,
730 SyntaxVariant::SyntaxList(elems) => {
737 FOLD_OVER_CHILDREN_OWNED
741 pub fn kind(&self) -> SyntaxKind {
743 SyntaxVariant::Missing => SyntaxKind::Missing,
744 SyntaxVariant::Token (t) => SyntaxKind::Token(t.kind()),
745 SyntaxVariant::SyntaxList (_) => SyntaxKind::SyntaxList,
749 pub fn from_children(kind : SyntaxKind, mut ts : Vec<Self>) -> SyntaxVariant<T, V> {
750 match (kind, ts.len()) {
751 (SyntaxKind::Missing, 0) => SyntaxVariant::Missing,
752 (SyntaxKind::SyntaxList, _) => SyntaxVariant::SyntaxList(ts),
753 SYNTAX_FROM_CHILDREN _ => panic!(\"from_children called with wrong number of children\"),
757 pub fn children(&self) -> &[Self] {
759 SyntaxVariant::Missing => &[],
760 SyntaxVariant::Token(..) => &[],
761 SyntaxVariant::SyntaxList(l) => l.as_slice(),
765 pub fn children_mut(&mut self) -> &mut [Self] {
766 match &mut self.syntax {
767 SyntaxVariant::Missing => &mut [],
768 SyntaxVariant::Token(..) => &mut [],
769 SyntaxVariant::SyntaxList(l) => l.as_mut_slice(),
770 SYNTAX_AS_SLICE_MUT }
775 #[derive(Debug, Clone)]
776 pub enum SyntaxVariant<T, V> {
779 SyntaxList(Vec<Syntax<T, V>>),
782 #[allow(clippy::assign_op_pattern)]
783 #[allow(clippy::let_and_return)]
785 impl<'a, T, V> SyntaxChildrenIterator<'a, T, V> {
786 pub fn next_impl(&mut self, direction : bool) -> Option<&'a Syntax<T, V>> {
787 use SyntaxVariant::*;
788 let get_index = |len| {
789 let back_index_plus_1 = len - self.index_back;
790 if back_index_plus_1 <= self.index {
796 Some (back_index_plus_1 - 1)
799 let res = match &self.syntax {
802 SyntaxList(elems) => {
803 get_index(elems.len()).and_then(|x| elems.get(x))
809 self.index = self.index + 1
811 self.index_back = self.index_back + 1
819 let full_fidelity_syntax =
820 Full_fidelity_schema.make_template_file
823 { pattern
= "SYNTAX_VARIANT"; func
= to_syntax_variant };
824 { pattern
= "SYNTAX_CHILDREN"; func
= to_syntax_variant_children };
825 { pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors };
826 { pattern
= "ITER_CHILDREN"; func
= to_iter_children };
827 { pattern
= "FOLD_OVER_CHILDREN_OWNED"; func
= fold_over_owned };
828 { pattern
= "TO_KIND"; func
= to_kind };
829 { pattern
= "SYNTAX_FROM_CHILDREN"; func
= to_syntax_from_children };
830 { pattern
= "SYNTAX_AS_SLICE"; func
= syntax_as_slice };
831 { pattern
= "SYNTAX_AS_SLICE_MUT"; func
= syntax_as_slice_mut };
833 ~filename
:(full_fidelity_path_prefix ^
"syntax_generated.rs")
834 ~
template:full_fidelity_syntax_template
838 (* GenerateFFRustSyntax *)
840 module GenerateFFRustSyntaxType
= struct
843 " SyntaxVariant::%s {..} => SyntaxKind::%s,\n"
848 let mapper prefix
(f
, _
) = sprintf
"&*%s_%s" prefix f
in
850 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
852 let mapper prefix
(f
, _
) = sprintf
"ref %s_%s" prefix f
in
854 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
864 let into_children x
=
865 let mapper prefix
(f
, _
) = sprintf
"x.%s_%s" prefix f
in
867 map_and_concat_separated
",\n " (mapper x
.prefix
) x
.fields
870 " SyntaxVariant::%s (x) => { vec!(
877 let mapper prefix
(f
, _
) = sprintf
"let acc = f(&x.%s_%s, acc)" prefix f
in
879 map_and_concat_separated
";\n " (mapper x
.prefix
) x
.fields
882 " SyntaxVariant::%s(x) => {
889 let to_syntax_constructors x
=
890 let mapper prefix
(f
, _
) = sprintf
"%s_%s: Self" prefix f
in
891 let args = map_and_concat_separated
", " (mapper x
.prefix
) x
.fields in
892 sprintf
" fn make_%s(ctx: &C, %s) -> Self;\n" x
.type_name args
894 let full_fidelity_syntax_template =
895 make_header CStyle
""
897 use crate::syntax::*;
899 pub trait SyntaxType<C>: SyntaxTypeBase<C>
905 let full_fidelity_syntax =
906 Full_fidelity_schema.make_template_file
908 [{ pattern
= "SYNTAX_CONSTRUCTORS"; func
= to_syntax_constructors }]
909 ~filename
:(full_fidelity_path_prefix ^
"syntax_type.rs")
910 ~
template:full_fidelity_syntax_template
914 (* GenerateFFRustSyntaxType *)
916 module GenerateFFSyntaxSig
= struct
917 let to_constructor_methods x
=
918 let mapper1 (_f
, _
) = " t ->" in
919 let fields1 = map_and_concat
mapper1 x
.fields in
920 sprintf
" val make_%s :%s t\n" x
.type_name fields1
922 let to_type_tests x
= sprintf
" val is_%s : t -> bool\n" x
.type_name
925 let field_width = 50 - String.length x
.prefix
in
926 let fmt = sprintf
"%s_%%-%ds: t\n" x
.prefix
field_width in
927 let mapper (f
, _
) = sprintf
(Scanf.format_from_string
fmt "%-1s") f
in
928 let fields = map_and_concat_separated
" ; " mapper x
.fields in
930 (" | " ^^
kind_name_fmt ^^
" of\n { %s }\n")
934 let full_fidelity_syntax_template : string =
938 * This module contains a signature which can be used to describe the public
939 * surface area of a constructable syntax tree.
943 module TriviaKind = Full_fidelity_trivia_kind
944 module TokenKind = Full_fidelity_token_kind
946 module type Syntax_S = sig
947 module Token : Lexable_token_sig.LexableToken_S
948 type value [@@deriving show, eq, sexp_of]
949 type t = { syntax : syntax ; value : value } [@@deriving show, eq, sexp_of]
953 | SyntaxList of t list
958 Full_fidelity_source_text.t ->
959 Full_fidelity_parser_env.t ->
960 unit * t * Full_fidelity_syntax_error.t list * Rust_pointer.t option
961 val rust_parser_errors :
962 Full_fidelity_source_text.t ->
964 ParserOptions.ffi_t ->
965 Full_fidelity_syntax_error.t list
966 val has_leading_trivia : TriviaKind.t -> Token.t -> bool
967 val to_json : ?with_value:bool -> ?ignore_missing:bool -> t -> Hh_json.json
968 val extract_text : t -> string option
969 val is_in_body : t -> int -> bool
970 val syntax_node_to_list : t -> t list
972 val full_width : t -> int
973 val trailing_width : t -> int
974 val leading_width : t -> int
975 val leading_token : t -> Token.t option
976 val children : t -> t list
977 val syntax : t -> syntax
978 val kind : t -> Full_fidelity_syntax_kind.t
979 val value : t -> value
980 val make_token : Token.t -> t
981 val get_token : t -> Token.t option
982 val all_tokens : t -> Token.t list
983 val make_missing : Full_fidelity_source_text.t -> int -> t
984 val make_list : Full_fidelity_source_text.t -> int -> t list -> t
985 val is_namespace_prefix : t -> bool
986 val syntax_list_fold : init:'a -> f:('a -> t -> 'a) -> t -> 'a
989 val position : Relative_path.t -> t -> Pos.t option
990 val offset : t -> int option
991 val is_missing : t -> bool
992 val is_list : t -> bool
995 val is_specific_token : TokenKind.t -> t -> bool
996 val is_loop_statement : t -> bool
997 val is_external : t -> bool
998 val is_name : t -> bool
999 val is_construct : t -> bool
1000 val is_static : t -> bool
1001 val is_private : t -> bool
1002 val is_public : t -> bool
1003 val is_protected : t -> bool
1004 val is_abstract : t -> bool
1005 val is_final : t -> bool
1006 val is_async : t -> bool
1007 val is_void : t -> bool
1008 val is_left_brace : t -> bool
1009 val is_ellipsis : t -> bool
1010 val is_comma : t -> bool
1011 val is_ampersand : t -> bool
1012 val is_inout : t -> bool
1018 let full_fidelity_syntax_sig =
1019 Full_fidelity_schema.make_template_file
1022 { pattern
= "SYNTAX"; func
= to_syntax };
1023 { pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods };
1024 { pattern
= "TYPE_TESTS"; func
= to_type_tests };
1026 ~filename
:(full_fidelity_path_prefix ^
"syntax_sig.ml")
1027 ~
template:full_fidelity_syntax_template
1031 (* GenerateFFSyntaxSig *)
1033 module GenerateFFSmartConstructors
= struct
1034 let full_fidelity_smart_constructors_template : string =
1038 * This module contains a signature which can be used to describe smart
1043 module ParserEnv = Full_fidelity_parser_env
1045 module type SmartConstructors_S = sig
1046 module Token : Lexable_token_sig.LexableToken_S
1048 type t (* state *) [@@deriving show, sexp_of]
1050 type r (* smart constructor return type *) [@@deriving show]
1053 Full_fidelity_source_text.t ->
1055 t * r * Full_fidelity_syntax_error.t list * Rust_pointer.t option
1057 val initial_state : ParserEnv.t -> t
1061 let full_fidelity_smart_constructors =
1062 Full_fidelity_schema.make_template_file
1065 (full_fidelity_path_prefix ^
"smart_constructors/smartConstructors.ml")
1066 ~
template:full_fidelity_smart_constructors_template
1070 (* GenerateFFSmartConstructors *)
1072 module GenerateFFRustSmartConstructors
= struct
1073 let to_make_methods x
=
1075 List.mapi x
.fields ~f
:(fun i _
->
1076 "arg" ^ string_of_int i ^
": Self::Output")
1078 let stack = String.concat ~sep
:", " fields in
1079 sprintf
" fn make_%s(&mut self, %s) -> Self::Output;\n" x
.type_name stack
1081 let full_fidelity_smart_constructors_template : string =
1082 make_header CStyle
""
1084 use parser_core_types::token_factory::TokenFactory;
1085 use parser_core_types::lexable_token::LexableToken;
1087 pub type Token<S> = <<S as SmartConstructors>::Factory as TokenFactory>::Token;
1088 pub type Trivia<S> = <Token<S> as LexableToken>::Trivia;
1090 pub trait SmartConstructors: Clone {
1091 type Factory: TokenFactory;
1095 fn state_mut(&mut self) -> &mut Self::State;
1096 fn into_state(self) -> Self::State;
1097 fn token_factory_mut(&mut self) -> &mut Self::Factory;
1099 fn make_missing(&mut self, offset : usize) -> Self::Output;
1100 fn make_token(&mut self, arg0: Token<Self>) -> Self::Output;
1101 fn make_list(&mut self, arg0: Vec<Self::Output>, offset: usize) -> Self::Output;
1103 fn begin_enumerator(&mut self) {}
1104 fn begin_enum_class_enumerator(&mut self) {}
1105 fn begin_constant_declarator(&mut self) {}
1111 let full_fidelity_smart_constructors =
1112 Full_fidelity_schema.make_template_file
1113 ~transformations
:[{ pattern
= "MAKE_METHODS"; func
= to_make_methods }]
1114 ~filename
:(full_fidelity_path_prefix ^
"smart_constructors_generated.rs")
1115 ~
template:full_fidelity_smart_constructors_template
1119 (* GenerateFFRustSmartConstructors *)
1121 module GenerateFFRustPositionedSmartConstructors
= struct
1122 let to_constructor_methods x
=
1124 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1126 let args = String.concat ~sep
:", " args in
1127 let fwd_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1128 let fwd_args = String.concat ~sep
:", " fwd_args in
1130 " fn make_%s(&mut self, %s) -> Self::Output {
1131 <Self as SyntaxSmartConstructors<S, TF, St>>::make_%s(self, %s)
1138 let positioned_smart_constructors_template : string =
1139 make_header CStyle
""
1143 use parser_core_types::{
1145 lexable_token::LexableToken,
1146 token_factory::TokenFactory,
1148 use smart_constructors::SmartConstructors;
1149 use syntax_smart_constructors::{SyntaxSmartConstructors, StateType};
1152 pub struct PositionedSmartConstructors<S, TF, St: StateType<S>> {
1155 phantom_s: std::marker::PhantomData<S>,
1158 impl<S, TF, St: StateType<S>> PositionedSmartConstructors<S, TF, St> {
1159 pub fn new(state: St, token_factory: TF) -> Self {
1160 Self { state, token_factory, phantom_s: std::marker::PhantomData }
1164 impl<S, TF, St> SyntaxSmartConstructors<S, TF, St> for PositionedSmartConstructors<S, TF, St>
1166 TF: TokenFactory<Token = S::Token>,
1168 S: SyntaxType<St> + Clone,
1169 S::Token: LexableToken,
1172 impl<S, TF, St> SmartConstructors for PositionedSmartConstructors<S, TF, St>
1174 TF: TokenFactory<Token = S::Token>,
1175 S::Token: LexableToken,
1176 S: SyntaxType<St> + Clone,
1183 fn state_mut(&mut self) -> &mut St {
1187 fn into_state(self) -> St {
1191 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1192 &mut self.token_factory
1195 fn make_missing(&mut self, offset: usize) -> Self::Output {
1196 <Self as SyntaxSmartConstructors<S, TF, St>>::make_missing(self, offset)
1199 fn make_token(&mut self, offset: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1200 <Self as SyntaxSmartConstructors<S, TF, St>>::make_token(self, offset)
1203 fn make_list(&mut self, lst: Vec<Self::Output>, offset: usize) -> Self::Output {
1204 <Self as SyntaxSmartConstructors<S, TF, St>>::make_list(self, lst, offset)
1206 CONSTRUCTOR_METHODS}
1209 let positioned_smart_constructors =
1210 Full_fidelity_schema.make_template_file
1212 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1213 ~filename
:(full_fidelity_path_prefix ^
"positioned_smart_constructors.rs")
1214 ~
template:positioned_smart_constructors_template
1218 module GenerateFFSyntaxSmartConstructors
= struct
1219 let full_fidelity_syntax_smart_constructors_template : string =
1223 * This module contains smart constructors implementation that can be used to
1229 module type SC_S = SmartConstructors.SmartConstructors_S
1231 module ParserEnv = Full_fidelity_parser_env
1233 module type State_S = sig
1234 type r [@@deriving show]
1236 type t [@@deriving show, sexp_of]
1238 val initial : ParserEnv.t -> t
1240 val next : t -> r list -> t
1243 module type RustParser_S = sig
1249 Full_fidelity_source_text.t ->
1251 t * r * Full_fidelity_syntax_error.t list * Rust_pointer.t option
1254 module WithSyntax (Syntax : Syntax_sig.Syntax_S) = struct
1255 module WithState (State : State_S with type r = Syntax.t) = struct
1256 module WithRustParser
1257 (RustParser : RustParser_S with type t = State.t with type r = Syntax.t) =
1259 module Token = Syntax.Token
1261 type t = State.t [@@deriving show, sexp_of]
1263 type r = Syntax.t [@@deriving show]
1265 let rust_parse = RustParser.rust_parse
1267 let initial_state = State.initial
1271 include WithState (struct
1272 type r = Syntax.t [@@deriving show]
1274 type t = unit [@@deriving show, sexp_of]
1281 include WithRustParser (struct
1286 let rust_parse = Syntax.rust_parse
1291 let full_fidelity_syntax_smart_constructors =
1292 Full_fidelity_schema.make_template_file
1295 (full_fidelity_path_prefix
1296 ^
"smart_constructors/syntaxSmartConstructors.ml")
1297 ~
template:full_fidelity_syntax_smart_constructors_template
1301 (* GenerateFFSyntaxSmartConstructors *)
1303 module GenerateFFRustSyntaxSmartConstructors
= struct
1304 let to_constructor_methods x
=
1306 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d : Self::Output" i
)
1308 let params = String.concat ~sep
:", " params in
1309 let args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1310 let args = String.concat ~sep
:", " args in
1311 let next_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"&arg%d" i
) in
1312 let next_args = String.concat ~sep
:", " next_args in
1314 " fn make_%s(&mut self, %s) -> Self::Output {
1315 self.state_mut().next(&[%s]);
1316 Self::Output::make_%s(self.state_mut(), %s)
1324 let full_fidelity_syntax_smart_constructors_template : string =
1325 make_header CStyle
""
1327 use parser_core_types::{
1329 token_factory::TokenFactory,
1331 use smart_constructors::{NoState, SmartConstructors};
1332 use crate::StateType;
1334 pub trait SyntaxSmartConstructors<S: SyntaxType<St>, TF: TokenFactory<Token = S::Token>, St = NoState>:
1335 SmartConstructors<State = St, Output=S, Factory = TF>
1339 fn make_missing(&mut self, offset: usize) -> Self::Output {
1340 let r = Self::Output::make_missing(self.state_mut(), offset);
1341 self.state_mut().next(&[]);
1345 fn make_token(&mut self, arg: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1346 let r = Self::Output::make_token(self.state_mut(), arg);
1347 self.state_mut().next(&[]);
1351 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1352 if items.is_empty() {
1353 <Self as SyntaxSmartConstructors<S, TF, St>>::make_missing(self, offset)
1355 let item_refs: Vec<_> = items.iter().collect();
1356 self.state_mut().next(&item_refs);
1357 Self::Output::make_list(self.state_mut(), items, offset)
1361 CONSTRUCTOR_METHODS}
1364 let full_fidelity_syntax_smart_constructors =
1365 Full_fidelity_schema.make_template_file
1367 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1369 (full_fidelity_path_prefix ^
"syntax_smart_constructors_generated.rs")
1370 ~
template:full_fidelity_syntax_smart_constructors_template
1374 (* GenerateFFRustSyntaxSmartConstructors *)
1376 module GenerateFFRustDeclModeSmartConstructors
= struct
1377 let to_constructor_methods x
=
1379 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1381 let args = String.concat ~sep
:", " args in
1382 let fwd_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1383 let fwd_args = String.concat ~sep
:", " fwd_args in
1385 " fn make_%s(&mut self, %s) -> Self::Output {
1386 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_%s(self, %s)
1393 let decl_mode_smart_constructors_template : string =
1394 make_header CStyle
""
1396 use parser_core_types::{
1397 lexable_token::LexableToken, syntax::SyntaxValueType, syntax_by_ref::syntax::Syntax,
1398 token_factory::TokenFactory,
1400 use smart_constructors::SmartConstructors;
1401 use syntax_smart_constructors::SyntaxSmartConstructors;
1404 impl<'s, 'a, Token, Value, TF> SmartConstructors
1405 for DeclModeSmartConstructors<'s, 'a, Syntax<'a, Token, Value>, Token, Value, TF>
1407 TF: TokenFactory<Token = SyntaxToken<'s, 'a, Token, Value>>,
1408 Token: LexableToken + Copy,
1409 Value: SyntaxValueType<Token> + Clone,
1411 type State = State<'s, 'a, Syntax<'a, Token, Value>>;
1413 type Output = Syntax<'a, Token, Value>;
1415 fn state_mut(&mut self) -> &mut State<'s, 'a, Syntax<'a, Token, Value>> {
1419 fn into_state(self) -> State<'s, 'a, Syntax<'a, Token, Value>> {
1423 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1424 &mut self.token_factory
1427 fn make_missing(&mut self, o: usize) -> Self::Output {
1428 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_missing(self, o)
1431 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1432 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_token(self, token)
1435 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1436 <Self as SyntaxSmartConstructors<Self::Output, Self::Factory, State<'_, '_, Self::Output>>>::make_list(self, items, offset)
1439 CONSTRUCTOR_METHODS}
1442 let decl_mode_smart_constructors =
1443 Full_fidelity_schema.make_template_file
1445 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1447 (full_fidelity_path_prefix ^
"decl_mode_smart_constructors_generated.rs")
1448 ~
template:decl_mode_smart_constructors_template
1452 (* GenerateFFRustDeclModeSmartConstructors *)
1454 module GenerateRustFlattenSmartConstructors
= struct
1455 let to_constructor_methods x
=
1457 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d: Self::Output" i
)
1459 let args = String.concat ~sep
:", " args in
1461 List.mapi x
.fields ~f
:(fun i _
-> sprintf
"Self::is_zero(&arg%d)" i
)
1463 let if_cond = String.concat ~sep
:" && " if_cond in
1464 let flatten_args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1465 let flatten_args = String.concat ~sep
:", " flatten_args in
1467 " fn make_%s(&mut self, %s) -> Self::Output {
1469 Self::zero(SyntaxKind::%s)
1471 self.flatten(SyntaxKind::%s, vec!(%s))
1481 let flatten_smart_constructors_template : string =
1482 make_header CStyle
""
1484 use smart_constructors::SmartConstructors;
1485 use parser_core_types::{
1486 lexable_token::LexableToken,
1487 syntax_kind::SyntaxKind,
1488 token_factory::TokenFactory,
1491 pub trait FlattenSmartConstructors: SmartConstructors
1493 fn is_zero(s: &Self::Output) -> bool;
1494 fn zero(kind: SyntaxKind) -> Self::Output;
1495 fn flatten(&self, kind: SyntaxKind, lst: Vec<Self::Output>) -> Self::Output;
1497 fn make_missing(&mut self, _: usize) -> Self::Output {
1498 Self::zero(SyntaxKind::Missing)
1501 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1502 Self::zero(SyntaxKind::Token(token.kind()))
1505 fn make_list(&mut self, _: Vec<Self::Output>, _: usize) -> Self::Output {
1506 Self::zero(SyntaxKind::SyntaxList)
1509 fn begin_enumerator(&mut self) {}
1511 fn begin_enum_class_enumerator(&mut self) {}
1513 fn begin_constant_declarator(&mut self) {}
1515 CONSTRUCTOR_METHODS}
1518 let flatten_smart_constructors =
1519 Full_fidelity_schema.make_template_file
1521 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1522 ~filename
:(full_fidelity_path_prefix ^
"flatten_smart_constructors.rs")
1523 ~
template:flatten_smart_constructors_template
1527 (* GenerateRustFlattenSmartConstructors *)
1529 module GenerateRustDirectDeclSmartConstructors
= struct
1530 let to_constructor_methods x
=
1532 List.map x
.fields ~f
:(fun (name
, _
) ->
1533 sprintf
"%s: Self::Output" (escape_rust_keyword name
))
1535 let args = String.concat ~sep
:", " args in
1537 List.map x
.fields ~f
:(fun (name
, _
) -> escape_rust_keyword name
)
1539 let fwd_args = String.concat ~sep
:", " fwd_args in
1541 " fn make_%s(&mut self, %s) -> Self::Output {
1542 <Self as FlattenSmartConstructors>::make_%s(self, %s)
1549 let direct_decl_smart_constructors_template : string =
1550 make_header CStyle
""
1552 use flatten_smart_constructors::*;
1553 use parser_core_types::compact_token::CompactToken;
1554 use parser_core_types::token_factory::SimpleTokenFactoryImpl;
1555 use smart_constructors::SmartConstructors;
1557 use crate::{DirectDeclSmartConstructors, Node, SourceTextAllocator};
1559 impl<'a, 'o, 't, S: SourceTextAllocator<'t, 'a>> SmartConstructors for DirectDeclSmartConstructors<'a, 'o, 't, S> {
1561 type Factory = SimpleTokenFactoryImpl<CompactToken>;
1562 type Output = Node<'a>;
1564 fn state_mut(&mut self) -> &mut Self {
1568 fn into_state(self) -> Self {
1572 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1573 &mut self.token_factory
1576 fn make_missing(&mut self, offset: usize) -> Self::Output {
1577 <Self as FlattenSmartConstructors>::make_missing(self, offset)
1580 fn make_token(&mut self, token: CompactToken) -> Self::Output {
1581 <Self as FlattenSmartConstructors>::make_token(self, token)
1584 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1585 <Self as FlattenSmartConstructors>::make_list(self, items, offset)
1588 fn begin_enumerator(&mut self) {
1589 <Self as FlattenSmartConstructors>::begin_enumerator(self)
1592 fn begin_enum_class_enumerator(&mut self) {
1593 <Self as FlattenSmartConstructors>::begin_enum_class_enumerator(self)
1596 fn begin_constant_declarator(&mut self) {
1597 <Self as FlattenSmartConstructors>::begin_constant_declarator(self)
1602 CONSTRUCTOR_METHODS}
1605 let direct_decl_smart_constructors =
1606 Full_fidelity_schema.make_template_file
1608 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1610 (full_fidelity_path_prefix
1611 ^
"../decl/direct_decl_smart_constructors_generated.rs")
1612 ~
template:direct_decl_smart_constructors_template
1616 (* GenerateRustDirectDeclSmartConstructors *)
1618 module GenerateRustPairSmartConstructors
= struct
1619 let to_constructor_methods x
=
1621 List.map x
.fields ~f
:(fun (name
, _
) ->
1622 sprintf
"%s: Self::Output" (escape_rust_keyword name
))
1624 let args = String.concat ~sep
:", " args in
1626 List.map x
.fields ~f
:(fun (name
, _
) -> escape_rust_keyword name
)
1629 List.map
fwd_args ~f
:(fun name
-> name ^
"." ^ idx
)
1630 |> String.concat ~sep
:", "
1633 " fn make_%s(&mut self, %s) -> Self::Output {
1634 Node(self.0.make_%s(%s), self.1.make_%s(%s))
1643 let pair_smart_constructors_template : string =
1644 make_header CStyle
""
1647 use parser_core_types::token_factory::TokenFactory;
1648 use smart_constructors::{NodeType, SmartConstructors};
1650 use crate::{PairTokenFactory, Node};
1653 pub struct PairSmartConstructors<SC0, SC1>(pub SC0, pub SC1, PairTokenFactory<SC0::Factory, SC1::Factory>)
1655 SC0: SmartConstructors,
1656 SC0::Output: NodeType,
1657 SC1: SmartConstructors,
1658 SC1::Output: NodeType;
1660 impl<SC0, SC1> PairSmartConstructors<SC0, SC1>
1662 SC0: SmartConstructors,
1663 SC0::Output: NodeType,
1664 SC1: SmartConstructors,
1665 SC1::Output: NodeType,
1667 pub fn new(mut sc0: SC0, mut sc1: SC1) -> Self {
1668 let tf0 = sc0.token_factory_mut().clone();
1669 let tf1 = sc1.token_factory_mut().clone();
1670 let tf = PairTokenFactory::new(tf0, tf1);
1675 impl<SC0, SC1> SmartConstructors for PairSmartConstructors<SC0, SC1>
1677 SC0: SmartConstructors,
1678 SC0::Output: NodeType,
1679 SC1: SmartConstructors,
1680 SC1::Output: NodeType,
1683 type Factory = PairTokenFactory<SC0::Factory, SC1::Factory>;
1684 type Output = Node<SC0::Output, SC1::Output>;
1686 fn state_mut(&mut self) -> &mut Self {
1690 fn into_state(self) -> Self {
1694 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1698 fn make_missing(&mut self, offset: usize) -> Self::Output {
1699 Node(self.0.make_missing(offset), self.1.make_missing(offset))
1702 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1703 Node(self.0.make_token(token.0), self.1.make_token(token.1))
1706 fn make_list(&mut self, items: Vec<Self::Output>, offset: usize) -> Self::Output {
1707 let (items0, items1) = items.into_iter().map(|n| (n.0, n.1)).unzip();
1708 Node(self.0.make_list(items0, offset), self.1.make_list(items1, offset))
1711 CONSTRUCTOR_METHODS}
1714 let pair_smart_constructors =
1715 Full_fidelity_schema.make_template_file
1717 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1719 (full_fidelity_path_prefix ^
"pair_smart_constructors_generated.rs")
1720 ~
template:pair_smart_constructors_template
1724 (* GenerateRustPairSmartConstructors *)
1726 module GenerateFFSmartConstructorsWrappers
= struct
1727 let full_fidelity_smart_constructors_wrappers_template : string =
1731 * This module contains smart constructors implementation that can be used to
1736 module type SC_S = SmartConstructors.SmartConstructors_S
1738 module SK = Full_fidelity_syntax_kind
1740 module type SyntaxKind_S = sig
1743 type original_sc_r [@@deriving show]
1746 module SyntaxKind (SC : SC_S) :
1748 with module Token = SC.Token
1749 and type original_sc_r = SC.r
1750 and type t = SC.t = struct
1751 module Token = SC.Token
1753 type original_sc_r = SC.r [@@deriving show]
1755 type t = SC.t [@@deriving show, sexp_of]
1757 type r = SK.t * SC.r [@@deriving show]
1759 let compose : SK.t -> t * SC.r -> t * r =
1760 (fun kind (state, res) -> (state, (kind, res)))
1762 let rust_parse text env =
1763 let (state, res, errors, pointer) = SC.rust_parse text env in
1764 let (state, res) = compose SK.Script (state, res) in
1765 (state, res, errors, pointer)
1767 let initial_state = SC.initial_state
1771 let full_fidelity_smart_constructors_wrappers =
1772 Full_fidelity_schema.make_template_file
1775 (full_fidelity_path_prefix
1776 ^
"smart_constructors/smartConstructorsWrappers.ml")
1777 ~
template:full_fidelity_smart_constructors_wrappers_template
1781 (* GenerateFFSmartConstructorsWrappers *)
1783 module GenerateFFRustSmartConstructorsWrappers
= struct
1784 let to_constructor_methods x
=
1786 List.mapi x
.fields ~f
:(fun i _
->
1787 "arg" ^ string_of_int i ^
" : Self::Output")
1789 let params = String.concat ~sep
:", " params in
1790 let args = List.mapi x
.fields ~f
:(fun i _
-> sprintf
"arg%d" i
) in
1791 let raw_args = map_and_concat_separated
", " (fun x
-> x ^
".1") args in
1793 " fn make_%s(&mut self, %s) -> Self::Output {
1794 compose(SyntaxKind::%s, self.s.make_%s(%s))
1802 let full_fidelity_smart_constructors_wrappers_template : string =
1803 make_header CStyle
""
1805 // This module contains smart constructors implementation that can be used to
1809 use parser_core_types::{
1810 lexable_token::LexableToken,
1811 syntax_kind::SyntaxKind,
1812 token_factory::TokenFactory,
1814 use crate::SmartConstructors;
1817 pub struct WithKind<S> {
1821 impl<S> WithKind<S> {
1822 pub fn new(s: S) -> Self {
1827 impl<S, St> SmartConstructors for WithKind<S>
1828 where S: SmartConstructors<State = St>,
1830 type Factory = S::Factory;
1832 type Output = (SyntaxKind, S::Output);
1834 fn state_mut(&mut self) -> &mut St {
1838 fn into_state(self) -> St {
1842 fn token_factory_mut(&mut self) -> &mut Self::Factory {
1843 self.s.token_factory_mut()
1847 fn make_token(&mut self, token: <Self::Factory as TokenFactory>::Token) -> Self::Output {
1848 compose(SyntaxKind::Token(token.kind()), self.s.make_token(token))
1851 fn make_missing(&mut self, p: usize) -> Self::Output {
1852 compose(SyntaxKind::Missing, self.s.make_missing(p))
1855 fn make_list(&mut self, items: Vec<Self::Output>, p: usize) -> Self::Output {
1856 let kind = if items.is_empty() {
1859 SyntaxKind::SyntaxList
1861 compose(kind, self.s.make_list(items.into_iter().map(|x| x.1).collect(), p))
1868 fn compose<R>(kind: SyntaxKind, r: R) -> (SyntaxKind, R) {
1873 let full_fidelity_smart_constructors_wrappers =
1874 Full_fidelity_schema.make_template_file
1876 [{ pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods }]
1877 ~filename
:(full_fidelity_path_prefix ^
"smart_constructors_wrappers.rs")
1878 ~
template:full_fidelity_smart_constructors_wrappers_template
1882 (* GenerateFFRustSmartConstructorsWrappers *)
1884 module GenerateFFSyntax
= struct
1887 (" | " ^^
kind_name_fmt ^^
" _ -> SyntaxKind.%s\n")
1891 let to_type_tests x
=
1893 (" let is_" ^^
type_name_fmt ^^
" = has_kind SyntaxKind.%s\n")
1898 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1899 let fields = map_and_concat
mapper x
.fields in
1901 " | %s {\n%s } -> [\n%s ]\n"
1906 let to_fold_from_syntax x
=
1907 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1908 let fields = map_and_concat
mapper x
.fields in
1909 let mapper2 (f
, _
) =
1910 sprintf
" let acc = f acc %s_%s in\n" x
.prefix f
1912 let fields2 = map_and_concat
mapper2 x
.fields in
1914 " | %s {\n%s } ->\n%s acc\n"
1919 let to_children_names x
=
1920 let mapper1 (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1921 let mapper2 (f
, _
) = sprintf
" \"%s_%s\";\n" x
.prefix f
in
1922 let fields1 = map_and_concat
mapper1 x
.fields in
1923 let fields2 = map_and_concat
mapper2 x
.fields in
1925 " | %s {\n%s } -> [\n%s ]\n"
1930 let to_syntax_from_children x
=
1931 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1932 let fields = map_and_concat
mapper x
.fields in
1934 " | (SyntaxKind.%s, [
1944 let to_constructor_methods x
=
1945 let mapper1 (f
, _
) = sprintf
" %s_%s\n" x
.prefix f
in
1946 let fields1 = map_and_concat
mapper1 x
.fields in
1947 let mapper2 (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1948 let fields2 = map_and_concat
mapper2 x
.fields in
1954 let value = ValueBuilder.value_from_syntax syntax in
1963 let to_from_methods x
=
1964 if omit_syntax_record x
then
1967 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1968 let fields = map_and_concat
mapper x
.fields in
1979 let to_get_methods x
=
1980 if omit_syntax_record x
then
1983 let mapper (f
, _
) = sprintf
" %s_%s;\n" x
.prefix f
in
1984 let fields = map_and_concat
mapper x
.fields in
1988 | %s {\n%s } -> {\n%s }
1989 | _ -> failwith \"get_%s: not a %s\"
1998 let full_fidelity_syntax_template =
2002 * With these factory methods, nodes can be built up from their child nodes. A
2003 * factory method must not just know all the children and the kind of node it is
2004 * constructing; it also must know how to construct the value that this node is
2005 * going to be tagged with. For that reason, an optional functor is provided.
2006 * This functor requires that methods be provided to construct the values
2007 * associated with a token or with any arbitrary node, given its children. If
2008 * this functor is used then the resulting module contains factory methods.
2010 * This module also provides some useful helper functions, like an iterator,
2011 * a rewriting visitor, and so on."
2015 open Full_fidelity_syntax_type
2017 module SyntaxKind = Full_fidelity_syntax_kind
2018 module TokenKind = Full_fidelity_token_kind
2019 module Operator = Full_fidelity_operator
2020 [@@@warning \"-27\"] (* unused variable *)
2022 module WithToken(Token: TokenType) = struct
2023 module WithSyntaxValue(SyntaxValue: SyntaxValueType) = struct
2025 include MakeSyntaxType(Token)(SyntaxValue)
2027 let make syntax value =
2036 let syntax_node_to_list node =
2037 match syntax node with
2042 let to_kind syntax =
2044 | Missing -> SyntaxKind.Missing
2045 | Token t -> SyntaxKind.Token (Token.kind t)
2046 | SyntaxList _ -> SyntaxKind.SyntaxList
2050 to_kind (syntax node)
2052 let has_kind syntax_kind node =
2053 SyntaxKind.equal (kind node) syntax_kind
2055 let is_missing node =
2056 match kind node with
2057 | SyntaxKind.Missing -> true
2061 match kind node with
2062 | SyntaxKind.SyntaxList -> true
2067 let is_loop_statement node =
2068 is_for_statement node ||
2069 is_foreach_statement node ||
2070 is_while_statement node ||
2071 is_do_statement node
2073 let is_separable_prefix node =
2074 match syntax node with
2076 TokenKind.(match Token.kind t with
2077 | PlusPlus | MinusMinus -> false
2081 let is_specific_token kind node =
2082 match syntax node with
2083 | Token t -> TokenKind.equal (Token.kind t) kind
2086 let is_namespace_prefix node =
2087 match syntax node with
2088 | QualifiedName e ->
2089 begin match List.last (syntax_node_to_list e.qualified_name_parts) with
2092 begin match syntax p with
2093 | ListItem p -> not (is_missing p.list_separator)
2099 let has_leading_trivia kind token =
2100 List.exists (Token.leading token)
2102 Full_fidelity_trivia_kind.equal (Token.Trivia.kind trivia) kind)
2105 is_specific_token TokenKind.Semicolon e || is_missing e
2107 let is_name = is_specific_token TokenKind.Name
2108 let is_construct = is_specific_token TokenKind.Construct
2109 let is_static = is_specific_token TokenKind.Static
2110 let is_private = is_specific_token TokenKind.Private
2111 let is_public = is_specific_token TokenKind.Public
2112 let is_protected = is_specific_token TokenKind.Protected
2113 let is_abstract = is_specific_token TokenKind.Abstract
2114 let is_final = is_specific_token TokenKind.Final
2115 let is_async = is_specific_token TokenKind.Async
2116 let is_void = is_specific_token TokenKind.Void
2117 let is_left_brace = is_specific_token TokenKind.LeftBrace
2118 let is_ellipsis = is_specific_token TokenKind.DotDotDot
2119 let is_comma = is_specific_token TokenKind.Comma
2120 let is_ampersand = is_specific_token TokenKind.Ampersand
2121 let is_inout = is_specific_token TokenKind.Inout
2123 let syntax_list_fold ~init ~f node =
2124 match syntax node with
2128 ~f:(fun init li -> match syntax li with
2129 | ListItem { list_item; _; }-> f init list_item
2136 let fold_over_children f acc syntax =
2140 | SyntaxList items ->
2141 List.fold_left ~f ~init:acc items
2144 (* The order that the children are returned in should match the order
2145 that they appear in the source text *)
2146 let children_from_syntax s =
2154 children_from_syntax node.syntax
2156 let children_names node =
2157 match node.syntax with
2160 | SyntaxList _ -> []
2163 let rec to_json_ ?(with_value = false) ?(ignore_missing = false) node =
2165 let ch = match node.syntax with
2166 | Token t -> [ \"token\", Token.to_json t ]
2167 | SyntaxList x -> [ (\"elements\",
2168 JSON_Array (List.filter_map ~f:(to_json_ ~with_value ~ignore_missing) x)) ]
2170 let rec aux acc c n =
2173 | ((hc :: tc), (hn :: tn)) ->
2174 let result = (to_json_ ~with_value ~ignore_missing) hc in
2176 | Some r -> aux ((hn, r):: acc) tc tn
2177 | None -> aux acc tc tn)
2178 | _ -> failwith \"mismatch between children and names\" in
2179 List.rev (aux [] (children node) (children_names node)) in
2180 let k = (\"kind\", JSON_String (SyntaxKind.to_string (kind node))) in
2181 let v = if with_value then
2182 (\"value\", SyntaxValue.to_json node.value) :: ch
2184 if ignore_missing && (List.is_empty ch) then None else Some(JSON_Object (k :: v))
2186 let to_json ?(with_value = false) ?(ignore_missing = false) node =
2187 match to_json_ ~with_value ~ignore_missing node with
2189 | None -> Hh_json.JSON_Object([])
2191 let binary_operator_kind b =
2194 let kind = Token.kind token in
2195 if Operator.is_trailing_operator_token kind then
2196 Some (Operator.trailing_from_token kind)
2201 let get_token node =
2202 match (syntax node) with
2203 | Token token -> Some token
2206 let leading_token node =
2211 let token = get_token h in
2212 if Option.is_none token then
2213 let result = aux (children h) in
2214 if Option.is_none result then aux t else result
2219 let trailing_token node =
2224 let token = get_token h in
2225 if Option.is_none token then
2226 let result = aux (List.rev (children h)) in
2227 if Option.is_none result then aux t else result
2232 let syntax_from_children kind ts =
2234 SYNTAX_FROM_CHILDREN | (SyntaxKind.Missing, []) -> Missing
2235 | (SyntaxKind.SyntaxList, items) -> SyntaxList items
2237 \"syntax_from_children called with wrong number of children\"
2239 let all_tokens node =
2240 let rec aux acc nodes =
2246 | Token token -> aux (token :: acc) t
2247 | _ -> aux (aux acc (children h)) t
2249 List.rev (aux [] [node])
2251 module type ValueBuilderType = sig
2252 val value_from_children:
2253 Full_fidelity_source_text.t ->
2255 Full_fidelity_syntax_kind.t ->
2258 val value_from_token: Token.t -> SyntaxValue.t
2259 val value_from_syntax: syntax -> SyntaxValue.t
2262 module WithValueBuilder(ValueBuilder: ValueBuilderType) = struct
2263 let from_children text offset kind ts =
2264 let syntax = syntax_from_children kind ts in
2265 let value = ValueBuilder.value_from_children text offset kind ts in
2268 let make_token token =
2269 let syntax = Token token in
2270 let value = ValueBuilder.value_from_token token in
2273 let make_missing text offset =
2274 from_children text offset SyntaxKind.Missing []
2276 (* An empty list is represented by Missing; everything else is a
2277 SyntaxList, even if the list has only one item. *)
2278 let make_list text offset items =
2280 | [] -> make_missing text offset
2281 | _ -> from_children text offset SyntaxKind.SyntaxList items
2294 let full_fidelity_syntax =
2295 Full_fidelity_schema.make_template_file
2298 { pattern
= "TO_KIND"; func
= to_to_kind };
2299 { pattern
= "TYPE_TESTS"; func
= to_type_tests };
2300 { pattern
= "CHILDREN"; func
= to_children };
2301 { pattern
= "FOLD_FROM_SYNTAX"; func
= to_fold_from_syntax };
2302 { pattern
= "CHILDREN_NAMES"; func
= to_children_names };
2303 { pattern
= "SYNTAX_FROM_CHILDREN"; func
= to_syntax_from_children };
2304 { pattern
= "CONSTRUCTOR_METHODS"; func
= to_constructor_methods };
2305 { pattern
= "FROM_METHODS"; func
= to_from_methods };
2306 { pattern
= "GET_METHODS"; func
= to_get_methods };
2308 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_syntax.ml")
2309 ~
template:full_fidelity_syntax_template
2313 module GenerateFFTriviaKind
= struct
2314 let to_trivia { trivia_kind
; trivia_text
= _
} =
2315 sprintf
" | %s\n" trivia_kind
2317 let to_to_string { trivia_kind
; trivia_text
} =
2319 (" | " ^^
trivia_kind_fmt ^^
" -> \"%s\"\n")
2323 let full_fidelity_trivia_kind_template =
2324 make_header MLStyle
""
2329 [@@deriving show, enum, eq, sexp_of]
2331 let to_string kind =
2335 let full_fidelity_trivia_kind =
2336 Full_fidelity_schema.make_template_file
2337 ~trivia_transformations
:
2339 { trivia_pattern
= "TRIVIA"; trivia_func
= map_and_concat
to_trivia };
2341 trivia_pattern
= "TO_STRING";
2342 trivia_func
= map_and_concat
to_to_string;
2345 ~filename
:(full_fidelity_path_prefix ^
"/full_fidelity_trivia_kind.ml")
2346 ~
template:full_fidelity_trivia_kind_template
2350 (* GenerateFFSyntaxKind *)
2352 module GenerateFFRustTriviaKind
= struct
2353 let ocaml_tag = ref (-1)
2355 let to_trivia { trivia_kind
; trivia_text
= _
} =
2357 sprintf
" %s = %d,\n" trivia_kind
!ocaml_tag
2359 let to_to_string { trivia_kind
; trivia_text
} =
2360 sprintf
" TriviaKind::%s => \"%s\",\n" trivia_kind trivia_text
2362 let full_fidelity_trivia_kind_template =
2363 make_header CStyle
""
2366 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2368 #[derive(Debug, Copy, Clone, FromOcamlRep, ToOcamlRep, PartialEq)]
2370 pub enum TriviaKind {
2374 pub fn to_string(&self) -> &str {
2379 pub const fn ocaml_tag(self) -> u8 {
2385 let full_fidelity_trivia_kind =
2386 Full_fidelity_schema.make_template_file
2387 ~trivia_transformations
:
2389 { trivia_pattern
= "TRIVIA"; trivia_func
= map_and_concat
to_trivia };
2391 trivia_pattern
= "TO_STRING";
2392 trivia_func
= map_and_concat
to_to_string;
2395 ~filename
:(full_fidelity_path_prefix ^
"trivia_kind.rs")
2396 ~
template:full_fidelity_trivia_kind_template
2400 (* GenerateFFRustTriviaKind *)
2402 module GenerateFFSyntaxKind
= struct
2403 let to_tokens x
= sprintf
" | %s\n" x
.kind_name
2405 let to_to_string x
=
2407 (" | " ^^
kind_name_fmt ^^
" -> \"%s\"\n")
2411 let full_fidelity_syntax_kind_template =
2412 make_header MLStyle
""
2416 | Token of Full_fidelity_token_kind.t
2420 [@@deriving show, eq]
2422 let to_string kind =
2424 | Token _ -> \"token\"
2425 | Missing -> \"missing\"
2426 | SyntaxList -> \"list\"
2429 let full_fidelity_syntax_kind =
2430 Full_fidelity_schema.make_template_file
2433 { pattern
= "TOKENS"; func
= to_tokens };
2434 { pattern
= "TO_STRING"; func
= to_to_string };
2436 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_syntax_kind.ml")
2437 ~
template:full_fidelity_syntax_kind_template
2441 (* GenerateFFTriviaKind *)
2443 module GenerateFFRustSyntaxKind
= struct
2444 let to_tokens x
= sprintf
" %s,\n" x
.kind_name
2446 let to_to_string x
=
2448 (" SyntaxKind::" ^^
kind_name_fmt ^^
" => \"%s\",\n")
2454 let to_ocaml_tag x
=
2456 sprintf
" SyntaxKind::%s => %d,\n" x
.kind_name
!tag
2458 let full_fidelity_syntax_kind_template =
2459 make_header CStyle
""
2462 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2464 use crate::token_kind::TokenKind;
2466 #[derive(Debug, Copy, Clone, FromOcamlRep, ToOcamlRep, PartialEq)]
2467 pub enum SyntaxKind {
2475 pub fn to_string(&self) -> &str {
2477 SyntaxKind::SyntaxList => \"list\",
2478 SyntaxKind::Missing => \"missing\",
2479 SyntaxKind::Token(_) => \"token\",
2483 pub fn ocaml_tag(self) -> u8 {
2485 SyntaxKind::Missing => 0,
2486 SyntaxKind::Token(_) => 0,
2487 SyntaxKind::SyntaxList => 1,
2493 let full_fidelity_syntax_kind =
2494 Full_fidelity_schema.make_template_file
2497 { pattern
= "TOKENS"; func
= to_tokens };
2498 { pattern
= "TO_STRING"; func
= to_to_string };
2499 { pattern
= "OCAML_TAG"; func
= to_ocaml_tag };
2501 ~filename
:(full_fidelity_path_prefix ^
"syntax_kind.rs")
2502 ~
template:full_fidelity_syntax_kind_template
2506 (* GenerateFFRustSyntaxKind *)
2508 module GenerateFFTokenKind
= struct
2509 let given_text_width =
2510 let folder acc x
= max
acc (String.length x
.token_text
) in
2511 List.fold_left ~f
:folder ~init
:0 given_text_tokens
2513 let to_kind_declaration x
= sprintf
" | %s\n" x
.token_kind
2515 let add_guard_or_pad :
2516 cond
:bool * string -> ?else_cond
:bool * string -> string -> string =
2517 fun ~cond
:(cond
, guard
) ?else_cond guards
->
2518 let pad str
= String.make (String.length str
) ' '
in
2519 let is_only_spaces str
= String.equal str
(pad str
) in
2520 let make_same_length str1 str2
=
2522 try String.make n ' '
with
2523 | Invalid_argument _
-> ""
2525 let (len1
, len2
) = (String.length str1
, String.length str2
) in
2526 let str1 = str1 ^
blanks (len2
- len1
) in
2527 let str2 = str2 ^
blanks (len1
- len2
) in
2530 let (else_cond
, else_guard
) =
2531 match else_cond
with
2532 | Some
(cond
, guard
) -> (cond
, guard
)
2533 | None
-> (false, "")
2536 if cond
|| else_cond
then
2537 if is_only_spaces guards
then
2544 let (guard
, else_guard
) = make_same_length guard else_guard
in
2548 else if else_cond
then
2553 guards ^
prefix ^
guard ^
" "
2555 let to_from_string x
=
2556 let token_text = escape_token_text x
.token_text in
2557 let spacer_width = given_text_width - String.length
token_text in
2558 let spacer = String.make spacer_width ' '
in
2560 add_guard_or_pad "" ~cond
:(x
.allowed_as_identifier
, "not only_reserved")
2562 sprintf
" | \"%s\"%s %s-> Some %s\n" token_text spacer guards x
.token_kind
2564 let to_to_string x
=
2565 let token_text = escape_token_text x
.token_text in
2566 sprintf
(" | " ^^
token_kind_fmt ^^
" -> \"%s\"\n") x
.token_kind
token_text
2568 let to_is_variable_text x
= sprintf
" | %s -> true\n" x
.token_kind
2570 let full_fidelity_token_kind_template =
2571 make_header MLStyle
""
2575 (* No text tokens *)
2576 KIND_DECLARATIONS_NO_TEXT (* Given text tokens *)
2577 KIND_DECLARATIONS_GIVEN_TEXT (* Variable text tokens *)
2578 KIND_DECLARATIONS_VARIABLE_TEXT
2579 [@@deriving show, eq, sexp_of]
2581 let from_string keyword ~only_reserved =
2583 | \"true\" when not only_reserved -> Some BooleanLiteral
2584 | \"false\" when not only_reserved -> Some BooleanLiteral
2585 FROM_STRING_GIVEN_TEXT | _ -> None
2587 let to_string kind =
2589 (* No text tokens *)
2590 TO_STRING_NO_TEXT (* Given text tokens *)
2591 TO_STRING_GIVEN_TEXT (* Variable text tokens *)
2592 TO_STRING_VARIABLE_TEXT
2594 let is_variable_text kind =
2596 IS_VARIABLE_TEXT_VARIABLE_TEXT | _ -> false
2599 let full_fidelity_token_kind =
2600 Full_fidelity_schema.make_template_file
2601 ~token_no_text_transformations
:
2604 token_pattern
= "KIND_DECLARATIONS_NO_TEXT";
2605 token_func
= map_and_concat
to_kind_declaration;
2608 token_pattern
= "TO_STRING_NO_TEXT";
2609 token_func
= map_and_concat
to_to_string;
2612 ~token_given_text_transformations
:
2615 token_pattern
= "KIND_DECLARATIONS_GIVEN_TEXT";
2616 token_func
= map_and_concat
to_kind_declaration;
2619 token_pattern
= "FROM_STRING_GIVEN_TEXT";
2620 token_func
= map_and_concat
to_from_string;
2623 token_pattern
= "TO_STRING_GIVEN_TEXT";
2624 token_func
= map_and_concat
to_to_string;
2627 ~token_variable_text_transformations
:
2630 token_pattern
= "KIND_DECLARATIONS_VARIABLE_TEXT";
2631 token_func
= map_and_concat
to_kind_declaration;
2634 token_pattern
= "TO_STRING_VARIABLE_TEXT";
2635 token_func
= map_and_concat
to_to_string;
2638 token_pattern
= "IS_VARIABLE_TEXT_VARIABLE_TEXT";
2639 token_func
= map_and_concat
to_is_variable_text;
2642 ~filename
:(full_fidelity_path_prefix ^
"full_fidelity_token_kind.ml")
2643 ~
template:full_fidelity_token_kind_template
2647 (* GenerateFFTokenKind *)
2649 module GenerateFFRustTokenKind
= struct
2651 match x
.token_kind with
2652 | "Self" -> "SelfToken"
2655 let to_from_string x
=
2656 let token_text = escape_token_text x
.token_text in
2658 if x
.allowed_as_identifier
then
2664 if String.equal
guard "" then
2670 " b\"%s\"%s => Some(TokenKind::%s),\n"
2675 let rust_tag = ref (-1)
2677 let to_kind_declaration x
=
2679 sprintf
" %s = %d,\n" (token_kind x
) !rust_tag
2681 let token_text x
= escape_token_text x
.token_text
2683 let to_to_string x
=
2685 " TokenKind::%s => \"%s\",\n"
2689 let ocaml_tag = ref (-1)
2691 let to_ocaml_tag x
=
2693 sprintf
" TokenKind::%s => %d,\n" (token_kind x
) !ocaml_tag
2695 let from_u8_tag = ref (-1)
2697 let to_try_from_u8 x
=
2700 " %d => Some(TokenKind::%s),\n"
2706 if String.equal
(token_kind x
) "Backslash" then
2709 String.length
(token_text x
)
2713 " TokenKind::%s => Some(unsafe { NonZeroUsize::new_unchecked(%d) }),\n"
2717 let full_fidelity_rust_token_kind_template =
2718 make_header CStyle
""
2721 use std::num::NonZeroUsize;
2723 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2725 #[allow(non_camel_case_types)] // allow Include_once and Require_once
2726 #[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd, FromOcamlRep, ToOcamlRep)]
2728 pub enum TokenKind {
2730 KIND_DECLARATIONS_NO_TEXT // Given text tokens
2731 KIND_DECLARATIONS_GIVEN_TEXT // Variable text tokens
2732 KIND_DECLARATIONS_VARIABLE_TEXT}
2735 pub fn to_string(self) -> &'static str {
2738 TO_STRING_NO_TEXT // Given text tokens
2739 TO_STRING_GIVEN_TEXT // Variable text tokes
2740 TO_STRING_VARIABLE_TEXT }
2745 only_reserved: bool,
2748 b\"true\" if !only_reserved => Some(TokenKind::BooleanLiteral),
2749 b\"false\" if !only_reserved => Some(TokenKind::BooleanLiteral),
2750 FROM_STRING_GIVEN_TEXT _ => None,
2754 pub fn ocaml_tag(self) -> u8 {
2756 OCAML_TAG_NO_TEXTOCAML_TAG_GIVEN_TEXTOCAML_TAG_VARIABLE_TEXT }
2759 pub fn try_from_u8(tag: u8) -> Option<Self> {
2761 FROM_U8_NO_TEXTFROM_U8_GIVEN_TEXTFROM_U8_VARIABLE_TEXT _ => None,
2765 pub fn fixed_width(self) -> Option<NonZeroUsize> {
2767 WIDTH_GIVEN_TEXT _ => None,
2773 let full_fidelity_token_kind =
2774 Full_fidelity_schema.make_template_file
2775 ~token_no_text_transformations
:
2778 token_pattern
= "KIND_DECLARATIONS_NO_TEXT";
2779 token_func
= map_and_concat
to_kind_declaration;
2782 token_pattern
= "TO_STRING_NO_TEXT";
2783 token_func
= map_and_concat
to_to_string;
2786 token_pattern
= "OCAML_TAG_NO_TEXT";
2787 token_func
= map_and_concat
to_ocaml_tag;
2790 token_pattern
= "FROM_U8_NO_TEXT";
2791 token_func
= map_and_concat
to_try_from_u8;
2794 ~token_given_text_transformations
:
2797 token_pattern
= "KIND_DECLARATIONS_GIVEN_TEXT";
2798 token_func
= map_and_concat
to_kind_declaration;
2801 token_pattern
= "FROM_STRING_GIVEN_TEXT";
2802 token_func
= map_and_concat
to_from_string;
2805 token_pattern
= "TO_STRING_GIVEN_TEXT";
2806 token_func
= map_and_concat
to_to_string;
2809 token_pattern
= "OCAML_TAG_GIVEN_TEXT";
2810 token_func
= map_and_concat
to_ocaml_tag;
2813 token_pattern
= "FROM_U8_GIVEN_TEXT";
2814 token_func
= map_and_concat
to_try_from_u8;
2817 token_pattern
= "WIDTH_GIVEN_TEXT";
2818 token_func
= map_and_concat
to_width;
2821 ~token_variable_text_transformations
:
2824 token_pattern
= "KIND_DECLARATIONS_VARIABLE_TEXT";
2825 token_func
= map_and_concat
to_kind_declaration;
2828 token_pattern
= "TO_STRING_VARIABLE_TEXT";
2829 token_func
= map_and_concat
to_to_string;
2832 token_pattern
= "OCAML_TAG_VARIABLE_TEXT";
2833 token_func
= map_and_concat
to_ocaml_tag;
2836 token_pattern
= "FROM_U8_VARIABLE_TEXT";
2837 token_func
= map_and_concat
to_try_from_u8;
2840 ~filename
:(full_fidelity_path_prefix ^
"token_kind.rs")
2841 ~
template:full_fidelity_rust_token_kind_template
2845 (* GenerateFFTRustTokenKind *)
2847 module GenerateFFOperatorRust
= struct
2849 make_header CStyle
""
2852 use ocamlrep::{FromOcamlRep, ToOcamlRep};
2854 #[derive(FromOcamlRep, ToOcamlRep)]
2859 let full_fidelity_operators =
2860 Full_fidelity_schema.make_template_file
2861 ~operator_transformations
:
2864 operator_pattern
= "OPERATORS";
2866 map_and_concat
(fun op
-> sprintf
" %sOperator,\n" op
.name
);
2869 ~filename
:(full_fidelity_path_prefix ^
"operator_generated.rs")
2874 (* GenerateFFOperatorRust *)
2876 module GenerateFFOperator
= struct
2878 make_header MLStyle
""
2880 module type Sig = sig
2882 OPERATOR_DECL_SIGend
2884 module Impl : Sig = struct
2886 OPERATOR_DECL_IMPLend
2889 let op_pattern prefix op
= sprintf
"%s| %sOperator\n" prefix op
.name
2891 let transform pattern
=
2893 operator_pattern
= pattern
;
2894 operator_func
= map_and_concat
(op_pattern " ");
2897 let full_fidelity_operator =
2898 Full_fidelity_schema.make_template_file
2899 ~operator_transformations
:
2900 [transform "OPERATOR_DECL_SIG"; transform "OPERATOR_DECL_IMPL"]
2902 (full_fidelity_path_prefix ^
"full_fidelity_operator_generated.ml")
2907 module GenerateSchemaVersion
= struct
2909 make_header CStyle
""
2912 pub const VERSION: &str = \"%s\";
2914 Full_fidelity_schema.full_fidelity_schema_version_number
2917 Full_fidelity_schema.make_template_file
2919 "hphp/hack/src/parser/schema/full_fidelity_schema_version_number.rs"
2926 GenerateFFOperatorRust.full_fidelity_operators;
2927 GenerateFFOperator.full_fidelity_operator;
2928 GenerateFFSyntaxType.full_fidelity_syntax_type;
2929 GenerateFFSyntaxSig.full_fidelity_syntax_sig;
2930 GenerateFFTriviaKind.full_fidelity_trivia_kind;
2931 GenerateFFRustTriviaKind.full_fidelity_trivia_kind;
2932 GenerateFFSyntax.full_fidelity_syntax;
2933 GenerateFFRustSyntax.full_fidelity_syntax;
2934 GenerateFFRustSyntaxType.full_fidelity_syntax;
2935 GenerateFFSyntaxKind.full_fidelity_syntax_kind;
2936 GenerateFFRustSyntaxKind.full_fidelity_syntax_kind;
2937 GenerateFFTokenKind.full_fidelity_token_kind;
2938 GenerateFFRustTokenKind.full_fidelity_token_kind;
2939 GenerateFFJSONSchema.full_fidelity_json_schema
;
2940 GenerateFFSmartConstructors.full_fidelity_smart_constructors;
2941 GenerateFFRustSmartConstructors.full_fidelity_smart_constructors;
2942 GenerateFFRustPositionedSmartConstructors.positioned_smart_constructors;
2943 GenerateFFSyntaxSmartConstructors.full_fidelity_syntax_smart_constructors;
2944 GenerateFFRustSyntaxSmartConstructors
2945 .full_fidelity_syntax_smart_constructors;
2946 GenerateFFRustDeclModeSmartConstructors.decl_mode_smart_constructors;
2947 GenerateRustFlattenSmartConstructors.flatten_smart_constructors;
2948 GenerateRustDirectDeclSmartConstructors.direct_decl_smart_constructors;
2949 GenerateRustPairSmartConstructors.pair_smart_constructors;
2950 GenerateFFSmartConstructorsWrappers
2951 .full_fidelity_smart_constructors_wrappers;
2952 GenerateFFRustSmartConstructorsWrappers
2953 .full_fidelity_smart_constructors_wrappers;
2954 GenerateFFRustSyntaxVariantByRef.full_fidelity_syntax;
2955 GenerateSyntaxTypeImpl.full_fidelity_syntax;
2956 GenerateSyntaxChildrenIterator.full_fidelity_syntax;
2957 GenerateFFRustSyntaxImplByRef.full_fidelity_syntax;
2958 GenerateSyntaxSerialize.gen;
2959 GenerateSchemaVersion.gen;