mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
internal: more reasonable grammar for blocks
Consider these expples { 92 } async { 92 } 'a: { 92 } #[a] { 92 } Previously the tree for them were BLOCK_EXPR { ... } EFFECT_EXPR async BLOCK_EXPR { ... } EFFECT_EXPR 'a: BLOCK_EXPR { ... } BLOCK_EXPR #[a] { ... } As you see, it gets progressively worse :) The last two items are especially odd. The last one even violates the balanced curleys invariant we have (#10357) The new approach is to say that the stuff in `{}` is stmt_list, and the block is stmt_list + optional modifiers BLOCK_EXPR STMT_LIST { ... } BLOCK_EXPR async STMT_LIST { ... } BLOCK_EXPR 'a: STMT_LIST { ... } BLOCK_EXPR #[a] STMT_LIST { ... }
This commit is contained in:
parent
c51a3c78cf
commit
2bf81922f7
233 changed files with 11762 additions and 11343 deletions
|
@ -148,24 +148,30 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option<Fu
|
|||
return match stmt {
|
||||
ast::Stmt::Item(_) => None,
|
||||
ast::Stmt::ExprStmt(_) | ast::Stmt::LetStmt(_) => Some(FunctionBody::from_range(
|
||||
node.parent().and_then(ast::BlockExpr::cast)?,
|
||||
node.parent().and_then(ast::StmtList::cast)?,
|
||||
node.text_range(),
|
||||
)),
|
||||
};
|
||||
}
|
||||
|
||||
// Covering element returned the parent block of one or multiple statements that have been selected
|
||||
if let Some(stmt_list) = ast::StmtList::cast(node.clone()) {
|
||||
if let Some(block_expr) = stmt_list.syntax().parent().and_then(ast::BlockExpr::cast) {
|
||||
if block_expr.syntax().text_range() == selection_range {
|
||||
return FunctionBody::from_expr(block_expr.into());
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the full statements.
|
||||
return Some(FunctionBody::from_range(stmt_list, selection_range));
|
||||
}
|
||||
|
||||
let expr = ast::Expr::cast(node.clone())?;
|
||||
// A node got selected fully
|
||||
if node.text_range() == selection_range {
|
||||
return FunctionBody::from_expr(expr.clone());
|
||||
}
|
||||
|
||||
// Covering element returned the parent block of one or multiple statements that have been selected
|
||||
if let ast::Expr::BlockExpr(block) = expr {
|
||||
// Extract the full statements.
|
||||
return Some(FunctionBody::from_range(block, selection_range));
|
||||
}
|
||||
|
||||
node.ancestors().find_map(ast::Expr::cast).and_then(FunctionBody::from_expr)
|
||||
}
|
||||
|
||||
|
@ -284,7 +290,7 @@ impl RetType {
|
|||
#[derive(Debug)]
|
||||
enum FunctionBody {
|
||||
Expr(ast::Expr),
|
||||
Span { parent: ast::BlockExpr, text_range: TextRange },
|
||||
Span { parent: ast::StmtList, text_range: TextRange },
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -441,7 +447,7 @@ impl FunctionBody {
|
|||
}
|
||||
}
|
||||
|
||||
fn from_range(parent: ast::BlockExpr, selected: TextRange) -> FunctionBody {
|
||||
fn from_range(parent: ast::StmtList, selected: TextRange) -> FunctionBody {
|
||||
let mut text_range = parent
|
||||
.statements()
|
||||
.map(|stmt| stmt.syntax().text_range())
|
||||
|
@ -643,14 +649,14 @@ impl FunctionBody {
|
|||
break match_ast! {
|
||||
match anc {
|
||||
ast::ClosureExpr(closure) => (false, closure.body(), infer_expr_opt(closure.body())),
|
||||
ast::EffectExpr(effect) => {
|
||||
let (constness, block) = match effect.effect() {
|
||||
ast::Effect::Const(_) => (true, effect.block_expr()),
|
||||
ast::Effect::Try(_) => (false, effect.block_expr()),
|
||||
ast::Effect::Label(label) if label.lifetime().is_some() => (false, effect.block_expr()),
|
||||
ast::BlockExpr(block_expr) => {
|
||||
let (constness, block) = match block_expr.modifier() {
|
||||
Some(ast::BlockModifier::Const(_)) => (true, block_expr),
|
||||
Some(ast::BlockModifier::Try(_)) => (false, block_expr),
|
||||
Some(ast::BlockModifier::Label(label)) if label.lifetime().is_some() => (false, block_expr),
|
||||
_ => continue,
|
||||
};
|
||||
let expr = block.map(ast::Expr::BlockExpr);
|
||||
let expr = Some(ast::Expr::BlockExpr(block));
|
||||
(constness, expr.clone(), infer_expr_opt(expr))
|
||||
},
|
||||
ast::Fn(fn_) => {
|
||||
|
@ -745,7 +751,7 @@ impl FunctionBody {
|
|||
ast::Expr::LoopExpr(_)
|
||||
| ast::Expr::ForExpr(_)
|
||||
| ast::Expr::WhileExpr(_) => loop_depth -= 1,
|
||||
ast::Expr::EffectExpr(effect) if effect.unsafe_token().is_some() => {
|
||||
ast::Expr::BlockExpr(block_expr) if block_expr.unsafe_token().is_some() => {
|
||||
unsafe_depth -= 1
|
||||
}
|
||||
_ => (),
|
||||
|
@ -757,7 +763,7 @@ impl FunctionBody {
|
|||
ast::Expr::LoopExpr(_) | ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) => {
|
||||
loop_depth += 1;
|
||||
}
|
||||
ast::Expr::EffectExpr(effect) if effect.unsafe_token().is_some() => {
|
||||
ast::Expr::BlockExpr(block_expr) if block_expr.unsafe_token().is_some() => {
|
||||
unsafe_depth += 1
|
||||
}
|
||||
ast::Expr::ReturnExpr(it) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue