diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:03:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:03:36 +0000 |
commit | 17d40c6057c88f4c432b0d7bac88e1b84cb7e67f (patch) | |
tree | 3f66c4a5918660bb8a758ab6cda5ff8ee4f6cdcd /src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-upstream/1.65.0+dfsg1.tar.xz rustc-upstream/1.65.0+dfsg1.zip |
Adding upstream version 1.65.0+dfsg1.upstream/1.65.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs | 298 |
1 files changed, 288 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs index 9999790fa..893e6fe4b 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs @@ -5,7 +5,7 @@ use std::mem; use mbe::{SyntheticToken, SyntheticTokenId, TokenMap}; use rustc_hash::FxHashMap; use syntax::{ - ast::{self, AstNode}, + ast::{self, AstNode, HasLoopBody}, match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, }; use tt::Subtree; @@ -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! { @@ -142,8 +141,127 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { ]); } }, + ast::WhileExpr(it) => { + if it.condition().is_none() { + // insert placeholder token after the while token + let while_token = match it.while_token() { + Some(t) => t, + None => continue, + }; + append.insert(while_token.into(), vec![ + SyntheticToken { + kind: SyntaxKind::IDENT, + text: "__ra_fixup".into(), + range: end_range, + id: EMPTY_ID, + }, + ]); + } + 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, + }, + ]); + } + }, + ast::LoopExpr(it) => { + 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, + }, + ]); + } + }, // FIXME: foo:: - // FIXME: for, loop, 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, + }, + ]); + } + }, _ => (), } } @@ -237,6 +355,111 @@ mod tests { } #[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( r#" @@ -245,7 +468,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {a . __ra_fixup} +fn foo () {a .__ra_fixup} "#]], ) } @@ -255,11 +478,11 @@ fn foo () {a . __ra_fixup} check( r#" fn foo() { - a. ; + a.; } "#, expect![[r#" -fn foo () {a . __ra_fixup ;} +fn foo () {a .__ra_fixup ;} "#]], ) } @@ -269,12 +492,12 @@ fn foo () {a . __ra_fixup ;} check( r#" fn foo() { - a. ; + a.; bar(); } "#, expect![[r#" -fn foo () {a . __ra_fixup ; bar () ;} +fn foo () {a .__ra_fixup ; bar () ;} "#]], ) } @@ -302,7 +525,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {let x = a . __ra_fixup ;} +fn foo () {let x = a .__ra_fixup ;} "#]], ) } @@ -318,7 +541,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {a . b ; bar () ;} +fn foo () {a .b ; bar () ;} "#]], ) } @@ -379,4 +602,59 @@ fn foo () {if {} {}} "#]], ) } + + #[test] + fn fixup_while_1() { + check( + r#" +fn foo() { + while +} +"#, + expect![[r#" +fn foo () {while __ra_fixup {}} +"#]], + ) + } + + #[test] + fn fixup_while_2() { + check( + r#" +fn foo() { + while foo +} +"#, + expect![[r#" +fn foo () {while foo {}} +"#]], + ) + } + #[test] + fn fixup_while_3() { + check( + r#" +fn foo() { + while {} +} +"#, + expect![[r#" +fn foo () {while __ra_fixup {}} +"#]], + ) + } + + #[test] + fn fixup_loop() { + check( + r#" +fn foo() { + loop +} +"#, + expect![[r#" +fn foo () {loop {}} +"#]], + ) + } } |