Skip to content

Commit e9ddd12

Browse files
Merge #4919
4919: Remove :expr from placeholders r=matklad a=davidlattimore Reasoning discussed at #3186 (comment) Co-authored-by: David Lattimore <dml@google.com>
2 parents 5d7974e + ac9166a commit e9ddd12

File tree

1 file changed

+20
-54
lines changed

1 file changed

+20
-54
lines changed

crates/ra_ide/src/ssr.rs

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ impl std::error::Error for SsrError {}
2727
//
2828
// Search and replace with named wildcards that will match any expression.
2929
// The syntax for a structural search replace command is `<search_pattern> ==>> <replace_pattern>`.
30-
// A `$<name>:expr` placeholder in the search pattern will match any expression and `$<name>` will reference it in the replacement.
30+
// A `$<name>` placeholder in the search pattern will match any AST node and `$<name>` will reference it in the replacement.
3131
// Available via the command `rust-analyzer.ssr`.
3232
//
3333
// ```rust
34-
// // Using structural search replace command [foo($a:expr, $b:expr) ==>> ($a).foo($b)]
34+
// // Using structural search replace command [foo($a, $b) ==>> ($a).foo($b)]
3535
//
3636
// // BEFORE
3737
// String::from(foo(y + 5, z))
@@ -79,7 +79,7 @@ struct SsrPattern {
7979
vars: Vec<Var>,
8080
}
8181

82-
/// represents an `$var` in an SSR query
82+
/// Represents a `$var` in an SSR query.
8383
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8484
struct Var(String);
8585

