generalize extend selection to work with nodes

This commit is contained in:
Aleksey Kladov 2018-12-31 19:01:51 +03:00
parent a3ee07ac14
commit f1e8ebfbeb
3 changed files with 22 additions and 21 deletions

View file

@ -1,6 +1,6 @@
use ra_db::SyntaxDatabase; use ra_db::SyntaxDatabase;
use ra_syntax::{ use ra_syntax::{
SyntaxNodeRef, AstNode, SyntaxNodeRef, AstNode, SourceFileNode,
ast, algo::find_covering_node, ast, algo::find_covering_node,
}; };
@ -11,18 +11,23 @@ use crate::{
pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
let source_file = db.source_file(frange.file_id); 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(range) = extend_selection_in_macro(db, &source_file, frange) {
if let Some(exp) = crate::macros::expand(db, frange.file_id, macro_call) { return range;
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.syntax(), frange.range).unwrap_or(frange.range)
} }
}
} fn extend_selection_in_macro(
ra_editor::extend_selection(&source_file, frange.range).unwrap_or(frange.range) db: &RootDatabase,
source_file: &SourceFileNode,
frange: FileRange,
) -> Option<TextRange> {
let macro_call = find_macro_call(source_file.syntax(), frange.range)?;
let exp = crate::macros::expand(db, frange.file_id, macro_call)?;
let dst_range = exp.map_range_forward(frange.range)?;
let dst_range = ra_editor::extend_selection(exp.source_file().syntax(), dst_range)?;
let src_range = exp.map_range_back(dst_range)?;
Some(src_range)
} }
fn find_macro_call(node: SyntaxNodeRef, range: TextRange) -> Option<ast::MacroCall> { fn find_macro_call(node: SyntaxNodeRef, range: TextRange) -> Option<ast::MacroCall> {

View file

@ -102,7 +102,7 @@ fn selections(file: &SourceFileNode, start: u32, end: u32) -> String {
let mut cur = Some(TextRange::from_to((start - 1).into(), (end - 1).into())); let mut cur = Some(TextRange::from_to((start - 1).into(), (end - 1).into()));
while let Some(r) = cur { while let Some(r) = cur {
ranges.push(r); ranges.push(r);
cur = extend_selection(&file, r); cur = extend_selection(file.syntax(), r);
} }
let ranges = ranges let ranges = ranges
.iter() .iter()

View file

@ -1,16 +1,11 @@
use ra_syntax::{ use ra_syntax::{
algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset}, algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
Direction, SourceFileNode, Direction,
SyntaxKind::*, SyntaxKind::*,
SyntaxNodeRef, TextRange, TextUnit, SyntaxNodeRef, TextRange, TextUnit,
}; };
pub fn extend_selection(file: &SourceFileNode, range: TextRange) -> Option<TextRange> { pub fn extend_selection(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> {
let syntax = file.syntax();
extend(syntax.borrowed(), range)
}
pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> {
if range.is_empty() { if range.is_empty() {
let offset = range.start(); let offset = range.start();
let mut leaves = find_leaf_at_offset(root, offset); let mut leaves = find_leaf_at_offset(root, offset);
@ -126,6 +121,7 @@ fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use ra_syntax::SourceFileNode;
use test_utils::extract_offset; use test_utils::extract_offset;
fn do_check(before: &str, afters: &[&str]) { fn do_check(before: &str, afters: &[&str]) {
@ -133,7 +129,7 @@ mod tests {
let file = SourceFileNode::parse(&before); let file = SourceFileNode::parse(&before);
let mut range = TextRange::offset_len(cursor, 0.into()); let mut range = TextRange::offset_len(cursor, 0.into());
for &after in afters { for &after in afters {
range = extend_selection(&file, range).unwrap(); range = extend_selection(file.syntax(), range).unwrap();
let actual = &before[range]; let actual = &before[range];
assert_eq!(after, actual); assert_eq!(after, actual);
} }