aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/semantics.rs18
1 files changed, 16 insertions, 2 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index f5283ab22..1436b1afe 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -89,6 +89,7 @@ pub struct Semantics<'db, DB> {
89pub struct SemanticsImpl<'db> { 89pub struct SemanticsImpl<'db> {
90 pub db: &'db dyn HirDatabase, 90 pub db: &'db dyn HirDatabase,
91 s2d_cache: RefCell<SourceToDefCache>, 91 s2d_cache: RefCell<SourceToDefCache>,
92 expansion_info_cache: RefCell<FxHashMap<HirFileId, Option<ExpansionInfo>>>,
92 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>, 93 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
93} 94}
94 95
@@ -275,7 +276,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
275 276
276impl<'db> SemanticsImpl<'db> { 277impl<'db> SemanticsImpl<'db> {
277 fn new(db: &'db dyn HirDatabase) -> Self { 278 fn new(db: &'db dyn HirDatabase) -> Self {
278 Self { db, s2d_cache: Default::default(), cache: Default::default() } 279 SemanticsImpl {
280 db,
281 s2d_cache: Default::default(),
282 cache: Default::default(),
283 expansion_info_cache: Default::default(),
284 }
279 } 285 }
280 286
281 fn parse(&self, file_id: FileId) -> ast::SourceFile { 287 fn parse(&self, file_id: FileId) -> ast::SourceFile {
@@ -315,18 +321,26 @@ impl<'db> SemanticsImpl<'db> {
315 } 321 }
316 322
317 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { 323 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
324 let _p = profile("descend_into_macros");
318 let parent = token.parent(); 325 let parent = token.parent();
319 let parent = self.find_file(parent); 326 let parent = self.find_file(parent);
320 let sa = self.analyze2(parent.as_ref(), None); 327 let sa = self.analyze2(parent.as_ref(), None);
321 328
322 let token = successors(Some(parent.with_value(token)), |token| { 329 let token = successors(Some(parent.with_value(token)), |token| {
330 self.db.check_canceled();
323 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 331 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
324 let tt = macro_call.token_tree()?; 332 let tt = macro_call.token_tree()?;
325 if !tt.syntax().text_range().contains_range(token.value.text_range()) { 333 if !tt.syntax().text_range().contains_range(token.value.text_range()) {
326 return None; 334 return None;
327 } 335 }
328 let file_id = sa.expand(self.db, token.with_value(&macro_call))?; 336 let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
329 let token = file_id.expansion_info(self.db.upcast())?.map_token_down(token.as_ref())?; 337 let token = self
338 .expansion_info_cache
339 .borrow_mut()
340 .entry(file_id)
341 .or_insert_with(|| file_id.expansion_info(self.db.upcast()))
342 .as_ref()?
343 .map_token_down(token.as_ref())?;
330 344
331 self.cache(find_root(&token.value.parent()), token.file_id); 345 self.cache(find_root(&token.value.parent()), token.file_id);
332 346