1 // Copyright (c) Facebook, Inc. and its affiliates.
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>
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>,
29 ) -> Option<Syntax<T, V>>
31 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
33 let kind = node.kind();
35 SyntaxKind::Token(_) => (),
37 let mut new_children = vec![];
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)
43 new_children.push(new_child);
46 node = path.pop().unwrap();
47 node.replace_children(kind, new_children);
53 pub fn parented_aggregating_rewrite_post<F>(
57 ) -> (Syntax<T, V>, A)
59 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
62 Self::parented_aggregating_rewrite_post_helper(&mut vec![], node, &mut acc, &mut f)
63 .expect("rewriter removed root node");
67 pub fn aggregating_rewrite_post<F>(node: Syntax<T, V>, acc: A, mut f: F) -> (Syntax<T, V>, A)
69 F: FnMut(Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
71 Self::parented_aggregating_rewrite_post(node, acc, |_, node, acc| f(node, acc))
74 fn parented_aggregating_rewrite_pre_helper<F>(
75 path: &mut Vec<Syntax<T, V>>,
79 ) -> Option<Syntax<T, V>>
81 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
83 let mut node = match f(path, node, acc) {
87 let kind = node.kind();
89 SyntaxKind::Token(_) => (),
91 let mut new_children = vec![];
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)
97 new_children.push(new_child);
100 node = path.pop().unwrap();
101 node.replace_children(kind, new_children);
107 pub fn parented_aggregating_rewrite_pre<F>(
111 ) -> (Syntax<T, V>, A)
113 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
116 Self::parented_aggregating_rewrite_pre_helper(&mut vec![], node, &mut acc, &mut f)
117 .expect("rewriter removed root node");
121 pub fn aggregating_rewrite_pre<F>(node: Syntax<T, V>, acc: A, mut f: F) -> (Syntax<T, V>, A)
123 F: FnMut(Syntax<T, V>, &mut A) -> Option<Syntax<T, V>>,
125 Self::parented_aggregating_rewrite_pre(node, acc, |_, node, acc| f(node, acc))
128 fn rewrite_pre_and_stop_with_acc_helper<F>(
132 ) -> Option<Syntax<T, V>>
134 F: FnMut(Syntax<T, V>, &mut A) -> (Option<Syntax<T, V>>, bool),
136 let mut node = match f(node, acc) {
137 (None, _) => return None,
138 (node, true) => return node,
139 (node, _) => node.unwrap(),
142 let kind = node.kind();
144 SyntaxKind::Token(_) => (),
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)
151 new_children.push(new_child);
154 node.replace_children(kind, new_children);
160 pub fn rewrite_pre_and_stop_with_acc<F>(
164 ) -> (Syntax<T, V>, A)
166 F: FnMut(Syntax<T, V>, &mut A) -> (Option<Syntax<T, V>>, bool),
168 let node = Self::rewrite_pre_and_stop_with_acc_helper(node, &mut acc, &mut f)
169 .expect("rewriter removed root node");
174 impl<'src, T, V> Rewriter<'src, T, V, ()>
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>
181 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>) -> Option<Syntax<T, V>>,
183 Self::parented_aggregating_rewrite_post(node, (), |parents, node, _| f(parents, node)).0
186 pub fn rewrite_post<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
188 F: FnMut(Syntax<T, V>) -> Option<Syntax<T, V>>,
190 Self::parented_aggregating_rewrite_post(node, (), |_, node, _| f(node)).0
193 pub fn parented_rewrite_pre<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
195 F: FnMut(&Vec<Syntax<T, V>>, Syntax<T, V>) -> Option<Syntax<T, V>>,
197 Self::parented_aggregating_rewrite_pre(node, (), |parents, node, _| f(parents, node)).0
200 pub fn rewrite_pre<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
202 F: FnMut(Syntax<T, V>) -> Option<Syntax<T, V>>,
204 Self::parented_aggregating_rewrite_pre(node, (), |_, node, _| f(node)).0
207 pub fn rewrite_pre_and_stop<F>(node: Syntax<T, V>, mut f: F) -> Syntax<T, V>
209 F: FnMut(Syntax<T, V>) -> (Option<Syntax<T, V>>, bool),
211 Self::rewrite_pre_and_stop_with_acc(node, (), |node, _| f(node)).0