mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
spans always come from real file
This commit is contained in:
parent
394d11b0fa
commit
30093a6d81
57 changed files with 1369 additions and 1224 deletions
|
@ -1,5 +1,6 @@
|
|||
//! Attributes & documentation for hir types.
|
||||
|
||||
use base_db::FileId;
|
||||
use hir_def::{
|
||||
attr::AttrsWithOwner,
|
||||
item_scope::ItemInNs,
|
||||
|
@ -8,7 +9,10 @@ use hir_def::{
|
|||
resolver::{HasResolver, Resolver, TypeNs},
|
||||
AssocItemId, AttrDefId, ModuleDefId,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use hir_expand::{
|
||||
name::Name,
|
||||
span::{RealSpanMap, SpanMapRef},
|
||||
};
|
||||
use hir_ty::db::HirDatabase;
|
||||
use syntax::{ast, AstNode};
|
||||
|
||||
|
@ -234,7 +238,11 @@ fn modpath_from_str(db: &dyn HirDatabase, link: &str) -> Option<ModPath> {
|
|||
if ast_path.syntax().text() != link {
|
||||
return None;
|
||||
}
|
||||
ModPath::from_src(db.upcast(), ast_path, &Default::default())
|
||||
ModPath::from_src(
|
||||
db.upcast(),
|
||||
ast_path,
|
||||
SpanMapRef::RealSpanMap(&RealSpanMap::empty(FileId(0))),
|
||||
)
|
||||
};
|
||||
|
||||
let full = try_get_modpath(link);
|
||||
|
|
|
@ -59,7 +59,7 @@ use hir_def::{
|
|||
Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, TraitAliasId, TraitId,
|
||||
TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
||||
};
|
||||
use hir_expand::{name::name, MacroCallKind};
|
||||
use hir_expand::{name::name, InMacroFile, MacroCallKind};
|
||||
use hir_ty::{
|
||||
all_super_traits, autoderef, check_orphan_rules,
|
||||
consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
|
||||
|
@ -3483,11 +3483,41 @@ impl Impl {
|
|||
self.id.lookup(db.upcast()).container.into()
|
||||
}
|
||||
|
||||
pub fn as_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
|
||||
pub fn as_builtin_derive_attr(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
|
||||
let src = self.source(db)?;
|
||||
src.file_id.as_builtin_derive_attr_node(db.upcast())
|
||||
}
|
||||
|
||||
pub fn as_builtin_derive_path(self, db: &dyn HirDatabase) -> Option<InMacroFile<ast::Path>> {
|
||||
let src = self.source(db)?;
|
||||
|
||||
let macro_file = src.file_id.macro_file()?;
|
||||
let loc = db.lookup_intern_macro_call(macro_file.macro_call_id);
|
||||
let (derive_attr, derive_index) = match loc.kind {
|
||||
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index } => {
|
||||
let module_id = self.id.lookup(db.upcast()).container;
|
||||
(
|
||||
db.crate_def_map(module_id.krate())[module_id.local_id]
|
||||
.scope
|
||||
.derive_macro_invoc(ast_id, derive_attr_index)?,
|
||||
derive_index,
|
||||
)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let file_id = MacroFile { macro_call_id: derive_attr };
|
||||
let path = db
|
||||
.parse_macro_expansion(file_id)
|
||||
.value
|
||||
.0
|
||||
.syntax_node()
|
||||
.children()
|
||||
.nth(derive_index as usize)
|
||||
.and_then(<ast::Attr as AstNode>::cast)
|
||||
.and_then(|it| it.path())?;
|
||||
Some(InMacroFile { file_id, value: path })
|
||||
}
|
||||
|
||||
pub fn check_orphan_rules(self, db: &dyn HirDatabase) -> bool {
|
||||
check_orphan_rules(db, self.id)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use hir_expand::{db::ExpandDatabase, name::AsName, ExpansionInfo, HirFileIdExt,
|
|||
use itertools::Itertools;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use stdx::TupleExt;
|
||||
use syntax::{
|
||||
algo::skip_trivia_token,
|
||||
ast::{self, HasAttrs as _, HasGenericParams, HasLoopBody},
|
||||
|
@ -529,11 +530,11 @@ impl<'db> SemanticsImpl<'db> {
|
|||
token: SyntaxToken,
|
||||
// FIXME: We might want this to be Option<TextSize> to be able to opt out of subrange
|
||||
// mapping, specifically for node downmapping
|
||||
offset: TextSize,
|
||||
_offset: TextSize,
|
||||
f: &mut dyn FnMut(InFile<SyntaxToken>) -> bool,
|
||||
) {
|
||||
// FIXME: Clean this up
|
||||
let _p = profile::span("descend_into_macros");
|
||||
let relative_token_offset = token.text_range().start().checked_sub(offset);
|
||||
let parent = match token.parent() {
|
||||
Some(it) => it,
|
||||
None => return,
|
||||
|
@ -543,13 +544,35 @@ impl<'db> SemanticsImpl<'db> {
|
|||
None => return,
|
||||
};
|
||||
let def_map = sa.resolver.def_map();
|
||||
let absolute_range = match sa.file_id.repr() {
|
||||
base_db::span::HirFileIdRepr::FileId(file_id) => {
|
||||
FileRange { file_id, range: token.text_range() }
|
||||
}
|
||||
base_db::span::HirFileIdRepr::MacroFile(m) => {
|
||||
let span =
|
||||
self.db.parse_macro_expansion(m).value.1.span_for_range(token.text_range());
|
||||
let range = span.range
|
||||
+ self
|
||||
.db
|
||||
.ast_id_map(span.anchor.file_id.into())
|
||||
.get_erased(span.anchor.ast_id)
|
||||
.text_range()
|
||||
.start();
|
||||
FileRange { file_id: span.anchor.file_id, range }
|
||||
}
|
||||
};
|
||||
|
||||
// fetch span information of token in real file, then use that look through expansions of
|
||||
// calls the token is in and afterwards recursively with the same span.
|
||||
// what about things where spans change? Due to being joined etc, that is we don't find the
|
||||
// exact span anymore?
|
||||
|
||||
let mut stack: SmallVec<[_; 4]> = smallvec![InFile::new(sa.file_id, token)];
|
||||
let mut cache = self.expansion_info_cache.borrow_mut();
|
||||
let mut mcache = self.macro_call_cache.borrow_mut();
|
||||
|
||||
let mut process_expansion_for_token =
|
||||
|stack: &mut SmallVec<_>, macro_file, token: InFile<&_>| {
|
||||
|stack: &mut SmallVec<_>, macro_file, _token: InFile<&_>| {
|
||||
let expansion_info = cache
|
||||
.entry(macro_file)
|
||||
.or_insert_with(|| macro_file.expansion_info(self.db.upcast()))
|
||||
|
@ -560,11 +583,8 @@ impl<'db> SemanticsImpl<'db> {
|
|||
self.cache(value, file_id);
|
||||
}
|
||||
|
||||
let mapped_tokens = expansion_info.map_token_down(
|
||||
self.db.upcast(),
|
||||
token,
|
||||
relative_token_offset,
|
||||
)?;
|
||||
let mapped_tokens =
|
||||
expansion_info.map_range_down(self.db.upcast(), absolute_range, None)?;
|
||||
let len = stack.len();
|
||||
|
||||
// requeue the tokens we got from mapping our current token down
|
||||
|
@ -728,6 +748,8 @@ impl<'db> SemanticsImpl<'db> {
|
|||
pub fn original_range_opt(&self, node: &SyntaxNode) -> Option<FileRange> {
|
||||
let node = self.find_file(node);
|
||||
node.original_file_range_opt(self.db.upcast())
|
||||
.filter(|(_, ctx)| ctx.is_root())
|
||||
.map(TupleExt::head)
|
||||
}
|
||||
|
||||
/// Attempts to map the node out of macro expanded files.
|
||||
|
|
|
@ -7,7 +7,7 @@ use hir_def::{
|
|||
AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, Lookup, MacroId, ModuleDefId, ModuleId,
|
||||
TraitId,
|
||||
};
|
||||
use hir_expand::{HirFileId, InFile};
|
||||
use hir_expand::{files::ascend_range_up_macros, HirFileId, InFile};
|
||||
use hir_ty::db::HirDatabase;
|
||||
use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr};
|
||||
|
||||
|
@ -50,13 +50,9 @@ impl DeclarationLocation {
|
|||
node.as_ref().original_file_range(db.upcast())
|
||||
}
|
||||
|
||||
pub fn original_name_range(&self, db: &dyn HirDatabase) -> Option<FileRange> {
|
||||
if let Some(file_id) = self.hir_file_id.file_id() {
|
||||
// fast path to prevent parsing
|
||||
return Some(FileRange { file_id, range: self.name_ptr.text_range() });
|
||||
}
|
||||
let node = resolve_node(db, self.hir_file_id, &self.name_ptr);
|
||||
node.as_ref().original_file_range_opt(db.upcast())
|
||||
pub fn original_name_range(&self, db: &dyn HirDatabase) -> FileRange {
|
||||
let mapping = InFile::new(self.hir_file_id, self.name_ptr.text_range());
|
||||
ascend_range_up_macros(db.upcast(), mapping).0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue