Multiply entities beyond necessity even more (force better build parallelism)
[hiphop-php.git] / hphp / hack / src / parser / rewriter.rs
blobf91d88827fbf01e69f3a35679f8b1f2c4653c022
1 // Copyright (c) Facebook, Inc. and its affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 use crate::lexable_token::LexableToken;
7 use crate::syntax::{Syntax, SyntaxValueType};
8 use crate::syntax_kind::SyntaxKind;
10 use std::marker::PhantomData;
12 pub struct Rewriter<'src, T, V, A> {
13     _phantom_src: PhantomData<&'src str>,
14     _phantom_t: PhantomData<*const T>,
15     _phantom_v: PhantomData<*const V>,
16     _phantom_a: PhantomData<*const A>,
19 impl<'src, T, V, A> Rewriter<'src, T, V, A>
20 where
21     T: LexableToken<'src>,
22     V: SyntaxValueType<T>,
24     fn parented_aggregating_rewrite_post_helper<F>(
25         path: &mut Vec<Syntax<T, V>>,
26         mut node: Syntax<T, V>,
27         acc: &mut A,
28         f: &mut F,
29     ) -> Option<Syntax<T, V>>
30     where
31         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
32     {
33         let kind = node.kind();
34         match kind {
35             SyntaxKind::Token(_) => (),
36             _ => {
37                 let mut new_children = vec![];
38                 path.push(node);
39                 for owned_child in path.last_mut().unwrap().drain_children() {
40                     if let Some(new_child) =
41                         Self::parented_aggregating_rewrite_post_helper(path, owned_child, acc, f)
42                     {
43                         new_children.push(new_child);
44                     }
45                 }
46                 node = path.pop().unwrap();
47                 node.replace_children(kind, new_children);
48             }
49         };
50         f(path, node, acc)
51     }
53     pub fn parented_aggregating_rewrite_post<F>(
54         node: Syntax<T, V>,
55         mut acc: A,
56         mut f: F,
57     ) -> (Syntax<T, V>, A)
58     where
59         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
60     {
61         let node =
62             Self::parented_aggregating_rewrite_post_helper(&mut vec![], node, &mut acc, &mut f)
63                 .expect("rewriter removed root node");
64         (node, acc)
65     }
67     pub fn aggregating_rewrite_post<F>(node: Syntax<T, V>, acc: A, mut f: F) -> (Syntax<T, V>, A)
68     where
69         F: FnMut(Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
70     {
71         Self::parented_aggregating_rewrite_post(node, acc, |_, node, acc| f(node, acc))
72     }
74     fn parented_aggregating_rewrite_pre_helper<F>(
75         path: &mut Vec<Syntax<T, V>>,
76         node: Syntax<T, V>,
77         acc: &mut A,
78         f: &mut F,
79     ) -> Option<Syntax<T, V>>
80     where
81         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
82     {
83         let mut node = match f(path, node, acc) {
84             Some(node) => node,
85             None => return None,
86         };
87         let kind = node.kind();
88         match kind {
89             SyntaxKind::Token(_) => (),
90             _ => {
91                 let mut new_children = vec![];
92                 path.push(node);
93                 for owned_child in path.last_mut().unwrap().drain_children() {
94                     if let Some(new_child) =
95                         Self::parented_aggregating_rewrite_pre_helper(path, owned_child, acc, f)
96                     {
97                         new_children.push(new_child);
98                     }
99                 }
100                 node = path.pop().unwrap();
101                 node.replace_children(kind, new_children);
102             }
103         };
104         Some(node)
105     }
107     pub fn parented_aggregating_rewrite_pre<F>(
108         node: Syntax<T, V>,
109         mut acc: A,
110         mut f: F,
111     ) -> (Syntax<T, V>, A)
112     where
113         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
114     {
115         let node =
116             Self::parented_aggregating_rewrite_pre_helper(&mut vec![], node, &mut acc, &mut f)
117                 .expect("rewriter removed root node");
118         (node, acc)
119     }
121     pub fn aggregating_rewrite_pre<F>(node: Syntax<T, V>, acc: A, mut f: F) -> (Syntax<T, V>, A)
122     where
123         F: FnMut(Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
124     {
125         Self::parented_aggregating_rewrite_pre(node, acc, |_, node, acc| f(node, acc))
126     }
128     fn rewrite_pre_and_stop_with_acc_helper<F>(
129         node: Syntax<T, V>,
130         acc: &mut A,
131         f: &mut F,
132     ) -> Option<Syntax<T, V>>
133     where
134         F: FnMut(Syntax<T, V>, &mut A) -> (Option<Syntax<T, V>>, bool),
135     {
136         let mut node = match f(node, acc) {
137             (None, _) => return None,
138             (node, true) => return node,
139             (node, _) => node.unwrap(),
140         };
142         let kind = node.kind();
143         match kind {
144             SyntaxKind::Token(_) => (),
145             _ => {
146                 let mut new_children = vec![];
147                 for owned_child in node.drain_children() {
148                     if let Some(new_child) =
149                         Self::rewrite_pre_and_stop_with_acc_helper(owned_child, acc, f)
150                     {
151                         new_children.push(new_child);
152                     }
153                 }
154                 node.replace_children(kind, new_children);
155             }
156         };
157         Some(node)
158     }
160     pub fn rewrite_pre_and_stop_with_acc<F>(
161         node: Syntax<T, V>,
162         mut acc: A,
163         mut f: F,
164     ) -> (Syntax<T, V>, A)
165     where
166         F: FnMut(Syntax<T, V>, &mut A) -> (Option<Syntax<T, V>>, bool),
167     {
168         let node = Self::rewrite_pre_and_stop_with_acc_helper(node, &mut acc, &mut f)
169             .expect("rewriter removed root node");
170         (node, acc)
171     }
174 impl<'src, T, V> Rewriter<'src, T, V, ()>
175 where
176     T: LexableToken<'src>,
177     V: SyntaxValueType<T>,
179     pub fn parented_rewrite_post<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
180     where
181         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>) -> Option<Syntax<T, V>>,
182     {
183         Self::parented_aggregating_rewrite_post(node, (), |parents, node, _| f(parents, node)).0
184     }
186     pub fn rewrite_post<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
187     where
188         F: FnMut(Syntax<T, V>) -> Option<Syntax<T, V>>,
189     {
190         Self::parented_aggregating_rewrite_post(node, (), |_, node, _| f(node)).0
191     }
193     pub fn parented_rewrite_pre<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
194     where
195         F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>) -> Option<Syntax<T, V>>,
196     {
197         Self::parented_aggregating_rewrite_pre(node, (), |parents, node, _| f(parents, node)).0
198     }
200     pub fn rewrite_pre<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
201     where
202         F: FnMut(Syntax<T, V>) -> Option<Syntax<T, V>>,
203     {
204         Self::parented_aggregating_rewrite_pre(node, (), |_, node, _| f(node)).0
205     }
207     pub fn rewrite_pre_and_stop<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
208     where
209         F: FnMut(Syntax<T, V>) -> (Option<Syntax<T, V>>, bool),
210     {
211         Self::rewrite_pre_and_stop_with_acc(node, (), |node, _| f(node)).0
212     }