diff options
Diffstat (limited to 'crates/ra_hir/src/semantics.rs')
-rw-r--r-- | crates/ra_hir/src/semantics.rs | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index f5283ab22..6f3b3dc9a 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs | |||
@@ -89,6 +89,7 @@ pub struct Semantics<'db, DB> { | |||
89 | pub struct SemanticsImpl<'db> { | 89 | pub 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 | ||
@@ -208,7 +209,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
208 | self.imp.resolve_field(field) | 209 | self.imp.resolve_field(field) |
209 | } | 210 | } |
210 | 211 | ||
211 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { | 212 | pub fn resolve_record_field( |
213 | &self, | ||
214 | field: &ast::RecordExprField, | ||
215 | ) -> Option<(Field, Option<Local>)> { | ||
212 | self.imp.resolve_record_field(field) | 216 | self.imp.resolve_record_field(field) |
213 | } | 217 | } |
214 | 218 | ||
@@ -224,7 +228,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
224 | self.imp.resolve_path(path) | 228 | self.imp.resolve_path(path) |
225 | } | 229 | } |
226 | 230 | ||
227 | pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantDef> { | 231 | pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> { |
228 | self.imp.resolve_variant(record_lit).map(VariantDef::from) | 232 | self.imp.resolve_variant(record_lit).map(VariantDef::from) |
229 | } | 233 | } |
230 | 234 | ||
@@ -239,7 +243,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
239 | // FIXME: use this instead? | 243 | // FIXME: use this instead? |
240 | // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>; | 244 | // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>; |
241 | 245 | ||
242 | pub fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> { | 246 | pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> { |
243 | self.imp.record_literal_missing_fields(literal) | 247 | self.imp.record_literal_missing_fields(literal) |
244 | } | 248 | } |
245 | 249 | ||
@@ -275,7 +279,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
275 | 279 | ||
276 | impl<'db> SemanticsImpl<'db> { | 280 | impl<'db> SemanticsImpl<'db> { |
277 | fn new(db: &'db dyn HirDatabase) -> Self { | 281 | fn new(db: &'db dyn HirDatabase) -> Self { |
278 | Self { db, s2d_cache: Default::default(), cache: Default::default() } | 282 | SemanticsImpl { |
283 | db, | ||
284 | s2d_cache: Default::default(), | ||
285 | cache: Default::default(), | ||
286 | expansion_info_cache: Default::default(), | ||
287 | } | ||
279 | } | 288 | } |
280 | 289 | ||
281 | fn parse(&self, file_id: FileId) -> ast::SourceFile { | 290 | fn parse(&self, file_id: FileId) -> ast::SourceFile { |
@@ -315,18 +324,26 @@ impl<'db> SemanticsImpl<'db> { | |||
315 | } | 324 | } |
316 | 325 | ||
317 | fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { | 326 | fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { |
327 | let _p = profile("descend_into_macros"); | ||
318 | let parent = token.parent(); | 328 | let parent = token.parent(); |
319 | let parent = self.find_file(parent); | 329 | let parent = self.find_file(parent); |
320 | let sa = self.analyze2(parent.as_ref(), None); | 330 | let sa = self.analyze2(parent.as_ref(), None); |
321 | 331 | ||
322 | let token = successors(Some(parent.with_value(token)), |token| { | 332 | let token = successors(Some(parent.with_value(token)), |token| { |
333 | self.db.check_canceled(); | ||
323 | let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; | 334 | let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; |
324 | let tt = macro_call.token_tree()?; | 335 | let tt = macro_call.token_tree()?; |
325 | if !tt.syntax().text_range().contains_range(token.value.text_range()) { | 336 | if !tt.syntax().text_range().contains_range(token.value.text_range()) { |
326 | return None; | 337 | return None; |
327 | } | 338 | } |
328 | let file_id = sa.expand(self.db, token.with_value(¯o_call))?; | 339 | let file_id = sa.expand(self.db, token.with_value(¯o_call))?; |
329 | let token = file_id.expansion_info(self.db.upcast())?.map_token_down(token.as_ref())?; | 340 | let token = self |
341 | .expansion_info_cache | ||
342 | .borrow_mut() | ||
343 | .entry(file_id) | ||
344 | .or_insert_with(|| file_id.expansion_info(self.db.upcast())) | ||
345 | .as_ref()? | ||
346 | .map_token_down(token.as_ref())?; | ||
330 | 347 | ||
331 | self.cache(find_root(&token.value.parent()), token.file_id); | 348 | self.cache(find_root(&token.value.parent()), token.file_id); |
332 | 349 | ||
@@ -408,7 +425,7 @@ impl<'db> SemanticsImpl<'db> { | |||
408 | self.analyze(field.syntax()).resolve_field(self.db, field) | 425 | self.analyze(field.syntax()).resolve_field(self.db, field) |
409 | } | 426 | } |
410 | 427 | ||
411 | fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { | 428 | fn resolve_record_field(&self, field: &ast::RecordExprField) -> Option<(Field, Option<Local>)> { |
412 | self.analyze(field.syntax()).resolve_record_field(self.db, field) | 429 | self.analyze(field.syntax()).resolve_record_field(self.db, field) |
413 | } | 430 | } |
414 | 431 | ||
@@ -426,7 +443,7 @@ impl<'db> SemanticsImpl<'db> { | |||
426 | self.analyze(path.syntax()).resolve_path(self.db, path) | 443 | self.analyze(path.syntax()).resolve_path(self.db, path) |
427 | } | 444 | } |
428 | 445 | ||
429 | fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { | 446 | fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> { |
430 | self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) | 447 | self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) |
431 | } | 448 | } |
432 | 449 | ||
@@ -439,7 +456,7 @@ impl<'db> SemanticsImpl<'db> { | |||
439 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) | 456 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) |
440 | } | 457 | } |
441 | 458 | ||
442 | fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> { | 459 | fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> { |
443 | self.analyze(literal.syntax()) | 460 | self.analyze(literal.syntax()) |
444 | .record_literal_missing_fields(self.db, literal) | 461 | .record_literal_missing_fields(self.db, literal) |
445 | .unwrap_or_default() | 462 | .unwrap_or_default() |
@@ -563,18 +580,18 @@ macro_rules! to_def_impls { | |||
563 | 580 | ||
564 | to_def_impls![ | 581 | to_def_impls![ |
565 | (crate::Module, ast::Module, module_to_def), | 582 | (crate::Module, ast::Module, module_to_def), |
566 | (crate::Struct, ast::StructDef, struct_to_def), | 583 | (crate::Struct, ast::Struct, struct_to_def), |
567 | (crate::Enum, ast::EnumDef, enum_to_def), | 584 | (crate::Enum, ast::Enum, enum_to_def), |
568 | (crate::Union, ast::UnionDef, union_to_def), | 585 | (crate::Union, ast::Union, union_to_def), |
569 | (crate::Trait, ast::TraitDef, trait_to_def), | 586 | (crate::Trait, ast::Trait, trait_to_def), |
570 | (crate::ImplDef, ast::ImplDef, impl_to_def), | 587 | (crate::ImplDef, ast::Impl, impl_to_def), |
571 | (crate::TypeAlias, ast::TypeAliasDef, type_alias_to_def), | 588 | (crate::TypeAlias, ast::TypeAlias, type_alias_to_def), |
572 | (crate::Const, ast::ConstDef, const_to_def), | 589 | (crate::Const, ast::Const, const_to_def), |
573 | (crate::Static, ast::StaticDef, static_to_def), | 590 | (crate::Static, ast::Static, static_to_def), |
574 | (crate::Function, ast::FnDef, fn_to_def), | 591 | (crate::Function, ast::Fn, fn_to_def), |
575 | (crate::Field, ast::RecordFieldDef, record_field_to_def), | 592 | (crate::Field, ast::RecordField, record_field_to_def), |
576 | (crate::Field, ast::TupleFieldDef, tuple_field_to_def), | 593 | (crate::Field, ast::TupleField, tuple_field_to_def), |
577 | (crate::EnumVariant, ast::EnumVariant, enum_variant_to_def), | 594 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), |
578 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 595 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
579 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros | 596 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros |
580 | (crate::Local, ast::BindPat, bind_pat_to_def), | 597 | (crate::Local, ast::BindPat, bind_pat_to_def), |