aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/syntax_highlighting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/syntax_highlighting.rs')
-rw-r--r--crates/ra_analysis/src/syntax_highlighting.rs62
1 files changed, 2 insertions, 60 deletions
diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs
index 98551df8f..38219da71 100644
--- a/crates/ra_analysis/src/syntax_highlighting.rs
+++ b/crates/ra_analysis/src/syntax_highlighting.rs
@@ -1,4 +1,4 @@
1use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; 1use ra_syntax::{ast, AstNode,};
2use ra_editor::HighlightedRange; 2use ra_editor::HighlightedRange;
3use ra_db::SyntaxDatabase; 3use ra_db::SyntaxDatabase;
4 4
@@ -15,7 +15,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable<Vec<Hi
15 .descendants() 15 .descendants()
16 .filter_map(ast::MacroCall::cast) 16 .filter_map(ast::MacroCall::cast)
17 { 17 {
18 if let Some(exp) = expand(db, file_id, macro_call) { 18 if let Some(exp) = crate::macros::expand(db, file_id, macro_call) {
19 let mapped_ranges = ra_editor::highlight(exp.source_file()) 19 let mapped_ranges = ra_editor::highlight(exp.source_file())
20 .into_iter() 20 .into_iter()
21 .filter_map(|r| { 21 .filter_map(|r| {
@@ -32,64 +32,6 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Cancelable<Vec<Hi
32 Ok(res) 32 Ok(res)
33} 33}
34 34
35fn expand(
36 _db: &RootDatabase,
37 _file_id: FileId,
38 macro_call: ast::MacroCall,
39) -> Option<MacroExpansion> {
40 let path = macro_call.path()?;
41 if path.qualifier().is_some() {
42 return None;
43 }
44 let name_ref = path.segment()?.name_ref()?;
45 if name_ref.text() != "ctry" {
46 return None;
47 }
48
49 let arg = macro_call.token_tree()?;
50 let text = format!(
51 r"
52 fn dummy() {{
53 match {} {{
54 None => return Ok(None),
55 Some(it) => it,
56 }}
57 }}",
58 arg.syntax().text()
59 );
60 let file = SourceFileNode::parse(&text);
61 let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?;
62 let match_arg = match_expr.expr()?;
63 let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())];
64 let res = MacroExpansion {
65 source_file: file,
66 ranges_map,
67 };
68 Some(res)
69}
70
71struct MacroExpansion {
72 source_file: SourceFileNode,
73 ranges_map: Vec<(TextRange, TextRange)>,
74}
75
76impl MacroExpansion {
77 fn source_file(&self) -> &SourceFileNode {
78 &self.source_file
79 }
80 fn map_range_back(&self, tgt_range: TextRange) -> Option<TextRange> {
81 for (s_range, t_range) in self.ranges_map.iter() {
82 if tgt_range.is_subrange(&t_range) {
83 let tgt_at_zero_range = tgt_range - tgt_range.start();
84 let tgt_range_offset = tgt_range.start() - t_range.start();
85 let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start();
86 return Some(src_range);
87 }
88 }
89 None
90 }
91}
92
93#[cfg(test)] 35#[cfg(test)]
94mod tests { 36mod tests {
95 use crate::mock_analysis::single_file; 37 use crate::mock_analysis::single_file;