aboutsummaryrefslogtreecommitdiff
path: root/crates/ssr
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ssr')
-rw-r--r--crates/ssr/src/parsing.rs15
-rw-r--r--crates/ssr/src/tests.rs91
2 files changed, 104 insertions, 2 deletions
diff --git a/crates/ssr/src/parsing.rs b/crates/ssr/src/parsing.rs
index f3b084baf..3d5e4feb7 100644
--- a/crates/ssr/src/parsing.rs
+++ b/crates/ssr/src/parsing.rs
@@ -73,11 +73,18 @@ impl ParsedRule {
73 placeholders_by_stand_in: pattern.placeholders_by_stand_in(), 73 placeholders_by_stand_in: pattern.placeholders_by_stand_in(),
74 rules: Vec::new(), 74 rules: Vec::new(),
75 }; 75 };
76 builder.try_add(ast::Expr::parse(&raw_pattern), raw_template.map(ast::Expr::parse)); 76
77 let raw_template_stmt = raw_template.map(ast::Stmt::parse);
78 if let raw_template_expr @ Some(Ok(_)) = raw_template.map(ast::Expr::parse) {
79 builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_expr);
80 } else {
81 builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_stmt.clone());
82 }
77 builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); 83 builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse));
78 builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); 84 builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse));
79 builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); 85 builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse));
80 builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); 86 builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse));
87 builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template_stmt);
81 builder.build() 88 builder.build()
82 } 89 }
83} 90}
@@ -88,7 +95,11 @@ struct RuleBuilder {
88} 95}
89 96
90impl RuleBuilder { 97impl RuleBuilder {
91 fn try_add<T: AstNode>(&mut self, pattern: Result<T, ()>, template: Option<Result<T, ()>>) { 98 fn try_add<T: AstNode, T2: AstNode>(
99 &mut self,
100 pattern: Result<T, ()>,
101 template: Option<Result<T2, ()>>,
102 ) {
92 match (pattern, template) { 103 match (pattern, template) {
93 (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { 104 (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule {
94 placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), 105 placeholders_by_stand_in: self.placeholders_by_stand_in.clone(),
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs
index 63131f6ca..db9cb8ca1 100644
--- a/crates/ssr/src/tests.rs
+++ b/crates/ssr/src/tests.rs
@@ -160,6 +160,97 @@ fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expecte
160} 160}
161 161
162#[test] 162#[test]
163fn ssr_let_stmt_in_macro_match() {
164 assert_matches(
165 "let a = 0",
166 r#"
167 macro_rules! m1 { ($a:stmt) => {$a}; }
168 fn f() {m1!{ let a = 0 };}"#,
169 // FIXME: Whitespace is not part of the matched block
170 &["leta=0"],
171 );
172}
173
174#[test]
175fn ssr_let_stmt_in_fn_match() {
176 assert_matches("let $a = 10;", "fn main() { let x = 10; x }", &["let x = 10;"]);
177 assert_matches("let $a = $b;", "fn main() { let x = 10; x }", &["let x = 10;"]);
178}
179
180#[test]
181fn ssr_block_expr_match() {
182 assert_matches("{ let $a = $b; }", "fn main() { let x = 10; }", &["{ let x = 10; }"]);
183 assert_matches("{ let $a = $b; $c }", "fn main() { let x = 10; x }", &["{ let x = 10; x }"]);
184}
185
186#[test]
187fn ssr_let_stmt_replace() {
188 // Pattern and template with trailing semicolon
189 assert_ssr_transform(
190 "let $a = $b; ==>> let $a = 11;",
191 "fn main() { let x = 10; x }",
192 expect![["fn main() { let x = 11; x }"]],
193 );
194}
195
196#[test]
197fn ssr_let_stmt_replace_expr() {
198 // Trailing semicolon should be dropped from the new expression
199 assert_ssr_transform(
200 "let $a = $b; ==>> $b",
201 "fn main() { let x = 10; }",
202 expect![["fn main() { 10 }"]],
203 );
204}
205
206#[test]
207fn ssr_blockexpr_replace_stmt_with_stmt() {
208 assert_ssr_transform(
209 "if $a() {$b;} ==>> $b;",
210 "{
211 if foo() {
212 bar();
213 }
214 Ok(())
215}",
216 expect![[r#"{
217 bar();
218 Ok(())
219}"#]],
220 );
221}
222
223#[test]
224fn ssr_blockexpr_match_trailing_expr() {
225 assert_matches(
226 "if $a() {$b;}",
227 "{
228 if foo() {
229 bar();
230 }
231}",
232 &["if foo() {
233 bar();
234 }"],
235 );
236}
237
238#[test]
239fn ssr_blockexpr_replace_trailing_expr_with_stmt() {
240 assert_ssr_transform(
241 "if $a() {$b;} ==>> $b;",
242 "{
243 if foo() {
244 bar();
245 }
246}",
247 expect![["{
248 bar();
249}"]],
250 );
251}
252
253#[test]
163fn ssr_function_to_method() { 254fn ssr_function_to_method() {
164 assert_ssr_transform( 255 assert_ssr_transform(
165 "my_function($a, $b) ==>> ($a).my_method($b)", 256 "my_function($a, $b) ==>> ($a).my_method($b)",