diff options
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 3 | ||||
-rw-r--r-- | crates/ra_analysis/src/extend_selection.rs | 8 | ||||
-rw-r--r-- | crates/ra_analysis/src/macros.rs | 67 | ||||
-rw-r--r-- | crates/ra_analysis/src/syntax_highlighting.rs | 6 |
4 files changed, 22 insertions, 62 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index b072a5eba..712f72484 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -98,5 +98,8 @@ salsa::database_storage! { | |||
98 | fn struct_data() for hir::db::StructDataQuery; | 98 | fn struct_data() for hir::db::StructDataQuery; |
99 | fn enum_data() for hir::db::EnumDataQuery; | 99 | fn enum_data() for hir::db::EnumDataQuery; |
100 | } | 100 | } |
101 | impl hir::MacroDatabase { | ||
102 | fn expand_macro() for hir::ExpandMacroQuery; | ||
103 | } | ||
101 | } | 104 | } |
102 | } | 105 | } |
diff --git a/crates/ra_analysis/src/extend_selection.rs b/crates/ra_analysis/src/extend_selection.rs index 805e9059e..62133ef29 100644 --- a/crates/ra_analysis/src/extend_selection.rs +++ b/crates/ra_analysis/src/extend_selection.rs | |||
@@ -23,10 +23,10 @@ fn extend_selection_in_macro( | |||
23 | frange: FileRange, | 23 | frange: FileRange, |
24 | ) -> Option<TextRange> { | 24 | ) -> Option<TextRange> { |
25 | let macro_call = find_macro_call(source_file.syntax(), frange.range)?; | 25 | let macro_call = find_macro_call(source_file.syntax(), frange.range)?; |
26 | let exp = crate::macros::expand(db, frange.file_id, macro_call)?; | 26 | let (off, exp) = crate::macros::expand(db, frange.file_id, macro_call)?; |
27 | let dst_range = exp.map_range_forward(frange.range)?; | 27 | let dst_range = exp.map_range_forward(frange.range - off)?; |
28 | let dst_range = ra_editor::extend_selection(exp.source_file().syntax(), dst_range)?; | 28 | let dst_range = ra_editor::extend_selection(exp.syntax().borrowed(), dst_range)?; |
29 | let src_range = exp.map_range_back(dst_range)?; | 29 | let src_range = exp.map_range_back(dst_range)? + off; |
30 | Some(src_range) | 30 | Some(src_range) |
31 | } | 31 | } |
32 | 32 | ||
diff --git a/crates/ra_analysis/src/macros.rs b/crates/ra_analysis/src/macros.rs index b9feb7fad..21ec36cd6 100644 --- a/crates/ra_analysis/src/macros.rs +++ b/crates/ra_analysis/src/macros.rs | |||
@@ -1,15 +1,18 @@ | |||
1 | /// Begining of macro expansion. | 1 | /// Begining of macro expansion. |
2 | /// | 2 | /// |
3 | /// This code should be moved out of ra_analysis into hir (?) ideally. | 3 | /// This code should be moved out of ra_analysis into hir (?) ideally. |
4 | use ra_syntax::{ast, AstNode, SourceFileNode, TextRange}; | 4 | use std::sync::Arc; |
5 | |||
6 | use ra_syntax::{ast, AstNode, TextUnit}; | ||
7 | use hir::MacroDatabase; | ||
5 | 8 | ||
6 | use crate::{db::RootDatabase, FileId}; | 9 | use crate::{db::RootDatabase, FileId}; |
7 | 10 | ||
8 | pub(crate) fn expand( | 11 | pub(crate) fn expand( |
9 | _db: &RootDatabase, | 12 | db: &RootDatabase, |
10 | _file_id: FileId, | 13 | _file_id: FileId, |
11 | macro_call: ast::MacroCall, | 14 | macro_call: ast::MacroCall, |
12 | ) -> Option<MacroExpansion> { | 15 | ) -> Option<(TextUnit, Arc<hir::MacroExpansion>)> { |
13 | let path = macro_call.path()?; | 16 | let path = macro_call.path()?; |
14 | if path.qualifier().is_some() { | 17 | if path.qualifier().is_some() { |
15 | return None; | 18 | return None; |
@@ -18,58 +21,12 @@ pub(crate) fn expand( | |||
18 | if name_ref.text() != "ctry" { | 21 | if name_ref.text() != "ctry" { |
19 | return None; | 22 | return None; |
20 | } | 23 | } |
24 | let arg = macro_call.token_tree()?.syntax(); | ||
21 | 25 | ||
22 | let arg = macro_call.token_tree()?; | 26 | let def = hir::MacroDef::CTry; |
23 | let text = format!( | 27 | let input = hir::MacroInput { |
24 | r" | 28 | text: arg.text().to_string(), |
25 | fn dummy() {{ | ||
26 | match {} {{ | ||
27 | None => return Ok(None), | ||
28 | Some(it) => it, | ||
29 | }} | ||
30 | }}", | ||
31 | arg.syntax().text() | ||
32 | ); | ||
33 | let file = SourceFileNode::parse(&text); | ||
34 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; | ||
35 | let match_arg = match_expr.expr()?; | ||
36 | let ranges_map = vec![(arg.syntax().range(), match_arg.syntax().range())]; | ||
37 | let res = MacroExpansion { | ||
38 | source_file: file, | ||
39 | ranges_map, | ||
40 | }; | 29 | }; |
41 | Some(res) | 30 | let exp = db.expand_macro(def, input)?; |
42 | } | 31 | Some((arg.range().start(), exp)) |
43 | |||
44 | pub(crate) struct MacroExpansion { | ||
45 | pub(crate) source_file: SourceFileNode, | ||
46 | pub(crate) ranges_map: Vec<(TextRange, TextRange)>, | ||
47 | } | ||
48 | |||
49 | impl MacroExpansion { | ||
50 | pub(crate) fn source_file(&self) -> &SourceFileNode { | ||
51 | &self.source_file | ||
52 | } | ||
53 | pub(crate) fn map_range_back(&self, tgt_range: TextRange) -> Option<TextRange> { | ||
54 | for (s_range, t_range) in self.ranges_map.iter() { | ||
55 | if tgt_range.is_subrange(&t_range) { | ||
56 | let tgt_at_zero_range = tgt_range - tgt_range.start(); | ||
57 | let tgt_range_offset = tgt_range.start() - t_range.start(); | ||
58 | let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start(); | ||
59 | return Some(src_range); | ||
60 | } | ||
61 | } | ||
62 | None | ||
63 | } | ||
64 | pub(crate) fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> { | ||
65 | for (s_range, t_range) in self.ranges_map.iter() { | ||
66 | if src_range.is_subrange(&s_range) { | ||
67 | let src_at_zero_range = src_range - src_range.start(); | ||
68 | let src_range_offset = src_range.start() - s_range.start(); | ||
69 | let src_range = src_at_zero_range + src_range_offset + t_range.start(); | ||
70 | return Some(src_range); | ||
71 | } | ||
72 | } | ||
73 | None | ||
74 | } | ||
75 | } | 32 | } |
diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs index 7e9139a74..35a4630e9 100644 --- a/crates/ra_analysis/src/syntax_highlighting.rs +++ b/crates/ra_analysis/src/syntax_highlighting.rs | |||
@@ -15,13 +15,13 @@ 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) = crate::macros::expand(db, file_id, macro_call) { | 18 | if let Some((off, exp)) = crate::macros::expand(db, file_id, macro_call) { |
19 | let mapped_ranges = ra_editor::highlight(exp.source_file().syntax()) | 19 | let mapped_ranges = ra_editor::highlight(exp.syntax().borrowed()) |
20 | .into_iter() | 20 | .into_iter() |
21 | .filter_map(|r| { | 21 | .filter_map(|r| { |
22 | let mapped_range = exp.map_range_back(r.range)?; | 22 | let mapped_range = exp.map_range_back(r.range)?; |
23 | let res = HighlightedRange { | 23 | let res = HighlightedRange { |
24 | range: mapped_range, | 24 | range: mapped_range + off, |
25 | tag: r.tag, | 25 | tag: r.tag, |
26 | }; | 26 | }; |
27 | Some(res) | 27 | Some(res) |