aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/lib.rs')
-rw-r--r--crates/ra_hir_expand/src/lib.rs88
1 files changed, 78 insertions, 10 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 9506f2e1c..3fce73e8a 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -12,6 +12,7 @@ pub mod diagnostics;
12pub mod builtin_derive; 12pub mod builtin_derive;
13pub mod builtin_macro; 13pub mod builtin_macro;
14pub mod quote; 14pub mod quote;
15pub mod eager;
15 16
16use std::hash::Hash; 17use std::hash::Hash;
17use std::sync::Arc; 18use std::sync::Arc;
@@ -25,7 +26,7 @@ use ra_syntax::{
25 26
26use crate::ast_id_map::FileAstId; 27use crate::ast_id_map::FileAstId;
27use crate::builtin_derive::BuiltinDeriveExpander; 28use crate::builtin_derive::BuiltinDeriveExpander;
28use crate::builtin_macro::BuiltinFnLikeExpander; 29use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander};
29 30
30#[cfg(test)] 31#[cfg(test)]
31mod test_db; 32mod test_db;
@@ -70,8 +71,17 @@ impl HirFileId {
70 match self.0 { 71 match self.0 {
71 HirFileIdRepr::FileId(file_id) => file_id, 72 HirFileIdRepr::FileId(file_id) => file_id,
72 HirFileIdRepr::MacroFile(macro_file) => { 73 HirFileIdRepr::MacroFile(macro_file) => {
73 let loc = db.lookup_intern_macro(macro_file.macro_call_id); 74 let file_id = match macro_file.macro_call_id {
74 loc.kind.file_id().original_file(db) 75 MacroCallId::LazyMacro(id) => {
76 let loc = db.lookup_intern_macro(id);
77 loc.kind.file_id()
78 }
79 MacroCallId::EagerMacro(id) => {
80 let loc = db.lookup_intern_eager_expansion(id);
81 loc.file_id
82 }
83 };
84 file_id.original_file(db)
75 } 85 }
76 } 86 }
77 } 87 }
@@ -81,7 +91,14 @@ impl HirFileId {
81 match self.0 { 91 match self.0 {
82 HirFileIdRepr::FileId(_) => None, 92 HirFileIdRepr::FileId(_) => None,
83 HirFileIdRepr::MacroFile(macro_file) => { 93 HirFileIdRepr::MacroFile(macro_file) => {
84 let loc = db.lookup_intern_macro(macro_file.macro_call_id); 94 let lazy_id = match macro_file.macro_call_id {
95 MacroCallId::LazyMacro(id) => id,
96 MacroCallId::EagerMacro(_id) => {
97 // FIXME: handle call node for eager macro
98 return None;
99 }
100 };
101 let loc = db.lookup_intern_macro(lazy_id);
85 Some(loc.kind.node(db)) 102 Some(loc.kind.node(db))
86 } 103 }
87 } 104 }
@@ -92,7 +109,14 @@ impl HirFileId {
92 match self.0 { 109 match self.0 {
93 HirFileIdRepr::FileId(_) => None, 110 HirFileIdRepr::FileId(_) => None,
94 HirFileIdRepr::MacroFile(macro_file) => { 111 HirFileIdRepr::MacroFile(macro_file) => {
95 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); 112 let lazy_id = match macro_file.macro_call_id {
113 MacroCallId::LazyMacro(id) => id,
114 MacroCallId::EagerMacro(_id) => {
115 // FIXME: handle expansion_info for eager macro
116 return None;
117 }
118 };
119 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
96 120
97 let arg_tt = loc.kind.arg(db)?; 121 let arg_tt = loc.kind.arg(db)?;
98 let def_tt = loc.def.ast_id?.to_node(db).token_tree()?; 122 let def_tt = loc.def.ast_id?.to_node(db).token_tree()?;
@@ -118,7 +142,13 @@ impl HirFileId {
118 match self.0 { 142 match self.0 {
119 HirFileIdRepr::FileId(_) => None, 143 HirFileIdRepr::FileId(_) => None,
120 HirFileIdRepr::MacroFile(macro_file) => { 144 HirFileIdRepr::MacroFile(macro_file) => {
121 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); 145 let lazy_id = match macro_file.macro_call_id {
146 MacroCallId::LazyMacro(id) => id,
147 MacroCallId::EagerMacro(_id) => {
148 return None;
149 }
150 };
151 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
122 let item = match loc.def.kind { 152 let item = match loc.def.kind {
123 MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), 153 MacroDefKind::BuiltInDerive(_) => loc.kind.node(db),
124 _ => return None, 154 _ => return None,
@@ -137,16 +167,44 @@ pub struct MacroFile {
137/// `MacroCallId` identifies a particular macro invocation, like 167/// `MacroCallId` identifies a particular macro invocation, like
138/// `println!("Hello, {}", world)`. 168/// `println!("Hello, {}", world)`.
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 169#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
140pub struct MacroCallId(salsa::InternId); 170pub enum MacroCallId {
141impl salsa::InternKey for MacroCallId { 171 LazyMacro(LazyMacroId),
172 EagerMacro(EagerMacroId),
173}
174
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
176pub struct LazyMacroId(salsa::InternId);
177impl salsa::InternKey for LazyMacroId {
178 fn from_intern_id(v: salsa::InternId) -> Self {
179 LazyMacroId(v)
180 }
181 fn as_intern_id(&self) -> salsa::InternId {
182 self.0
183 }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
187pub struct EagerMacroId(salsa::InternId);
188impl salsa::InternKey for EagerMacroId {
142 fn from_intern_id(v: salsa::InternId) -> Self { 189 fn from_intern_id(v: salsa::InternId) -> Self {
143 MacroCallId(v) 190 EagerMacroId(v)
144 } 191 }
145 fn as_intern_id(&self) -> salsa::InternId { 192 fn as_intern_id(&self) -> salsa::InternId {
146 self.0 193 self.0
147 } 194 }
148} 195}
149 196
197impl From<LazyMacroId> for MacroCallId {
198 fn from(it: LazyMacroId) -> Self {
199 MacroCallId::LazyMacro(it)
200 }
201}
202impl From<EagerMacroId> for MacroCallId {
203 fn from(it: EagerMacroId) -> Self {
204 MacroCallId::EagerMacro(it)
205 }
206}
207
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
151pub struct MacroDefId { 209pub struct MacroDefId {
152 // FIXME: krate and ast_id are currently optional because we don't have a 210 // FIXME: krate and ast_id are currently optional because we don't have a
@@ -161,7 +219,7 @@ pub struct MacroDefId {
161} 219}
162 220
163impl MacroDefId { 221impl MacroDefId {
164 pub fn as_call_id(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> MacroCallId { 222 pub fn as_lazy_macro(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> LazyMacroId {
165 db.intern_macro(MacroCallLoc { def: self, kind }) 223 db.intern_macro(MacroCallLoc { def: self, kind })
166 } 224 }
167} 225}
@@ -172,6 +230,7 @@ pub enum MacroDefKind {
172 BuiltIn(BuiltinFnLikeExpander), 230 BuiltIn(BuiltinFnLikeExpander),
173 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander 231 // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander
174 BuiltInDerive(BuiltinDeriveExpander), 232 BuiltInDerive(BuiltinDeriveExpander),
233 BuiltInEager(EagerExpander),
175} 234}
176 235
177#[derive(Debug, Clone, PartialEq, Eq, Hash)] 236#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -217,6 +276,14 @@ impl MacroCallId {
217 } 276 }
218} 277}
219 278
279#[derive(Debug, Clone, PartialEq, Eq, Hash)]
280pub struct EagerCallLoc {
281 pub(crate) def: MacroDefId,
282 pub(crate) fragment: FragmentKind,
283 pub(crate) subtree: Arc<tt::Subtree>,
284 pub(crate) file_id: HirFileId,
285}
286
220/// ExpansionInfo mainly describes how to map text range between src and expanded macro 287/// ExpansionInfo mainly describes how to map text range between src and expanded macro
221#[derive(Debug, Clone, PartialEq, Eq)] 288#[derive(Debug, Clone, PartialEq, Eq)]
222pub struct ExpansionInfo { 289pub struct ExpansionInfo {
@@ -230,6 +297,7 @@ pub struct ExpansionInfo {
230} 297}
231 298
232pub use mbe::Origin; 299pub use mbe::Origin;
300use ra_parser::FragmentKind;
233 301
234impl ExpansionInfo { 302impl ExpansionInfo {
235 pub fn call_node(&self) -> Option<InFile<SyntaxNode>> { 303 pub fn call_node(&self) -> Option<InFile<SyntaxNode>> {