@@ -892,7 +892,7 @@ impl<'db> SemanticsImpl<'db> {
892
892
893
893
if first == last {
894
894
// node is just the token, so descend the token
895
- self.descend_into_macros_impl (
895
+ self.descend_into_macros_all (
896
896
InFile::new(file.file_id, first),
897
897
false,
898
898
&mut |InFile { value, .. }, _ctx| {
@@ -903,23 +903,19 @@ impl<'db> SemanticsImpl<'db> {
903
903
{
904
904
res.push(node)
905
905
}
906
- CONTINUE_NO_BREAKS
907
906
},
908
907
);
909
908
} else {
910
909
// Descend first and last token, then zip them to look for the node they belong to
911
910
let mut scratch: SmallVec<[_; 1]> = smallvec![];
912
- self.descend_into_macros_impl (
911
+ self.descend_into_macros_all (
913
912
InFile::new(file.file_id, first),
914
913
false,
915
- &mut |token, _ctx| {
916
- scratch.push(token);
917
- CONTINUE_NO_BREAKS
918
- },
914
+ &mut |token, _ctx| scratch.push(token),
919
915
);
920
916
921
917
let mut scratch = scratch.into_iter();
922
- self.descend_into_macros_impl (
918
+ self.descend_into_macros_all (
923
919
InFile::new(file.file_id, last),
924
920
false,
925
921
&mut |InFile { value: last, file_id: last_fid }, _ctx| {
@@ -938,17 +934,18 @@ impl<'db> SemanticsImpl<'db> {
938
934
}
939
935
}
940
936
}
941
- CONTINUE_NO_BREAKS
942
937
},
943
938
);
944
939
}
945
940
res
946
941
}
947
942
948
- pub fn is_inside_macro_call(&self, token: InFile<&SyntaxToken>) -> bool {
949
- // FIXME: Maybe `ancestors_with_macros()` is more suitable here? Currently
950
- // this is only used on real (not macro) files so this is not a problem.
951
- token.value.parent_ancestors().any(|ancestor| {
943
+ /// Returns true if the given input is within a macro call.
944
+ ///
945
+ /// Note that if this token itself is within the context of a macro expansion does not matter.
946
+ /// That is, we strictly check if it lies inside the input of a macro call.
947
+ pub fn is_inside_macro_call(&self, token @ InFile { value, .. }: InFile<&SyntaxToken>) -> bool {
948
+ value.parent_ancestors().any(|ancestor| {
952
949
if ast::MacroCall::can_cast(ancestor.kind()) {
953
950
return true;
954
951
}
@@ -983,21 +980,17 @@ impl<'db> SemanticsImpl<'db> {
983
980
token: SyntaxToken,
984
981
mut cb: impl FnMut(InFile<SyntaxToken>, SyntaxContext),
985
982
) {
986
- self.descend_into_macros_impl(self.wrap_token_infile(token), false, &mut |t, ctx| {
987
- cb(t, ctx);
988
- CONTINUE_NO_BREAKS
983
+ self.descend_into_macros_all(self.wrap_token_infile(token), false, &mut |t, ctx| {
984
+ cb(t, ctx)
989
985
});
990
986
}
991
987
992
988
pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
993
989
let mut res = smallvec![];
994
- self.descend_into_macros_impl (
990
+ self.descend_into_macros_all (
995
991
self.wrap_token_infile(token.clone()),
996
992
false,
997
- &mut |t, _ctx| {
998
- res.push(t.value);
999
- CONTINUE_NO_BREAKS
1000
- },
993
+ &mut |t, _ctx| res.push(t.value),
1001
994
);
1002
995
if res.is_empty() {
1003
996
res.push(token);
@@ -1011,12 +1004,11 @@ impl<'db> SemanticsImpl<'db> {
1011
1004
) -> SmallVec<[InFile<SyntaxToken>; 1]> {
1012
1005
let mut res = smallvec![];
1013
1006
let token = self.wrap_token_infile(token);
1014
- self.descend_into_macros_impl (token.clone(), true, &mut |t, ctx| {
1007
+ self.descend_into_macros_all (token.clone(), true, &mut |t, ctx| {
1015
1008
if !ctx.is_opaque(self.db) {
1016
1009
// Don't descend into opaque contexts
1017
1010
res.push(t);
1018
1011
}
1019
- CONTINUE_NO_BREAKS
1020
1012
});
1021
1013
if res.is_empty() {
1022
1014
res.push(token);
@@ -1099,6 +1091,18 @@ impl<'db> SemanticsImpl<'db> {
1099
1091
.unwrap_or(token)
1100
1092
}
1101
1093
1094
+ fn descend_into_macros_all(
1095
+ &self,
1096
+ token: InFile<SyntaxToken>,
1097
+ always_descend_into_derives: bool,
1098
+ f: &mut dyn FnMut(InFile<SyntaxToken>, SyntaxContext),
1099
+ ) {
1100
+ self.descend_into_macros_impl(token, always_descend_into_derives, &mut |tok, ctx| {
1101
+ f(tok, ctx);
1102
+ CONTINUE_NO_BREAKS
1103
+ });
1104
+ }
1105
+
1102
1106
fn descend_into_macros_impl<T>(
1103
1107
&self,
1104
1108
InFile { value: token, file_id }: InFile<SyntaxToken>,
@@ -1467,25 +1471,31 @@ impl<'db> SemanticsImpl<'db> {
1467
1471
}
1468
1472
1469
1473
/// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
1474
+ // FIXME: Replace with `ancestors_with_macros_file` when all usages are updated.
1470
1475
pub fn ancestors_with_macros(
1471
1476
&self,
1472
1477
node: SyntaxNode,
1473
1478
) -> impl Iterator<Item = SyntaxNode> + Clone + '_ {
1474
1479
let node = self.find_file(&node);
1475
- iter::successors(Some(node.cloned()), move |&InFile { file_id, ref value }| {
1476
- match value.parent() {
1477
- Some(parent) => Some(InFile::new(file_id, parent)),
1478
- None => {
1479
- let macro_file = file_id.macro_file()?;
1480
-
1481
- self.with_ctx(|ctx| {
1482
- let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
1483
- expansion_info.arg().map(|node| node?.parent()).transpose()
1484
- })
1485
- }
1480
+ self.ancestors_with_macros_file(node.cloned()).map(|it| it.value)
1481
+ }
1482
+
1483
+ /// Iterates the ancestors of the given node, climbing up macro expansions while doing so.
1484
+ pub fn ancestors_with_macros_file(
1485
+ &self,
1486
+ node: InFile<SyntaxNode>,
1487
+ ) -> impl Iterator<Item = InFile<SyntaxNode>> + Clone + '_ {
1488
+ iter::successors(Some(node), move |&InFile { file_id, ref value }| match value.parent() {
1489
+ Some(parent) => Some(InFile::new(file_id, parent)),
1490
+ None => {
1491
+ let macro_file = file_id.macro_file()?;
1492
+
1493
+ self.with_ctx(|ctx| {
1494
+ let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file);
1495
+ expansion_info.arg().map(|node| node?.parent()).transpose()
1496
+ })
1486
1497
}
1487
1498
})
1488
- .map(|it| it.value)
1489
1499
}
1490
1500
1491
1501
pub fn ancestors_at_offset_with_macros(
0 commit comments