diff options
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r-- | crates/hir/src/semantics.rs | 76 |
1 files changed, 4 insertions, 72 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index c61a430e1..4315ad48b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -13,10 +13,7 @@ use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; | |||
13 | use hir_ty::associated_type_shorthand_candidates; | 13 | use hir_ty::associated_type_shorthand_candidates; |
14 | use itertools::Itertools; | 14 | use itertools::Itertools; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use syntax::{ | 16 | use syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode, SyntaxToken, TextSize}; |
17 | algo::{find_node_at_offset, skip_trivia_token}, | ||
18 | ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize, | ||
19 | }; | ||
20 | 17 | ||
21 | use crate::{ | 18 | use crate::{ |
22 | code_model::Access, | 19 | code_model::Access, |
@@ -25,7 +22,7 @@ use crate::{ | |||
25 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 22 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
26 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 23 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
27 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, | 24 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, |
28 | Module, ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, | 25 | Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, |
29 | }; | 26 | }; |
30 | 27 | ||
31 | #[derive(Debug, Clone, PartialEq, Eq)] | 28 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -372,7 +369,7 @@ impl<'db> SemanticsImpl<'db> { | |||
372 | 369 | ||
373 | fn original_range(&self, node: &SyntaxNode) -> FileRange { | 370 | fn original_range(&self, node: &SyntaxNode) -> FileRange { |
374 | let node = self.find_file(node.clone()); | 371 | let node = self.find_file(node.clone()); |
375 | original_range(self.db, node.as_ref()) | 372 | node.as_ref().original_file_range(self.db.upcast()) |
376 | } | 373 | } |
377 | 374 | ||
378 | fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { | 375 | fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { |
@@ -380,7 +377,7 @@ impl<'db> SemanticsImpl<'db> { | |||
380 | let root = self.db.parse_or_expand(src.file_id).unwrap(); | 377 | let root = self.db.parse_or_expand(src.file_id).unwrap(); |
381 | let node = src.value.to_node(&root); | 378 | let node = src.value.to_node(&root); |
382 | self.cache(root, src.file_id); | 379 | self.cache(root, src.file_id); |
383 | original_range(self.db, src.with_value(&node)) | 380 | src.with_value(&node).original_file_range(self.db.upcast()) |
384 | } | 381 | } |
385 | 382 | ||
386 | fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { | 383 | fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { |
@@ -771,68 +768,3 @@ impl<'a> SemanticsScope<'a> { | |||
771 | resolve_hir_path(self.db, &self.resolver, &path) | 768 | resolve_hir_path(self.db, &self.resolver, &path) |
772 | } | 769 | } |
773 | } | 770 | } |
774 | |||
775 | // FIXME: Change `HasSource` trait to work with `Semantics` and remove this? | ||
776 | pub fn original_range(db: &dyn HirDatabase, node: InFile<&SyntaxNode>) -> FileRange { | ||
777 | if let Some(range) = original_range_opt(db, node) { | ||
778 | let original_file = range.file_id.original_file(db.upcast()); | ||
779 | if range.file_id == original_file.into() { | ||
780 | return FileRange { file_id: original_file, range: range.value }; | ||
781 | } | ||
782 | |||
783 | log::error!("Fail to mapping up more for {:?}", range); | ||
784 | return FileRange { file_id: range.file_id.original_file(db.upcast()), range: range.value }; | ||
785 | } | ||
786 | |||
787 | // Fall back to whole macro call | ||
788 | if let Some(expansion) = node.file_id.expansion_info(db.upcast()) { | ||
789 | if let Some(call_node) = expansion.call_node() { | ||
790 | return FileRange { | ||
791 | file_id: call_node.file_id.original_file(db.upcast()), | ||
792 | range: call_node.value.text_range(), | ||
793 | }; | ||
794 | } | ||
795 | } | ||
796 | |||
797 | FileRange { file_id: node.file_id.original_file(db.upcast()), range: node.value.text_range() } | ||
798 | } | ||
799 | |||
800 | fn original_range_opt( | ||
801 | db: &dyn HirDatabase, | ||
802 | node: InFile<&SyntaxNode>, | ||
803 | ) -> Option<InFile<TextRange>> { | ||
804 | let expansion = node.file_id.expansion_info(db.upcast())?; | ||
805 | |||
806 | // the input node has only one token ? | ||
807 | let single = skip_trivia_token(node.value.first_token()?, Direction::Next)? | ||
808 | == skip_trivia_token(node.value.last_token()?, Direction::Prev)?; | ||
809 | |||
810 | Some(node.value.descendants().find_map(|it| { | ||
811 | let first = skip_trivia_token(it.first_token()?, Direction::Next)?; | ||
812 | let first = ascend_call_token(db, &expansion, node.with_value(first))?; | ||
813 | |||
814 | let last = skip_trivia_token(it.last_token()?, Direction::Prev)?; | ||
815 | let last = ascend_call_token(db, &expansion, node.with_value(last))?; | ||
816 | |||
817 | if (!single && first == last) || (first.file_id != last.file_id) { | ||
818 | return None; | ||
819 | } | ||
820 | |||
821 | Some(first.with_value(first.value.text_range().cover(last.value.text_range()))) | ||
822 | })?) | ||
823 | } | ||
824 | |||
825 | fn ascend_call_token( | ||
826 | db: &dyn HirDatabase, | ||
827 | expansion: &ExpansionInfo, | ||
828 | token: InFile<SyntaxToken>, | ||
829 | ) -> Option<InFile<SyntaxToken>> { | ||
830 | let (mapped, origin) = expansion.map_token_up(token.as_ref())?; | ||
831 | if origin != Origin::Call { | ||
832 | return None; | ||
833 | } | ||
834 | if let Some(info) = mapped.file_id.expansion_info(db.upcast()) { | ||
835 | return ascend_call_token(db, &info, mapped); | ||
836 | } | ||
837 | Some(mapped) | ||
838 | } | ||