diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/macros.rs | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index d9de2d8bd..932e2b574 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | use ra_db::{LocalSyntaxPtr, LocationIntener}; | 3 | use ra_db::{LocalSyntaxPtr, LocationIntener}; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode, | 5 | TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode, |
6 | ast, | 6 | ast::{self, NameOwner}, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::{SourceRootId, module::ModuleId, SourceItemId, HirDatabase}; | 9 | use crate::{SourceRootId, module::ModuleId, SourceItemId, HirDatabase}; |
@@ -44,6 +44,7 @@ impl MacroCallLoc { | |||
44 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 44 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
45 | pub enum MacroDef { | 45 | pub enum MacroDef { |
46 | CTry, | 46 | CTry, |
47 | QueryGroup, | ||
47 | } | 48 | } |
48 | 49 | ||
49 | impl MacroDef { | 50 | impl MacroDef { |
@@ -57,14 +58,14 @@ impl MacroDef { | |||
57 | fn from_call(macro_call: ast::MacroCall) -> Option<(MacroDef, MacroInput)> { | 58 | fn from_call(macro_call: ast::MacroCall) -> Option<(MacroDef, MacroInput)> { |
58 | let def = { | 59 | let def = { |
59 | let path = macro_call.path()?; | 60 | let path = macro_call.path()?; |
60 | if path.qualifier().is_some() { | ||
61 | return None; | ||
62 | } | ||
63 | let name_ref = path.segment()?.name_ref()?; | 61 | let name_ref = path.segment()?.name_ref()?; |
64 | if name_ref.text() != "ctry" { | 62 | if name_ref.text() == "ctry" { |
63 | MacroDef::CTry | ||
64 | } else if name_ref.text() == "query_group" { | ||
65 | MacroDef::QueryGroup | ||
66 | } else { | ||
65 | return None; | 67 | return None; |
66 | } | 68 | } |
67 | MacroDef::CTry | ||
68 | }; | 69 | }; |
69 | 70 | ||
70 | let input = { | 71 | let input = { |
@@ -77,7 +78,12 @@ impl MacroDef { | |||
77 | } | 78 | } |
78 | 79 | ||
79 | fn expand(self, input: MacroInput) -> Option<MacroExpansion> { | 80 | fn expand(self, input: MacroInput) -> Option<MacroExpansion> { |
80 | let MacroDef::CTry = self; | 81 | match self { |
82 | MacroDef::CTry => self.expand_ctry(input), | ||
83 | MacroDef::QueryGroup => self.expand_query_group(input), | ||
84 | } | ||
85 | } | ||
86 | fn expand_ctry(self, input: MacroInput) -> Option<MacroExpansion> { | ||
81 | let text = format!( | 87 | let text = format!( |
82 | r" | 88 | r" |
83 | fn dummy() {{ | 89 | fn dummy() {{ |
@@ -101,6 +107,30 @@ impl MacroDef { | |||
101 | }; | 107 | }; |
102 | Some(res) | 108 | Some(res) |
103 | } | 109 | } |
110 | fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { | ||
111 | let anchor = "trait "; | ||
112 | let pos = input.text.find(anchor)? + anchor.len(); | ||
113 | let trait_name = input.text[pos..] | ||
114 | .chars() | ||
115 | .take_while(|c| c.is_alphabetic()) | ||
116 | .collect::<String>(); | ||
117 | if trait_name.is_empty() { | ||
118 | return None; | ||
119 | } | ||
120 | let src_range = TextRange::offset_len((pos as u32).into(), TextUnit::of_str(&trait_name)); | ||
121 | let text = format!(r"trait {} {{ }}", trait_name); | ||
122 | let file = SourceFileNode::parse(&text); | ||
123 | let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; | ||
124 | let name = trait_def.name()?; | ||
125 | let ptr = LocalSyntaxPtr::new(trait_def.syntax()); | ||
126 | let ranges_map = vec![(src_range, name.syntax().range())]; | ||
127 | let res = MacroExpansion { | ||
128 | text, | ||
129 | ranges_map, | ||
130 | ptr, | ||
131 | }; | ||
132 | Some(res) | ||
133 | } | ||
104 | } | 134 | } |
105 | 135 | ||
106 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 136 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |