deprecate coroutine
[hiphop-php.git] / hphp / hack / src / parser / syntax.rs
blob96de3999b0b9dd12cce0bc2919de499983d1e159
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
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 crate::lexable_token::LexableToken;
8 use crate::syntax_kind::SyntaxKind;
9 use crate::token_kind::TokenKind;
11 use std::fmt::Debug;
12 use std::marker::Sized;
14 use itertools::Either::{Left, Right};
16 pub use crate::syntax_generated::*;
17 pub use crate::syntax_type::*;
19 pub trait SyntaxValueType<T>
20 where
21     Self: Sized,
23     fn from_syntax(syntax: &SyntaxVariant<T, Self>) -> Self;
24     fn from_values(ndoes: &[&Self]) -> Self;
25     fn from_children(kind: SyntaxKind, offset: usize, nodes: &[&Self]) -> Self;
26     fn from_token(token: &T) -> Self;
28     /// Returns a range [inclusive, exclusive] for the corresponding text if meaningful
29     /// (note: each implementor will either always return Some(range) or always return None).
30     fn text_range(&self) -> Option<(usize, usize)>; // corresponds to extract_text in OCaml impl.
33 pub trait SyntaxValueWithKind
34 where
35     Self: Debug,
37     fn is_missing(&self) -> bool;
38     fn token_kind(&self) -> Option<TokenKind>;
41 #[derive(Debug, Clone)]
42 pub struct Syntax<T, V> {
43     pub syntax: SyntaxVariant<T, V>,
44     pub value: V,
47 pub trait SyntaxTypeBase<'a, C> {
48     type Token: LexableToken<'a>;
49     type Value: SyntaxValueType<Self::Token>;
51     fn make_missing(ctx: &C, offset: usize) -> Self;
52     fn make_token(ctx: &C, arg: Self::Token) -> Self;
53     fn make_list(ctx: &C, arg: Vec<Self>, offset: usize) -> Self
54     where
55         Self: Sized;
57     fn value(&self) -> &Self::Value;
60 impl<'a, T, V, C> SyntaxTypeBase<'a, C> for Syntax<T, V>
61 where
62     T: LexableToken<'a>,
63     V: SyntaxValueType<T>,
65     type Token = T;
66     type Value = V;
68     fn make_missing(_: &C, offset: usize) -> Self {
69         let value = V::from_children(SyntaxKind::Missing, offset, &[]);
70         let syntax = SyntaxVariant::Missing;
71         Self::make(syntax, value)
72     }
74     fn make_token(_: &C, arg: T) -> Self {
75         Self::make_token(arg)
76     }
78     fn make_list(ctx: &C, arg: Vec<Self>, offset: usize) -> Self {
79         // An empty list is represented by Missing; everything else is a
80         // SyntaxList, even if the list has only one item.
81         if arg.is_empty() {
82             Self::make_missing(ctx, offset)
83         } else {
84             // todo: pass iter directly
85             let nodes = &arg.iter().map(|x| &x.value).collect::<Vec<_>>();
86             let value = V::from_children(SyntaxKind::SyntaxList, offset, nodes);
87             let syntax = SyntaxVariant::SyntaxList(arg);
88             Self::make(syntax, value)
89         }
90     }
92     fn value(&self) -> &Self::Value {
93         &self.value
94     }
97 impl<'src, T, V> Syntax<T, V>
98 where
99     T: LexableToken<'src>,
100     V: SyntaxValueType<T>,
102     pub fn make(syntax: SyntaxVariant<T, V>, value: V) -> Self {
103         Self { syntax, value }
104     }
106     pub fn make_token(arg: T) -> Self {
107         let value = V::from_token(&arg);
108         let syntax = SyntaxVariant::Token(Box::new(arg));
109         Self::make(syntax, value)
110     }
112     fn is_specific_token(&self, kind: TokenKind) -> bool {
113         match &self.syntax {
114             SyntaxVariant::Token(t) => t.kind() == kind,
115             _ => false,
116         }
117     }
119     pub fn is_public(&self) -> bool {
120         self.is_specific_token(TokenKind::Public)
121     }
123     pub fn is_private(&self) -> bool {
124         self.is_specific_token(TokenKind::Private)
125     }
127     pub fn is_protected(&self) -> bool {
128         self.is_specific_token(TokenKind::Protected)
129     }
131     pub fn is_abstract(&self) -> bool {
132         self.is_specific_token(TokenKind::Abstract)
133     }
135     pub fn is_static(&self) -> bool {
136         self.is_specific_token(TokenKind::Static)
137     }
139     pub fn is_ampersand(&self) -> bool {
140         self.is_specific_token(TokenKind::Ampersand)
141     }
143     pub fn is_ellipsis(&self) -> bool {
144         self.is_specific_token(TokenKind::DotDotDot)
145     }
147     pub fn is_final(&self) -> bool {
148         self.is_specific_token(TokenKind::Final)
149     }
151     pub fn is_xhp(&self) -> bool {
152         self.is_specific_token(TokenKind::XHP)
153     }
155     pub fn is_async(&self) -> bool {
156         self.is_specific_token(TokenKind::Async)
157     }
159     pub fn is_yield(&self) -> bool {
160         self.is_specific_token(TokenKind::Yield)
161     }
163     pub fn is_construct(&self) -> bool {
164         self.is_specific_token(TokenKind::Construct)
165     }
167     pub fn is_void(&self) -> bool {
168         self.is_specific_token(TokenKind::Void)
169     }
171     pub fn is_left_brace(&self) -> bool {
172         self.is_specific_token(TokenKind::LeftBrace)
173     }
175     pub fn is_comma(&self) -> bool {
176         self.is_specific_token(TokenKind::Comma)
177     }
179     pub fn is_inout(&self) -> bool {
180         self.is_specific_token(TokenKind::Inout)
181     }
183     pub fn is_this(&self) -> bool {
184         self.is_specific_token(TokenKind::This)
185     }
187     pub fn is_name(&self) -> bool {
188         self.is_specific_token(TokenKind::Name)
189     }
191     pub fn is_as_expression(&self) -> bool {
192         self.kind() == SyntaxKind::AsExpression
193     }
195     pub fn is_missing(&self) -> bool {
196         self.kind() == SyntaxKind::Missing
197     }
199     pub fn is_external(&self) -> bool {
200         self.is_specific_token(TokenKind::Semicolon) || self.is_missing()
201     }
203     pub fn is_namespace_empty_body(&self) -> bool {
204         self.kind() == SyntaxKind::NamespaceEmptyBody
205     }
207     pub fn is_attribute_specification(&self) -> bool {
208         self.kind() == SyntaxKind::AttributeSpecification
209     }
211     pub fn is_old_attribute_specification(&self) -> bool {
212         self.kind() == SyntaxKind::OldAttributeSpecification
213     }
215     pub fn is_file_attribute_specification(&self) -> bool {
216         self.kind() == SyntaxKind::FileAttributeSpecification
217     }
219     pub fn is_return_statement(&self) -> bool {
220         self.kind() == SyntaxKind::ReturnStatement
221     }
223     pub fn is_conditional_expression(&self) -> bool {
224         self.kind() == SyntaxKind::ConditionalExpression
225     }
227     pub fn is_safe_member_selection_expression(&self) -> bool {
228         self.kind() == SyntaxKind::SafeMemberSelectionExpression
229     }
231     pub fn is_object_creation_expression(&self) -> bool {
232         self.kind() == SyntaxKind::ObjectCreationExpression
233     }
235     pub fn is_compound_statement(&self) -> bool {
236         self.kind() == SyntaxKind::CompoundStatement
237     }
239     pub fn is_methodish_declaration(&self) -> bool {
240         self.kind() == SyntaxKind::MethodishDeclaration
241     }
243     pub fn is_function_declaration(&self) -> bool {
244         self.kind() == SyntaxKind::FunctionDeclaration
245     }
247     pub fn is_xhp_open(&self) -> bool {
248         self.kind() == SyntaxKind::XHPOpen
249     }
251     pub fn is_braced_expression(&self) -> bool {
252         self.kind() == SyntaxKind::BracedExpression
253     }
255     pub fn is_syntax_list(&self) -> bool {
256         self.kind() == SyntaxKind::SyntaxList
257     }
259     pub fn syntax_node_to_list<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Self> {
260         use std::iter::{empty, once};
261         match &self.syntax {
262             SyntaxVariant::SyntaxList(x) => Left(x.iter()),
263             SyntaxVariant::Missing => Right(Left(empty())),
264             _ => Right(Right(once(self))),
265         }
266     }
268     pub fn syntax_node_into_list(self) -> impl DoubleEndedIterator<Item = Self> {
269         use std::iter::{empty, once};
270         match self.syntax {
271             SyntaxVariant::SyntaxList(x) => Left(x.into_iter()),
272             SyntaxVariant::Missing => Right(Left(empty())),
273             _ => Right(Right(once(self))),
274         }
275     }
277     pub fn syntax_node_to_list_skip_separator<'a>(
278         &'a self,
279     ) -> impl DoubleEndedIterator<Item = &'a Self> {
280         use std::iter::{empty, once};
281         match &self.syntax {
282             SyntaxVariant::SyntaxList(l) => Left(l.iter().map(|n| match &n.syntax {
283                 SyntaxVariant::ListItem(i) => &i.list_item,
284                 _ => n,
285             })),
286             SyntaxVariant::Missing => Right(Left(empty())),
287             _ => Right(Right(once(self))),
288         }
289     }
291     pub fn is_namespace_prefix(&self) -> bool {
292         if let SyntaxVariant::QualifiedName(x) = &self.syntax {
293             x.qualified_name_parts
294                 .syntax_node_to_list()
295                 .last()
296                 .map_or(false, |p| match &p.syntax {
297                     SyntaxVariant::ListItem(x) => !&x.list_separator.is_missing(),
298                     _ => false,
299                 })
300         } else {
301             false
302         }
303     }
305     pub fn drain_children(&mut self) -> Vec<Self> {
306         let f = |node: Self, mut acc: Vec<Self>| {
307             acc.push(node);
308             acc
309         };
310         let syntax = std::mem::replace(&mut self.syntax, SyntaxVariant::Missing);
311         Self::fold_over_children_owned(&f, vec![], syntax)
312     }
314     pub fn replace_children(
315         &mut self,
316         kind: SyntaxKind,
317         children: Vec<Self>,
318         children_changed: bool,
319     ) {
320         if !children_changed {
321             self.syntax = Syntax::from_children(kind, children);
322         } else {
323             let children_values = &children.iter().map(|x| &x.value).collect::<Vec<_>>();
324             let value = V::from_children(kind, 0, children_values);
325             let syntax = Syntax::from_children(kind, children);
326             *self = Self::make(syntax, value);
327         }
328     }
330     pub fn get_token(&self) -> Option<&T> {
331         match &self.syntax {
332             SyntaxVariant::Token(t) => Some(&t),
333             _ => None,
334         }
335     }
337     pub fn leading_token(&self) -> Option<&T> {
338         match self.get_token() {
339             Some(token) => Some(token),
340             None => {
341                 for node in self.iter_children() {
342                     if let Some(token) = node.leading_token() {
343                         return Some(token);
344                     }
345                 }
346                 None
347             }
348         }
349     }
351     pub fn trailing_token(&self) -> Option<&T> {
352         match self.get_token() {
353             Some(token) => Some(token),
354             None => {
355                 for node in self.iter_children().rev() {
356                     if let Some(token) = node.trailing_token() {
357                         return Some(token);
358                     }
359                 }
360                 None
361             }
362         }
363     }
365     pub fn iter_children<'a>(&'a self) -> SyntaxChildrenIterator<'a, T, V> {
366         self.syntax.iter_children()
367     }
369     pub fn all_tokens<'a>(node: &'a Self) -> Vec<&'a T> {
370         Self::all_tokens_with_acc(node, vec![])
371     }
373     fn all_tokens_with_acc<'a>(node: &'a Self, mut acc: Vec<&'a T>) -> Vec<&'a T> {
374         match &node.syntax {
375             SyntaxVariant::Token(t) => acc.push(t),
376             _ => {
377                 for child in node.iter_children() {
378                     acc = Self::all_tokens_with_acc(child, acc)
379                 }
380             }
381         };
382         acc
383     }
386 pub struct SyntaxChildrenIterator<'a, T, V> {
387     pub syntax: &'a SyntaxVariant<T, V>,
388     pub index: usize,
389     pub index_back: usize,
392 impl<'src, T, V> SyntaxVariant<T, V> {
393     pub fn iter_children<'a>(&'a self) -> SyntaxChildrenIterator<'a, T, V> {
394         SyntaxChildrenIterator {
395             syntax: &self,
396             index: 0,
397             index_back: 0,
398         }
399     }
402 impl<'a, T, V> Iterator for SyntaxChildrenIterator<'a, T, V> {
403     type Item = &'a Syntax<T, V>;
404     fn next(&mut self) -> Option<Self::Item> {
405         self.next_impl(true)
406     }
409 impl<'a, T, V> DoubleEndedIterator for SyntaxChildrenIterator<'a, T, V> {
410     fn next_back(&mut self) -> Option<Self::Item> {
411         self.next_impl(false)
412     }