diff options
author | Aleksey Kladov <[email protected]> | 2018-08-14 11:33:44 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-14 11:33:44 +0100 |
commit | 1141d448d960eedba0a5647d525910de706bf778 (patch) | |
tree | 144842663edc382addc6b2cb115717d5bb7eb736 /crates/libsyntax2 | |
parent | 5953a348bd6102a868f303d3f732a6ec7d465833 (diff) |
Add derive intention
Diffstat (limited to 'crates/libsyntax2')
-rw-r--r-- | crates/libsyntax2/src/algo/search.rs | 136 | ||||
-rw-r--r-- | crates/libsyntax2/src/ast/generated.rs | 25 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar.ron | 4 |
3 files changed, 28 insertions, 137 deletions
diff --git a/crates/libsyntax2/src/algo/search.rs b/crates/libsyntax2/src/algo/search.rs deleted file mode 100644 index 46404f537..000000000 --- a/crates/libsyntax2/src/algo/search.rs +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | use {Node, NodeType, TextUnit, TextRange}; | ||
2 | use ::visitor::{visitor, process_subtree_bottom_up}; | ||
3 | |||
4 | pub fn child_of_type(node: Node, ty: NodeType) -> Option<Node> { | ||
5 | node.children().find(|n| n.ty() == ty) | ||
6 | } | ||
7 | |||
8 | pub fn children_of_type<'f>(node: Node<'f>, ty: NodeType) -> Box<Iterator<Item=Node<'f>> + 'f> { | ||
9 | Box::new(node.children().filter(move |n| n.ty() == ty)) | ||
10 | } | ||
11 | |||
12 | pub fn subtree<'f>(node: Node<'f>) -> Box<Iterator<Item=Node<'f>> + 'f> { | ||
13 | Box::new(node.children().flat_map(subtree).chain(::std::iter::once(node))) | ||
14 | } | ||
15 | |||
16 | pub fn descendants_of_type<'f>(node: Node<'f>, ty: NodeType) -> Vec<Node<'f>> { | ||
17 | process_subtree_bottom_up( | ||
18 | node, | ||
19 | visitor(Vec::new()) | ||
20 | .visit_nodes(&[ty], |node, nodes| nodes.push(node)) | ||
21 | ) | ||
22 | } | ||
23 | |||
24 | pub fn child_of_type_exn(node: Node, ty: NodeType) -> Node { | ||
25 | child_of_type(node, ty).unwrap_or_else(|| { | ||
26 | panic!("No child of type {:?} for {:?}\ | ||
27 | ----\ | ||
28 | {}\ | ||
29 | ----", ty, node.ty(), node.text()) | ||
30 | }) | ||
31 | } | ||
32 | |||
33 | |||
34 | pub fn ancestors(node: Node) -> Ancestors { | ||
35 | Ancestors(Some(node)) | ||
36 | } | ||
37 | |||
38 | pub struct Ancestors<'f>(Option<Node<'f>>); | ||
39 | |||
40 | impl<'f> Iterator for Ancestors<'f> { | ||
41 | type Item = Node<'f>; | ||
42 | |||
43 | fn next(&mut self) -> Option<Self::Item> { | ||
44 | let current = self.0; | ||
45 | self.0 = current.and_then(|n| n.parent()); | ||
46 | current | ||
47 | } | ||
48 | } | ||
49 | |||
50 | pub fn is_leaf(node: Node) -> bool { | ||
51 | node.children().next().is_none() && !node.range().is_empty() | ||
52 | } | ||
53 | |||
54 | |||
55 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] | ||
56 | pub enum Direction { | ||
57 | Left, Right | ||
58 | } | ||
59 | |||
60 | pub fn sibling(node: Node, dir: Direction) -> Option<Node> { | ||
61 | let (parent, idx) = child_position(node)?; | ||
62 | let idx = match dir { | ||
63 | Direction::Left => idx.checked_sub(1)?, | ||
64 | Direction::Right => idx + 1, | ||
65 | }; | ||
66 | parent.children().nth(idx) | ||
67 | } | ||
68 | |||
69 | pub mod ast { | ||
70 | use {Node, AstNode, TextUnit, AstChildren}; | ||
71 | use visitor::{visitor, process_subtree_bottom_up}; | ||
72 | use super::{ancestors, find_leaf_at_offset, LeafAtOffset}; | ||
73 | |||
74 | pub fn ancestor<'f, T: AstNode<'f>>(node: Node<'f>) -> Option<T> { | ||
75 | ancestors(node) | ||
76 | .filter_map(T::wrap) | ||
77 | .next() | ||
78 | } | ||
79 | |||
80 | pub fn ancestor_exn<'f, T: AstNode<'f>>(node: Node<'f>) -> T { | ||
81 | ancestor(node).unwrap() | ||
82 | } | ||
83 | |||
84 | pub fn children_of_type<'f, N: AstNode<'f>>(node: Node<'f>) -> AstChildren<N> { | ||
85 | AstChildren::new(node.children()) | ||
86 | } | ||
87 | |||
88 | pub fn descendants_of_type<'f, N: AstNode<'f>>(node: Node<'f>) -> Vec<N> { | ||
89 | process_subtree_bottom_up( | ||
90 | node, | ||
91 | visitor(Vec::new()) | ||
92 | .visit::<N, _>(|node, acc| acc.push(node)) | ||
93 | ) | ||
94 | } | ||
95 | |||
96 | pub fn node_at_offset<'f, T: AstNode<'f>>(node: Node<'f>, offset: TextUnit) -> Option<T> { | ||
97 | match find_leaf_at_offset(node, offset) { | ||
98 | LeafAtOffset::None => None, | ||
99 | LeafAtOffset::Single(node) => ancestor(node), | ||
100 | LeafAtOffset::Between(left, right) => ancestor(left).or_else(|| ancestor(right)), | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | |||
105 | pub mod traversal { | ||
106 | use {Node}; | ||
107 | |||
108 | pub fn bottom_up<'f, F: FnMut(Node<'f>)>(node: Node<'f>, mut f: F) | ||
109 | { | ||
110 | go(node, &mut f); | ||
111 | |||
112 | fn go<'f, F: FnMut(Node<'f>)>(node: Node<'f>, f: &mut F) { | ||
113 | for child in node.children() { | ||
114 | go(child, f) | ||
115 | } | ||
116 | f(node); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | fn child_position(child: Node) -> Option<(Node, usize)> { | ||
122 | child.parent() | ||
123 | .map(|parent| { | ||
124 | (parent, parent.children().position(|n| n == child).unwrap()) | ||
125 | }) | ||
126 | } | ||
127 | |||
128 | fn common_ancestor<'f>(n1: Node<'f>, n2: Node<'f>) -> Node<'f> { | ||
129 | for p in ancestors(n1) { | ||
130 | if ancestors(n2).any(|a| a == p) { | ||
131 | return p; | ||
132 | } | ||
133 | } | ||
134 | panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) | ||
135 | } | ||
136 | |||
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 3e6c673ab..80670ce71 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs | |||
@@ -267,6 +267,31 @@ impl<R: TreeRoot> AstNode<R> for NeverType<R> { | |||
267 | 267 | ||
268 | impl<R: TreeRoot> NeverType<R> {} | 268 | impl<R: TreeRoot> NeverType<R> {} |
269 | 269 | ||
270 | // NominalDef | ||
271 | #[derive(Debug, Clone, Copy)] | ||
272 | pub enum NominalDef<R: TreeRoot = Arc<SyntaxRoot>> { | ||
273 | StructDef(StructDef<R>), | ||
274 | EnumDef(EnumDef<R>), | ||
275 | } | ||
276 | |||
277 | impl<R: TreeRoot> AstNode<R> for NominalDef<R> { | ||
278 | fn cast(syntax: SyntaxNode<R>) -> Option<Self> { | ||
279 | match syntax.kind() { | ||
280 | STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })), | ||
281 | ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })), | ||
282 | _ => None, | ||
283 | } | ||
284 | } | ||
285 | fn syntax(&self) -> &SyntaxNode<R> { | ||
286 | match self { | ||
287 | NominalDef::StructDef(inner) => inner.syntax(), | ||
288 | NominalDef::EnumDef(inner) => inner.syntax(), | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
293 | impl<R: TreeRoot> NominalDef<R> {} | ||
294 | |||
270 | // ParenType | 295 | // ParenType |
271 | #[derive(Debug, Clone, Copy)] | 296 | #[derive(Debug, Clone, Copy)] |
272 | pub struct ParenType<R: TreeRoot = Arc<SyntaxRoot>> { | 297 | pub struct ParenType<R: TreeRoot = Arc<SyntaxRoot>> { |
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index 3641b65e2..3ae403bb5 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron | |||
@@ -261,6 +261,8 @@ Grammar( | |||
261 | "ForType", | 261 | "ForType", |
262 | "ImplTraitType", | 262 | "ImplTraitType", |
263 | "DynTraitType", | 263 | "DynTraitType", |
264 | ]) | 264 | ]), |
265 | |||
266 | "NominalDef": ( enum: ["StructDef", "EnumDef"]), | ||
265 | }, | 267 | }, |
266 | ) | 268 | ) |