1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 use ocamlrep_derive::OcamlRep;
9 use parser_core_types::syntax_kind::SyntaxKind;
10 use parser_core_types::token_kind::TokenKind;
12 pub use crate::smart_constructors_generated::*;
13 pub use crate::smart_constructors_wrappers::*;
15 // Usage: S!(make_foo, parser, arg1, ...) (in OCaml: Make.foo parser arg1 ...)
16 // Corresponds to a call to Make.foo followed by sc_call in OCaml (see *{precedence,simple}_parser)
17 // - Make.foo first calls SmartConstructorsWrapper, which calls parser's call method,
18 // - parser's call method forwards to SmartConstructors' make_foo(parser.sc_state, ...),
19 // returning (sc_state, result)
20 // - parser's sc_state is updated with sc_state, and result is forwarded
21 // Instead of generating two 183-method SC wrappers in Rust, just use a simple macro.
23 // special cases to avoid borrow checker error in common cases (150+) such as:
24 // S!(make_missing, self, self.pos())
25 (make_list, $parser: expr, $r: expr, $pos: expr) => {{
27 S_!(make_list, $parser, $r, pos)
29 (make_missing, $parser: expr, $pos: expr) => {{
31 S_!(make_missing, $parser, pos)
34 ($f: ident, $parser: expr, $($rs:expr),* $(,)*) => {
35 S_!($f, $parser, $($rs),+)
39 ($f: ident, $parser: expr, $($rs:expr),* $(,)*) => {{
40 let result = $parser.sc_mut().$f($($rs),+);
41 $parser.check_stack_limit();
46 #[derive(Clone, OcamlRep)]
47 pub struct NoState; // zero-overhead placeholder when there is no state
51 fn extract(self) -> Self::R;
52 fn is_missing(&self) -> bool;
53 fn is_abstract(&self) -> bool;
54 fn is_variable_expression(&self) -> bool;
55 fn is_subscript_expression(&self) -> bool;
56 fn is_member_selection_expression(&self) -> bool;
57 fn is_scope_resolution_expression(&self) -> bool;
58 fn is_object_creation_expression(&self) -> bool;
59 fn is_qualified_name(&self) -> bool;
60 fn is_safe_member_selection_expression(&self) -> bool;
61 fn is_function_call_expression(&self) -> bool;
62 fn is_list_expression(&self) -> bool;
63 fn is_name(&self) -> bool;
64 fn is_halt_compiler_expression(&self) -> bool;
65 fn is_prefix_unary_expression(&self) -> bool;
68 impl<R> NodeType for (SyntaxKind, R) {
71 fn extract(self) -> Self::R {
75 fn is_missing(&self) -> bool {
77 SyntaxKind::Missing => true,
82 fn is_abstract(&self) -> bool {
84 SyntaxKind::Token(TokenKind::Abstract) => true,
89 fn is_name(&self) -> bool {
91 SyntaxKind::Token(TokenKind::Name) => true,
96 // Note: we could generate ~150 methods like those below but most would be dead
98 fn is_variable_expression(&self) -> bool {
100 SyntaxKind::VariableExpression { .. } => true,
105 fn is_subscript_expression(&self) -> bool {
107 SyntaxKind::SubscriptExpression { .. } => true,
112 fn is_member_selection_expression(&self) -> bool {
114 SyntaxKind::MemberSelectionExpression { .. } => true,
119 fn is_scope_resolution_expression(&self) -> bool {
121 SyntaxKind::ScopeResolutionExpression { .. } => true,
126 fn is_object_creation_expression(&self) -> bool {
128 SyntaxKind::ObjectCreationExpression { .. } => true,
133 fn is_qualified_name(&self) -> bool {
135 SyntaxKind::QualifiedName { .. } => true,
140 fn is_safe_member_selection_expression(&self) -> bool {
142 SyntaxKind::SafeMemberSelectionExpression { .. } => true,
147 fn is_function_call_expression(&self) -> bool {
149 SyntaxKind::FunctionCallExpression { .. } => true,
154 fn is_list_expression(&self) -> bool {
156 SyntaxKind::ListExpression { .. } => true,
161 fn is_halt_compiler_expression(&self) -> bool {
163 SyntaxKind::HaltCompilerExpression { .. } => true,
168 fn is_prefix_unary_expression(&self) -> bool {
170 SyntaxKind::PrefixUnaryExpression { .. } => true,