aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/extend_selection.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-12-28 17:33:39 +0000
committerAleksey Kladov <[email protected]>2018-12-28 17:33:39 +0000
commit5299a35e3dc484ea2e7d42cfeed89aee806425d3 (patch)
tree87a7ef3976e50ef120246a777da0593823f15d9d /crates/ra_analysis/src/extend_selection.rs
parent10e687f281e4850ae258d5dae84dee871e24e8ed (diff)
extend selection works with macros
Diffstat (limited to 'crates/ra_analysis/src/extend_selection.rs')
-rw-r--r--crates/ra_analysis/src/extend_selection.rs44
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 @@
1use ra_db::SyntaxDatabase; 1use ra_db::SyntaxDatabase;
2use ra_syntax::{
3 SyntaxNodeRef, AstNode,
4 ast, algo::find_covering_node,
5};
2 6
3use crate::{ 7use crate::{
4 TextRange, FileRange, 8 TextRange, FileRange,
@@ -6,6 +10,42 @@ use crate::{
6}; 10};
7 11
8pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { 12pub(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
28fn 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)]
35mod 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}