mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Simplify
This commit is contained in:
parent
9cb13b6efb
commit
634d588fd7
13 changed files with 137 additions and 176 deletions
|
@ -6,9 +6,9 @@ use base_db::{
|
|||
FileId, FileRange,
|
||||
};
|
||||
use either::Either;
|
||||
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange};
|
||||
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize};
|
||||
|
||||
use crate::{db, ExpansionInfo, HirFileIdExt as _};
|
||||
use crate::{db, ExpansionInfo, MacroFileIdExt};
|
||||
|
||||
/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
|
||||
///
|
||||
|
@ -119,16 +119,6 @@ impl<FileId: Copy, N: AstNode> InFileWrapper<FileId, N> {
|
|||
// region:specific impls
|
||||
|
||||
impl InFile<&SyntaxNode> {
|
||||
pub fn ancestors_with_macros(
|
||||
self,
|
||||
db: &dyn db::ExpandDatabase,
|
||||
) -> impl Iterator<Item = InFile<SyntaxNode>> + Clone + '_ {
|
||||
iter::successors(Some(self.cloned()), move |node| match node.value.parent() {
|
||||
Some(parent) => Some(node.with_value(parent)),
|
||||
None => node.file_id.call_node(db),
|
||||
})
|
||||
}
|
||||
|
||||
/// Skips the attributed item that caused the macro invocation we are climbing up
|
||||
pub fn ancestors_with_macros_skip_attr_item(
|
||||
self,
|
||||
|
@ -137,8 +127,9 @@ impl InFile<&SyntaxNode> {
|
|||
let succ = move |node: &InFile<SyntaxNode>| match node.value.parent() {
|
||||
Some(parent) => Some(node.with_value(parent)),
|
||||
None => {
|
||||
let parent_node = node.file_id.call_node(db)?;
|
||||
if node.file_id.is_attr_macro(db) {
|
||||
let macro_file_id = node.file_id.macro_file()?;
|
||||
let parent_node = macro_file_id.call_node(db);
|
||||
if macro_file_id.is_attr_macro(db) {
|
||||
// macro call was an attributed item, skip it
|
||||
// FIXME: does this fail if this is a direct expansion of another macro?
|
||||
parent_node.map(|node| node.parent()).transpose()
|
||||
|
@ -222,7 +213,7 @@ impl InFile<&SyntaxNode> {
|
|||
}
|
||||
HirFileIdRepr::MacroFile(m) => m,
|
||||
};
|
||||
if !self.file_id.is_attr_macro(db) {
|
||||
if !file_id.is_attr_macro(db) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -243,21 +234,23 @@ impl InFile<&SyntaxNode> {
|
|||
}
|
||||
}
|
||||
|
||||
impl InFile<SyntaxToken> {
|
||||
impl InMacroFile<SyntaxToken> {
|
||||
pub fn upmap_once(
|
||||
self,
|
||||
db: &dyn db::ExpandDatabase,
|
||||
) -> Option<InFile<smallvec::SmallVec<[TextRange; 1]>>> {
|
||||
Some(self.file_id.expansion_info(db)?.map_range_up_once(db, self.value.text_range()))
|
||||
) -> InFile<smallvec::SmallVec<[TextRange; 1]>> {
|
||||
self.file_id.expansion_info(db).map_range_up_once(db, self.value.text_range())
|
||||
}
|
||||
}
|
||||
|
||||
impl InFile<SyntaxToken> {
|
||||
/// Falls back to the macro call range if the node cannot be mapped up fully.
|
||||
pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> FileRange {
|
||||
match self.file_id.repr() {
|
||||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
let (range, ctxt) = ExpansionInfo::new(db, mac_file)
|
||||
.map_token_range_up(db, self.value.text_range());
|
||||
.span_for_offset(db, self.value.text_range().start());
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -280,7 +273,7 @@ impl InFile<SyntaxToken> {
|
|||
}
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
let (range, ctxt) = ExpansionInfo::new(db, mac_file)
|
||||
.map_token_range_up(db, self.value.text_range());
|
||||
.span_for_offset(db, self.value.text_range().start());
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -294,20 +287,13 @@ 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) = 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 InMacroFile<TextSize> {
|
||||
pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> (FileRange, SyntaxContextId) {
|
||||
ExpansionInfo::new(db, self.file_id).span_for_offset(db, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl InFile<TextRange> {
|
||||
pub fn original_node_file_range(
|
||||
self,
|
||||
db: &dyn db::ExpandDatabase,
|
||||
|
@ -353,7 +339,7 @@ impl<N: AstNode> InFile<N> {
|
|||
}
|
||||
HirFileIdRepr::MacroFile(m) => m,
|
||||
};
|
||||
if !self.file_id.is_attr_macro(db) {
|
||||
if !file_id.is_attr_macro(db) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,9 +179,6 @@ pub trait HirFileIdExt {
|
|||
/// 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<InRealFile<SyntaxNode>>;
|
||||
|
||||
|
@ -190,19 +187,6 @@ pub trait HirFileIdExt {
|
|||
|
||||
fn as_builtin_derive_attr_node(&self, db: &dyn db::ExpandDatabase)
|
||||
-> Option<InFile<ast::Attr>>;
|
||||
fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
fn is_custom_derive(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
/// Return whether this file is an include macro
|
||||
fn is_include_macro(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
fn is_eager(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
/// Return whether this file is an attr macro
|
||||
fn is_attr_macro(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
/// Return whether this file is the pseudo expansion of the derive attribute.
|
||||
/// See [`crate::builtin_attr_macro::derive_attr_expand`].
|
||||
fn is_derive_attr_pseudo_expansion(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
}
|
||||
|
||||
impl HirFileIdExt for HirFileId {
|
||||
|
@ -241,12 +225,6 @@ impl HirFileIdExt for HirFileId {
|
|||
}
|
||||
}
|
||||
|
||||
fn call_node(self, db: &dyn db::ExpandDatabase) -> Option<InFile<SyntaxNode>> {
|
||||
let macro_file = self.macro_file()?;
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
|
||||
Some(loc.to_node(db))
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -278,77 +256,34 @@ impl HirFileIdExt for HirFileId {
|
|||
};
|
||||
Some(attr.with_value(ast::Attr::cast(attr.value.clone())?))
|
||||
}
|
||||
|
||||
fn is_custom_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
matches!(
|
||||
db.lookup_intern_macro_call(macro_file.macro_call_id).def.kind,
|
||||
MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _)
|
||||
)
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
matches!(
|
||||
db.lookup_intern_macro_call(macro_file.macro_call_id).def.kind,
|
||||
MacroDefKind::BuiltInDerive(..)
|
||||
)
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_include_macro(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
db.lookup_intern_macro_call(macro_file.macro_call_id).def.is_include()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_eager(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
|
||||
matches!(loc.def.kind, MacroDefKind::BuiltInEager(..))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_attr_macro(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
|
||||
matches!(loc.kind, MacroCallKind::Attr { .. })
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_derive_attr_pseudo_expansion(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
match self.macro_file() {
|
||||
Some(macro_file) => {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
|
||||
loc.def.is_attribute_derive()
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MacroFileIdExt {
|
||||
fn expansion_level(self, db: &dyn db::ExpandDatabase) -> u32;
|
||||
/// If this is a macro call, returns the syntax node of the call.
|
||||
fn call_node(self, db: &dyn db::ExpandDatabase) -> InFile<SyntaxNode>;
|
||||
|
||||
fn expansion_info(self, db: &dyn db::ExpandDatabase) -> ExpansionInfo;
|
||||
|
||||
fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
fn is_custom_derive(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
/// Return whether this file is an include macro
|
||||
fn is_include_macro(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
fn is_eager(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
/// Return whether this file is an attr macro
|
||||
fn is_attr_macro(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
|
||||
/// Return whether this file is the pseudo expansion of the derive attribute.
|
||||
/// See [`crate::builtin_attr_macro::derive_attr_expand`].
|
||||
fn is_derive_attr_pseudo_expansion(&self, db: &dyn db::ExpandDatabase) -> bool;
|
||||
}
|
||||
|
||||
impl MacroFileIdExt for MacroFileId {
|
||||
fn call_node(self, db: &dyn db::ExpandDatabase) -> InFile<SyntaxNode> {
|
||||
db.lookup_intern_macro_call(self.macro_call_id).to_node(db)
|
||||
}
|
||||
fn expansion_level(self, db: &dyn db::ExpandDatabase) -> u32 {
|
||||
let mut level = 0;
|
||||
let mut macro_file = self;
|
||||
|
@ -367,6 +302,39 @@ impl MacroFileIdExt for MacroFileId {
|
|||
fn expansion_info(self, db: &dyn db::ExpandDatabase) -> ExpansionInfo {
|
||||
ExpansionInfo::new(db, self)
|
||||
}
|
||||
|
||||
fn is_custom_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
matches!(
|
||||
db.lookup_intern_macro_call(self.macro_call_id).def.kind,
|
||||
MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _)
|
||||
)
|
||||
}
|
||||
|
||||
fn is_builtin_derive(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
matches!(
|
||||
db.lookup_intern_macro_call(self.macro_call_id).def.kind,
|
||||
MacroDefKind::BuiltInDerive(..)
|
||||
)
|
||||
}
|
||||
|
||||
fn is_include_macro(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
db.lookup_intern_macro_call(self.macro_call_id).def.is_include()
|
||||
}
|
||||
|
||||
fn is_eager(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(self.macro_call_id);
|
||||
matches!(loc.def.kind, MacroDefKind::BuiltInEager(..))
|
||||
}
|
||||
|
||||
fn is_attr_macro(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(self.macro_call_id);
|
||||
matches!(loc.kind, MacroCallKind::Attr { .. })
|
||||
}
|
||||
|
||||
fn is_derive_attr_pseudo_expansion(&self, db: &dyn db::ExpandDatabase) -> bool {
|
||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(self.macro_call_id);
|
||||
loc.def.is_attribute_derive()
|
||||
}
|
||||
}
|
||||
|
||||
impl MacroDefId {
|
||||
|
@ -653,14 +621,14 @@ impl ExpansionInfo {
|
|||
Some(tokens.map(move |token| InMacroFile::new(self.expanded.file_id, token)))
|
||||
}
|
||||
|
||||
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
|
||||
pub fn map_token_range_up(
|
||||
/// Looks up the span at the given offset.
|
||||
pub fn span_for_offset(
|
||||
&self,
|
||||
db: &dyn db::ExpandDatabase,
|
||||
range: TextRange,
|
||||
offset: TextSize,
|
||||
) -> (FileRange, SyntaxContextId) {
|
||||
debug_assert!(self.expanded.value.text_range().contains_range(range));
|
||||
let span = self.exp_map.span_at(range.start());
|
||||
debug_assert!(self.expanded.value.text_range().contains(offset));
|
||||
let span = self.exp_map.span_at(offset);
|
||||
let anchor_offset = db
|
||||
.ast_id_map(span.anchor.file_id.into())
|
||||
.get_erased(span.anchor.ast_id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue