diff options
author | Aleksey Kladov <[email protected]> | 2019-03-26 10:09:39 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-03-26 10:20:54 +0000 |
commit | 5270bca5f72fa65f0515be776e06d3d6a4d1efca (patch) | |
tree | fa1b8b8ac66713ba29b676e1c2fdd4c4357f24ff | |
parent | dc94f3612583c5e960b334761ad0c18d328840ea (diff) |
store macro def inside macro id
This solves the problem of "macro expansion can't call into name
resolution, because name resolution calls back into macro expansion"
Because we store macro def as a part of call id, macro expansion just
knows the def!
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 93 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/incremental.rs | 23 |
7 files changed, 73 insertions, 119 deletions
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 14237060c..790e2b80f 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -76,7 +76,7 @@ impl Module { | |||
76 | import: ImportId, | 76 | import: ImportId, |
77 | ) -> TreeArc<ast::PathSegment> { | 77 | ) -> TreeArc<ast::PathSegment> { |
78 | let (file_id, source) = self.definition_source(db); | 78 | let (file_id, source) = self.definition_source(db); |
79 | let (_, source_map) = db.raw_items_with_source_map(file_id.original_file(db)); | 79 | let (_, source_map) = db.raw_items_with_source_map(file_id); |
80 | source_map.get(&source, import) | 80 | source_map.get(&source, import) |
81 | } | 81 | } |
82 | 82 | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 143919cdc..6eb916149 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; |
4 | use ra_db::{SourceDatabase, salsa, FileId}; | 4 | use ra_db::{SourceDatabase, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | HirFileId, SourceFileItems, SourceItemId, Crate, Module, HirInterner, | 7 | HirFileId, SourceFileItems, SourceItemId, Crate, Module, HirInterner, |
@@ -38,10 +38,13 @@ pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { | |||
38 | fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>; | 38 | fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>; |
39 | 39 | ||
40 | #[salsa::invoke(RawItems::raw_items_query)] | 40 | #[salsa::invoke(RawItems::raw_items_query)] |
41 | fn raw_items(&self, file_id: FileId) -> Arc<RawItems>; | 41 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; |
42 | 42 | ||
43 | #[salsa::invoke(RawItems::raw_items_with_source_map_query)] | 43 | #[salsa::invoke(RawItems::raw_items_with_source_map_query)] |
44 | fn raw_items_with_source_map(&self, file_id: FileId) -> (Arc<RawItems>, Arc<ImportSourceMap>); | 44 | fn raw_items_with_source_map( |
45 | &self, | ||
46 | file_id: HirFileId, | ||
47 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>); | ||
45 | 48 | ||
46 | #[salsa::invoke(CrateDefMap::crate_def_map_query)] | 49 | #[salsa::invoke(CrateDefMap::crate_def_map_query)] |
47 | fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>; | 50 | fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 18401f865..cf0566308 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -7,6 +7,7 @@ use std::{ | |||
7 | use ra_db::{LocationInterner, FileId}; | 7 | use ra_db::{LocationInterner, FileId}; |
8 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; | 8 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; |
9 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; | 9 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; |
10 | use mbe::MacroRules; | ||
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
12 | Module, | 13 | Module, |
@@ -100,10 +101,7 @@ fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<Tree | |||
100 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); | 101 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); |
101 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; | 102 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; |
102 | 103 | ||
103 | let def_map = db.crate_def_map(loc.module.krate); | 104 | let macro_rules = macro_def_query(db, loc.def)?; |
104 | let (krate, macro_id) = def_map.resolve_macro(macro_call_id)?; | ||
105 | let def_map = db.crate_def_map(krate); | ||
106 | let macro_rules = &def_map[macro_id]; | ||
107 | let tt = macro_rules.expand(¯o_arg).ok()?; | 105 | let tt = macro_rules.expand(¯o_arg).ok()?; |
108 | Some(mbe::token_tree_to_ast_item_list(&tt)) | 106 | Some(mbe::token_tree_to_ast_item_list(&tt)) |
109 | } | 107 | } |
@@ -126,6 +124,22 @@ impl From<MacroCallId> for HirFileId { | |||
126 | } | 124 | } |
127 | } | 125 | } |
128 | 126 | ||
127 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
128 | pub(crate) enum MacroDefId { | ||
129 | MacroByExample { source_item_id: SourceItemId }, | ||
130 | } | ||
131 | |||
132 | fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { | ||
133 | let syntax_node = match id { | ||
134 | MacroDefId::MacroByExample { source_item_id } => db.file_item(source_item_id), | ||
135 | }; | ||
136 | let macro_call = ast::MacroCall::cast(&syntax_node).unwrap(); | ||
137 | let arg = macro_call.token_tree()?; | ||
138 | let (tt, _) = mbe::ast_to_token_tree(arg)?; | ||
139 | let rules = MacroRules::parse(&tt).ok()?; | ||
140 | Some(Arc::new(rules)) | ||
141 | } | ||
142 | |||
129 | /// `MacroCallId` identifies a particular macro invocation, like | 143 | /// `MacroCallId` identifies a particular macro invocation, like |
130 | /// `println!("Hello, {}", world)`. | 144 | /// `println!("Hello, {}", world)`. |
131 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 145 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -134,7 +148,7 @@ impl_arena_id!(MacroCallId); | |||
134 | 148 | ||
135 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 149 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
136 | pub struct MacroCallLoc { | 150 | pub struct MacroCallLoc { |
137 | pub(crate) module: Module, | 151 | pub(crate) def: MacroDefId, |
138 | pub(crate) source_item_id: SourceItemId, | 152 | pub(crate) source_item_id: SourceItemId, |
139 | } | 153 | } |
140 | 154 | ||
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index c34aa4b50..93c11f271 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -63,7 +63,7 @@ use test_utils::tested_by; | |||
63 | use crate::{ | 63 | use crate::{ |
64 | ModuleDef, Name, Crate, Module, | 64 | ModuleDef, Name, Crate, Module, |
65 | DefDatabase, Path, PathKind, HirFileId, Trait, | 65 | DefDatabase, Path, PathKind, HirFileId, Trait, |
66 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, | 66 | ids::{SourceItemId, SourceFileItemId, MacroCallId, MacroDefId}, |
67 | diagnostics::DiagnosticSink, | 67 | diagnostics::DiagnosticSink, |
68 | nameres::diagnostics::DefDiagnostic, | 68 | nameres::diagnostics::DefDiagnostic, |
69 | }; | 69 | }; |
@@ -85,7 +85,7 @@ pub struct CrateDefMap { | |||
85 | root: CrateModuleId, | 85 | root: CrateModuleId, |
86 | modules: Arena<CrateModuleId, ModuleData>, | 86 | modules: Arena<CrateModuleId, ModuleData>, |
87 | macros: Arena<CrateMacroId, mbe::MacroRules>, | 87 | macros: Arena<CrateMacroId, mbe::MacroRules>, |
88 | public_macros: FxHashMap<Name, CrateMacroId>, | 88 | public_macros: FxHashMap<Name, MacroDefId>, |
89 | macro_resolutions: FxHashMap<MacroCallId, (Crate, CrateMacroId)>, | 89 | macro_resolutions: FxHashMap<MacroCallId, (Crate, CrateMacroId)>, |
90 | diagnostics: Vec<DefDiagnostic>, | 90 | diagnostics: Vec<DefDiagnostic>, |
91 | } | 91 | } |
@@ -238,13 +238,6 @@ impl CrateDefMap { | |||
238 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) | 238 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) |
239 | } | 239 | } |
240 | 240 | ||
241 | pub(crate) fn resolve_macro( | ||
242 | &self, | ||
243 | macro_call_id: MacroCallId, | ||
244 | ) -> Option<(Crate, CrateMacroId)> { | ||
245 | self.macro_resolutions.get(¯o_call_id).map(|&it| it) | ||
246 | } | ||
247 | |||
248 | pub(crate) fn find_module_by_source( | 241 | pub(crate) fn find_module_by_source( |
249 | &self, | 242 | &self, |
250 | file_id: HirFileId, | 243 | file_id: HirFileId, |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 8830b4624..89300d2ec 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -6,15 +6,15 @@ use ra_db::FileId; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
9 | DefDatabase, HirFileId, Name, Path, Crate, | 9 | DefDatabase, HirFileId, Name, Path, |
10 | KnownName, | 10 | KnownName, |
11 | nameres::{ | 11 | nameres::{ |
12 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, | 12 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, |
13 | CrateDefMap, CrateModuleId, ModuleData, CrateMacroId, | 13 | CrateDefMap, CrateModuleId, ModuleData, |
14 | diagnostics::DefDiagnostic, | 14 | diagnostics::DefDiagnostic, |
15 | raw, | 15 | raw, |
16 | }, | 16 | }, |
17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, | 17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId, MacroDefId}, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -51,8 +51,8 @@ struct DefCollector<DB> { | |||
51 | def_map: CrateDefMap, | 51 | def_map: CrateDefMap, |
52 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, | 52 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, |
53 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, | 53 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, |
54 | unexpanded_macros: Vec<(CrateModuleId, MacroCallId, Path, tt::Subtree)>, | 54 | unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, |
55 | global_macro_scope: FxHashMap<Name, CrateMacroId>, | 55 | global_macro_scope: FxHashMap<Name, MacroDefId>, |
56 | } | 56 | } |
57 | 57 | ||
58 | impl<'a, DB> DefCollector<&'a DB> | 58 | impl<'a, DB> DefCollector<&'a DB> |
@@ -62,7 +62,7 @@ where | |||
62 | fn collect(&mut self) { | 62 | fn collect(&mut self) { |
63 | let crate_graph = self.db.crate_graph(); | 63 | let crate_graph = self.db.crate_graph(); |
64 | let file_id = crate_graph.crate_root(self.def_map.krate.crate_id()); | 64 | let file_id = crate_graph.crate_root(self.def_map.krate.crate_id()); |
65 | let raw_items = self.db.raw_items(file_id); | 65 | let raw_items = self.db.raw_items(file_id.into()); |
66 | let module_id = self.def_map.root; | 66 | let module_id = self.def_map.root; |
67 | self.def_map.modules[module_id].definition = Some(file_id); | 67 | self.def_map.modules[module_id].definition = Some(file_id); |
68 | ModCollector { | 68 | ModCollector { |
@@ -93,14 +93,11 @@ where | |||
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) { | 96 | fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { |
97 | if let Ok(rules) = mbe::MacroRules::parse(tt) { | 97 | if export { |
98 | let macro_id = self.def_map.macros.alloc(rules); | 98 | self.def_map.public_macros.insert(name.clone(), macro_id); |
99 | if export { | ||
100 | self.def_map.public_macros.insert(name.clone(), macro_id); | ||
101 | } | ||
102 | self.global_macro_scope.insert(name, macro_id); | ||
103 | } | 99 | } |
100 | self.global_macro_scope.insert(name, macro_id); | ||
104 | } | 101 | } |
105 | 102 | ||
106 | fn resolve_imports(&mut self) -> ReachedFixedPoint { | 103 | fn resolve_imports(&mut self) -> ReachedFixedPoint { |
@@ -296,7 +293,7 @@ where | |||
296 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); | 293 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); |
297 | let mut resolved = Vec::new(); | 294 | let mut resolved = Vec::new(); |
298 | let mut res = ReachedFixedPoint::Yes; | 295 | let mut res = ReachedFixedPoint::Yes; |
299 | macros.retain(|(module_id, call_id, path, tt)| { | 296 | macros.retain(|(module_id, source_item_id, path)| { |
300 | if path.segments.len() != 2 { | 297 | if path.segments.len() != 2 { |
301 | return true; | 298 | return true; |
302 | } | 299 | } |
@@ -312,47 +309,24 @@ where | |||
312 | res = ReachedFixedPoint::No; | 309 | res = ReachedFixedPoint::No; |
313 | let def_map = self.db.crate_def_map(krate); | 310 | let def_map = self.db.crate_def_map(krate); |
314 | if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { | 311 | if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { |
315 | resolved.push((*module_id, *call_id, (krate, macro_id), tt.clone())); | 312 | let call_id = |
313 | MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db); | ||
314 | resolved.push((*module_id, call_id)); | ||
316 | } | 315 | } |
317 | false | 316 | false |
318 | }); | 317 | }); |
319 | 318 | ||
320 | for (module_id, macro_call_id, macro_def_id, arg) in resolved { | 319 | for (module_id, macro_call_id) in resolved { |
321 | self.collect_macro_expansion(module_id, macro_call_id, macro_def_id, arg); | 320 | self.collect_macro_expansion(module_id, macro_call_id); |
322 | } | 321 | } |
323 | res | 322 | res |
324 | } | 323 | } |
325 | 324 | ||
326 | fn collect_macro_expansion( | 325 | fn collect_macro_expansion(&mut self, module_id: CrateModuleId, macro_call_id: MacroCallId) { |
327 | &mut self, | 326 | let file_id: HirFileId = macro_call_id.into(); |
328 | module_id: CrateModuleId, | 327 | let raw_items = self.db.raw_items(file_id); |
329 | macro_call_id: MacroCallId, | 328 | ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } |
330 | macro_def_id: (Crate, CrateMacroId), | 329 | .collect(raw_items.items()) |
331 | macro_arg: tt::Subtree, | ||
332 | ) { | ||
333 | let (macro_krate, macro_id) = macro_def_id; | ||
334 | let dm; | ||
335 | let rules = if macro_krate == self.def_map.krate { | ||
336 | &self.def_map[macro_id] | ||
337 | } else { | ||
338 | dm = self.db.crate_def_map(macro_krate); | ||
339 | &dm[macro_id] | ||
340 | }; | ||
341 | if let Ok(expansion) = rules.expand(¯o_arg) { | ||
342 | self.def_map.macro_resolutions.insert(macro_call_id, macro_def_id); | ||
343 | // XXX: this **does not** go through a database, because we can't | ||
344 | // identify macro_call without adding the whole state of name resolution | ||
345 | // as a parameter to the query. | ||
346 | // | ||
347 | // So, we run the queries "manually" and we must ensure that | ||
348 | // `db.hir_parse(macro_call_id)` returns the same source_file. | ||
349 | let file_id: HirFileId = macro_call_id.into(); | ||
350 | let source_file = mbe::token_tree_to_ast_item_list(&expansion); | ||
351 | |||
352 | let raw_items = raw::RawItems::from_source_file(&source_file, file_id); | ||
353 | ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } | ||
354 | .collect(raw_items.items()) | ||
355 | } | ||
356 | } | 330 | } |
357 | 331 | ||
358 | fn finish(self) -> CrateDefMap { | 332 | fn finish(self) -> CrateDefMap { |
@@ -412,7 +386,7 @@ where | |||
412 | Ok(file_id) => { | 386 | Ok(file_id) => { |
413 | let module_id = | 387 | let module_id = |
414 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); | 388 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); |
415 | let raw_items = self.def_collector.db.raw_items(file_id); | 389 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
416 | ModCollector { | 390 | ModCollector { |
417 | def_collector: &mut *self.def_collector, | 391 | def_collector: &mut *self.def_collector, |
418 | module_id, | 392 | module_id, |
@@ -484,38 +458,33 @@ where | |||
484 | // Case 1: macro rules, define a macro in crate-global mutable scope | 458 | // Case 1: macro rules, define a macro in crate-global mutable scope |
485 | if is_macro_rules(&mac.path) { | 459 | if is_macro_rules(&mac.path) { |
486 | if let Some(name) = &mac.name { | 460 | if let Some(name) = &mac.name { |
487 | self.def_collector.define_macro(name.clone(), &mac.arg, mac.export) | 461 | let macro_id = MacroDefId::MacroByExample { |
462 | source_item_id: mac.source_item_id.with_file_id(self.file_id), | ||
463 | }; | ||
464 | self.def_collector.define_macro(name.clone(), macro_id, mac.export) | ||
488 | } | 465 | } |
489 | return; | 466 | return; |
490 | } | 467 | } |
491 | 468 | ||
492 | let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; | 469 | let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; |
493 | let macro_call_id = MacroCallLoc { | ||
494 | module: Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }, | ||
495 | source_item_id, | ||
496 | } | ||
497 | .id(self.def_collector.db); | ||
498 | 470 | ||
499 | // Case 2: try to expand macro_rules from this crate, triggering | 471 | // Case 2: try to expand macro_rules from this crate, triggering |
500 | // recursive item collection. | 472 | // recursive item collection. |
501 | if let Some(¯o_id) = | 473 | if let Some(¯o_id) = |
502 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) | 474 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) |
503 | { | 475 | { |
504 | self.def_collector.collect_macro_expansion( | 476 | let macro_call_id = |
505 | self.module_id, | 477 | MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db); |
506 | macro_call_id, | 478 | |
507 | (self.def_collector.def_map.krate, macro_id), | 479 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); |
508 | mac.arg.clone(), | ||
509 | ); | ||
510 | return; | 480 | return; |
511 | } | 481 | } |
512 | 482 | ||
513 | // Case 3: path to a macro from another crate, expand during name resolution | 483 | // Case 3: path to a macro from another crate, expand during name resolution |
514 | self.def_collector.unexpanded_macros.push(( | 484 | self.def_collector.unexpanded_macros.push(( |
515 | self.module_id, | 485 | self.module_id, |
516 | macro_call_id, | 486 | source_item_id, |
517 | mac.path.clone(), | 487 | mac.path.clone(), |
518 | mac.arg.clone(), | ||
519 | )) | 488 | )) |
520 | } | 489 | } |
521 | } | 490 | } |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f8ba398ec..7a516e556 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -4,7 +4,6 @@ use std::{ | |||
4 | }; | 4 | }; |
5 | 5 | ||
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | use ra_db::FileId; | ||
8 | use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; | 7 | use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; |
9 | use ra_syntax::{ | 8 | use ra_syntax::{ |
10 | AstNode, SourceFile, AstPtr, TreeArc, | 9 | AstNode, SourceFile, AstPtr, TreeArc, |
@@ -47,20 +46,20 @@ impl ImportSourceMap { | |||
47 | } | 46 | } |
48 | 47 | ||
49 | impl RawItems { | 48 | impl RawItems { |
50 | pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: FileId) -> Arc<RawItems> { | 49 | pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: HirFileId) -> Arc<RawItems> { |
51 | db.raw_items_with_source_map(file_id).0 | 50 | db.raw_items_with_source_map(file_id).0 |
52 | } | 51 | } |
53 | 52 | ||
54 | pub(crate) fn raw_items_with_source_map_query( | 53 | pub(crate) fn raw_items_with_source_map_query( |
55 | db: &impl DefDatabase, | 54 | db: &impl DefDatabase, |
56 | file_id: FileId, | 55 | file_id: HirFileId, |
57 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | 56 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { |
58 | let mut collector = RawItemsCollector { | 57 | let mut collector = RawItemsCollector { |
59 | raw_items: RawItems::default(), | 58 | raw_items: RawItems::default(), |
60 | source_file_items: db.file_items(file_id.into()), | 59 | source_file_items: db.file_items(file_id.into()), |
61 | source_map: ImportSourceMap::default(), | 60 | source_map: ImportSourceMap::default(), |
62 | }; | 61 | }; |
63 | let source_file = db.parse(file_id); | 62 | let source_file = db.hir_parse(file_id); |
64 | collector.process_module(None, &*source_file); | 63 | collector.process_module(None, &*source_file); |
65 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) | 64 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) |
66 | } | 65 | } |
@@ -68,19 +67,6 @@ impl RawItems { | |||
68 | pub(crate) fn items(&self) -> &[RawItem] { | 67 | pub(crate) fn items(&self) -> &[RawItem] { |
69 | &self.items | 68 | &self.items |
70 | } | 69 | } |
71 | |||
72 | // We can't use queries during name resolution for fear of cycles, so this | ||
73 | // is a query-less variant of the above function. | ||
74 | pub(crate) fn from_source_file(source_file: &SourceFile, file_id: HirFileId) -> RawItems { | ||
75 | let source_file_items = SourceFileItems::from_source_file(source_file, file_id); | ||
76 | let mut collector = RawItemsCollector { | ||
77 | raw_items: RawItems::default(), | ||
78 | source_file_items: Arc::new(source_file_items), | ||
79 | source_map: ImportSourceMap::default(), | ||
80 | }; | ||
81 | collector.process_module(None, &*source_file); | ||
82 | collector.raw_items | ||
83 | } | ||
84 | } | 70 | } |
85 | 71 | ||
86 | impl Index<Module> for RawItems { | 72 | impl Index<Module> for RawItems { |
@@ -173,7 +159,6 @@ pub(crate) struct MacroData { | |||
173 | pub(crate) source_item_id: SourceFileItemId, | 159 | pub(crate) source_item_id: SourceFileItemId, |
174 | pub(crate) path: Path, | 160 | pub(crate) path: Path, |
175 | pub(crate) name: Option<Name>, | 161 | pub(crate) name: Option<Name>, |
176 | pub(crate) arg: tt::Subtree, | ||
177 | pub(crate) export: bool, | 162 | pub(crate) export: bool, |
178 | } | 163 | } |
179 | 164 | ||
@@ -291,18 +276,15 @@ impl RawItemsCollector { | |||
291 | } | 276 | } |
292 | 277 | ||
293 | fn add_macro(&mut self, current_module: Option<Module>, m: &ast::MacroCall) { | 278 | fn add_macro(&mut self, current_module: Option<Module>, m: &ast::MacroCall) { |
294 | let (path, arg) = match ( | 279 | let path = match m.path().and_then(Path::from_ast) { |
295 | m.path().and_then(Path::from_ast), | 280 | Some(it) => it, |
296 | m.token_tree().and_then(mbe::ast_to_token_tree), | ||
297 | ) { | ||
298 | (Some(path), Some((token_tree, _token_map))) => (path, token_tree), | ||
299 | _ => return, | 281 | _ => return, |
300 | }; | 282 | }; |
301 | 283 | ||
302 | let name = m.name().map(|it| it.as_name()); | 284 | let name = m.name().map(|it| it.as_name()); |
303 | let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); | 285 | let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); |
304 | let export = m.has_atom_attr("macro_export"); | 286 | let export = m.has_atom_attr("macro_export"); |
305 | let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, arg, name, export }); | 287 | let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export }); |
306 | self.push_item(current_module, RawItem::Macro(m)); | 288 | self.push_item(current_module, RawItem::Macro(m)); |
307 | } | 289 | } |
308 | 290 | ||
diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir/src/nameres/tests/incremental.rs index 698781923..a059634e2 100644 --- a/crates/ra_hir/src/nameres/tests/incremental.rs +++ b/crates/ra_hir/src/nameres/tests/incremental.rs | |||
@@ -90,34 +90,27 @@ fn adding_inner_items_should_not_invalidate_def_map() { | |||
90 | ); | 90 | ); |
91 | } | 91 | } |
92 | 92 | ||
93 | // It would be awesome to make this work, but it's unclear how | ||
94 | #[test] | 93 | #[test] |
95 | #[ignore] | 94 | fn typing_inside_a_macro_should_not_invalidate_def_map() { |
96 | fn typing_inside_a_function_inside_a_macro_should_not_invalidate_def_map() { | ||
97 | check_def_map_is_not_recomputed( | 95 | check_def_map_is_not_recomputed( |
98 | " | 96 | " |
99 | //- /lib.rs | 97 | //- /lib.rs |
98 | macro_rules! m { | ||
99 | ($ident:ident) => { | ||
100 | struct Foo; | ||
101 | } | ||
102 | } | ||
100 | mod foo; | 103 | mod foo; |
101 | 104 | ||
102 | use crate::foo::bar::Baz; | ||
103 | |||
104 | //- /foo/mod.rs | 105 | //- /foo/mod.rs |
105 | pub mod bar; | 106 | pub mod bar; |
106 | 107 | ||
107 | //- /foo/bar.rs | 108 | //- /foo/bar.rs |
108 | <|> | 109 | <|> |
109 | salsa::query_group! { | 110 | m!(X); |
110 | trait Baz { | ||
111 | fn foo() -> i32 { 1 + 1 } | ||
112 | } | ||
113 | } | ||
114 | ", | 111 | ", |
115 | " | 112 | " |
116 | salsa::query_group! { | 113 | m!(Y); |
117 | trait Baz { | ||
118 | fn foo() -> i32 { 92 } | ||
119 | } | ||
120 | } | ||
121 | ", | 114 | ", |
122 | ); | 115 | ); |
123 | } | 116 | } |