From 81410ab50065db9c657cfbb3ef6333119a209d5d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 2 Dec 2023 19:32:53 +0100 Subject: [PATCH] Cleanup FileId stuff --- crates/hir-expand/src/files.rs | 97 ++++++++++--------- crates/hir-expand/src/lib.rs | 13 ++- .../src/handlers/remove_unused_imports.rs | 4 +- crates/ide-db/src/search.rs | 7 +- crates/ide/src/navigation_target.rs | 9 +- 5 files changed, 73 insertions(+), 57 deletions(-) diff --git a/crates/hir-expand/src/files.rs b/crates/hir-expand/src/files.rs index 36eb2dbb27..ed8639d7a1 100644 --- a/crates/hir-expand/src/files.rs +++ b/crates/hir-expand/src/files.rs @@ -83,26 +83,41 @@ impl InFileWrapper> { // endregion:transpose impls +trait FileIdToSyntax: Copy { + fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode; +} + +impl FileIdToSyntax for FileId { + fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode { + db.parse(self).syntax_node() + } +} +impl FileIdToSyntax for MacroFileId { + fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode { + db.parse_macro_expansion(self).value.0.syntax_node() + } +} +impl FileIdToSyntax for HirFileId { + fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode { + db.parse_or_expand(self) + } +} + +#[allow(private_bounds)] +impl InFileWrapper { + pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode { + FileIdToSyntax::file_syntax(self.file_id, db) + } +} + +impl InFileWrapper { + pub fn syntax(&self) -> InFileWrapper { + self.with_value(self.value.syntax()) + } +} + // region:specific impls -impl InFile { - pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode { - db.parse_or_expand(self.file_id) - } -} - -impl InRealFile { - pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode { - db.parse(self.file_id).syntax_node() - } -} - -impl InMacroFile { - pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode { - db.parse_macro_expansion(self.file_id).value.0.syntax_node() - } -} - impl InFile<&SyntaxNode> { pub fn ancestors_with_macros( self, @@ -241,9 +256,15 @@ impl InFile { match self.file_id.repr() { HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() }, HirFileIdRepr::MacroFile(mac_file) => { - if let Some(res) = self.original_file_range_opt(db) { - return res; + let (range, ctxt) = ExpansionInfo::new(db, mac_file) + .map_token_range_up(db, self.value.text_range()); + + // FIXME: Figure out an API that makes proper use of ctx, this only exists to + // keep pre-token map rewrite behaviour. + if ctxt.is_root() { + return range; } + // Fall back to whole macro call. let loc = db.lookup_intern_macro_call(mac_file.macro_call_id); loc.kind.original_call_range(db) @@ -257,8 +278,9 @@ impl InFile { HirFileIdRepr::FileId(file_id) => { Some(FileRange { file_id, range: self.value.text_range() }) } - HirFileIdRepr::MacroFile(_) => { - let (range, ctxt) = ascend_range_up_macros(db, self.map(|it| it.text_range())); + HirFileIdRepr::MacroFile(mac_file) => { + let (range, ctxt) = ExpansionInfo::new(db, mac_file) + .map_token_range_up(db, self.value.text_range()); // FIXME: Figure out an API that makes proper use of ctx, this only exists to // keep pre-token map rewrite behaviour. @@ -275,16 +297,19 @@ impl InFile { impl InFile { /// Attempts to map the syntax node back up its macro calls. pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> FileRange { - let (range, _ctxt) = ascend_range_up_macros(db, self); + let (range, _ctxt) = match self.file_id.repr() { + HirFileIdRepr::FileId(file_id) => { + (FileRange { file_id, range: self.value }, SyntaxContextId::ROOT) + } + HirFileIdRepr::MacroFile(m) => { + ExpansionInfo::new(db, m).map_token_range_up(db, self.value) + } + }; range } } impl InFile { - pub fn descendants(self) -> impl Iterator> { - self.value.syntax().descendants().filter_map(T::cast).map(move |n| self.with_value(n)) - } - pub fn original_ast_node(self, db: &dyn db::ExpandDatabase) -> Option> { // This kind of upmapping can only be achieved in attribute expanded files, // as we don't have node inputs otherwise and therefore can't find an `N` node in the input @@ -312,22 +337,4 @@ impl InFile { let value = anc.ancestors().find_map(N::cast)?; Some(InRealFile::new(file_id, value)) } - - pub fn syntax(&self) -> InFile<&SyntaxNode> { - self.with_value(self.value.syntax()) - } -} - -fn ascend_range_up_macros( - db: &dyn db::ExpandDatabase, - range: InFile, -) -> (FileRange, SyntaxContextId) { - match range.file_id.repr() { - HirFileIdRepr::FileId(file_id) => { - (FileRange { file_id, range: range.value }, SyntaxContextId::ROOT) - } - HirFileIdRepr::MacroFile(m) => { - ExpansionInfo::new(db, m).map_token_range_up(db, range.value) - } - } } diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index f328431372..1d5b7dfa59 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -172,17 +172,18 @@ pub enum MacroCallKind { } pub trait HirFileIdExt { - /// For macro-expansion files, returns the file original source file the - /// expansion originated from. + /// Returns the original file of this macro call hierarchy. fn original_file(self, db: &dyn db::ExpandDatabase) -> FileId; + /// Returns the original file of this macro call hierarchy while going into the included file if + /// one of the calls comes from an `include!``. fn original_file_respecting_includes(self, db: &dyn db::ExpandDatabase) -> FileId; /// If this is a macro call, returns the syntax node of the call. fn call_node(self, db: &dyn db::ExpandDatabase) -> Option>; /// If this is a macro call, returns the syntax node of the very first macro call this file resides in. - fn original_call_node(self, db: &dyn db::ExpandDatabase) -> Option<(FileId, SyntaxNode)>; + fn original_call_node(self, db: &dyn db::ExpandDatabase) -> Option>; /// Return expansion information if it is a macro-expansion file fn expansion_info(self, db: &dyn db::ExpandDatabase) -> Option; @@ -246,11 +247,13 @@ impl HirFileIdExt for HirFileId { Some(loc.to_node(db)) } - fn original_call_node(self, db: &dyn db::ExpandDatabase) -> Option<(FileId, SyntaxNode)> { + fn original_call_node(self, db: &dyn db::ExpandDatabase) -> Option> { let mut call = db.lookup_intern_macro_call(self.macro_file()?.macro_call_id).to_node(db); loop { match call.file_id.repr() { - HirFileIdRepr::FileId(file_id) => break Some((file_id, call.value)), + HirFileIdRepr::FileId(file_id) => { + break Some(InRealFile { file_id, value: call.value }) + } HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => { call = db.lookup_intern_macro_call(macro_call_id).to_node(db); } diff --git a/crates/ide-assists/src/handlers/remove_unused_imports.rs b/crates/ide-assists/src/handlers/remove_unused_imports.rs index 10076e60c3..ee44064e7c 100644 --- a/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -1,6 +1,6 @@ use std::collections::{hash_map::Entry, HashMap}; -use hir::{HirFileIdExt, InFile, Module, ModuleSource}; +use hir::{HirFileIdExt, InFile, InRealFile, Module, ModuleSource}; use ide_db::{ base_db::FileRange, defs::Definition, @@ -167,7 +167,7 @@ fn used_once_in_scope(ctx: &AssistContext<'_>, def: Definition, scopes: &Vec Vec { let (file_id, range) = { let InFile { file_id, value } = module.definition_source(db); - if let Some((file_id, call_source)) = file_id.original_call_node(db) { + if let Some(InRealFile { file_id, value: call_source }) = file_id.original_call_node(db) { (file_id, Some(call_source.text_range())) } else { ( diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index 68f2ad4945..2ce036c044 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -8,8 +8,8 @@ use std::mem; use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt}; use hir::{ - AsAssocItem, DefWithBody, HasAttrs, HasSource, HirFileIdExt, InFile, ModuleSource, Semantics, - Visibility, + AsAssocItem, DefWithBody, HasAttrs, HasSource, HirFileIdExt, InFile, InRealFile, ModuleSource, + Semantics, Visibility, }; use memchr::memmem::Finder; use nohash_hasher::IntMap; @@ -133,7 +133,8 @@ impl SearchScope { let (file_id, range) = { let InFile { file_id, value } = module.definition_source(db); - if let Some((file_id, call_source)) = file_id.original_call_node(db) { + if let Some(InRealFile { file_id, value: call_source }) = file_id.original_call_node(db) + { (file_id, Some(call_source.text_range())) } else { ( diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 1e4d0e8cdc..df0c4a6ade 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -169,8 +169,13 @@ impl TryToNav for FileSymbol { fn try_to_nav(&self, db: &RootDatabase) -> Option { let full_range = self.loc.original_range(db); let focus_range = self.loc.original_name_range(db); - let focus_range = - if focus_range.file_id == full_range.file_id { Some(focus_range.range) } else { None }; + let focus_range = if focus_range.file_id == full_range.file_id + && full_range.range.contains_range(focus_range.range) + { + Some(focus_range.range) + } else { + None + }; Some(NavigationTarget { file_id: full_range.file_id,