diff options
Diffstat (limited to 'crates/ra_analysis/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ra_analysis/src/syntax_highlighting.rs | 62 |
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 @@ | |||
1 | use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; | 1 | use ra_syntax::{ast, AstNode,}; |
2 | use ra_editor::HighlightedRange; | 2 | use ra_editor::HighlightedRange; |
3 | use ra_db::SyntaxDatabase; | 3 | use 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 | ||
35 | fn 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 | |||
71 | struct MacroExpansion { | ||
72 | source_file: SourceFileNode, | ||
73 | ranges_map: Vec<(TextRange, TextRange)>, | ||
74 | } | ||
75 | |||
76 | impl 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)] |
94 | mod tests { | 36 | mod tests { |
95 | use crate::mock_analysis::single_file; | 37 | use crate::mock_analysis::single_file; |