Unnamed repository; edit this file 'description' to name the repository.
Cleanup FileId stuff
Lukas Wirth 2023-12-03
parent 02a3a94 · commit 81410ab
-rw-r--r--crates/hir-expand/src/files.rs79
-rw-r--r--crates/hir-expand/src/lib.rs13
-rw-r--r--crates/ide-assists/src/handlers/remove_unused_imports.rs4
-rw-r--r--crates/ide-db/src/search.rs7
-rw-r--r--crates/ide/src/navigation_target.rs9
5 files changed, 64 insertions, 48 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<FileKind, L, R> InFileWrapper<FileKind, Either<L, R>> {
// endregion:transpose impls
-// region:specific impls
+trait FileIdToSyntax: Copy {
+ fn file_syntax(self, db: &dyn db::ExpandDatabase) -> SyntaxNode;
+}
-impl<T> InFile<T> {
- pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
- db.parse_or_expand(self.file_id)
+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)
}
}
-impl<T> InRealFile<T> {
+#[allow(private_bounds)]
+impl<FileId: FileIdToSyntax, T> InFileWrapper<FileId, T> {
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
- db.parse(self.file_id).syntax_node()
+ FileIdToSyntax::file_syntax(self.file_id, db)
}
}
-impl<T> InMacroFile<T> {
- pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
- db.parse_macro_expansion(self.file_id).value.0.syntax_node()
+impl<FileId: Copy, N: AstNode> InFileWrapper<FileId, N> {
+ pub fn syntax(&self) -> InFileWrapper<FileId, &SyntaxNode> {
+ self.with_value(self.value.syntax())
}
}
+// region:specific impls
+
impl InFile<&SyntaxNode> {
pub fn ancestors_with_macros(
self,
@@ -241,9 +256,15 @@ impl InFile<SyntaxToken> {
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<SyntaxToken> {
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<SyntaxToken> {
impl InFile<TextRange> {
/// 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<N: AstNode> InFile<N> {
- pub fn descendants<T: AstNode>(self) -> impl Iterator<Item = InFile<T>> {
- 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<InRealFile<N>> {
// 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<N: AstNode> InFile<N> {
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<TextRange>,
-) -> (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<InFile<SyntaxNode>>;
/// 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<InRealFile<SyntaxNode>>;
/// Return expansion information if it is a macro-expansion file
fn expansion_info(self, db: &dyn db::ExpandDatabase) -> Option<ExpansionInfo>;
@@ -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<InRealFile<SyntaxNode>> {
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<Sea
fn module_search_scope(db: &RootDatabase, module: hir::Module) -> Vec<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-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<NavigationTarget> {
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,