diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-28 18:35:52 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-12-28 18:35:52 +0000 |
commit | 751616f062b07f5dee2921f69886bd1a5b1234aa (patch) | |
tree | 616bcd980ac69eb5070c1e7a6d90ebee71cb7348 /crates/ra_analysis/src/extend_selection.rs | |
parent | 10e687f281e4850ae258d5dae84dee871e24e8ed (diff) | |
parent | 792899587647f5aa0293c2588173677682187c0a (diff) |
Merge #352
352: Macro extend selection r=matklad a=matklad
and a bunch of unrelated stuff
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/extend_selection.rs')
-rw-r--r-- | crates/ra_analysis/src/extend_selection.rs | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/crates/ra_analysis/src/extend_selection.rs b/crates/ra_analysis/src/extend_selection.rs index 5e1fbee18..cde6ee101 100644 --- a/crates/ra_analysis/src/extend_selection.rs +++ b/crates/ra_analysis/src/extend_selection.rs | |||
@@ -1,4 +1,8 @@ | |||
1 | use ra_db::SyntaxDatabase; | 1 | use ra_db::SyntaxDatabase; |
2 | use ra_syntax::{ | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | ast, algo::find_covering_node, | ||
5 | }; | ||
2 | 6 | ||
3 | use crate::{ | 7 | use crate::{ |
4 | TextRange, FileRange, | 8 | TextRange, FileRange, |
@@ -6,6 +10,42 @@ use crate::{ | |||
6 | }; | 10 | }; |
7 | 11 | ||
8 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { | 12 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { |
9 | let file = db.source_file(frange.file_id); | 13 | let source_file = db.source_file(frange.file_id); |
10 | ra_editor::extend_selection(&file, frange.range).unwrap_or(frange.range) | 14 | if let Some(macro_call) = find_macro_call(source_file.syntax(), frange.range) { |
15 | if let Some(exp) = crate::macros::expand(db, frange.file_id, macro_call) { | ||
16 | if let Some(dst_range) = exp.map_range_forward(frange.range) { | ||
17 | if let Some(dst_range) = ra_editor::extend_selection(exp.source_file(), dst_range) { | ||
18 | if let Some(src_range) = exp.map_range_back(dst_range) { | ||
19 | return src_range; | ||
20 | } | ||
21 | } | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | ra_editor::extend_selection(&source_file, frange.range).unwrap_or(frange.range) | ||
26 | } | ||
27 | |||
28 | fn find_macro_call(node: SyntaxNodeRef, range: TextRange) -> Option<ast::MacroCall> { | ||
29 | find_covering_node(node, range) | ||
30 | .ancestors() | ||
31 | .find_map(ast::MacroCall::cast) | ||
32 | } | ||
33 | |||
34 | #[cfg(test)] | ||
35 | mod tests { | ||
36 | use crate::mock_analysis::single_file_with_range; | ||
37 | use test_utils::assert_eq_dbg; | ||
38 | |||
39 | #[test] | ||
40 | fn extend_selection_inside_macros() { | ||
41 | let (analysis, frange) = single_file_with_range( | ||
42 | " | ||
43 | fn main() { | ||
44 | ctry!(foo(|x| <|>x<|>)); | ||
45 | } | ||
46 | ", | ||
47 | ); | ||
48 | let r = analysis.extend_selection(frange); | ||
49 | assert_eq_dbg("[51; 56)", &r); | ||
50 | } | ||
11 | } | 51 | } |