diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_ide/src/ssr.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_ide/src/ssr.rs')
-rw-r--r-- | crates/ra_ide/src/ssr.rs | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index 6cb96608b..4348b43be 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs | |||
@@ -1,15 +1,43 @@ | |||
1 | use ra_db::SourceDatabaseExt; | 1 | use ra_db::{FilePosition, FileRange}; |
2 | use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; | 2 | use ra_ide_db::RootDatabase; |
3 | 3 | ||
4 | use crate::SourceFileEdit; | 4 | use crate::SourceFileEdit; |
5 | use ra_ssr::{MatchFinder, SsrError, SsrRule}; | 5 | use ra_ssr::{MatchFinder, SsrError, SsrRule}; |
6 | 6 | ||
7 | // Feature: Structural Seach and Replace | 7 | // Feature: Structural Search and Replace |
8 | // | 8 | // |
9 | // Search and replace with named wildcards that will match any expression, type, path, pattern or item. | 9 | // Search and replace with named wildcards that will match any expression, type, path, pattern or item. |
10 | // The syntax for a structural search replace command is `<search_pattern> ==>> <replace_pattern>`. | 10 | // The syntax for a structural search replace command is `<search_pattern> ==>> <replace_pattern>`. |
11 | // A `$<name>` placeholder in the search pattern will match any AST node and `$<name>` will reference it in the replacement. | 11 | // A `$<name>` placeholder in the search pattern will match any AST node and `$<name>` will reference it in the replacement. |
12 | // Within a macro call, a placeholder will match up until whatever token follows the placeholder. | 12 | // Within a macro call, a placeholder will match up until whatever token follows the placeholder. |
13 | // | ||
14 | // All paths in both the search pattern and the replacement template must resolve in the context | ||
15 | // in which this command is invoked. Paths in the search pattern will then match the code if they | ||
16 | // resolve to the same item, even if they're written differently. For example if we invoke the | ||
17 | // command in the module `foo` with a pattern of `Bar`, then code in the parent module that refers | ||
18 | // to `foo::Bar` will match. | ||
19 | // | ||
20 | // Paths in the replacement template will be rendered appropriately for the context in which the | ||
21 | // replacement occurs. For example if our replacement template is `foo::Bar` and we match some | ||
22 | // code in the `foo` module, we'll insert just `Bar`. | ||
23 | // | ||
24 | // Method calls should generally be written in UFCS form. e.g. `foo::Bar::baz($s, $a)` will match | ||
25 | // `$s.baz($a)`, provided the method call `baz` resolves to the method `foo::Bar::baz`. | ||
26 | // | ||
27 | // The scope of the search / replace will be restricted to the current selection if any, otherwise | ||
28 | // it will apply to the whole workspace. | ||
29 | // | ||
30 | // Placeholders may be given constraints by writing them as `${<name>:<constraint1>:<constraint2>...}`. | ||
31 | // | ||
32 | // Supported constraints: | ||
33 | // | ||
34 | // |=== | ||
35 | // | Constraint | Restricts placeholder | ||
36 | // | ||
37 | // | kind(literal) | Is a literal (e.g. `42` or `"forty two"`) | ||
38 | // | not(a) | Negates the constraint `a` | ||
39 | // |=== | ||
40 | // | ||
13 | // Available via the command `rust-analyzer.ssr`. | 41 | // Available via the command `rust-analyzer.ssr`. |
14 | // | 42 | // |
15 | // ```rust | 43 | // ```rust |
@@ -31,21 +59,14 @@ pub fn parse_search_replace( | |||
31 | rule: &str, | 59 | rule: &str, |
32 | parse_only: bool, | 60 | parse_only: bool, |
33 | db: &RootDatabase, | 61 | db: &RootDatabase, |
62 | resolve_context: FilePosition, | ||
63 | selections: Vec<FileRange>, | ||
34 | ) -> Result<Vec<SourceFileEdit>, SsrError> { | 64 | ) -> Result<Vec<SourceFileEdit>, SsrError> { |
35 | let mut edits = vec![]; | ||
36 | let rule: SsrRule = rule.parse()?; | 65 | let rule: SsrRule = rule.parse()?; |
66 | let mut match_finder = MatchFinder::in_context(db, resolve_context, selections); | ||
67 | match_finder.add_rule(rule)?; | ||
37 | if parse_only { | 68 | if parse_only { |
38 | return Ok(edits); | 69 | return Ok(Vec::new()); |
39 | } | ||
40 | let mut match_finder = MatchFinder::new(db); | ||
41 | match_finder.add_rule(rule); | ||
42 | for &root in db.local_roots().iter() { | ||
43 | let sr = db.source_root(root); | ||
44 | for file_id in sr.iter() { | ||
45 | if let Some(edit) = match_finder.edits_for_file(file_id) { | ||
46 | edits.push(SourceFileEdit { file_id, edit }); | ||
47 | } | ||
48 | } | ||
49 | } | 70 | } |
50 | Ok(edits) | 71 | Ok(match_finder.edits()) |
51 | } | 72 | } |