mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #19905 from Veykril/push-unwwyqpwqxky
refactor: Cleanup descension stuff
This commit is contained in:
commit
55b733103e
@ -892,7 +892,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
|
|
||||||
if first == last {
|
if first == last {
|
||||||
// node is just the token, so descend the token
|
// node is just the token, so descend the token
|
||||||
self.descend_into_macros_impl(
|
self.descend_into_macros_all(
|
||||||
InFile::new(file.file_id, first),
|
InFile::new(file.file_id, first),
|
||||||
false,
|
false,
|
||||||
&mut |InFile { value, .. }, _ctx| {
|
&mut |InFile { value, .. }, _ctx| {
|
||||||
@ -903,23 +903,19 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
{
|
{
|
||||||
res.push(node)
|
res.push(node)
|
||||||
}
|
}
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Descend first and last token, then zip them to look for the node they belong to
|
// Descend first and last token, then zip them to look for the node they belong to
|
||||||
let mut scratch: SmallVec<[_; 1]> = smallvec![];
|
let mut scratch: SmallVec<[_; 1]> = smallvec![];
|
||||||
self.descend_into_macros_impl(
|
self.descend_into_macros_all(
|
||||||
InFile::new(file.file_id, first),
|
InFile::new(file.file_id, first),
|
||||||
false,
|
false,
|
||||||
&mut |token, _ctx| {
|
&mut |token, _ctx| scratch.push(token),
|
||||||
scratch.push(token);
|
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut scratch = scratch.into_iter();
|
let mut scratch = scratch.into_iter();
|
||||||
self.descend_into_macros_impl(
|
self.descend_into_macros_all(
|
||||||
InFile::new(file.file_id, last),
|
InFile::new(file.file_id, last),
|
||||||
false,
|
false,
|
||||||
&mut |InFile { value: last, file_id: last_fid }, _ctx| {
|
&mut |InFile { value: last, file_id: last_fid }, _ctx| {
|
||||||
@ -938,17 +934,18 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_inside_macro_call(&self, token: InFile<&SyntaxToken>) -> bool {
|
/// Returns true if the given input is within a macro call.
|
||||||
// FIXME: Maybe `ancestors_with_macros()` is more suitable here? Currently
|
///
|
||||||
// this is only used on real (not macro) files so this is not a problem.
|
/// Note that if this token itself is within the context of a macro expansion does not matter.
|
||||||
token.value.parent_ancestors().any(|ancestor| {
|
/// That is, we strictly check if it lies inside the input of a macro call.
|
||||||
|
pub fn is_inside_macro_call(&self, token @ InFile { value, .. }: InFile<&SyntaxToken>) -> bool {
|
||||||
|
value.parent_ancestors().any(|ancestor| {
|
||||||
if ast::MacroCall::can_cast(ancestor.kind()) {
|
if ast::MacroCall::can_cast(ancestor.kind()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -983,21 +980,17 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
token: SyntaxToken,
|
token: SyntaxToken,
|
||||||
mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext),
|
mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext),
|
||||||
) {
|
) {
|
||||||
self.descend_into_macros_impl(self.wrap_token_infile(token), false, &mut |t, ctx| {
|
self.descend_into_macros_all(self.wrap_token_infile(token), false, &mut |t, ctx| {
|
||||||
cb(t, ctx);
|
cb(t, ctx)
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
|
pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
|
||||||
let mut res = smallvec![];
|
let mut res = smallvec![];
|
||||||
self.descend_into_macros_impl(
|
self.descend_into_macros_all(
|
||||||
self.wrap_token_infile(token.clone()),
|
self.wrap_token_infile(token.clone()),
|
||||||
false,
|
false,
|
||||||
&mut |t, _ctx| {
|
&mut |t, _ctx| res.push(t.value),
|
||||||
res.push(t.value);
|
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if res.is_empty() {
|
if res.is_empty() {
|
||||||
res.push(token);
|
res.push(token);
|
||||||
@ -1011,12 +1004,11 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
) -> SmallVec<[InFile<SyntaxToken>; 1]> {
|
) -> SmallVec<[InFile<SyntaxToken>; 1]> {
|
||||||
let mut res = smallvec![];
|
let mut res = smallvec![];
|
||||||
let token = self.wrap_token_infile(token);
|
let token = self.wrap_token_infile(token);
|
||||||
self.descend_into_macros_impl(token.clone(), true, &mut |t, ctx| {
|
self.descend_into_macros_all(token.clone(), true, &mut |t, ctx| {
|
||||||
if !ctx.is_opaque(self.db) {
|
if !ctx.is_opaque(self.db) {
|
||||||
// Don't descend into opaque contexts
|
// Don't descend into opaque contexts
|
||||||
res.push(t);
|
res.push(t);
|
||||||
}
|
}
|
||||||
CONTINUE_NO_BREAKS
|
|
||||||
});
|
});
|
||||||
if res.is_empty() {
|
if res.is_empty() {
|
||||||
res.push(token);
|
res.push(token);
|
||||||
@ -1099,6 +1091,18 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
.unwrap_or(token)
|
.unwrap_or(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn descend_into_macros_all(
|
||||||
|
&self,
|
||||||
|
token: InFile<SyntaxToken>,
|
||||||
|
always_descend_into_derives: bool,
|
||||||
|
f: &mut dyn FnMut(InFile<SyntaxToken>, SyntaxContext),
|
||||||
|
) {
|
||||||
|
self.descend_into_macros_impl(token, always_descend_into_derives, &mut |tok, ctx| {
|
||||||
|
f(tok, ctx);
|
||||||
|
CONTINUE_NO_BREAKS
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn descend_into_macros_impl<T>(
|
fn descend_into_macros_impl<T>(
|
||||||
&self,
|
&self,
|
||||||
InFile { value: token, file_id }: InFile<SyntaxToken>,
|
InFile { value: token, file_id }: InFile<SyntaxToken>,
|
||||||
@ -1467,13 +1471,21 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
|
/// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
|
||||||
|
// FIXME: Replace with `ancestors_with_macros_file` when all usages are updated.
|
||||||
pub fn ancestors_with_macros(
|
pub fn ancestors_with_macros(
|
||||||
&self,
|
&self,
|
||||||
node: SyntaxNode,
|
node: SyntaxNode,
|
||||||
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
|
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
|
||||||
let node = self.find_file(&node);
|
let node = self.find_file(&node);
|
||||||
iter::successors(Some(node.cloned()), move |&InFile { file_id, ref value }| {
|
self.ancestors_with_macros_file(node.cloned()).map(|it| it.value)
|
||||||
match value.parent() {
|
}
|
||||||
|
|
||||||
|
/// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
|
||||||
|
pub fn ancestors_with_macros_file(
|
||||||
|
&self,
|
||||||
|
node: InFile<SyntaxNode>,
|
||||||
|
) -> impl Iterator<Item = InFile<SyntaxNode>> + Clone + '_ {
|
||||||
|
iter::successors(Some(node), move |&InFile { file_id, ref value }| match value.parent() {
|
||||||
Some(parent) => Some(InFile::new(file_id, parent)),
|
Some(parent) => Some(InFile::new(file_id, parent)),
|
||||||
None => {
|
None => {
|
||||||
let macro_file = file_id.macro_file()?;
|
let macro_file = file_id.macro_file()?;
|
||||||
@ -1483,9 +1495,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
expansion_info.arg().map(|node| node?.parent()).transpose()
|
expansion_info.arg().map(|node| node?.parent()).transpose()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|it| it.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ancestors_at_offset_with_macros(
|
pub fn ancestors_at_offset_with_macros(
|
||||||
|
@ -411,6 +411,7 @@ impl SourceToDefCtx<'_, '_> {
|
|||||||
.map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids))
|
.map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Make this more fine grained! This should be a `adt_has_derives`!
|
||||||
pub(super) fn file_of_adt_has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool {
|
pub(super) fn file_of_adt_has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool {
|
||||||
self.dyn_map(adt).as_ref().is_some_and(|map| !map[keys::DERIVE_MACRO_CALL].is_empty())
|
self.dyn_map(adt).as_ref().is_some_and(|map| !map[keys::DERIVE_MACRO_CALL].is_empty())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user