From a45682ed96f18f962ac403419b4d143d59ba5283 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Wed, 22 Jul 2020 16:23:43 +1000 Subject: Move iteration over all files into the SSR crate The methods `edits_for_file` and `find_matches_in_file` are replaced with just `edits` and `matches`. This simplifies the API a bit, but more importantly it makes it possible in a subsequent commit for SSR to decide to not search all files. --- crates/ra_ide/src/ssr.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'crates/ra_ide') diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index b3e9e5dfe..ca7e0ad86 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs @@ -1,5 +1,4 @@ -use ra_db::SourceDatabaseExt; -use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; +use ra_ide_db::RootDatabase; use crate::SourceFileEdit; use ra_ssr::{MatchFinder, SsrError, SsrRule}; @@ -44,20 +43,11 @@ pub fn parse_search_replace( parse_only: bool, db: &RootDatabase, ) -> Result, SsrError> { - let mut edits = vec![]; let rule: SsrRule = rule.parse()?; if parse_only { - return Ok(edits); + return Ok(Vec::new()); } let mut match_finder = MatchFinder::new(db); match_finder.add_rule(rule); - for &root in db.local_roots().iter() { - let sr = db.source_root(root); - for file_id in sr.iter() { - if let Some(edit) = match_finder.edits_for_file(file_id) { - edits.push(SourceFileEdit { file_id, edit }); - } - } - } - Ok(edits) + Ok(match_finder.edits()) } -- cgit v1.2.3 From 3975952601888d9f77e466c12e8e389748984b33 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Wed, 22 Jul 2020 15:00:28 +1000 Subject: SSR: Pass current file position through to SSR code. In a subsequent commit, it will be used for resolving paths. --- crates/ra_ide/src/lib.rs | 3 ++- crates/ra_ide/src/ssr.rs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'crates/ra_ide') diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index dc9192d42..7356e947b 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -505,9 +505,10 @@ impl Analysis { &self, query: &str, parse_only: bool, + position: FilePosition, ) -> Cancelable> { self.with_db(|db| { - let edits = ssr::parse_search_replace(query, parse_only, db)?; + let edits = ssr::parse_search_replace(query, parse_only, db, position)?; Ok(SourceChange::from(edits)) }) } diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index ca7e0ad86..3e2705d62 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs @@ -1,3 +1,4 @@ +use ra_db::FilePosition; use ra_ide_db::RootDatabase; use crate::SourceFileEdit; @@ -42,12 +43,13 @@ pub fn parse_search_replace( rule: &str, parse_only: bool, db: &RootDatabase, + position: FilePosition, ) -> Result, SsrError> { let rule: SsrRule = rule.parse()?; + let mut match_finder = MatchFinder::in_context(db, position); + match_finder.add_rule(rule); if parse_only { return Ok(Vec::new()); } - let mut match_finder = MatchFinder::new(db); - match_finder.add_rule(rule); Ok(match_finder.edits()) } -- cgit v1.2.3 From 757f755c29e041fd319af466d7d0418f54cb090a Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Wed, 22 Jul 2020 16:46:29 +1000 Subject: SSR: Match paths based on what they resolve to Also render template paths appropriately for their context. --- crates/ra_ide/src/ssr.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'crates/ra_ide') diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index 3e2705d62..2f40bac08 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs @@ -11,6 +11,16 @@ use ra_ssr::{MatchFinder, SsrError, SsrRule}; // A `$` placeholder in the search pattern will match any AST node and `$` will reference it in the replacement. // Within a macro call, a placeholder will match up until whatever token follows the placeholder. // +// All paths in both the search pattern and the replacement template must resolve in the context +// in which this command is invoked. Paths in the search pattern will then match the code if they +// resolve to the same item, even if they're written differently. For example if we invoke the +// command in the module `foo` with a pattern of `Bar`, then code in the parent module that refers +// to `foo::Bar` will match. +// +// Paths in the replacement template will be rendered appropriately for the context in which the +// replacement occurs. For example if our replacement template is `foo::Bar` and we match some +// code in the `foo` module, we'll insert just `Bar`. +// // Placeholders may be given constraints by writing them as `${::...}`. // // Supported constraints: @@ -47,7 +57,7 @@ pub fn parse_search_replace( ) -> Result, SsrError> { let rule: SsrRule = rule.parse()?; let mut match_finder = MatchFinder::in_context(db, position); - match_finder.add_rule(rule); + match_finder.add_rule(rule)?; if parse_only { return Ok(Vec::new()); } -- cgit v1.2.3 From 3dac31fe80b9d7279e87b94615b0d55805e83412 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Fri, 24 Jul 2020 20:53:48 +1000 Subject: SSR: Allow function calls to match method calls This differs from how this used to work before I removed it in that: a) It's only one direction. Function calls in the pattern can match method calls in the code, but not the other way around. b) We now check that the function call in the pattern resolves to the same function as the method call in the code. The lack of (b) was the reason I felt the need to remove the feature before. --- crates/ra_ide/src/ssr.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'crates/ra_ide') diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs index 2f40bac08..95d8f79b8 100644 --- a/crates/ra_ide/src/ssr.rs +++ b/crates/ra_ide/src/ssr.rs @@ -21,6 +21,9 @@ use ra_ssr::{MatchFinder, SsrError, SsrRule}; // replacement occurs. For example if our replacement template is `foo::Bar` and we match some // code in the `foo` module, we'll insert just `Bar`. // +// Method calls should generally be written in UFCS form. e.g. `foo::Bar::baz($s, $a)` will match +// `$s.baz($a)`, provided the method call `baz` resolves to the method `foo::Bar::baz`. +// // Placeholders may be given constraints by writing them as `${::...}`. // // Supported constraints: -- cgit v1.2.3