aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ssr/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ssr/src/lib.rs')
-rw-r--r--crates/ra_ssr/src/lib.rs61
1 files changed, 44 insertions, 17 deletions
diff --git a/crates/ra_ssr/src/lib.rs b/crates/ra_ssr/src/lib.rs
index a0a5c9762..286619f59 100644
--- a/crates/ra_ssr/src/lib.rs
+++ b/crates/ra_ssr/src/lib.rs
@@ -7,6 +7,7 @@ mod matching;
7mod nester; 7mod nester;
8mod parsing; 8mod parsing;
9mod replacing; 9mod replacing;
10mod resolving;
10mod search; 11mod search;
11#[macro_use] 12#[macro_use]
12mod errors; 13mod errors;
@@ -21,6 +22,7 @@ use hir::Semantics;
21use ra_db::{FileId, FilePosition, FileRange}; 22use ra_db::{FileId, FilePosition, FileRange};
22use ra_ide_db::source_change::SourceFileEdit; 23use ra_ide_db::source_change::SourceFileEdit;
23use ra_syntax::{ast, AstNode, SyntaxNode, TextRange}; 24use ra_syntax::{ast, AstNode, SyntaxNode, TextRange};
25use resolving::ResolvedRule;
24use rustc_hash::FxHashMap; 26use rustc_hash::FxHashMap;
25 27
26// A structured search replace rule. Create by calling `parse` on a str. 28// A structured search replace rule. Create by calling `parse` on a str.
@@ -48,7 +50,9 @@ pub struct SsrMatches {
48pub struct MatchFinder<'db> { 50pub struct MatchFinder<'db> {
49 /// Our source of information about the user's code. 51 /// Our source of information about the user's code.
50 sema: Semantics<'db, ra_ide_db::RootDatabase>, 52 sema: Semantics<'db, ra_ide_db::RootDatabase>,
51 rules: Vec<parsing::ParsedRule>, 53 rules: Vec<ResolvedRule>,
54 scope: hir::SemanticsScope<'db>,
55 hygiene: hir::Hygiene,
52} 56}
53 57
54impl<'db> MatchFinder<'db> { 58impl<'db> MatchFinder<'db> {
@@ -56,10 +60,24 @@ impl<'db> MatchFinder<'db> {
56 /// `lookup_context`. 60 /// `lookup_context`.
57 pub fn in_context( 61 pub fn in_context(
58 db: &'db ra_ide_db::RootDatabase, 62 db: &'db ra_ide_db::RootDatabase,
59 _lookup_context: FilePosition, 63 lookup_context: FilePosition,
60 ) -> MatchFinder<'db> { 64 ) -> MatchFinder<'db> {
61 // FIXME: Use lookup_context 65 let sema = Semantics::new(db);
62 MatchFinder { sema: Semantics::new(db), rules: Vec::new() } 66 let file = sema.parse(lookup_context.file_id);
67 // Find a node at the requested position, falling back to the whole file.
68 let node = file
69 .syntax()
70 .token_at_offset(lookup_context.offset)
71 .left_biased()
72 .map(|token| token.parent())
73 .unwrap_or_else(|| file.syntax().clone());
74 let scope = sema.scope(&node);
75 MatchFinder {
76 sema: Semantics::new(db),
77 rules: Vec::new(),
78 scope,
79 hygiene: hir::Hygiene::new(db, lookup_context.file_id.into()),
80 }
63 } 81 }
64 82
65 /// Constructs an instance using the start of the first file in `db` as the lookup context. 83 /// Constructs an instance using the start of the first file in `db` as the lookup context.
@@ -84,8 +102,16 @@ impl<'db> MatchFinder<'db> {
84 /// Adds a rule to be applied. The order in which rules are added matters. Earlier rules take 102 /// Adds a rule to be applied. The order in which rules are added matters. Earlier rules take
85 /// precedence. If a node is matched by an earlier rule, then later rules won't be permitted to 103 /// precedence. If a node is matched by an earlier rule, then later rules won't be permitted to
86 /// match to it. 104 /// match to it.
87 pub fn add_rule(&mut self, rule: SsrRule) { 105 pub fn add_rule(&mut self, rule: SsrRule) -> Result<(), SsrError> {
88 self.add_parsed_rules(rule.parsed_rules); 106 for parsed_rule in rule.parsed_rules {
107 self.rules.push(ResolvedRule::new(
108 parsed_rule,
109 &self.scope,
110 &self.hygiene,
111 self.rules.len(),
112 )?);
113 }
114 Ok(())
89 } 115 }
90 116
91 /// Finds matches for all added rules and returns edits for all found matches. 117 /// Finds matches for all added rules and returns edits for all found matches.
@@ -110,8 +136,16 @@ impl<'db> MatchFinder<'db> {
110 136
111 /// Adds a search pattern. For use if you intend to only call `find_matches_in_file`. If you 137 /// Adds a search pattern. For use if you intend to only call `find_matches_in_file`. If you
112 /// intend to do replacement, use `add_rule` instead. 138 /// intend to do replacement, use `add_rule` instead.
113 pub fn add_search_pattern(&mut self, pattern: SsrPattern) { 139 pub fn add_search_pattern(&mut self, pattern: SsrPattern) -> Result<(), SsrError> {
114 self.add_parsed_rules(pattern.parsed_rules); 140 for parsed_rule in pattern.parsed_rules {
141 self.rules.push(ResolvedRule::new(
142 parsed_rule,
143 &self.scope,
144 &self.hygiene,
145 self.rules.len(),
146 )?);
147 }
148 Ok(())
115 } 149 }
116 150
117 /// Returns matches for all added rules. 151 /// Returns matches for all added rules.
@@ -149,13 +183,6 @@ impl<'db> MatchFinder<'db> {
149 res 183 res
150 } 184 }
151 185
152 fn add_parsed_rules(&mut self, parsed_rules: Vec<parsing::ParsedRule>) {
153 for mut parsed_rule in parsed_rules {
154 parsed_rule.index = self.rules.len();
155 self.rules.push(parsed_rule);
156 }
157 }
158
159 fn output_debug_for_nodes_at_range( 186 fn output_debug_for_nodes_at_range(
160 &self, 187 &self,
161 node: &SyntaxNode, 188 node: &SyntaxNode,
@@ -175,7 +202,7 @@ impl<'db> MatchFinder<'db> {
175 // we get lots of noise. If at some point we add support for restricting rules 202 // we get lots of noise. If at some point we add support for restricting rules
176 // to a particular kind of thing (e.g. only match type references), then we can 203 // to a particular kind of thing (e.g. only match type references), then we can
177 // relax this. 204 // relax this.
178 if rule.pattern.kind() != node.kind() { 205 if rule.pattern.node.kind() != node.kind() {
179 continue; 206 continue;
180 } 207 }
181 out.push(MatchDebugInfo { 208 out.push(MatchDebugInfo {
@@ -185,7 +212,7 @@ impl<'db> MatchFinder<'db> {
185 "Match failed, but no reason was given".to_owned() 212 "Match failed, but no reason was given".to_owned()
186 }), 213 }),
187 }), 214 }),
188 pattern: rule.pattern.clone(), 215 pattern: rule.pattern.node.clone(),
189 node: node.clone(), 216 node: node.clone(),
190 }); 217 });
191 } 218 }