Add heuristic sensing is_in_block
Example
---
```rust
fn foo() -> [i32; 2] {
l$0
[0, n]
}
```
**Before this PR**:
```text
loop~
line!(…)~ macro_rules! line
```
**After this PR**:
```text
let~
loop~
letm~
line!(…)~ macro_rules! line
```
This commit is contained in:
parent
3643535c16
commit
911edbfe81
2 changed files with 193 additions and 0 deletions
|
|
@ -1890,11 +1890,37 @@ fn is_in_breakable(node: &SyntaxNode) -> Option<(BreakableKind, SyntaxNode)> {
|
|||
}
|
||||
|
||||
fn is_in_block(node: &SyntaxNode) -> bool {
|
||||
if has_in_newline_expr_first(node) {
|
||||
return true;
|
||||
};
|
||||
node.parent()
|
||||
.map(|node| ast::ExprStmt::can_cast(node.kind()) || ast::StmtList::can_cast(node.kind()))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Similar to `has_parens`, heuristic sensing incomplete statement before ambigiguous `Expr`
|
||||
///
|
||||
/// Heuristic:
|
||||
///
|
||||
/// If the `PathExpr` is left part of the `Expr` and there is a newline after the `PathExpr`,
|
||||
/// it is considered that the `PathExpr` is not part of the `Expr`.
|
||||
fn has_in_newline_expr_first(node: &SyntaxNode) -> bool {
|
||||
if ast::PathExpr::can_cast(node.kind())
|
||||
&& let Some(NodeOrToken::Token(next)) = node.next_sibling_or_token()
|
||||
&& next.kind() == SyntaxKind::WHITESPACE
|
||||
&& next.text().contains('\n')
|
||||
&& let Some(stmt_like) = node
|
||||
.ancestors()
|
||||
.take_while(|it| it.text_range().start() == node.text_range().start())
|
||||
.filter_map(Either::<ast::ExprStmt, ast::Expr>::cast)
|
||||
.last()
|
||||
{
|
||||
stmt_like.syntax().parent().and_then(ast::StmtList::cast).is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> {
|
||||
let mut token = match e.into() {
|
||||
SyntaxElement::Node(n) => n.last_token()?,
|
||||
|
|
|
|||
|
|
@ -2946,6 +2946,173 @@ fn let_in_let_chain() {
|
|||
check_edit("let", r#"fn f() { if true && $0 {} }"#, r#"fn f() { if true && let $1 = $0 {} }"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_in_previous_line_of_ambiguous_expr() {
|
||||
check_edit(
|
||||
"let",
|
||||
r#"
|
||||
fn f() {
|
||||
$0
|
||||
(1, 2).foo();
|
||||
}"#,
|
||||
r#"
|
||||
fn f() {
|
||||
let $1 = $0;
|
||||
(1, 2).foo();
|
||||
}"#,
|
||||
);
|
||||
|
||||
check_edit(
|
||||
"let",
|
||||
r#"
|
||||
fn f() {
|
||||
$0
|
||||
(1, 2)
|
||||
}"#,
|
||||
r#"
|
||||
fn f() {
|
||||
let $1 = $0;
|
||||
(1, 2)
|
||||
}"#,
|
||||
);
|
||||
|
||||
check_edit(
|
||||
"let",
|
||||
r#"
|
||||
fn f() -> i32 {
|
||||
$0
|
||||
-2
|
||||
}"#,
|
||||
r#"
|
||||
fn f() -> i32 {
|
||||
let $1 = $0;
|
||||
-2
|
||||
}"#,
|
||||
);
|
||||
|
||||
check_edit(
|
||||
"let",
|
||||
r#"
|
||||
fn f() -> [i32; 2] {
|
||||
$0
|
||||
[1, 2]
|
||||
}"#,
|
||||
r#"
|
||||
fn f() -> [i32; 2] {
|
||||
let $1 = $0;
|
||||
[1, 2]
|
||||
}"#,
|
||||
);
|
||||
|
||||
check_edit(
|
||||
"let",
|
||||
r#"
|
||||
fn f() -> [u8; 2] {
|
||||
$0
|
||||
*b"01"
|
||||
}"#,
|
||||
r#"
|
||||
fn f() -> [u8; 2] {
|
||||
let $1 = $0;
|
||||
*b"01"
|
||||
}"#,
|
||||
);
|
||||
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
$0
|
||||
*b"01"
|
||||
}"#,
|
||||
expect![[r#"
|
||||
fn foo() fn()
|
||||
bt u32 u32
|
||||
kw async
|
||||
kw const
|
||||
kw crate::
|
||||
kw enum
|
||||
kw extern
|
||||
kw false
|
||||
kw fn
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw impl
|
||||
kw impl for
|
||||
kw let
|
||||
kw letm
|
||||
kw loop
|
||||
kw match
|
||||
kw mod
|
||||
kw return
|
||||
kw self::
|
||||
kw static
|
||||
kw struct
|
||||
kw trait
|
||||
kw true
|
||||
kw type
|
||||
kw union
|
||||
kw unsafe
|
||||
kw use
|
||||
kw while
|
||||
kw while let
|
||||
sn macro_rules
|
||||
sn pd
|
||||
sn ppd
|
||||
"#]],
|
||||
);
|
||||
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
match $0 {}
|
||||
}"#,
|
||||
expect![[r#"
|
||||
fn foo() fn()
|
||||
bt u32 u32
|
||||
kw const
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
);
|
||||
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
$0 *b"01"
|
||||
}"#,
|
||||
expect![[r#"
|
||||
fn foo() fn()
|
||||
bt u32 u32
|
||||
kw const
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private_inherent_and_public_trait() {
|
||||
check(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue