aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/macros.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-12-31 16:19:50 +0000
committerAleksey Kladov <[email protected]>2019-01-01 19:15:35 +0000
commit57030f587bb0bbe4dea9a97016b4e0f49a7ef5f3 (patch)
treeb30fe16afdaffcd5bb74d434101732dc20908d43 /crates/ra_hir/src/macros.rs
parentd75365619212983d2b7abf7b5b5e73c70dd07fb4 (diff)
use macros database in analysis
Diffstat (limited to 'crates/ra_hir/src/macros.rs')
-rw-r--r--crates/ra_hir/src/macros.rs53
1 files changed, 47 insertions, 6 deletions
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs
index 050b97081..ef6502524 100644
--- a/crates/ra_hir/src/macros.rs
+++ b/crates/ra_hir/src/macros.rs
@@ -1,7 +1,10 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::SyntaxDatabase; 3use ra_db::{SyntaxDatabase, LocalSyntaxPtr};
4use ra_syntax::{TextRange, TextUnit, SourceFileNode, AstNode, ast}; 4use ra_syntax::{
5 TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode,
6 ast,
7};
5 8
6// Hard-coded defs for now :-( 9// Hard-coded defs for now :-(
7#[derive(Debug, Clone, PartialEq, Eq, Hash)] 10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -12,18 +15,19 @@ pub enum MacroDef {
12#[derive(Debug, Clone, PartialEq, Eq, Hash)] 15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct MacroInput { 16pub struct MacroInput {
14 // Should be token trees 17 // Should be token trees
15 text: String, 18 pub text: String,
16} 19}
17 20
18#[derive(Debug, Clone, PartialEq, Eq)] 21#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct MacroExpansion { 22pub struct MacroExpansion {
20 text: String, 23 text: String,
21 ranges_map: Vec<(TextRange, TextRange)>, 24 ranges_map: Vec<(TextRange, TextRange)>,
25 ptr: LocalSyntaxPtr,
22} 26}
23 27
24salsa::query_group! { 28salsa::query_group! {
25 29
26pub trait MacrosDatabase: SyntaxDatabase { 30pub trait MacroDatabase: SyntaxDatabase {
27 fn expand_macro(def: MacroDef, input: MacroInput) -> Option<Arc<MacroExpansion>> { 31 fn expand_macro(def: MacroDef, input: MacroInput) -> Option<Arc<MacroExpansion>> {
28 type ExpandMacroQuery; 32 type ExpandMacroQuery;
29 } 33 }
@@ -32,7 +36,7 @@ pub trait MacrosDatabase: SyntaxDatabase {
32} 36}
33 37
34fn expand_macro( 38fn expand_macro(
35 _db: &impl MacrosDatabase, 39 _db: &impl MacroDatabase,
36 def: MacroDef, 40 def: MacroDef,
37 input: MacroInput, 41 input: MacroInput,
38) -> Option<Arc<MacroExpansion>> { 42) -> Option<Arc<MacroExpansion>> {
@@ -50,8 +54,45 @@ fn expand_macro(
50 let file = SourceFileNode::parse(&text); 54 let file = SourceFileNode::parse(&text);
51 let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; 55 let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?;
52 let match_arg = match_expr.expr()?; 56 let match_arg = match_expr.expr()?;
57 let ptr = LocalSyntaxPtr::new(match_arg.syntax());
53 let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); 58 let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text));
54 let ranges_map = vec![(src_range, match_arg.syntax().range())]; 59 let ranges_map = vec![(src_range, match_arg.syntax().range())];
55 let res = MacroExpansion { text, ranges_map }; 60 let res = MacroExpansion {
61 text,
62 ranges_map,
63 ptr,
64 };
56 Some(Arc::new(res)) 65 Some(Arc::new(res))
57} 66}
67
68impl MacroExpansion {
69 pub fn file(&self) -> SourceFileNode {
70 SourceFileNode::parse(&self.text)
71 }
72
73 pub fn syntax(&self) -> SyntaxNode {
74 self.ptr.resolve(&self.file())
75 }
76 pub fn map_range_back(&self, tgt_range: TextRange) -> Option<TextRange> {
77 for (s_range, t_range) in self.ranges_map.iter() {
78 if tgt_range.is_subrange(&t_range) {
79 let tgt_at_zero_range = tgt_range - tgt_range.start();
80 let tgt_range_offset = tgt_range.start() - t_range.start();
81 let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start();
82 return Some(src_range);
83 }
84 }
85 None
86 }
87 pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> {
88 for (s_range, t_range) in self.ranges_map.iter() {
89 if src_range.is_subrange(&s_range) {
90 let src_at_zero_range = src_range - src_range.start();
91 let src_range_offset = src_range.start() - s_range.start();
92 let src_range = src_at_zero_range + src_range_offset + t_range.start();
93 return Some(src_range);
94 }
95 }
96 None
97 }
98}