mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-29 06:23:25 +00:00
Auto merge of #12937 - fprasx:master, r=Veykril
Add fixups for incomplete in proc-macros Partially implements https://github.com/rust-lang/rust-analyzer/issues/12777. Added support for for loops and match statements. I couldn't do paths like `crate::foo::` as I wasn't able to add `SyntheticTokens` to the end of `foo::`, they always ended up after `crate::` This is my first contribution so please don't be shy about letting me know if I've done anything wrong!
This commit is contained in:
commit
b481b59be5
1 changed files with 174 additions and 2 deletions
|
@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
|
|||
preorder.skip_subtree();
|
||||
continue;
|
||||
}
|
||||
|
||||
// In some other situations, we can fix things by just appending some tokens.
|
||||
let end_range = TextRange::empty(node.text_range().end());
|
||||
match_ast! {
|
||||
|
@ -194,7 +193,75 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
|
|||
}
|
||||
},
|
||||
// FIXME: foo::
|
||||
// FIXME: for, match etc.
|
||||
ast::MatchExpr(it) => {
|
||||
if it.expr().is_none() {
|
||||
let match_token = match it.match_token() {
|
||||
Some(t) => t,
|
||||
None => continue
|
||||
};
|
||||
append.insert(match_token.into(), vec![
|
||||
SyntheticToken {
|
||||
kind: SyntaxKind::IDENT,
|
||||
text: "__ra_fixup".into(),
|
||||
range: end_range,
|
||||
id: EMPTY_ID
|
||||
},
|
||||
]);
|
||||
}
|
||||
if it.match_arm_list().is_none() {
|
||||
// No match arms
|
||||
append.insert(node.clone().into(), vec![
|
||||
SyntheticToken {
|
||||
kind: SyntaxKind::L_CURLY,
|
||||
text: "{".into(),
|
||||
range: end_range,
|
||||
id: EMPTY_ID,
|
||||
},
|
||||
SyntheticToken {
|
||||
kind: SyntaxKind::R_CURLY,
|
||||
text: "}".into(),
|
||||
range: end_range,
|
||||
id: EMPTY_ID,
|
||||
},
|
||||
]);
|
||||
}
|
||||
},
|
||||
ast::ForExpr(it) => {
|
||||
let for_token = match it.for_token() {
|
||||
Some(token) => token,
|
||||
None => continue
|
||||
};
|
||||
|
||||
let [pat, in_token, iter] = [
|
||||
(SyntaxKind::UNDERSCORE, "_"),
|
||||
(SyntaxKind::IN_KW, "in"),
|
||||
(SyntaxKind::IDENT, "__ra_fixup")
|
||||
].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
|
||||
|
||||
if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
|
||||
append.insert(for_token.into(), vec![pat, in_token, iter]);
|
||||
// does something funky -- see test case for_no_pat
|
||||
} else if it.pat().is_none() {
|
||||
append.insert(for_token.into(), vec![pat]);
|
||||
}
|
||||
|
||||
if it.loop_body().is_none() {
|
||||
append.insert(node.clone().into(), vec![
|
||||
SyntheticToken {
|
||||
kind: SyntaxKind::L_CURLY,
|
||||
text: "{".into(),
|
||||
range: end_range,
|
||||
id: EMPTY_ID,
|
||||
},
|
||||
SyntheticToken {
|
||||
kind: SyntaxKind::R_CURLY,
|
||||
text: "}".into(),
|
||||
range: end_range,
|
||||
id: EMPTY_ID,
|
||||
},
|
||||
]);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +354,111 @@ mod tests {
|
|||
assert_eq!(tt.to_string(), original_as_tt.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn just_for_token() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
for
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {for _ in __ra_fixup {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_no_iter_pattern() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
for {}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {for _ in __ra_fixup {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_no_body() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
for bar in qux
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {for bar in qux {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
// FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
|
||||
#[test]
|
||||
fn for_no_pat() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
for in qux {
|
||||
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {__ra_fixup}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_no_expr_no_arms() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
match
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {match __ra_fixup {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_expr_no_arms() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
match x {
|
||||
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {match x {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_no_expr() {
|
||||
check(
|
||||
r#"
|
||||
fn foo() {
|
||||
match {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo () {match __ra_fixup {}}
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn incomplete_field_expr_1() {
|
||||
check(
|
||||
|
|
Loading…
Reference in a new issue