diff options
author | Jonas Schievink <[email protected]> | 2021-03-18 15:11:18 +0000 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2021-03-18 15:11:18 +0000 |
commit | c05a1a6e37156b956380d57049a72cfe6f21095d (patch) | |
tree | cecbf9cb7ee8b6706d2d70aeb04bbf67a6c43ac0 | |
parent | 3ab9b39dd47d99ffd97f485c27f38b8944e12a3e (diff) |
Store an `AstId` for procedural macros
-rw-r--r-- | crates/hir/src/has_source.rs | 15 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/hir_def/src/item_scope.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 13 | ||||
-rw-r--r-- | crates/hir_expand/src/db.rs | 4 | ||||
-rw-r--r-- | crates/hir_expand/src/eager.rs | 2 | ||||
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 2 | ||||
-rw-r--r-- | crates/hir_expand/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/display/navigation_target.rs | 8 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 14 | ||||
-rw-r--r-- | crates/ide_completion/src/render/macro_.rs | 2 |
11 files changed, 47 insertions, 26 deletions
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 5b22ab58b..d57fad9ed 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -6,7 +6,7 @@ use hir_def::{ | |||
6 | src::{HasChildSource, HasSource as _}, | 6 | src::{HasChildSource, HasSource as _}, |
7 | Lookup, VariantId, | 7 | Lookup, VariantId, |
8 | }; | 8 | }; |
9 | use hir_expand::InFile; | 9 | use hir_expand::{InFile, MacroDefKind}; |
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
@@ -111,10 +111,17 @@ impl HasSource for TypeAlias { | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | impl HasSource for MacroDef { | 113 | impl HasSource for MacroDef { |
114 | type Ast = ast::Macro; | 114 | type Ast = Either<ast::Macro, ast::Fn>; |
115 | fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { | 115 | fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { |
116 | let ast_id = self.id.ast_id()?; | 116 | Some(match &self.id.kind { |
117 | Some(InFile { file_id: ast_id.file_id, value: ast_id.to_node(db.upcast()) }) | 117 | MacroDefKind::Declarative(id) |
118 | | MacroDefKind::BuiltIn(_, id) | ||
119 | | MacroDefKind::BuiltInDerive(_, id) | ||
120 | | MacroDefKind::BuiltInEager(_, id) => { | ||
121 | id.with_value(Either::Left(id.to_node(db.upcast()))) | ||
122 | } | ||
123 | MacroDefKind::ProcMacro(_, id) => id.map(|_| Either::Right(id.to_node(db.upcast()))), | ||
124 | }) | ||
118 | } | 125 | } |
119 | } | 126 | } |
120 | impl HasSource for Impl { | 127 | impl HasSource for Impl { |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index b860cbf3c..95cfde61c 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1144,12 +1144,15 @@ impl MacroDef { | |||
1144 | 1144 | ||
1145 | /// XXX: this parses the file | 1145 | /// XXX: this parses the file |
1146 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 1146 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
1147 | self.source(db)?.value.name().map(|it| it.as_name()) | 1147 | match self.source(db)?.value { |
1148 | Either::Left(it) => it.name().map(|it| it.as_name()), | ||
1149 | Either::Right(it) => it.name().map(|it| it.as_name()), | ||
1150 | } | ||
1148 | } | 1151 | } |
1149 | 1152 | ||
1150 | /// Indicate it is a proc-macro | 1153 | /// Indicate it is a proc-macro |
1151 | pub fn is_proc_macro(&self) -> bool { | 1154 | pub fn is_proc_macro(&self) -> bool { |
1152 | matches!(self.id.kind, MacroDefKind::ProcMacro(_)) | 1155 | matches!(self.id.kind, MacroDefKind::ProcMacro(..)) |
1153 | } | 1156 | } |
1154 | 1157 | ||
1155 | /// Indicate it is a derive macro | 1158 | /// Indicate it is a derive macro |
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index aafd73b60..f3ebe7c72 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs | |||
@@ -252,7 +252,7 @@ impl ItemScope { | |||
252 | .for_each(|vis| *vis = Visibility::Module(this_module)); | 252 | .for_each(|vis| *vis = Visibility::Module(this_module)); |
253 | 253 | ||
254 | for (mac, vis) in self.macros.values_mut() { | 254 | for (mac, vis) in self.macros.values_mut() { |
255 | if let MacroDefKind::ProcMacro(_) = mac.kind { | 255 | if let MacroDefKind::ProcMacro(..) = mac.kind { |
256 | // FIXME: Technically this is insufficient since reexports of proc macros are also | 256 | // FIXME: Technically this is insufficient since reexports of proc macros are also |
257 | // forbidden. Practically nobody does that. | 257 | // forbidden. Practically nobody does that. |
258 | continue; | 258 | continue; |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 45a79e896..696370ada 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -353,17 +353,17 @@ impl DefCollector<'_> { | |||
353 | /// use a dummy expander that always errors. This comes with the drawback of macros potentially | 353 | /// use a dummy expander that always errors. This comes with the drawback of macros potentially |
354 | /// going out of sync with what the build system sees (since we resolve using VFS state, but | 354 | /// going out of sync with what the build system sees (since we resolve using VFS state, but |
355 | /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. | 355 | /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. |
356 | fn resolve_proc_macro(&mut self, name: &Name) { | 356 | fn resolve_proc_macro(&mut self, name: &Name, ast_id: AstId<ast::Fn>) { |
357 | self.exports_proc_macros = true; | 357 | self.exports_proc_macros = true; |
358 | let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { | 358 | let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { |
359 | Some((_, expander)) => MacroDefId { | 359 | Some((_, expander)) => MacroDefId { |
360 | krate: self.def_map.krate, | 360 | krate: self.def_map.krate, |
361 | kind: MacroDefKind::ProcMacro(*expander), | 361 | kind: MacroDefKind::ProcMacro(*expander, ast_id), |
362 | local_inner: false, | 362 | local_inner: false, |
363 | }, | 363 | }, |
364 | None => MacroDefId { | 364 | None => MacroDefId { |
365 | krate: self.def_map.krate, | 365 | krate: self.def_map.krate, |
366 | kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), | 366 | kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate), ast_id), |
367 | local_inner: false, | 367 | local_inner: false, |
368 | }, | 368 | }, |
369 | }; | 369 | }; |
@@ -1116,7 +1116,8 @@ impl ModCollector<'_, '_> { | |||
1116 | ModItem::Function(id) => { | 1116 | ModItem::Function(id) => { |
1117 | let func = &self.item_tree[id]; | 1117 | let func = &self.item_tree[id]; |
1118 | 1118 | ||
1119 | self.collect_proc_macro_def(&func.name, &attrs); | 1119 | let ast_id = InFile::new(self.file_id, func.ast_id); |
1120 | self.collect_proc_macro_def(&func.name, ast_id, &attrs); | ||
1120 | 1121 | ||
1121 | def = Some(DefData { | 1122 | def = Some(DefData { |
1122 | id: FunctionLoc { | 1123 | id: FunctionLoc { |
@@ -1383,7 +1384,7 @@ impl ModCollector<'_, '_> { | |||
1383 | } | 1384 | } |
1384 | 1385 | ||
1385 | /// If `attrs` registers a procedural macro, collects its definition. | 1386 | /// If `attrs` registers a procedural macro, collects its definition. |
1386 | fn collect_proc_macro_def(&mut self, func_name: &Name, attrs: &Attrs) { | 1387 | fn collect_proc_macro_def(&mut self, func_name: &Name, ast_id: AstId<ast::Fn>, attrs: &Attrs) { |
1387 | // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere | 1388 | // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere |
1388 | // FIXME: distinguish the type of macro | 1389 | // FIXME: distinguish the type of macro |
1389 | let macro_name = if attrs.by_key("proc_macro").exists() | 1390 | let macro_name = if attrs.by_key("proc_macro").exists() |
@@ -1404,7 +1405,7 @@ impl ModCollector<'_, '_> { | |||
1404 | } | 1405 | } |
1405 | }; | 1406 | }; |
1406 | 1407 | ||
1407 | self.def_collector.resolve_proc_macro(¯o_name); | 1408 | self.def_collector.resolve_proc_macro(¯o_name, ast_id); |
1408 | } | 1409 | } |
1409 | 1410 | ||
1410 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { | 1411 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { |
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 4107d7781..2748e25cf 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -157,7 +157,7 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, | |||
157 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) | 157 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) |
158 | } | 158 | } |
159 | MacroDefKind::BuiltInEager(..) => None, | 159 | MacroDefKind::BuiltInEager(..) => None, |
160 | MacroDefKind::ProcMacro(expander) => { | 160 | MacroDefKind::ProcMacro(expander, ..) => { |
161 | Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) | 161 | Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default()))) |
162 | } | 162 | } |
163 | } | 163 | } |
@@ -269,7 +269,7 @@ fn expand_proc_macro( | |||
269 | }; | 269 | }; |
270 | 270 | ||
271 | let expander = match loc.def.kind { | 271 | let expander = match loc.def.kind { |
272 | MacroDefKind::ProcMacro(expander) => expander, | 272 | MacroDefKind::ProcMacro(expander, ..) => expander, |
273 | _ => unreachable!(), | 273 | _ => unreachable!(), |
274 | }; | 274 | }; |
275 | 275 | ||
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs index ddadaffd3..04f374a29 100644 --- a/crates/hir_expand/src/eager.rs +++ b/crates/hir_expand/src/eager.rs | |||
@@ -209,7 +209,7 @@ fn eager_macro_recur( | |||
209 | MacroDefKind::Declarative(_) | 209 | MacroDefKind::Declarative(_) |
210 | | MacroDefKind::BuiltIn(..) | 210 | | MacroDefKind::BuiltIn(..) |
211 | | MacroDefKind::BuiltInDerive(..) | 211 | | MacroDefKind::BuiltInDerive(..) |
212 | | MacroDefKind::ProcMacro(_) => { | 212 | | MacroDefKind::ProcMacro(..) => { |
213 | let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); | 213 | let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); |
214 | let val = diagnostic_sink.expand_result_option(res)?; | 214 | let val = diagnostic_sink.expand_result_option(res)?; |
215 | 215 | ||
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index e758b3c0a..20cda1683 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -182,7 +182,7 @@ impl HygieneFrame { | |||
182 | MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), | 182 | MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), |
183 | MacroDefKind::BuiltInDerive(..) => (info, None, false), | 183 | MacroDefKind::BuiltInDerive(..) => (info, None, false), |
184 | MacroDefKind::BuiltInEager(..) => (info, None, false), | 184 | MacroDefKind::BuiltInEager(..) => (info, None, false), |
185 | MacroDefKind::ProcMacro(_) => (info, None, false), | 185 | MacroDefKind::ProcMacro(..) => (info, None, false), |
186 | } | 186 | } |
187 | } | 187 | } |
188 | }, | 188 | }, |
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 83e11019f..0a379651f 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -245,7 +245,7 @@ impl MacroDefId { | |||
245 | MacroDefKind::BuiltIn(_, id) => id, | 245 | MacroDefKind::BuiltIn(_, id) => id, |
246 | MacroDefKind::BuiltInDerive(_, id) => id, | 246 | MacroDefKind::BuiltInDerive(_, id) => id, |
247 | MacroDefKind::BuiltInEager(_, id) => id, | 247 | MacroDefKind::BuiltInEager(_, id) => id, |
248 | MacroDefKind::ProcMacro(_) => return None, | 248 | MacroDefKind::ProcMacro(..) => return None, |
249 | }; | 249 | }; |
250 | Some(*id) | 250 | Some(*id) |
251 | } | 251 | } |
@@ -258,7 +258,7 @@ pub enum MacroDefKind { | |||
258 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander | 258 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander |
259 | BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), | 259 | BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), |
260 | BuiltInEager(EagerExpander, AstId<ast::Macro>), | 260 | BuiltInEager(EagerExpander, AstId<ast::Macro>), |
261 | ProcMacro(ProcMacroExpander), | 261 | ProcMacro(ProcMacroExpander, AstId<ast::Fn>), |
262 | } | 262 | } |
263 | 263 | ||
264 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 264 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index c086de163..364be260c 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -339,10 +339,14 @@ impl TryToNav for hir::Field { | |||
339 | impl TryToNav for hir::MacroDef { | 339 | impl TryToNav for hir::MacroDef { |
340 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | 340 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { |
341 | let src = self.source(db)?; | 341 | let src = self.source(db)?; |
342 | log::debug!("nav target {:#?}", src.value.syntax()); | 342 | let name_owner: &dyn ast::NameOwner = match &src.value { |
343 | Either::Left(it) => it, | ||
344 | Either::Right(it) => it, | ||
345 | }; | ||
346 | log::debug!("nav target {:#?}", name_owner.syntax()); | ||
343 | let mut res = NavigationTarget::from_named( | 347 | let mut res = NavigationTarget::from_named( |
344 | db, | 348 | db, |
345 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 349 | src.as_ref().with_value(name_owner), |
346 | SymbolKind::Macro, | 350 | SymbolKind::Macro, |
347 | ); | 351 | ); |
348 | res.docs = self.docs(db); | 352 | res.docs = self.docs(db); |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 15d309d7d..a3fb17c0a 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -331,10 +331,16 @@ fn hover_for_definition( | |||
331 | ) -> Option<Markup> { | 331 | ) -> Option<Markup> { |
332 | let mod_path = definition_mod_path(db, &def); | 332 | let mod_path = definition_mod_path(db, &def); |
333 | return match def { | 333 | return match def { |
334 | Definition::Macro(it) => { | 334 | Definition::Macro(it) => match &it.source(db)?.value { |
335 | let label = macro_label(&it.source(db)?.value); | 335 | Either::Left(mac) => { |
336 | from_def_source_labeled(db, it, Some(label), mod_path) | 336 | let label = macro_label(&mac); |
337 | } | 337 | from_def_source_labeled(db, it, Some(label), mod_path) |
338 | } | ||
339 | Either::Right(_) => { | ||
340 | // FIXME | ||
341 | None | ||
342 | } | ||
343 | }, | ||
338 | Definition::Field(def) => from_hir_fmt(db, def, mod_path), | 344 | Definition::Field(def) => from_hir_fmt(db, def, mod_path), |
339 | Definition::ModuleDef(it) => match it { | 345 | Definition::ModuleDef(it) => match it { |
340 | ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path), | 346 | ModuleDef::Module(it) => from_hir_fmt(db, it, mod_path), |
diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs index 3fa21ba7c..7578ad50b 100644 --- a/crates/ide_completion/src/render/macro_.rs +++ b/crates/ide_completion/src/render/macro_.rs | |||
@@ -91,7 +91,7 @@ impl<'a> MacroRender<'a> { | |||
91 | } | 91 | } |
92 | 92 | ||
93 | fn detail(&self) -> Option<String> { | 93 | fn detail(&self) -> Option<String> { |
94 | let ast_node = self.macro_.source(self.ctx.db())?.value; | 94 | let ast_node = self.macro_.source(self.ctx.db())?.value.left()?; |
95 | Some(macro_label(&ast_node)) | 95 | Some(macro_label(&ast_node)) |
96 | } | 96 | } |
97 | } | 97 | } |