aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/macros.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-02 13:05:54 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-02 13:05:54 +0000
commitafa972e78d2d81598c02b742ab84d70c88208300 (patch)
tree2ec32a586d0ee00e0d35a489efeaf31c91d14a15 /crates/ra_analysis/src/macros.rs
parente4ffd7b31780b1f2ac6dcb731566b583bf562647 (diff)
parent1076e82856f353763de8426d378fcd1e371cbed4 (diff)
Merge #403
403: initial support for macros r=matklad a=matklad I'll write a more comprehensive description when this is closer to being done. Basically this investigates one question: "how do we represent code which is a result of a macro call". This is an interesting question: currently everything is `FileId` based, but macro expansion does not have a file! Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/macros.rs')
-rw-r--r--crates/ra_analysis/src/macros.rs75
1 files changed, 0 insertions, 75 deletions
diff --git a/crates/ra_analysis/src/macros.rs b/crates/ra_analysis/src/macros.rs
deleted file mode 100644
index b9feb7fad..000000000
--- a/crates/ra_analysis/src/macros.rs
+++ /dev/null
@@ -1,75 +0,0 @@
1/// Begining of macro expansion.
2///
3/// This code should be moved out of ra_analysis into hir (?) ideally.
4use ra_syntax::{ast, AstNode, SourceFileNode, TextRange};
5
6use crate::{db::RootDatabase, FileId};
7
8pub(crate) fn expand(
9 _db: &RootDatabase,
10 _file_id: FileId,
11 macro_call: ast::MacroCall,
12) -> Option<MacroExpansion> {
13 let path = macro_call.path()?;
14 if path.qualifier().is_some() {
15 return None;
16 }
17 let name_ref = path.segment()?.name_ref()?;
18 if name_ref.text() != "ctry" {
19 return None;
20 }
21
22 let arg = macro_call.token_tree()?;
23 let text = format!(
24 r"
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 };
41 Some(res)
42}
43
44pub(crate) struct MacroExpansion {
45 pub(crate) source_file: SourceFileNode,
46 pub(crate) ranges_map: Vec<(TextRange, TextRange)>,
47}
48
49impl 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}