mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 10:39:45 +00:00
refactor: enhance highlighting for control flow kws in macros
This commit is contained in:
parent
79de21bd9d
commit
15e70c21d8
2 changed files with 45 additions and 33 deletions
|
|
@ -412,45 +412,30 @@ pub(crate) fn find_branch_root(
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
token: &SyntaxToken,
|
token: &SyntaxToken,
|
||||||
) -> Vec<SyntaxNode> {
|
) -> Vec<SyntaxNode> {
|
||||||
fn find_root(
|
let find_nodes = |node_filter: fn(SyntaxNode) -> Option<SyntaxNode>| {
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema.descend_into_macros(token.clone())
|
||||||
token: &SyntaxToken,
|
.into_iter()
|
||||||
pred: impl Fn(SyntaxNode) -> Option<SyntaxNode>,
|
.filter_map(|token| node_filter(token.parent()?))
|
||||||
) -> Vec<SyntaxNode> {
|
.collect_vec()
|
||||||
let mut result = Vec::new();
|
};
|
||||||
for token in sema.descend_into_macros(token.clone()) {
|
|
||||||
for node in sema.token_ancestors_with_macros(token) {
|
|
||||||
if ast::MacroCall::can_cast(node.kind()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(node) = pred(node) {
|
|
||||||
result.push(node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
match token.kind() {
|
match token.kind() {
|
||||||
T![match] => {
|
T![match] => find_nodes(|node| Some(ast::MatchExpr::cast(node)?.syntax().clone())),
|
||||||
find_root(sema, token, |node| Some(ast::MatchExpr::cast(node)?.syntax().clone()))
|
T![=>] => find_nodes(|node| Some(ast::MatchArm::cast(node)?.syntax().clone())),
|
||||||
}
|
T![if] => find_nodes(|node| {
|
||||||
T![=>] => find_root(sema, token, |node| Some(ast::MatchArm::cast(node)?.syntax().clone())),
|
|
||||||
T![if] => find_root(sema, token, |node| {
|
|
||||||
let if_expr = ast::IfExpr::cast(node)?;
|
let if_expr = ast::IfExpr::cast(node)?;
|
||||||
|
|
||||||
iter::successors(Some(if_expr.clone()), |if_expr| {
|
let root_if = iter::successors(Some(if_expr.clone()), |if_expr| {
|
||||||
let parent_if = if_expr.syntax().parent().and_then(ast::IfExpr::cast)?;
|
let parent_if = if_expr.syntax().parent().and_then(ast::IfExpr::cast)?;
|
||||||
if let ast::ElseBranch::IfExpr(nested_if) = parent_if.else_branch()? {
|
let ast::ElseBranch::IfExpr(else_branch) = parent_if.else_branch()? else {
|
||||||
(nested_if.syntax() == if_expr.syntax()).then_some(parent_if)
|
return None;
|
||||||
} else {
|
};
|
||||||
None
|
|
||||||
}
|
(else_branch.syntax() == if_expr.syntax()).then_some(parent_if)
|
||||||
})
|
})
|
||||||
.last()
|
.last()?;
|
||||||
.map(|if_expr| if_expr.syntax().clone())
|
|
||||||
|
Some(root_if.syntax().clone())
|
||||||
}),
|
}),
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2356,6 +2356,33 @@ fn main() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn match_in_macro_highlight_2() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
macro_rules! match_ast {
|
||||||
|
(match $node:ident { $($tt:tt)* }) => { $crate::match_ast!(match ($node) { $($tt)* }) };
|
||||||
|
|
||||||
|
(match ($node:expr) {
|
||||||
|
$( $( $path:ident )::+ ($it:pat) => $res:expr, )*
|
||||||
|
_ => $catch_all:expr $(,)?
|
||||||
|
}) => {{
|
||||||
|
$( if let Some($it) = $($path::)+cast($node.clone()) { $res } else )*
|
||||||
|
{ $catch_all }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match_ast! {
|
||||||
|
match$0 Some(1) {
|
||||||
|
Some(x) => x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_if_else() {
|
fn nested_if_else() {
|
||||||
check(
|
check(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue