diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ssr/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ssr/src/replacing.rs | 13 | ||||
-rw-r--r-- | crates/ssr/src/tests.rs | 1 |
4 files changed, 10 insertions, 6 deletions
diff --git a/Cargo.lock b/Cargo.lock index 2386c8f3a..c1f1c07a2 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1450,6 +1450,7 @@ dependencies = [ | |||
1450 | "expect", | 1450 | "expect", |
1451 | "hir", | 1451 | "hir", |
1452 | "ide_db", | 1452 | "ide_db", |
1453 | "itertools", | ||
1453 | "rustc-hash", | 1454 | "rustc-hash", |
1454 | "syntax", | 1455 | "syntax", |
1455 | "test_utils", | 1456 | "test_utils", |
diff --git a/crates/ssr/Cargo.toml b/crates/ssr/Cargo.toml index 56c1f7761..7c2090de3 100644 --- a/crates/ssr/Cargo.toml +++ b/crates/ssr/Cargo.toml | |||
@@ -12,6 +12,7 @@ doctest = false | |||
12 | 12 | ||
13 | [dependencies] | 13 | [dependencies] |
14 | rustc-hash = "1.1.0" | 14 | rustc-hash = "1.1.0" |
15 | itertools = "0.9.0" | ||
15 | 16 | ||
16 | text_edit = { path = "../text_edit" } | 17 | text_edit = { path = "../text_edit" } |
17 | syntax = { path = "../syntax" } | 18 | syntax = { path = "../syntax" } |
diff --git a/crates/ssr/src/replacing.rs b/crates/ssr/src/replacing.rs index 21d0aa8a8..29284e3f1 100644 --- a/crates/ssr/src/replacing.rs +++ b/crates/ssr/src/replacing.rs | |||
@@ -1,9 +1,11 @@ | |||
1 | //! Code for applying replacement templates for matches that have previously been found. | 1 | //! Code for applying replacement templates for matches that have previously been found. |
2 | 2 | ||
3 | use crate::{resolving::ResolvedRule, Match, SsrMatches}; | 3 | use crate::{resolving::ResolvedRule, Match, SsrMatches}; |
4 | use itertools::Itertools; | ||
4 | use rustc_hash::{FxHashMap, FxHashSet}; | 5 | use rustc_hash::{FxHashMap, FxHashSet}; |
5 | use syntax::ast::{self, AstToken}; | 6 | use syntax::ast::{self, AstToken}; |
6 | use syntax::{SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize}; | 7 | use syntax::{SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize}; |
8 | use test_utils::mark; | ||
7 | use text_edit::TextEdit; | 9 | use text_edit::TextEdit; |
8 | 10 | ||
9 | /// Returns a text edit that will replace each match in `matches` with its corresponding replacement | 11 | /// Returns a text edit that will replace each match in `matches` with its corresponding replacement |
@@ -127,6 +129,7 @@ impl ReplacementRenderer<'_> { | |||
127 | && (placeholder_value.autoderef_count > 0 | 129 | && (placeholder_value.autoderef_count > 0 |
128 | || placeholder_value.autoref_kind != ast::SelfParamKind::Owned) | 130 | || placeholder_value.autoref_kind != ast::SelfParamKind::Owned) |
129 | { | 131 | { |
132 | mark::hit!(replace_autoref_autoderef_capture); | ||
130 | let ref_kind = match placeholder_value.autoref_kind { | 133 | let ref_kind = match placeholder_value.autoref_kind { |
131 | ast::SelfParamKind::Owned => "", | 134 | ast::SelfParamKind::Owned => "", |
132 | ast::SelfParamKind::Ref => "&", | 135 | ast::SelfParamKind::Ref => "&", |
@@ -206,18 +209,16 @@ fn token_is_method_call_receiver(token: &SyntaxToken) -> bool { | |||
206 | use syntax::ast::AstNode; | 209 | use syntax::ast::AstNode; |
207 | // Find the first method call among the ancestors of `token`, then check if the only token | 210 | // Find the first method call among the ancestors of `token`, then check if the only token |
208 | // within the receiver is `token`. | 211 | // within the receiver is `token`. |
209 | if let Some(receiver) = token | 212 | if let Some(receiver) = |
210 | .ancestors() | 213 | token.ancestors().find_map(ast::MethodCallExpr::cast).and_then(|call| call.expr()) |
211 | .find(|node| node.kind() == SyntaxKind::METHOD_CALL_EXPR) | ||
212 | .and_then(|node| ast::MethodCallExpr::cast(node).unwrap().expr()) | ||
213 | { | 214 | { |
214 | let mut tokens = receiver.syntax().descendants_with_tokens().filter_map(|node_or_token| { | 215 | let tokens = receiver.syntax().descendants_with_tokens().filter_map(|node_or_token| { |
215 | match node_or_token { | 216 | match node_or_token { |
216 | SyntaxElement::Token(t) => Some(t), | 217 | SyntaxElement::Token(t) => Some(t), |
217 | _ => None, | 218 | _ => None, |
218 | } | 219 | } |
219 | }); | 220 | }); |
220 | if let (Some(only_token), None) = (tokens.next(), tokens.next()) { | 221 | if let Some((only_token,)) = tokens.collect_tuple() { |
221 | return only_token == *token; | 222 | return only_token == *token; |
222 | } | 223 | } |
223 | } | 224 | } |
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs index 0ad3512ba..e45c88864 100644 --- a/crates/ssr/src/tests.rs +++ b/crates/ssr/src/tests.rs | |||
@@ -1179,6 +1179,7 @@ fn replace_autoref_autoderef_capture() { | |||
1179 | // second, we already have a reference, so it isn't. When $a is used in a context where autoref | 1179 | // second, we already have a reference, so it isn't. When $a is used in a context where autoref |
1180 | // doesn't apply, we need to prefix it with `&`. Finally, we have some cases where autoderef | 1180 | // doesn't apply, we need to prefix it with `&`. Finally, we have some cases where autoderef |
1181 | // needs to be applied. | 1181 | // needs to be applied. |
1182 | mark::check!(replace_autoref_autoderef_capture); | ||
1182 | let code = r#" | 1183 | let code = r#" |
1183 | struct Foo {} | 1184 | struct Foo {} |
1184 | impl Foo { | 1185 | impl Foo { |