mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 01:38:13 +00:00
Merge #395
395: generalize r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
6044ec5057
5 changed files with 27 additions and 26 deletions
|
@ -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, frange.range).unwrap_or(frange.range)
|
ra_editor::extend_selection(source_file.syntax(), frange.range).unwrap_or(frange.range)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extend_selection_in_macro(
|
||||||
|
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> {
|
||||||
|
|
|
@ -9,14 +9,14 @@ use crate::{
|
||||||
|
|
||||||
pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> {
|
pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> {
|
||||||
let source_file = db.source_file(file_id);
|
let source_file = db.source_file(file_id);
|
||||||
let mut res = ra_editor::highlight(&source_file);
|
let mut res = ra_editor::highlight(source_file.syntax());
|
||||||
for macro_call in source_file
|
for macro_call in source_file
|
||||||
.syntax()
|
.syntax()
|
||||||
.descendants()
|
.descendants()
|
||||||
.filter_map(ast::MacroCall::cast)
|
.filter_map(ast::MacroCall::cast)
|
||||||
{
|
{
|
||||||
if let Some(exp) = crate::macros::expand(db, file_id, macro_call) {
|
if let Some(exp) = crate::macros::expand(db, file_id, macro_call) {
|
||||||
let mapped_ranges = ra_editor::highlight(exp.source_file())
|
let mapped_ranges = ra_editor::highlight(exp.source_file().syntax())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|r| {
|
.filter_map(|r| {
|
||||||
let mapped_range = exp.map_range_back(r.range)?;
|
let mapped_range = exp.map_range_back(r.range)?;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,11 +67,11 @@ pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option<TextUni
|
||||||
Some(matching_node.range().start())
|
Some(matching_node.range().start())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight(file: &SourceFileNode) -> Vec<HighlightedRange> {
|
pub fn highlight(root: SyntaxNodeRef) -> Vec<HighlightedRange> {
|
||||||
// Visited nodes to handle highlighting priorities
|
// Visited nodes to handle highlighting priorities
|
||||||
let mut highlighted = FxHashSet::default();
|
let mut highlighted = FxHashSet::default();
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
for node in file.syntax().descendants() {
|
for node in root.descendants() {
|
||||||
if highlighted.contains(&node) {
|
if highlighted.contains(&node) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ fn main() {}
|
||||||
println!("Hello, {}!", 92);
|
println!("Hello, {}!", 92);
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let hls = highlight(&file);
|
let hls = highlight(file.syntax());
|
||||||
assert_eq_dbg(
|
assert_eq_dbg(
|
||||||
r#"[HighlightedRange { range: [1; 11), tag: "comment" },
|
r#"[HighlightedRange { range: [1; 11), tag: "comment" },
|
||||||
HighlightedRange { range: [12; 14), tag: "keyword" },
|
HighlightedRange { range: [12; 14), tag: "keyword" },
|
||||||
|
|
Loading…
Reference in a new issue