diff options
-rw-r--r-- | crates/ra_editor/src/code_actions.rs | 18 | ||||
-rw-r--r-- | crates/ra_editor/src/completion.rs | 13 | ||||
-rw-r--r-- | crates/ra_editor/src/extend_selection.rs | 18 | ||||
-rw-r--r-- | crates/ra_editor/src/folding_ranges.rs | 10 | ||||
-rw-r--r-- | crates/ra_editor/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_editor/src/scope/fn_scope.rs | 6 | ||||
-rw-r--r-- | crates/ra_editor/src/symbols.rs | 4 | ||||
-rw-r--r-- | crates/ra_editor/src/typing.rs | 3 | ||||
-rw-r--r-- | crates/ra_syntax/src/algo/mod.rs | 24 | ||||
-rw-r--r-- | crates/ra_syntax/src/algo/walk.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/reparsing.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/utils.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/mod.rs | 26 | ||||
-rw-r--r-- | crates/ra_syntax/src/yellow/syntax_text.rs | 4 |
15 files changed, 70 insertions, 80 deletions
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs index 83f7956d2..216d592ff 100644 --- a/crates/ra_editor/src/code_actions.rs +++ b/crates/ra_editor/src/code_actions.rs | |||
@@ -1,15 +1,13 @@ | |||
1 | use join_to_string::join; | 1 | use join_to_string::join; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | File, TextUnit, TextRange, | 4 | File, TextUnit, TextRange, Direction, |
5 | ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner}, | 5 | ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner}, |
6 | SyntaxKind::{COMMA, WHITESPACE}, | 6 | SyntaxKind::{COMMA, WHITESPACE}, |
7 | SyntaxNodeRef, | 7 | SyntaxNodeRef, |
8 | algo::{ | 8 | algo::{ |
9 | Direction, siblings, | ||
10 | find_leaf_at_offset, | 9 | find_leaf_at_offset, |
11 | find_covering_node, | 10 | find_covering_node, |
12 | ancestors, | ||
13 | }, | 11 | }, |
14 | }; | 12 | }; |
15 | 13 | ||
@@ -25,12 +23,12 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() | |||
25 | let syntax = file.syntax(); | 23 | let syntax = file.syntax(); |
26 | 24 | ||
27 | let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?; | 25 | let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?; |
28 | let left = non_trivia_sibling(comma, Direction::Backward)?; | 26 | let prev = non_trivia_sibling(comma, Direction::Prev)?; |
29 | let right = non_trivia_sibling(comma, Direction::Forward)?; | 27 | let next = non_trivia_sibling(comma, Direction::Next)?; |
30 | Some(move || { | 28 | Some(move || { |
31 | let mut edit = EditBuilder::new(); | 29 | let mut edit = EditBuilder::new(); |
32 | edit.replace(left.range(), right.text().to_string()); | 30 | edit.replace(prev.range(), next.text().to_string()); |
33 | edit.replace(right.range(), left.text().to_string()); | 31 | edit.replace(next.range(), prev.text().to_string()); |
34 | LocalEdit { | 32 | LocalEdit { |
35 | edit: edit.finish(), | 33 | edit: edit.finish(), |
36 | cursor_position: None, | 34 | cursor_position: None, |
@@ -101,8 +99,8 @@ pub fn add_impl<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> | |||
101 | 99 | ||
102 | pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl FnOnce() -> LocalEdit + 'a> { | 100 | pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl FnOnce() -> LocalEdit + 'a> { |
103 | let node = find_covering_node(file.syntax(), range); | 101 | let node = find_covering_node(file.syntax(), range); |
104 | let expr = ancestors(node).filter_map(ast::Expr::cast).next()?; | 102 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; |
105 | let anchor_stmt = ancestors(expr.syntax()).filter_map(ast::Stmt::cast).next()?; | 103 | let anchor_stmt = expr.syntax().ancestors().filter_map(ast::Stmt::cast).next()?; |
106 | let indent = anchor_stmt.syntax().prev_sibling()?; | 104 | let indent = anchor_stmt.syntax().prev_sibling()?; |
107 | if indent.kind() != WHITESPACE { | 105 | if indent.kind() != WHITESPACE { |
108 | return None; | 106 | return None; |
@@ -130,7 +128,7 @@ pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl F | |||
130 | } | 128 | } |
131 | 129 | ||
132 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { | 130 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { |
133 | siblings(node, direction) | 131 | node.siblings(direction) |
134 | .skip(1) | 132 | .skip(1) |
135 | .find(|node| !node.kind().is_trivia()) | 133 | .find(|node| !node.kind().is_trivia()) |
136 | } | 134 | } |
diff --git a/crates/ra_editor/src/completion.rs b/crates/ra_editor/src/completion.rs index ff9de20d3..62a63fb04 100644 --- a/crates/ra_editor/src/completion.rs +++ b/crates/ra_editor/src/completion.rs | |||
@@ -4,7 +4,6 @@ use ra_syntax::{ | |||
4 | File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*, | 4 | File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*, |
5 | ast::{self, LoopBodyOwner, ModuleItemOwner}, | 5 | ast::{self, LoopBodyOwner, ModuleItemOwner}, |
6 | algo::{ | 6 | algo::{ |
7 | ancestors, | ||
8 | visit::{visitor, Visitor, visitor_ctx, VisitorCtx}, | 7 | visit::{visitor, Visitor, visitor_ctx, VisitorCtx}, |
9 | }, | 8 | }, |
10 | text_utils::is_subrange, | 9 | text_utils::is_subrange, |
@@ -59,7 +58,7 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi | |||
59 | return; | 58 | return; |
60 | } | 59 | } |
61 | let mut visited_fn = false; | 60 | let mut visited_fn = false; |
62 | for node in ancestors(name_ref.syntax()) { | 61 | for node in name_ref.syntax().ancestors() { |
63 | if let Some(items) = visitor() | 62 | if let Some(items) = visitor() |
64 | .visit::<ast::Root, _>(|it| Some(it.items())) | 63 | .visit::<ast::Root, _>(|it| Some(it.items())) |
65 | .visit::<ast::Module, _>(|it| Some(it.item_list()?.items())) | 64 | .visit::<ast::Module, _>(|it| Some(it.item_list()?.items())) |
@@ -92,7 +91,7 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi | |||
92 | 91 | ||
93 | fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { | 92 | fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { |
94 | let mut params = HashMap::new(); | 93 | let mut params = HashMap::new(); |
95 | for node in ancestors(ctx) { | 94 | for node in ctx.ancestors() { |
96 | let _ = visitor_ctx(&mut params) | 95 | let _ = visitor_ctx(&mut params) |
97 | .visit::<ast::Root, _>(process) | 96 | .visit::<ast::Root, _>(process) |
98 | .visit::<ast::ItemList, _>(process) | 97 | .visit::<ast::ItemList, _>(process) |
@@ -123,7 +122,7 @@ fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { | |||
123 | } | 122 | } |
124 | 123 | ||
125 | fn is_node<'a, N: AstNode<'a>>(node: SyntaxNodeRef<'a>) -> bool { | 124 | fn is_node<'a, N: AstNode<'a>>(node: SyntaxNodeRef<'a>) -> bool { |
126 | match ancestors(node).filter_map(N::cast).next() { | 125 | match node.ancestors().filter_map(N::cast).next() { |
127 | None => false, | 126 | None => false, |
128 | Some(n) => n.syntax().range() == node.range(), | 127 | Some(n) => n.syntax().range() == node.range(), |
129 | } | 128 | } |
@@ -152,7 +151,7 @@ fn complete_expr_keywords(file: &File, fn_def: ast::FnDef, name_ref: ast::NameRe | |||
152 | } | 151 | } |
153 | 152 | ||
154 | fn is_in_loop_body(name_ref: ast::NameRef) -> bool { | 153 | fn is_in_loop_body(name_ref: ast::NameRef) -> bool { |
155 | for node in ancestors(name_ref.syntax()) { | 154 | for node in name_ref.syntax().ancestors() { |
156 | if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR { | 155 | if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR { |
157 | break; | 156 | break; |
158 | } | 157 | } |
@@ -171,7 +170,7 @@ fn is_in_loop_body(name_ref: ast::NameRef) -> bool { | |||
171 | } | 170 | } |
172 | 171 | ||
173 | fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<CompletionItem> { | 172 | fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<CompletionItem> { |
174 | // let is_last_in_block = ancestors(name_ref.syntax()).filter_map(ast::Expr::cast) | 173 | // let is_last_in_block = name_ref.syntax().ancestors().filter_map(ast::Expr::cast) |
175 | // .next() | 174 | // .next() |
176 | // .and_then(|it| it.syntax().parent()) | 175 | // .and_then(|it| it.syntax().parent()) |
177 | // .and_then(ast::Block::cast) | 176 | // .and_then(ast::Block::cast) |
@@ -181,7 +180,7 @@ fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<Complet | |||
181 | // return None; | 180 | // return None; |
182 | // } | 181 | // } |
183 | 182 | ||
184 | let is_stmt = match ancestors(name_ref.syntax()).filter_map(ast::ExprStmt::cast).next() { | 183 | let is_stmt = match name_ref.syntax().ancestors().filter_map(ast::ExprStmt::cast).next() { |
185 | None => false, | 184 | None => false, |
186 | Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range() | 185 | Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range() |
187 | }; | 186 | }; |
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index dc914a26a..b00a457b9 100644 --- a/crates/ra_editor/src/extend_selection.rs +++ b/crates/ra_editor/src/extend_selection.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use ra_syntax::{ | 1 | use ra_syntax::{ |
2 | File, TextRange, SyntaxNodeRef, TextUnit, | 2 | File, TextRange, SyntaxNodeRef, TextUnit, Direction, |
3 | SyntaxKind::*, | 3 | SyntaxKind::*, |
4 | algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node, ancestors, Direction, siblings}, | 4 | algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node}, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { | 7 | pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { |
@@ -30,7 +30,7 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> | |||
30 | } | 30 | } |
31 | } | 31 | } |
32 | 32 | ||
33 | match ancestors(node).skip_while(|n| n.range() == range).next() { | 33 | match node.ancestors().skip_while(|n| n.range() == range).next() { |
34 | None => None, | 34 | None => None, |
35 | Some(parent) => Some(parent.range()), | 35 | Some(parent) => Some(parent.range()), |
36 | } | 36 | } |
@@ -71,12 +71,12 @@ fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a | |||
71 | } | 71 | } |
72 | 72 | ||
73 | fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { | 73 | fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { |
74 | let left = adj_comments(node, Direction::Backward); | 74 | let prev = adj_comments(node, Direction::Prev); |
75 | let right = adj_comments(node, Direction::Forward); | 75 | let next = adj_comments(node, Direction::Next); |
76 | if left != right { | 76 | if prev != next { |
77 | Some(TextRange::from_to( | 77 | Some(TextRange::from_to( |
78 | left.range().start(), | 78 | prev.range().start(), |
79 | right.range().end(), | 79 | next.range().end(), |
80 | )) | 80 | )) |
81 | } else { | 81 | } else { |
82 | None | 82 | None |
@@ -85,7 +85,7 @@ fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { | |||
85 | 85 | ||
86 | fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { | 86 | fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { |
87 | let mut res = node; | 87 | let mut res = node; |
88 | for node in siblings(node, dir) { | 88 | for node in node.siblings(dir) { |
89 | match node.kind() { | 89 | match node.kind() { |
90 | COMMENT => res = node, | 90 | COMMENT => res = node, |
91 | WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), | 91 | WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), |
diff --git a/crates/ra_editor/src/folding_ranges.rs b/crates/ra_editor/src/folding_ranges.rs index 817da28d1..733512368 100644 --- a/crates/ra_editor/src/folding_ranges.rs +++ b/crates/ra_editor/src/folding_ranges.rs | |||
@@ -3,7 +3,7 @@ use std::collections::HashSet; | |||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | File, TextRange, SyntaxNodeRef, | 4 | File, TextRange, SyntaxNodeRef, |
5 | SyntaxKind, | 5 | SyntaxKind, |
6 | algo::{walk, Direction, siblings}, | 6 | Direction, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | #[derive(Debug, PartialEq, Eq)] | 9 | #[derive(Debug, PartialEq, Eq)] |
@@ -19,12 +19,10 @@ pub struct Fold { | |||
19 | } | 19 | } |
20 | 20 | ||
21 | pub fn folding_ranges(file: &File) -> Vec<Fold> { | 21 | pub fn folding_ranges(file: &File) -> Vec<Fold> { |
22 | let syntax = file.syntax(); | ||
23 | |||
24 | let mut res = vec![]; | 22 | let mut res = vec![]; |
25 | let mut visited = HashSet::new(); | 23 | let mut visited = HashSet::new(); |
26 | 24 | ||
27 | for node in walk::preorder(syntax) { | 25 | for node in file.syntax().descendants() { |
28 | if visited.contains(&node) { | 26 | if visited.contains(&node) { |
29 | continue; | 27 | continue; |
30 | } | 28 | } |
@@ -64,7 +62,7 @@ fn contiguous_range_for<'a>( | |||
64 | 62 | ||
65 | let left = node; | 63 | let left = node; |
66 | let mut right = node; | 64 | let mut right = node; |
67 | for node in siblings(node, Direction::Forward) { | 65 | for node in node.siblings(Direction::Next) { |
68 | visited.insert(node); | 66 | visited.insert(node); |
69 | match node.kind() { | 67 | match node.kind() { |
70 | SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), | 68 | SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), |
@@ -139,4 +137,4 @@ fn main() { | |||
139 | } | 137 | } |
140 | 138 | ||
141 | 139 | ||
142 | } \ No newline at end of file | 140 | } |
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index de929d73a..a93924e00 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs | |||
@@ -21,7 +21,7 @@ mod test_utils; | |||
21 | use ra_syntax::{ | 21 | use ra_syntax::{ |
22 | File, TextUnit, TextRange, SyntaxNodeRef, | 22 | File, TextUnit, TextRange, SyntaxNodeRef, |
23 | ast::{self, AstNode, NameOwner}, | 23 | ast::{self, AstNode, NameOwner}, |
24 | algo::{walk, find_leaf_at_offset, ancestors}, | 24 | algo::find_leaf_at_offset, |
25 | SyntaxKind::{self, *}, | 25 | SyntaxKind::{self, *}, |
26 | }; | 26 | }; |
27 | pub use ra_syntax::AtomEdit; | 27 | pub use ra_syntax::AtomEdit; |
@@ -86,7 +86,7 @@ pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> { | |||
86 | 86 | ||
87 | pub fn highlight(file: &File) -> Vec<HighlightedRange> { | 87 | pub fn highlight(file: &File) -> Vec<HighlightedRange> { |
88 | let mut res = Vec::new(); | 88 | let mut res = Vec::new(); |
89 | for node in walk::preorder(file.syntax()) { | 89 | for node in file.syntax().descendants() { |
90 | let tag = match node.kind() { | 90 | let tag = match node.kind() { |
91 | ERROR => "error", | 91 | ERROR => "error", |
92 | COMMENT | DOC_COMMENT => "comment", | 92 | COMMENT | DOC_COMMENT => "comment", |
@@ -110,7 +110,7 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> { | |||
110 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { | 110 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { |
111 | let mut res = Vec::new(); | 111 | let mut res = Vec::new(); |
112 | 112 | ||
113 | for node in walk::preorder(file.syntax()) { | 113 | for node in file.syntax().descendants() { |
114 | if node.kind() == ERROR { | 114 | if node.kind() == ERROR { |
115 | res.push(Diagnostic { | 115 | res.push(Diagnostic { |
116 | range: node.range(), | 116 | range: node.range(), |
@@ -130,7 +130,7 @@ pub fn syntax_tree(file: &File) -> String { | |||
130 | } | 130 | } |
131 | 131 | ||
132 | pub fn runnables(file: &File) -> Vec<Runnable> { | 132 | pub fn runnables(file: &File) -> Vec<Runnable> { |
133 | walk::preorder(file.syntax()) | 133 | file.syntax().descendants() |
134 | .filter_map(ast::FnDef::cast) | 134 | .filter_map(ast::FnDef::cast) |
135 | .filter_map(|f| { | 135 | .filter_map(|f| { |
136 | let name = f.name()?.text(); | 136 | let name = f.name()?.text(); |
@@ -159,7 +159,7 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>( | |||
159 | let leaf = leaves.clone() | 159 | let leaf = leaves.clone() |
160 | .find(|leaf| !leaf.kind().is_trivia()) | 160 | .find(|leaf| !leaf.kind().is_trivia()) |
161 | .or_else(|| leaves.right_biased())?; | 161 | .or_else(|| leaves.right_biased())?; |
162 | ancestors(leaf) | 162 | leaf.ancestors() |
163 | .filter_map(N::cast) | 163 | .filter_map(N::cast) |
164 | .next() | 164 | .next() |
165 | } | 165 | } |
diff --git a/crates/ra_editor/src/scope/fn_scope.rs b/crates/ra_editor/src/scope/fn_scope.rs index 3ae5276a2..eddd87495 100644 --- a/crates/ra_editor/src/scope/fn_scope.rs +++ b/crates/ra_editor/src/scope/fn_scope.rs | |||
@@ -6,7 +6,7 @@ use std::{ | |||
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | SyntaxNodeRef, SyntaxNode, SmolStr, AstNode, | 7 | SyntaxNodeRef, SyntaxNode, SmolStr, AstNode, |
8 | ast::{self, NameOwner, LoopBodyOwner, ArgListOwner}, | 8 | ast::{self, NameOwner, LoopBodyOwner, ArgListOwner}, |
9 | algo::{ancestors, generate, walk::preorder} | 9 | algo::{generate} |
10 | }; | 10 | }; |
11 | 11 | ||
12 | type ScopeId = usize; | 12 | type ScopeId = usize; |
@@ -51,7 +51,7 @@ impl FnScopes { | |||
51 | res | 51 | res |
52 | } | 52 | } |
53 | fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { | 53 | fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { |
54 | let entries = preorder(pat.syntax()) | 54 | let entries = pat.syntax().descendants() |
55 | .filter_map(ast::BindPat::cast) | 55 | .filter_map(ast::BindPat::cast) |
56 | .filter_map(ScopeEntry::new); | 56 | .filter_map(ScopeEntry::new); |
57 | self.scopes[scope].entries.extend(entries); | 57 | self.scopes[scope].entries.extend(entries); |
@@ -66,7 +66,7 @@ impl FnScopes { | |||
66 | self.scope_for.insert(node.owned(), scope); | 66 | self.scope_for.insert(node.owned(), scope); |
67 | } | 67 | } |
68 | fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> { | 68 | fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> { |
69 | ancestors(node) | 69 | node.ancestors() |
70 | .filter_map(|it| self.scope_for.get(&it.owned()).map(|&scope| scope)) | 70 | .filter_map(|it| self.scope_for.get(&it.owned()).map(|&scope| scope)) |
71 | .next() | 71 | .next() |
72 | } | 72 | } |
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs index 917984177..e5cc5ca28 100644 --- a/crates/ra_editor/src/symbols.rs +++ b/crates/ra_editor/src/symbols.rs | |||
@@ -3,7 +3,7 @@ use ra_syntax::{ | |||
3 | ast::{self, NameOwner}, | 3 | ast::{self, NameOwner}, |
4 | algo::{ | 4 | algo::{ |
5 | visit::{visitor, Visitor}, | 5 | visit::{visitor, Visitor}, |
6 | walk::{walk, WalkEvent, preorder}, | 6 | walk::{walk, WalkEvent}, |
7 | }, | 7 | }, |
8 | }; | 8 | }; |
9 | use TextRange; | 9 | use TextRange; |
@@ -25,7 +25,7 @@ pub struct FileSymbol { | |||
25 | } | 25 | } |
26 | 26 | ||
27 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { | 27 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { |
28 | preorder(file.syntax()) | 28 | file.syntax().descendants() |
29 | .filter_map(to_symbol) | 29 | .filter_map(to_symbol) |
30 | .collect() | 30 | .collect() |
31 | } | 31 | } |
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs index 0f4e7e0d0..512076941 100644 --- a/crates/ra_editor/src/typing.rs +++ b/crates/ra_editor/src/typing.rs | |||
@@ -4,7 +4,6 @@ use ra_syntax::{ | |||
4 | TextUnit, TextRange, SyntaxNodeRef, File, AstNode, SyntaxKind, | 4 | TextUnit, TextRange, SyntaxNodeRef, File, AstNode, SyntaxKind, |
5 | ast, | 5 | ast, |
6 | algo::{ | 6 | algo::{ |
7 | walk::preorder, | ||
8 | find_covering_node, | 7 | find_covering_node, |
9 | }, | 8 | }, |
10 | text_utils::{intersect, contains_offset_nonstrict}, | 9 | text_utils::{intersect, contains_offset_nonstrict}, |
@@ -33,7 +32,7 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit { | |||
33 | }; | 32 | }; |
34 | let node = find_covering_node(file.syntax(), range); | 33 | let node = find_covering_node(file.syntax(), range); |
35 | let mut edit = EditBuilder::new(); | 34 | let mut edit = EditBuilder::new(); |
36 | for node in preorder(node) { | 35 | for node in node.descendants() { |
37 | let text = match node.leaf_text() { | 36 | let text = match node.leaf_text() { |
38 | Some(text) => text, | 37 | Some(text) => text, |
39 | None => continue, | 38 | None => continue, |
diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs index 8de44c586..a6678093d 100644 --- a/crates/ra_syntax/src/algo/mod.rs +++ b/crates/ra_syntax/src/algo/mod.rs | |||
@@ -94,29 +94,9 @@ pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRe | |||
94 | common_ancestor(left, right) | 94 | common_ancestor(left, right) |
95 | } | 95 | } |
96 | 96 | ||
97 | pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
98 | generate(Some(node), |&node| node.parent()) | ||
99 | } | ||
100 | |||
101 | #[derive(Debug)] | ||
102 | pub enum Direction { | ||
103 | Forward, | ||
104 | Backward, | ||
105 | } | ||
106 | |||
107 | pub fn siblings<'a>( | ||
108 | node: SyntaxNodeRef<'a>, | ||
109 | direction: Direction | ||
110 | ) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
111 | generate(Some(node), move |&node| match direction { | ||
112 | Direction::Forward => node.next_sibling(), | ||
113 | Direction::Backward => node.prev_sibling(), | ||
114 | }) | ||
115 | } | ||
116 | |||
117 | fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { | 97 | fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { |
118 | for p in ancestors(n1) { | 98 | for p in n1.ancestors() { |
119 | if ancestors(n2).any(|a| a == p) { | 99 | if n2.ancestors().any(|a| a == p) { |
120 | return p; | 100 | return p; |
121 | } | 101 | } |
122 | } | 102 | } |
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs index 536ee705f..8e294d965 100644 --- a/crates/ra_syntax/src/algo/walk.rs +++ b/crates/ra_syntax/src/algo/walk.rs | |||
@@ -3,12 +3,6 @@ use { | |||
3 | algo::generate, | 3 | algo::generate, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> { | ||
7 | walk(root).filter_map(|event| match event { | ||
8 | WalkEvent::Enter(node) => Some(node), | ||
9 | WalkEvent::Exit(_) => None, | ||
10 | }) | ||
11 | } | ||
12 | 6 | ||
13 | #[derive(Debug, Copy, Clone)] | 7 | #[derive(Debug, Copy, Clone)] |
14 | pub enum WalkEvent<'a> { | 8 | pub enum WalkEvent<'a> { |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index c7eda4563..738664afd 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -51,7 +51,7 @@ pub use { | |||
51 | ast::AstNode, | 51 | ast::AstNode, |
52 | lexer::{tokenize, Token}, | 52 | lexer::{tokenize, Token}, |
53 | syntax_kinds::SyntaxKind, | 53 | syntax_kinds::SyntaxKind, |
54 | yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, | 54 | yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError, Direction}, |
55 | reparsing::AtomEdit, | 55 | reparsing::AtomEdit, |
56 | }; | 56 | }; |
57 | 57 | ||
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs index e3c200d1e..dcafd2c40 100644 --- a/crates/ra_syntax/src/reparsing.rs +++ b/crates/ra_syntax/src/reparsing.rs | |||
@@ -112,7 +112,7 @@ fn find_reparsable_node<'node>( | |||
112 | range: TextRange, | 112 | range: TextRange, |
113 | ) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> { | 113 | ) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> { |
114 | let node = algo::find_covering_node(node, range); | 114 | let node = algo::find_covering_node(node, range); |
115 | return algo::ancestors(node) | 115 | return node.ancestors() |
116 | .filter_map(|node| reparser(node).map(|r| (node, r))) | 116 | .filter_map(|node| reparser(node).map(|r| (node, r))) |
117 | .next(); | 117 | .next(); |
118 | 118 | ||
diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs index 8bc5f0e24..e274f7471 100644 --- a/crates/ra_syntax/src/utils.rs +++ b/crates/ra_syntax/src/utils.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::fmt::Write; | 1 | use std::fmt::Write; |
2 | use { | 2 | use { |
3 | algo::walk::{preorder, walk, WalkEvent}, | 3 | algo::walk::{walk, WalkEvent}, |
4 | SyntaxKind, File, SyntaxNodeRef | 4 | SyntaxKind, File, SyntaxNodeRef |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -56,7 +56,7 @@ pub fn check_fuzz_invariants(text: &str) { | |||
56 | 56 | ||
57 | pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { | 57 | pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { |
58 | let mut stack = Vec::new(); | 58 | let mut stack = Vec::new(); |
59 | for node in preorder(root) { | 59 | for node in root.descendants() { |
60 | match node.kind() { | 60 | match node.kind() { |
61 | SyntaxKind::L_CURLY => { | 61 | SyntaxKind::L_CURLY => { |
62 | stack.push(node) | 62 | stack.push(node) |
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs index c621b1d6a..710320f47 100644 --- a/crates/ra_syntax/src/yellow/mod.rs +++ b/crates/ra_syntax/src/yellow/mod.rs | |||
@@ -53,15 +53,37 @@ impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> { | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | impl SyntaxNode<OwnedRoot> { | 56 | impl SyntaxNode { |
57 | pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode { | 57 | pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode { |
58 | SyntaxNode(::rowan::SyntaxNode::new(green, errors)) | 58 | SyntaxNode(::rowan::SyntaxNode::new(green, errors)) |
59 | } | 59 | } |
60 | } | 60 | } |
61 | impl<'a> SyntaxNode<RefRoot<'a>> { | 61 | |
62 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
63 | pub enum Direction { | ||
64 | Next, | ||
65 | Prev, | ||
66 | } | ||
67 | |||
68 | impl<'a> SyntaxNodeRef<'a> { | ||
62 | pub fn leaf_text(self) -> Option<&'a SmolStr> { | 69 | pub fn leaf_text(self) -> Option<&'a SmolStr> { |
63 | self.0.leaf_text() | 70 | self.0.leaf_text() |
64 | } | 71 | } |
72 | pub fn ancestors(self) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
73 | ::algo::generate(Some(self), |&node| node.parent()) | ||
74 | } | ||
75 | pub fn descendants(self) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
76 | ::algo::walk::walk(self).filter_map(|event| match event { | ||
77 | ::algo::walk::WalkEvent::Enter(node) => Some(node), | ||
78 | ::algo::walk::WalkEvent::Exit(_) => None, | ||
79 | }) | ||
80 | } | ||
81 | pub fn siblings(self, direction: Direction) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
82 | ::algo::generate(Some(self), move |&node| match direction { | ||
83 | Direction::Next => node.next_sibling(), | ||
84 | Direction::Prev => node.prev_sibling(), | ||
85 | }) | ||
86 | } | ||
65 | } | 87 | } |
66 | 88 | ||
67 | impl<R: TreeRoot<RaTypes>> SyntaxNode<R> { | 89 | impl<R: TreeRoot<RaTypes>> SyntaxNode<R> { |
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs index affd7f9c7..0db1049de 100644 --- a/crates/ra_syntax/src/yellow/syntax_text.rs +++ b/crates/ra_syntax/src/yellow/syntax_text.rs | |||
@@ -4,7 +4,6 @@ use std::{ | |||
4 | 4 | ||
5 | use { | 5 | use { |
6 | SyntaxNodeRef, TextRange, TextUnit, | 6 | SyntaxNodeRef, TextRange, TextUnit, |
7 | algo::walk::preorder, | ||
8 | text_utils::{intersect, contains_offset_nonstrict}, | 7 | text_utils::{intersect, contains_offset_nonstrict}, |
9 | }; | 8 | }; |
10 | 9 | ||
@@ -23,7 +22,8 @@ impl<'a> SyntaxText<'a> { | |||
23 | } | 22 | } |
24 | pub fn chunks(&self) -> impl Iterator<Item=&'a str> { | 23 | pub fn chunks(&self) -> impl Iterator<Item=&'a str> { |
25 | let range = self.range; | 24 | let range = self.range; |
26 | preorder(self.node) | 25 | self.node |
26 | .descendants() | ||
27 | .filter_map(move |node| { | 27 | .filter_map(move |node| { |
28 | let text = node.leaf_text()?; | 28 | let text = node.leaf_text()?; |
29 | let range = intersect(range, node.range())?; | 29 | let range = intersect(range, node.range())?; |