diff options
author | Edwin Cheng <[email protected]> | 2020-03-18 09:47:59 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-03-25 11:50:12 +0000 |
commit | 34dc8d25c1e461cc311d6d4404f74502513cd3ae (patch) | |
tree | 00aab26b07c1cd42dfa350eeddc6c41e5bea178b /crates/ra_hir_expand | |
parent | e2dd17f75b1bb5e1185acff66211e74430177592 (diff) |
Add basic custom derive lowering
Diffstat (limited to 'crates/ra_hir_expand')
-rw-r--r-- | crates/ra_hir_expand/src/builtin_derive.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/db.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/eager.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/hygiene.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/proc_macro.rs | 32 |
6 files changed, 63 insertions, 19 deletions
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index a5b50a832..7f753bbca 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs | |||
@@ -229,9 +229,12 @@ fn partial_ord_expand( | |||
229 | mod tests { | 229 | mod tests { |
230 | use super::*; | 230 | use super::*; |
231 | use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; | 231 | use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; |
232 | use name::Name; | ||
232 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 233 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
233 | 234 | ||
234 | fn expand_builtin_derive(s: &str, expander: BuiltinDeriveExpander) -> String { | 235 | fn expand_builtin_derive(s: &str, name: Name) -> String { |
236 | let def = find_builtin_derive(&name).unwrap(); | ||
237 | |||
235 | let (db, file_id) = TestDB::with_single_file(&s); | 238 | let (db, file_id) = TestDB::with_single_file(&s); |
236 | let parsed = db.parse(file_id); | 239 | let parsed = db.parse(file_id); |
237 | let items: Vec<_> = | 240 | let items: Vec<_> = |
@@ -239,14 +242,9 @@ mod tests { | |||
239 | 242 | ||
240 | let ast_id_map = db.ast_id_map(file_id.into()); | 243 | let ast_id_map = db.ast_id_map(file_id.into()); |
241 | 244 | ||
242 | // the first one should be a macro_rules | 245 | let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); |
243 | let def = | ||
244 | MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(expander) }; | ||
245 | 246 | ||
246 | let loc = MacroCallLoc { | 247 | let loc = MacroCallLoc { def, kind: MacroCallKind::Attr(attr_id, name.to_string()) }; |
247 | def, | ||
248 | kind: MacroCallKind::Attr(AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]))), | ||
249 | }; | ||
250 | 248 | ||
251 | let id: MacroCallId = db.intern_macro(loc).into(); | 249 | let id: MacroCallId = db.intern_macro(loc).into(); |
252 | let parsed = db.parse_or_expand(id.as_file()).unwrap(); | 250 | let parsed = db.parse_or_expand(id.as_file()).unwrap(); |
@@ -263,7 +261,7 @@ mod tests { | |||
263 | #[derive(Copy)] | 261 | #[derive(Copy)] |
264 | struct Foo; | 262 | struct Foo; |
265 | "#, | 263 | "#, |
266 | BuiltinDeriveExpander::Copy, | 264 | name::known::Copy, |
267 | ); | 265 | ); |
268 | 266 | ||
269 | assert_eq!(expanded, "impl< >std::marker::CopyforFoo< >{}"); | 267 | assert_eq!(expanded, "impl< >std::marker::CopyforFoo< >{}"); |
@@ -276,7 +274,7 @@ mod tests { | |||
276 | #[derive(Copy)] | 274 | #[derive(Copy)] |
277 | struct Foo<A, B>; | 275 | struct Foo<A, B>; |
278 | "#, | 276 | "#, |
279 | BuiltinDeriveExpander::Copy, | 277 | name::known::Copy, |
280 | ); | 278 | ); |
281 | 279 | ||
282 | assert_eq!( | 280 | assert_eq!( |
@@ -292,7 +290,7 @@ mod tests { | |||
292 | #[derive(Copy)] | 290 | #[derive(Copy)] |
293 | struct Foo<A, B, 'a, 'b>; | 291 | struct Foo<A, B, 'a, 'b>; |
294 | "#, | 292 | "#, |
295 | BuiltinDeriveExpander::Copy, | 293 | name::known::Copy, |
296 | ); | 294 | ); |
297 | 295 | ||
298 | // We currently just ignore lifetimes | 296 | // We currently just ignore lifetimes |
@@ -310,7 +308,7 @@ mod tests { | |||
310 | #[derive(Clone)] | 308 | #[derive(Clone)] |
311 | struct Foo<A, B>; | 309 | struct Foo<A, B>; |
312 | "#, | 310 | "#, |
313 | BuiltinDeriveExpander::Clone, | 311 | name::known::Clone, |
314 | ); | 312 | ); |
315 | 313 | ||
316 | assert_eq!( | 314 | assert_eq!( |
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 5a696542f..c2eb75ee5 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{algo::diff, AstNode, Parse, SyntaxKind::*, SyntaxNode}; | |||
11 | use crate::{ | 11 | use crate::{ |
12 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, | 12 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, |
13 | HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, | 13 | HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, |
14 | MacroFile, | 14 | MacroFile, ProcMacroExpander, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #[derive(Debug, Clone, Eq, PartialEq)] | 17 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -19,6 +19,7 @@ pub enum TokenExpander { | |||
19 | MacroRules(mbe::MacroRules), | 19 | MacroRules(mbe::MacroRules), |
20 | Builtin(BuiltinFnLikeExpander), | 20 | Builtin(BuiltinFnLikeExpander), |
21 | BuiltinDerive(BuiltinDeriveExpander), | 21 | BuiltinDerive(BuiltinDeriveExpander), |
22 | ProcMacro(ProcMacroExpander), | ||
22 | } | 23 | } |
23 | 24 | ||
24 | impl TokenExpander { | 25 | impl TokenExpander { |
@@ -33,6 +34,7 @@ impl TokenExpander { | |||
33 | // FIXME switch these to ExpandResult as well | 34 | // FIXME switch these to ExpandResult as well |
34 | TokenExpander::Builtin(it) => it.expand(db, id, tt).into(), | 35 | TokenExpander::Builtin(it) => it.expand(db, id, tt).into(), |
35 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), | 36 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), |
37 | TokenExpander::ProcMacro(it) => it.expand(db, id, tt).into(), | ||
36 | } | 38 | } |
37 | } | 39 | } |
38 | 40 | ||
@@ -41,6 +43,7 @@ impl TokenExpander { | |||
41 | TokenExpander::MacroRules(it) => it.map_id_down(id), | 43 | TokenExpander::MacroRules(it) => it.map_id_down(id), |
42 | TokenExpander::Builtin(..) => id, | 44 | TokenExpander::Builtin(..) => id, |
43 | TokenExpander::BuiltinDerive(..) => id, | 45 | TokenExpander::BuiltinDerive(..) => id, |
46 | TokenExpander::ProcMacro(..) => id, | ||
44 | } | 47 | } |
45 | } | 48 | } |
46 | 49 | ||
@@ -49,6 +52,7 @@ impl TokenExpander { | |||
49 | TokenExpander::MacroRules(it) => it.map_id_up(id), | 52 | TokenExpander::MacroRules(it) => it.map_id_up(id), |
50 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), | 53 | TokenExpander::Builtin(..) => (id, mbe::Origin::Call), |
51 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), | 54 | TokenExpander::BuiltinDerive(..) => (id, mbe::Origin::Call), |
55 | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), | ||
52 | } | 56 | } |
53 | } | 57 | } |
54 | } | 58 | } |
@@ -130,7 +134,10 @@ pub(crate) fn macro_def( | |||
130 | MacroDefKind::BuiltInDerive(expander) => { | 134 | MacroDefKind::BuiltInDerive(expander) => { |
131 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) | 135 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) |
132 | } | 136 | } |
133 | MacroDefKind::BuiltInEager(_expander) => None, | 137 | MacroDefKind::BuiltInEager(_) => None, |
138 | MacroDefKind::ProcMacro(expander) => { | ||
139 | Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) | ||
140 | } | ||
134 | } | 141 | } |
135 | } | 142 | } |
136 | 143 | ||
diff --git a/crates/ra_hir_expand/src/eager.rs b/crates/ra_hir_expand/src/eager.rs index 687d40294..9ff743b9e 100644 --- a/crates/ra_hir_expand/src/eager.rs +++ b/crates/ra_hir_expand/src/eager.rs | |||
@@ -112,7 +112,8 @@ fn eager_macro_recur( | |||
112 | } | 112 | } |
113 | MacroDefKind::Declarative | 113 | MacroDefKind::Declarative |
114 | | MacroDefKind::BuiltIn(_) | 114 | | MacroDefKind::BuiltIn(_) |
115 | | MacroDefKind::BuiltInDerive(_) => { | 115 | | MacroDefKind::BuiltInDerive(_) |
116 | | MacroDefKind::ProcMacro(_) => { | ||
116 | let expanded = lazy_expand(db, &def, curr.with_value(child.clone()))?; | 117 | let expanded = lazy_expand(db, &def, curr.with_value(child.clone()))?; |
117 | // replace macro inside | 118 | // replace macro inside |
118 | eager_macro_recur(db, expanded, macro_resolver)? | 119 | eager_macro_recur(db, expanded, macro_resolver)? |
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs index dfbac494f..182c08eb3 100644 --- a/crates/ra_hir_expand/src/hygiene.rs +++ b/crates/ra_hir_expand/src/hygiene.rs | |||
@@ -30,6 +30,7 @@ impl Hygiene { | |||
30 | MacroDefKind::BuiltIn(_) => None, | 30 | MacroDefKind::BuiltIn(_) => None, |
31 | MacroDefKind::BuiltInDerive(_) => None, | 31 | MacroDefKind::BuiltInDerive(_) => None, |
32 | MacroDefKind::BuiltInEager(_) => None, | 32 | MacroDefKind::BuiltInEager(_) => None, |
33 | MacroDefKind::ProcMacro(_) => None, | ||
33 | } | 34 | } |
34 | } | 35 | } |
35 | MacroCallId::EagerMacro(_id) => None, | 36 | MacroCallId::EagerMacro(_id) => None, |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 6b59ea4c9..ac1d12252 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -11,6 +11,7 @@ pub mod hygiene; | |||
11 | pub mod diagnostics; | 11 | pub mod diagnostics; |
12 | pub mod builtin_derive; | 12 | pub mod builtin_derive; |
13 | pub mod builtin_macro; | 13 | pub mod builtin_macro; |
14 | pub mod proc_macro; | ||
14 | pub mod quote; | 15 | pub mod quote; |
15 | pub mod eager; | 16 | pub mod eager; |
16 | 17 | ||
@@ -27,6 +28,7 @@ use ra_syntax::{ | |||
27 | use crate::ast_id_map::FileAstId; | 28 | use crate::ast_id_map::FileAstId; |
28 | use crate::builtin_derive::BuiltinDeriveExpander; | 29 | use crate::builtin_derive::BuiltinDeriveExpander; |
29 | use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; | 30 | use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; |
31 | use crate::proc_macro::ProcMacroExpander; | ||
30 | 32 | ||
31 | #[cfg(test)] | 33 | #[cfg(test)] |
32 | mod test_db; | 34 | mod test_db; |
@@ -217,6 +219,7 @@ pub enum MacroDefKind { | |||
217 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander | 219 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander |
218 | BuiltInDerive(BuiltinDeriveExpander), | 220 | BuiltInDerive(BuiltinDeriveExpander), |
219 | BuiltInEager(EagerExpander), | 221 | BuiltInEager(EagerExpander), |
222 | ProcMacro(ProcMacroExpander), | ||
220 | } | 223 | } |
221 | 224 | ||
222 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 225 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -228,21 +231,23 @@ pub struct MacroCallLoc { | |||
228 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 231 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
229 | pub enum MacroCallKind { | 232 | pub enum MacroCallKind { |
230 | FnLike(AstId<ast::MacroCall>), | 233 | FnLike(AstId<ast::MacroCall>), |
231 | Attr(AstId<ast::ModuleItem>), | 234 | Attr(AstId<ast::ModuleItem>, String), |
232 | } | 235 | } |
233 | 236 | ||
234 | impl MacroCallKind { | 237 | impl MacroCallKind { |
235 | pub fn file_id(&self) -> HirFileId { | 238 | pub fn file_id(&self) -> HirFileId { |
236 | match self { | 239 | match self { |
237 | MacroCallKind::FnLike(ast_id) => ast_id.file_id, | 240 | MacroCallKind::FnLike(ast_id) => ast_id.file_id, |
238 | MacroCallKind::Attr(ast_id) => ast_id.file_id, | 241 | MacroCallKind::Attr(ast_id, _) => ast_id.file_id, |
239 | } | 242 | } |
240 | } | 243 | } |
241 | 244 | ||
242 | pub fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { | 245 | pub fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { |
243 | match self { | 246 | match self { |
244 | MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), | 247 | MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), |
245 | MacroCallKind::Attr(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), | 248 | MacroCallKind::Attr(ast_id, _) => { |
249 | ast_id.with_value(ast_id.to_node(db).syntax().clone()) | ||
250 | } | ||
246 | } | 251 | } |
247 | } | 252 | } |
248 | 253 | ||
@@ -251,7 +256,7 @@ impl MacroCallKind { | |||
251 | MacroCallKind::FnLike(ast_id) => { | 256 | MacroCallKind::FnLike(ast_id) => { |
252 | Some(ast_id.to_node(db).token_tree()?.syntax().clone()) | 257 | Some(ast_id.to_node(db).token_tree()?.syntax().clone()) |
253 | } | 258 | } |
254 | MacroCallKind::Attr(ast_id) => Some(ast_id.to_node(db).syntax().clone()), | 259 | MacroCallKind::Attr(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()), |
255 | } | 260 | } |
256 | } | 261 | } |
257 | } | 262 | } |
diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs new file mode 100644 index 000000000..68c828790 --- /dev/null +++ b/crates/ra_hir_expand/src/proc_macro.rs | |||
@@ -0,0 +1,32 @@ | |||
1 | //! Proc Macro Expander stub | ||
2 | |||
3 | use crate::{db::AstDatabase, LazyMacroId, MacroCallKind, MacroCallLoc}; | ||
4 | use ra_db::CrateId; | ||
5 | |||
6 | #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] | ||
7 | pub struct ProcMacroExpander { | ||
8 | krate: CrateId, | ||
9 | } | ||
10 | |||
11 | impl ProcMacroExpander { | ||
12 | pub fn new(krate: CrateId) -> ProcMacroExpander { | ||
13 | ProcMacroExpander { krate } | ||
14 | } | ||
15 | |||
16 | pub fn expand( | ||
17 | &self, | ||
18 | db: &dyn AstDatabase, | ||
19 | id: LazyMacroId, | ||
20 | _tt: &tt::Subtree, | ||
21 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
22 | let loc: MacroCallLoc = db.lookup_intern_macro(id); | ||
23 | let name = match loc.kind { | ||
24 | MacroCallKind::FnLike(_) => return Err(mbe::ExpandError::ConversionError), | ||
25 | MacroCallKind::Attr(_, name) => name, | ||
26 | }; | ||
27 | |||
28 | dbg!(name); | ||
29 | |||
30 | unimplemented!() | ||
31 | } | ||
32 | } | ||