@@ -122,8 +122,7 @@ impl FromStr for SsrQuery {
122122
let mut pattern = it.next().expect("something").to_string();
123123

124124
for part in it.map(split_by_var) {
125-
let (var, var_type, remainder) = part?;
126-
is_expr(var_type)?;
125+
let (var, remainder) = part?;
127126
let new_var = create_name(var, &mut vars)?;
128127
pattern.push_str(new_var);
129128
pattern.push_str(remainder);
@@ -166,15 +165,11 @@ fn traverse(node: &SyntaxNode, go: &mut impl FnMut(&SyntaxNode) -> bool) {
166165
}
167166
}
168167

169-
fn split_by_var(s: &str) -> Result<(&str, &str, &str), SsrError> {
170-
let end_of_name = s.find(':').ok_or_else(|| SsrError("Use $<name>:expr".into()))?;
171-
let name = &s[0..end_of_name];
168+
fn split_by_var(s: &str) -> Result<(&str, &str), SsrError> {
169+
let end_of_name = s.find(|c| !char::is_ascii_alphanumeric(&c)).unwrap_or_else(|| s.len());
170+
let name = &s[..end_of_name];
172171
is_name(name)?;
173-
let type_begin = end_of_name + 1;
174-
let type_length =
175-
s[type_begin..].find(|c| !char::is_ascii_alphanumeric(&c)).unwrap_or_else(|| s.len());
176-
let type_name = &s[type_begin..type_begin + type_length];
177-
Ok((name, type_name, &s[type_begin + type_length..]))
172+
Ok((name, &s[end_of_name..]))
178173
}
179174

180175
fn is_name(s: &str) -> Result<(), SsrError> {
@@ -185,14 +180,6 @@ fn is_name(s: &str) -> Result<(), SsrError> {
185180
}
186181
}
187182

188-
fn is_expr(s: &str) -> Result<(), SsrError> {
189-
if s == "expr" {
190-
Ok(())
191-
} else {
192-
Err(SsrError("Only $<name>:expr is supported".into()))
193-
}
194-
}
195-
196183
fn replace_in_template(template: String, var: &str, new_var: &str) -> String {
197184
let name = format!("${}", var);
198185
template.replace(&name, new_var)
@@ -450,7 +437,7 @@ mod tests {
450437

451438
#[test]
452439
fn parser_happy_case() {
453-
let result: SsrQuery = "foo($a:expr, $b:expr) ==>> bar($b, $a)".parse().unwrap();
440+
let result: SsrQuery = "foo($a, $b) ==>> bar($b, $a)".parse().unwrap();
454441
assert_eq!(&result.pattern.pattern.text(), "foo(__search_pattern_a, __search_pattern_b)");
455442
assert_eq!(result.pattern.vars.len(), 2);
456443
assert_eq!(result.pattern.vars[0].0, "__search_pattern_a");
@@ -476,31 +463,10 @@ mod tests {
476463
);
477464
}
478465

479-
#[test]
480-
fn parser_no_pattern_type() {
481-
assert_eq!(parse_error_text("foo($a) ==>>"), "Parse error: Use $<name>:expr");
482-
}
483-
484-
#[test]
485-
fn parser_invalid_name() {
486-
assert_eq!(
487-
parse_error_text("foo($a+:expr) ==>>"),
488-
"Parse error: Name can contain only alphanumerics and _"
489-
);
490-
}
491-
492-
#[test]
493-
fn parser_invalid_type() {
494-
assert_eq!(
495-
parse_error_text("foo($a:ident) ==>>"),
496-
"Parse error: Only $<name>:expr is supported"
497-
);
498-
}
499-
500466
#[test]
501467
fn parser_repeated_name() {
502468
assert_eq!(
503-
parse_error_text("foo($a:expr, $a:expr) ==>>"),
469+
parse_error_text("foo($a, $a) ==>>"),
504470
"Parse error: Name `a` repeats more than once"
505471
);
506472
}
@@ -517,7 +483,7 @@ mod tests {
517483

518484
#[test]
519485
fn parse_match_replace() {
520-
let query: SsrQuery = "foo($x:expr) ==>> bar($x)".parse().unwrap();
486+
let query: SsrQuery = "foo($x) ==>> bar($x)".parse().unwrap();
521487
let input = "fn main() { foo(1+2); }";
522488

523489
let code = SourceFile::parse(input).tree();
@@ -549,7 +515,7 @@ mod tests {
549515
#[test]
550516
fn ssr_function_to_method() {
551517
assert_ssr_transform(
552-
"my_function($a:expr, $b:expr) ==>> ($a).my_method($b)",
518+
"my_function($a, $b) ==>> ($a).my_method($b)",
553519
"loop { my_function( other_func(x, y), z + w) }",
554520
"loop { (other_func(x, y)).my_method(z + w) }",
555521
)
@@ -558,7 +524,7 @@ mod tests {
558524
#[test]
559525
fn ssr_nested_function() {
560526
assert_ssr_transform(
561-
"foo($a:expr, $b:expr, $c:expr) ==>> bar($c, baz($a, $b))",
527+
"foo($a, $b, $c) ==>> bar($c, baz($a, $b))",
562528
"fn main { foo (x + value.method(b), x+y-z, true && false) }",
563529
"fn main { bar(true && false, baz(x + value.method(b), x+y-z)) }",
564530
)
@@ -567,7 +533,7 @@ mod tests {
567533
#[test]
568534
fn ssr_expected_spacing() {
569535
assert_ssr_transform(
570-
"foo($x:expr) + bar() ==>> bar($x)",
536+
"foo($x) + bar() ==>> bar($x)",
571537
"fn main() { foo(5) + bar() }",
572538
"fn main() { bar(5) }",
573539
);
@@ -576,7 +542,7 @@ mod tests {
576542
#[test]
577543
fn ssr_with_extra_space() {
578544
assert_ssr_transform(
579-
"foo($x:expr ) + bar() ==>> bar($x)",
545+
"foo($x ) + bar() ==>> bar($x)",
580546
"fn main() { foo( 5 ) +bar( ) }",
581547
"fn main() { bar(5) }",
582548
);
@@ -585,7 +551,7 @@ mod tests {
585551
#[test]
586552
fn ssr_keeps_nested_comment() {
587553
assert_ssr_transform(
588-
"foo($x:expr) ==>> bar($x)",
554+
"foo($x) ==>> bar($x)",
589555
"fn main() { foo(other(5 /* using 5 */)) }",
590556
"fn main() { bar(other(5 /* using 5 */)) }",
591557
)
@@ -594,7 +560,7 @@ mod tests {
594560
#[test]
595561
fn ssr_keeps_comment() {
596562
assert_ssr_transform(
597-
"foo($x:expr) ==>> bar($x)",
563+
"foo($x) ==>> bar($x)",
598564
"fn main() { foo(5 /* using 5 */) }",
599565
"fn main() { bar(5)/* using 5 */ }",
600566
)
@@ -603,7 +569,7 @@ mod tests {
603569
#[test]
604570
fn ssr_struct_lit() {
605571
assert_ssr_transform(
606-
"foo{a: $a:expr, b: $b:expr} ==>> foo::new($a, $b)",
572+
"foo{a: $a, b: $b} ==>> foo::new($a, $b)",
607573
"fn main() { foo{b:2, a:1} }",
608574
"fn main() { foo::new(1, 2) }",
609575
)
@@ -612,7 +578,7 @@ mod tests {
612578
#[test]
613579
fn ssr_call_and_method_call() {
614580
assert_ssr_transform(
615-
"foo::<'a>($a:expr, $b:expr)) ==>> foo2($a, $b)",
581+
"foo::<'a>($a, $b)) ==>> foo2($a, $b)",
616582
"fn main() { get().bar.foo::<'a>(1); }",
617583
"fn main() { foo2(get().bar, 1); }",
618584
)
@@ -621,7 +587,7 @@ mod tests {
621587
#[test]
622588
fn ssr_method_call_and_call() {
623589
assert_ssr_transform(
624-
"$o:expr.foo::<i32>($a:expr)) ==>> $o.foo2($a)",
590+
"$o.foo::<i32>($a)) ==>> $o.foo2($a)",
625591
"fn main() { X::foo::<i32>(x, 1); }",
626592
"fn main() { x.foo2(1); }",
627593
)

0 commit comments

Comments
 (0)