aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/macros.rs44
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;
3use ra_db::{LocalSyntaxPtr, LocationIntener}; 3use ra_db::{LocalSyntaxPtr, LocationIntener};
4use ra_syntax::{ 4use ra_syntax::{
5 TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode, 5 TextRange, TextUnit, SourceFileNode, AstNode, SyntaxNode,
6 ast, 6 ast::{self, NameOwner},
7}; 7};
8 8
9use crate::{SourceRootId, module::ModuleId, SourceItemId, HirDatabase}; 9use 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)]
45pub enum MacroDef { 45pub enum MacroDef {
46 CTry, 46 CTry,
47 QueryGroup,
47} 48}
48 49
49impl MacroDef { 50impl 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)]