diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/macros.rs | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 5bbb09c01..e89410a76 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -22,6 +22,7 @@ mod path; | |||
22 | mod arena; | 22 | mod arena; |
23 | pub mod source_binder; | 23 | pub mod source_binder; |
24 | 24 | ||
25 | mod macros; | ||
25 | mod name; | 26 | mod name; |
26 | mod krate; | 27 | mod krate; |
27 | mod module; | 28 | mod module; |
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs new file mode 100644 index 000000000..050b97081 --- /dev/null +++ b/crates/ra_hir/src/macros.rs | |||
@@ -0,0 +1,57 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use ra_db::SyntaxDatabase; | ||
4 | use ra_syntax::{TextRange, TextUnit, SourceFileNode, AstNode, ast}; | ||
5 | |||
6 | // Hard-coded defs for now :-( | ||
7 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
8 | pub enum MacroDef { | ||
9 | CTry, | ||
10 | } | ||
11 | |||
12 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
13 | pub struct MacroInput { | ||
14 | // Should be token trees | ||
15 | text: String, | ||
16 | } | ||
17 | |||
18 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
19 | pub struct MacroExpansion { | ||
20 | text: String, | ||
21 | ranges_map: Vec<(TextRange, TextRange)>, | ||
22 | } | ||
23 | |||
24 | salsa::query_group! { | ||
25 | |||
26 | pub trait MacrosDatabase: SyntaxDatabase { | ||
27 | fn expand_macro(def: MacroDef, input: MacroInput) -> Option<Arc<MacroExpansion>> { | ||
28 | type ExpandMacroQuery; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | } | ||
33 | |||
34 | fn expand_macro( | ||
35 | _db: &impl MacrosDatabase, | ||
36 | def: MacroDef, | ||
37 | input: MacroInput, | ||
38 | ) -> Option<Arc<MacroExpansion>> { | ||
39 | let MacroDef::CTry = def; | ||
40 | let text = format!( | ||
41 | r" | ||
42 | fn dummy() {{ | ||
43 | match {} {{ | ||
44 | None => return Ok(None), | ||
45 | Some(it) => it, | ||
46 | }} | ||
47 | }}", | ||
48 | input.text | ||
49 | ); | ||
50 | let file = SourceFileNode::parse(&text); | ||
51 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; | ||
52 | let match_arg = match_expr.expr()?; | ||
53 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | ||
54 | let ranges_map = vec![(src_range, match_arg.syntax().range())]; | ||
55 | let res = MacroExpansion { text, ranges_map }; | ||
56 | Some(Arc::new(res)) | ||
57 | } | ||