From 5299a35e3dc484ea2e7d42cfeed89aee806425d3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 28 Dec 2018 20:33:39 +0300 Subject: extend selection works with macros --- crates/ra_analysis/src/extend_selection.rs | 44 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'crates/ra_analysis/src/extend_selection.rs') 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 @@ use ra_db::SyntaxDatabase; +use ra_syntax::{ + SyntaxNodeRef, AstNode, + ast, algo::find_covering_node, +}; use crate::{ TextRange, FileRange, @@ -6,6 +10,42 @@ use crate::{ }; pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { - let file = db.source_file(frange.file_id); - ra_editor::extend_selection(&file, frange.range).unwrap_or(frange.range) + let source_file = db.source_file(frange.file_id); + if let Some(macro_call) = find_macro_call(source_file.syntax(), frange.range) { + if let Some(exp) = crate::macros::expand(db, frange.file_id, macro_call) { + if let Some(dst_range) = exp.map_range_forward(frange.range) { + if let Some(dst_range) = ra_editor::extend_selection(exp.source_file(), dst_range) { + if let Some(src_range) = exp.map_range_back(dst_range) { + return src_range; + } + } + } + } + } + ra_editor::extend_selection(&source_file, frange.range).unwrap_or(frange.range) +} + +fn find_macro_call(node: SyntaxNodeRef, range: TextRange) -> Option { + find_covering_node(node, range) + .ancestors() + .find_map(ast::MacroCall::cast) +} + +#[cfg(test)] +mod tests { + use crate::mock_analysis::single_file_with_range; + use test_utils::assert_eq_dbg; + + #[test] + fn extend_selection_inside_macros() { + let (analysis, frange) = single_file_with_range( + " + fn main() { + ctry!(foo(|x| <|>x<|>)); + } + ", + ); + let r = analysis.extend_selection(frange); + assert_eq_dbg("[51; 56)", &r); + } } -- cgit v1.2.3