diff options
Diffstat (limited to 'crates/ra_syntax/src/algo.rs')
-rw-r--r-- | crates/ra_syntax/src/algo.rs | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs index 21fca99a6..ebf59288a 100644 --- a/crates/ra_syntax/src/algo.rs +++ b/crates/ra_syntax/src/algo.rs | |||
@@ -4,10 +4,11 @@ use std::ops::RangeInclusive; | |||
4 | 4 | ||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | use ra_text_edit::TextEditBuilder; | 6 | use ra_text_edit::TextEditBuilder; |
7 | use rustc_hash::FxHashMap; | 7 | use rustc_hash::{FxHashMap, FxHashSet}; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, | 10 | AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, |
11 | TextRange, TextUnit, | ||
11 | }; | 12 | }; |
12 | 13 | ||
13 | /// Returns ancestors of the node at the offset, sorted by length. This should | 14 | /// Returns ancestors of the node at the offset, sorted by length. This should |
@@ -37,6 +38,17 @@ pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> | |||
37 | ancestors_at_offset(syntax, offset).find_map(N::cast) | 38 | ancestors_at_offset(syntax, offset).find_map(N::cast) |
38 | } | 39 | } |
39 | 40 | ||
41 | /// Skip to next non `trivia` token | ||
42 | pub fn skip_trivia_token(mut token: SyntaxToken, direction: Direction) -> Option<SyntaxToken> { | ||
43 | while token.kind().is_trivia() { | ||
44 | token = match direction { | ||
45 | Direction::Next => token.next_token()?, | ||
46 | Direction::Prev => token.prev_token()?, | ||
47 | } | ||
48 | } | ||
49 | Some(token) | ||
50 | } | ||
51 | |||
40 | /// Finds the first sibling in the given direction which is not `trivia` | 52 | /// Finds the first sibling in the given direction which is not `trivia` |
41 | pub fn non_trivia_sibling(element: SyntaxElement, direction: Direction) -> Option<SyntaxElement> { | 53 | pub fn non_trivia_sibling(element: SyntaxElement, direction: Direction) -> Option<SyntaxElement> { |
42 | return match element { | 54 | return match element { |
@@ -56,6 +68,11 @@ pub fn find_covering_element(root: &SyntaxNode, range: TextRange) -> SyntaxEleme | |||
56 | root.covering_element(range) | 68 | root.covering_element(range) |
57 | } | 69 | } |
58 | 70 | ||
71 | pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { | ||
72 | let u_ancestors = u.ancestors().collect::<FxHashSet<SyntaxNode>>(); | ||
73 | v.ancestors().find(|it| u_ancestors.contains(it)) | ||
74 | } | ||
75 | |||
59 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 76 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
60 | pub enum InsertPosition<T> { | 77 | pub enum InsertPosition<T> { |
61 | First, | 78 | First, |