diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-25 12:25:46 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-25 12:25:46 +0000 |
commit | 8d667bb32ed8460988bf9fe3515a6f8318adb8b0 (patch) | |
tree | 5d41d254dc94ff7d8d20063a08df2b9b133d34d9 /crates | |
parent | e2dd17f75b1bb5e1185acff66211e74430177592 (diff) | |
parent | 2adc9a8d5f8f7686a125a478330c67a2d46fba98 (diff) |
Merge #3692
3692: Introduce `MacroDefKind::CustomDerive` r=matklad a=edwin0cheng
This PR introduce a new `MacroDefKind` `CustomDerive`. And use a new `ProcMacroExpander` for its expanding. And the expander is a dummy for now.
Related: #3654
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 60 | ||||
-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 | 33 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 19 | ||||
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 2 |
10 files changed, 144 insertions, 28 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 516dd773e..bd32ac20a 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -475,6 +475,12 @@ impl AsMacroCall for AstIdWithPath<ast::ModuleItem> { | |||
475 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 475 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
476 | ) -> Option<MacroCallId> { | 476 | ) -> Option<MacroCallId> { |
477 | let def = resolver(self.path.clone())?; | 477 | let def = resolver(self.path.clone())?; |
478 | Some(def.as_lazy_macro(db.upcast(), MacroCallKind::Attr(self.ast_id)).into()) | 478 | Some( |
479 | def.as_lazy_macro( | ||
480 | db.upcast(), | ||
481 | MacroCallKind::Attr(self.ast_id, self.path.segments.last()?.to_string()), | ||
482 | ) | ||
483 | .into(), | ||
484 | ) | ||
479 | } | 485 | } |
480 | } | 486 | } |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 5b292c250..9c125f32f 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -7,6 +7,7 @@ use hir_expand::{ | |||
7 | builtin_derive::find_builtin_derive, | 7 | builtin_derive::find_builtin_derive, |
8 | builtin_macro::find_builtin_macro, | 8 | builtin_macro::find_builtin_macro, |
9 | name::{name, AsName, Name}, | 9 | name::{name, AsName, Name}, |
10 | proc_macro::ProcMacroExpander, | ||
10 | HirFileId, MacroCallId, MacroDefId, MacroDefKind, | 11 | HirFileId, MacroCallId, MacroDefId, MacroDefKind, |
11 | }; | 12 | }; |
12 | use ra_cfg::CfgOptions; | 13 | use ra_cfg::CfgOptions; |
@@ -64,6 +65,9 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr | |||
64 | unexpanded_attribute_macros: Vec::new(), | 65 | unexpanded_attribute_macros: Vec::new(), |
65 | mod_dirs: FxHashMap::default(), | 66 | mod_dirs: FxHashMap::default(), |
66 | cfg_options, | 67 | cfg_options, |
68 | |||
69 | // FIXME: pass proc-macro from crate-graph | ||
70 | proc_macros: Default::default(), | ||
67 | }; | 71 | }; |
68 | collector.collect(); | 72 | collector.collect(); |
69 | collector.finish() | 73 | collector.finish() |
@@ -122,6 +126,7 @@ struct DefCollector<'a> { | |||
122 | unexpanded_attribute_macros: Vec<DeriveDirective>, | 126 | unexpanded_attribute_macros: Vec<DeriveDirective>, |
123 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, | 127 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, |
124 | cfg_options: &'a CfgOptions, | 128 | cfg_options: &'a CfgOptions, |
129 | proc_macros: Vec<(Name, ProcMacroExpander)>, | ||
125 | } | 130 | } |
126 | 131 | ||
127 | impl DefCollector<'_> { | 132 | impl DefCollector<'_> { |
@@ -177,6 +182,24 @@ impl DefCollector<'_> { | |||
177 | for directive in unresolved_imports { | 182 | for directive in unresolved_imports { |
178 | self.record_resolved_import(&directive) | 183 | self.record_resolved_import(&directive) |
179 | } | 184 | } |
185 | |||
186 | // Record proc-macros | ||
187 | self.collect_proc_macro(); | ||
188 | } | ||
189 | |||
190 | fn collect_proc_macro(&mut self) { | ||
191 | let proc_macros = std::mem::take(&mut self.proc_macros); | ||
192 | for (name, expander) in proc_macros { | ||
193 | let krate = self.def_map.krate; | ||
194 | |||
195 | let macro_id = MacroDefId { | ||
196 | ast_id: None, | ||
197 | krate: Some(krate), | ||
198 | kind: MacroDefKind::CustomDerive(expander), | ||
199 | }; | ||
200 | |||
201 | self.define_proc_macro(name.clone(), macro_id); | ||
202 | } | ||
180 | } | 203 | } |
181 | 204 | ||
182 | /// Define a macro with `macro_rules`. | 205 | /// Define a macro with `macro_rules`. |
@@ -238,6 +261,18 @@ impl DefCollector<'_> { | |||
238 | self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); | 261 | self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); |
239 | } | 262 | } |
240 | 263 | ||
264 | /// Define a proc macro | ||
265 | /// | ||
266 | /// A proc macro is similar to normal macro scope, but it would not visiable in legacy textual scoped. | ||
267 | /// And unconditionally exported. | ||
268 | fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { | ||
269 | self.update( | ||
270 | self.def_map.root, | ||
271 | &[(name, PerNs::macros(macro_, Visibility::Public))], | ||
272 | Visibility::Public, | ||
273 | ); | ||
274 | } | ||
275 | |||
241 | /// Import macros from `#[macro_use] extern crate`. | 276 | /// Import macros from `#[macro_use] extern crate`. |
242 | fn import_macros_from_extern_crate( | 277 | fn import_macros_from_extern_crate( |
243 | &mut self, | 278 | &mut self, |
@@ -537,8 +572,9 @@ impl DefCollector<'_> { | |||
537 | true | 572 | true |
538 | }); | 573 | }); |
539 | attribute_macros.retain(|directive| { | 574 | attribute_macros.retain(|directive| { |
540 | if let Some(call_id) = | 575 | if let Some(call_id) = directive |
541 | directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path)) | 576 | .ast_id |
577 | .as_call_id(self.db, |path| self.resolve_attribute_macro(&directive, &path)) | ||
542 | { | 578 | { |
543 | resolved.push((directive.module_id, call_id, 0)); | 579 | resolved.push((directive.module_id, call_id, 0)); |
544 | res = ReachedFixedPoint::No; | 580 | res = ReachedFixedPoint::No; |
@@ -562,9 +598,11 @@ impl DefCollector<'_> { | |||
562 | res | 598 | res |
563 | } | 599 | } |
564 | 600 | ||
565 | fn resolve_attribute_macro(&self, path: &ModPath) -> Option<MacroDefId> { | 601 | fn resolve_attribute_macro( |
566 | // FIXME this is currently super hacky, just enough to support the | 602 | &self, |
567 | // built-in derives | 603 | directive: &DeriveDirective, |
604 | path: &ModPath, | ||
605 | ) -> Option<MacroDefId> { | ||
568 | if let Some(name) = path.as_ident() { | 606 | if let Some(name) = path.as_ident() { |
569 | // FIXME this should actually be handled with the normal name | 607 | // FIXME this should actually be handled with the normal name |
570 | // resolution; the std lib defines built-in stubs for the derives, | 608 | // resolution; the std lib defines built-in stubs for the derives, |
@@ -573,7 +611,15 @@ impl DefCollector<'_> { | |||
573 | return Some(def_id); | 611 | return Some(def_id); |
574 | } | 612 | } |
575 | } | 613 | } |
576 | None | 614 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
615 | self.db, | ||
616 | ResolveMode::Other, | ||
617 | directive.module_id, | ||
618 | &path, | ||
619 | BuiltinShadowMode::Module, | ||
620 | ); | ||
621 | |||
622 | resolved_res.resolved_def.take_macros() | ||
577 | } | 623 | } |
578 | 624 | ||
579 | fn collect_macro_expansion( | 625 | fn collect_macro_expansion( |
@@ -776,7 +822,6 @@ impl ModCollector<'_, '_> { | |||
776 | // FIXME: check attrs to see if this is an attribute macro invocation; | 822 | // FIXME: check attrs to see if this is an attribute macro invocation; |
777 | // in which case we don't add the invocation, just a single attribute | 823 | // in which case we don't add the invocation, just a single attribute |
778 | // macro invocation | 824 | // macro invocation |
779 | |||
780 | self.collect_derives(attrs, def); | 825 | self.collect_derives(attrs, def); |
781 | 826 | ||
782 | let name = def.name.clone(); | 827 | let name = def.name.clone(); |
@@ -955,6 +1000,7 @@ mod tests { | |||
955 | unexpanded_attribute_macros: Vec::new(), | 1000 | unexpanded_attribute_macros: Vec::new(), |
956 | mod_dirs: FxHashMap::default(), | 1001 | mod_dirs: FxHashMap::default(), |
957 | cfg_options: &CfgOptions::default(), | 1002 | cfg_options: &CfgOptions::default(), |
1003 | proc_macros: Default::default(), | ||
958 | }; | 1004 | }; |
959 | collector.collect(); | 1005 | collector.collect(); |
960 | collector.def_map | 1006 | collector.def_map |
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index a5b50a832..79aea5806 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::{known, 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 | 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 | 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 | 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 | 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..047452306 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::CustomDerive(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..932f47c30 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::CustomDerive(_) => { | ||
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..0b41d0e95 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::CustomDerive(_) => 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..86299459f 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 | CustomDerive(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..a8dee2052 --- /dev/null +++ b/crates/ra_hir_expand/src/proc_macro.rs | |||
@@ -0,0 +1,33 @@ | |||
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 | log::debug!("Proc-macro-expanding name = {}", name); | ||
29 | |||
30 | // Return nothing for now | ||
31 | return Ok(tt::Subtree::default()); | ||
32 | } | ||
33 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 2e309a379..eb97288f1 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -639,3 +639,22 @@ mod clone { | |||
639 | ); | 639 | ); |
640 | assert_eq!("(Wrapper<S>, {unknown})", type_at_pos(&db, pos)); | 640 | assert_eq!("(Wrapper<S>, {unknown})", type_at_pos(&db, pos)); |
641 | } | 641 | } |
642 | |||
643 | #[test] | ||
644 | fn infer_custom_derive_simple() { | ||
645 | // FIXME: this test current now do nothing | ||
646 | let (db, pos) = TestDB::with_position( | ||
647 | r#" | ||
648 | //- /main.rs crate:main | ||
649 | use foo::Foo; | ||
650 | |||
651 | #[derive(Foo)] | ||
652 | struct S{} | ||
653 | |||
654 | fn test() { | ||
655 | S{}<|>; | ||
656 | } | ||
657 | "#, | ||
658 | ); | ||
659 | assert_eq!("S", type_at_pos(&db, pos)); | ||
660 | } | ||
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index e3cde9eed..8e8ae2b29 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -33,7 +33,7 @@ impl TokenTextRange { | |||
33 | } | 33 | } |
34 | 34 | ||
35 | /// Maps `tt::TokenId` to the relative range of the original token. | 35 | /// Maps `tt::TokenId` to the relative range of the original token. |
36 | #[derive(Debug, PartialEq, Eq, Default)] | 36 | #[derive(Debug, PartialEq, Eq, Clone, Default)] |
37 | pub struct TokenMap { | 37 | pub struct TokenMap { |
38 | /// Maps `tt::TokenId` to the *relative* source range. | 38 | /// Maps `tt::TokenId` to the *relative* source range. |
39 | entries: Vec<(tt::TokenId, TokenTextRange)>, | 39 | entries: Vec<(tt::TokenId, TokenTextRange)>, |