mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
Cleanup FileId stuff
This commit is contained in:
parent
02a3a9438a
commit
81410ab500
5 changed files with 73 additions and 57 deletions
|
@ -83,26 +83,41 @@ impl<FileKind, L, R> InFileWrapper<FileKind, Either<L, R>> {
|
||||||
|
|
||||||
// endregion:transpose impls
|
// 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<FileId: FileIdToSyntax, T> InFileWrapper<FileId, T> {
|
||||||
|
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
|
||||||
|
FileIdToSyntax::file_syntax(self.file_id, db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<FileId: Copy, N: AstNode> InFileWrapper<FileId, N> {
|
||||||
|
pub fn syntax(&self) -> InFileWrapper<FileId, &SyntaxNode> {
|
||||||
|
self.with_value(self.value.syntax())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// region:specific impls
|
// region:specific impls
|
||||||
|
|
||||||
impl<T> InFile<T> {
|
|
||||||
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
|
|
||||||
db.parse_or_expand(self.file_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> InRealFile<T> {
|
|
||||||
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
|
|
||||||
db.parse(self.file_id).syntax_node()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 InFile<&SyntaxNode> {
|
impl InFile<&SyntaxNode> {
|
||||||
pub fn ancestors_with_macros(
|
pub fn ancestors_with_macros(
|
||||||
self,
|
self,
|
||||||
|
@ -241,9 +256,15 @@ impl InFile<SyntaxToken> {
|
||||||
match self.file_id.repr() {
|
match self.file_id.repr() {
|
||||||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
||||||
HirFileIdRepr::MacroFile(mac_file) => {
|
HirFileIdRepr::MacroFile(mac_file) => {
|
||||||
if let Some(res) = self.original_file_range_opt(db) {
|
let (range, ctxt) = ExpansionInfo::new(db, mac_file)
|
||||||
return res;
|
.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.
|
// Fall back to whole macro call.
|
||||||
let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
|
let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
|
||||||
loc.kind.original_call_range(db)
|
loc.kind.original_call_range(db)
|
||||||
|
@ -257,8 +278,9 @@ impl InFile<SyntaxToken> {
|
||||||
HirFileIdRepr::FileId(file_id) => {
|
HirFileIdRepr::FileId(file_id) => {
|
||||||
Some(FileRange { file_id, range: self.value.text_range() })
|
Some(FileRange { file_id, range: self.value.text_range() })
|
||||||
}
|
}
|
||||||
HirFileIdRepr::MacroFile(_) => {
|
HirFileIdRepr::MacroFile(mac_file) => {
|
||||||
let (range, ctxt) = ascend_range_up_macros(db, self.map(|it| it.text_range()));
|
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
|
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||||
// keep pre-token map rewrite behaviour.
|
// keep pre-token map rewrite behaviour.
|
||||||
|
@ -275,16 +297,19 @@ impl InFile<SyntaxToken> {
|
||||||
impl InFile<TextRange> {
|
impl InFile<TextRange> {
|
||||||
/// Attempts to map the syntax node back up its macro calls.
|
/// Attempts to map the syntax node back up its macro calls.
|
||||||
pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> FileRange {
|
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
|
range
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: AstNode> InFile<N> {
|
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>> {
|
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,
|
// 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
|
// 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)?;
|
let value = anc.ancestors().find_map(N::cast)?;
|
||||||
Some(InRealFile::new(file_id, value))
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,17 +172,18 @@ pub enum MacroCallKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HirFileIdExt {
|
pub trait HirFileIdExt {
|
||||||
/// For macro-expansion files, returns the file original source file the
|
/// Returns the original file of this macro call hierarchy.
|
||||||
/// expansion originated from.
|
|
||||||
fn original_file(self, db: &dyn db::ExpandDatabase) -> FileId;
|
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;
|
fn original_file_respecting_includes(self, db: &dyn db::ExpandDatabase) -> FileId;
|
||||||
|
|
||||||
/// If this is a macro call, returns the syntax node of the call.
|
/// If this is a macro call, returns the syntax node of the call.
|
||||||
fn call_node(self, db: &dyn db::ExpandDatabase) -> Option<InFile<SyntaxNode>>;
|
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.
|
/// 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
|
/// Return expansion information if it is a macro-expansion file
|
||||||
fn expansion_info(self, db: &dyn db::ExpandDatabase) -> Option<ExpansionInfo>;
|
fn expansion_info(self, db: &dyn db::ExpandDatabase) -> Option<ExpansionInfo>;
|
||||||
|
@ -246,11 +247,13 @@ impl HirFileIdExt for HirFileId {
|
||||||
Some(loc.to_node(db))
|
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);
|
let mut call = db.lookup_intern_macro_call(self.macro_file()?.macro_call_id).to_node(db);
|
||||||
loop {
|
loop {
|
||||||
match call.file_id.repr() {
|
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 }) => {
|
HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => {
|
||||||
call = db.lookup_intern_macro_call(macro_call_id).to_node(db);
|
call = db.lookup_intern_macro_call(macro_call_id).to_node(db);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::{hash_map::Entry, HashMap};
|
use std::collections::{hash_map::Entry, HashMap};
|
||||||
|
|
||||||
use hir::{HirFileIdExt, InFile, Module, ModuleSource};
|
use hir::{HirFileIdExt, InFile, InRealFile, Module, ModuleSource};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::FileRange,
|
base_db::FileRange,
|
||||||
defs::Definition,
|
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> {
|
fn module_search_scope(db: &RootDatabase, module: hir::Module) -> Vec<SearchScope> {
|
||||||
let (file_id, range) = {
|
let (file_id, range) = {
|
||||||
let InFile { file_id, value } = module.definition_source(db);
|
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()))
|
(file_id, Some(call_source.text_range()))
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
|
|
|
@ -8,8 +8,8 @@ use std::mem;
|
||||||
|
|
||||||
use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt};
|
use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt};
|
||||||
use hir::{
|
use hir::{
|
||||||
AsAssocItem, DefWithBody, HasAttrs, HasSource, HirFileIdExt, InFile, ModuleSource, Semantics,
|
AsAssocItem, DefWithBody, HasAttrs, HasSource, HirFileIdExt, InFile, InRealFile, ModuleSource,
|
||||||
Visibility,
|
Semantics, Visibility,
|
||||||
};
|
};
|
||||||
use memchr::memmem::Finder;
|
use memchr::memmem::Finder;
|
||||||
use nohash_hasher::IntMap;
|
use nohash_hasher::IntMap;
|
||||||
|
@ -133,7 +133,8 @@ impl SearchScope {
|
||||||
|
|
||||||
let (file_id, range) = {
|
let (file_id, range) = {
|
||||||
let InFile { file_id, value } = module.definition_source(db);
|
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()))
|
(file_id, Some(call_source.text_range()))
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
|
|
|
@ -169,8 +169,13 @@ impl TryToNav for FileSymbol {
|
||||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||||
let full_range = self.loc.original_range(db);
|
let full_range = self.loc.original_range(db);
|
||||||
let focus_range = self.loc.original_name_range(db);
|
let focus_range = self.loc.original_name_range(db);
|
||||||
let focus_range =
|
let focus_range = if focus_range.file_id == full_range.file_id
|
||||||
if focus_range.file_id == full_range.file_id { Some(focus_range.range) } else { None };
|
&& full_range.range.contains_range(focus_range.range)
|
||||||
|
{
|
||||||
|
Some(focus_range.range)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Some(NavigationTarget {
|
Some(NavigationTarget {
|
||||||
file_id: full_range.file_id,
|
file_id: full_range.file_id,
|
||||||
|
|
Loading…
Reference in a new issue