aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir/src/macros.rs57
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;
22mod arena; 22mod arena;
23pub mod source_binder; 23pub mod source_binder;
24 24
25mod macros;
25mod name; 26mod name;
26mod krate; 27mod krate;
27mod module; 28mod 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 @@
1use std::sync::Arc;
2
3use ra_db::SyntaxDatabase;
4use ra_syntax::{TextRange, TextUnit, SourceFileNode, AstNode, ast};
5
6// Hard-coded defs for now :-(
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub enum MacroDef {
9 CTry,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct MacroInput {
14 // Should be token trees
15 text: String,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct MacroExpansion {
20 text: String,
21 ranges_map: Vec<(TextRange, TextRange)>,
22}
23
24salsa::query_group! {
25
26pub trait MacrosDatabase: SyntaxDatabase {
27 fn expand_macro(def: MacroDef, input: MacroInput) -> Option<Arc<MacroExpansion>> {
28 type ExpandMacroQuery;
29 }
30}
31
32}
33
34fn 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}