aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_expand/src/lib.rs20
-rw-r--r--crates/ra_ide/src/lib.rs3
-rw-r--r--crates/ra_ide/src/ssr.rs36
-rw-r--r--crates/ra_syntax/src/ast/make.rs16
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs5
-rw-r--r--crates/rust-analyzer/src/req.rs4
6 files changed, 55 insertions, 29 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 3fce73e8a..7b72eb7a0 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -17,7 +17,7 @@ pub mod eager;
17use std::hash::Hash; 17use std::hash::Hash;
18use std::sync::Arc; 18use std::sync::Arc;
19 19
20use ra_db::{salsa, CrateId, FileId}; 20use ra_db::{impl_intern_key, salsa, CrateId, FileId};
21use ra_syntax::{ 21use ra_syntax::{
22 algo, 22 algo,
23 ast::{self, AstNode}, 23 ast::{self, AstNode},
@@ -174,25 +174,11 @@ pub enum MacroCallId {
174 174
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
176pub struct LazyMacroId(salsa::InternId); 176pub struct LazyMacroId(salsa::InternId);
177impl salsa::InternKey for LazyMacroId { 177impl_intern_key!(LazyMacroId);
178 fn from_intern_id(v: salsa::InternId) -> Self {
179 LazyMacroId(v)
180 }
181 fn as_intern_id(&self) -> salsa::InternId {
182 self.0
183 }
184}
185 178
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
187pub struct EagerMacroId(salsa::InternId); 180pub struct EagerMacroId(salsa::InternId);
188impl salsa::InternKey for EagerMacroId { 181impl_intern_key!(EagerMacroId);
189 fn from_intern_id(v: salsa::InternId) -> Self {
190 EagerMacroId(v)
191 }
192 fn as_intern_id(&self) -> salsa::InternId {
193 self.0
194 }
195}
196 182
197impl From<LazyMacroId> for MacroCallId { 183impl From<LazyMacroId> for MacroCallId {
198 fn from(it: LazyMacroId) -> Self { 184 fn from(it: LazyMacroId) -> Self {
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index e9af80b6c..5ab06c6cf 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -473,9 +473,10 @@ impl Analysis {
473 pub fn structural_search_replace( 473 pub fn structural_search_replace(
474 &self, 474 &self,
475 query: &str, 475 query: &str,
476 parse_only: bool,
476 ) -> Cancelable<Result<SourceChange, SsrError>> { 477 ) -> Cancelable<Result<SourceChange, SsrError>> {
477 self.with_db(|db| { 478 self.with_db(|db| {
478 let edits = ssr::parse_search_replace(query, db)?; 479 let edits = ssr::parse_search_replace(query, parse_only, db)?;
479 Ok(SourceChange::source_file_edits("ssr", edits)) 480 Ok(SourceChange::source_file_edits("ssr", edits))
480 }) 481 })
481 } 482 }
diff --git a/crates/ra_ide/src/ssr.rs b/crates/ra_ide/src/ssr.rs
index c011a2e74..1c9710a5d 100644
--- a/crates/ra_ide/src/ssr.rs
+++ b/crates/ra_ide/src/ssr.rs
@@ -1,8 +1,10 @@
1//! structural search replace 1//! structural search replace
2 2
3use crate::source_change::SourceFileEdit; 3use crate::source_change::SourceFileEdit;
4use ra_db::{SourceDatabase, SourceDatabaseExt};
5use ra_ide_db::symbol_index::SymbolsDatabase;
4use ra_ide_db::RootDatabase; 6use ra_ide_db::RootDatabase;
5use ra_syntax::ast::make::expr_from_text; 7use ra_syntax::ast::make::try_expr_from_text;
6use ra_syntax::ast::{AstToken, Comment}; 8use ra_syntax::ast::{AstToken, Comment};
7use ra_syntax::{AstNode, SyntaxElement, SyntaxNode}; 9use ra_syntax::{AstNode, SyntaxElement, SyntaxNode};
8use ra_text_edit::{TextEdit, TextEditBuilder}; 10use ra_text_edit::{TextEdit, TextEditBuilder};
@@ -10,9 +12,6 @@ use rustc_hash::FxHashMap;
10use std::collections::HashMap; 12use std::collections::HashMap;
11use std::str::FromStr; 13use std::str::FromStr;
12 14
13pub use ra_db::{SourceDatabase, SourceDatabaseExt};
14use ra_ide_db::symbol_index::SymbolsDatabase;
15
16#[derive(Debug, PartialEq)] 15#[derive(Debug, PartialEq)]
17pub struct SsrError(String); 16pub struct SsrError(String);
18 17
@@ -26,14 +25,17 @@ impl std::error::Error for SsrError {}
26 25
27pub fn parse_search_replace( 26pub fn parse_search_replace(
28 query: &str, 27 query: &str,
28 parse_only: bool,
29 db: &RootDatabase, 29 db: &RootDatabase,
30) -> Result<Vec<SourceFileEdit>, SsrError> { 30) -> Result<Vec<SourceFileEdit>, SsrError> {
31 let mut edits = vec![]; 31 let mut edits = vec![];
32 let query: SsrQuery = query.parse()?; 32 let query: SsrQuery = query.parse()?;
33 if parse_only {
34 return Ok(edits);
35 }
33 for &root in db.local_roots().iter() { 36 for &root in db.local_roots().iter() {
34 let sr = db.source_root(root); 37 let sr = db.source_root(root);
35 for file_id in sr.walk() { 38 for file_id in sr.walk() {
36 dbg!(db.file_relative_path(file_id));
37 let matches = find(&query.pattern, db.parse(file_id).tree().syntax()); 39 let matches = find(&query.pattern, db.parse(file_id).tree().syntax());
38 if !matches.matches.is_empty() { 40 if !matches.matches.is_empty() {
39 edits.push(SourceFileEdit { file_id, edit: replace(&matches, &query.template) }); 41 edits.push(SourceFileEdit { file_id, edit: replace(&matches, &query.template) });
@@ -106,7 +108,10 @@ impl FromStr for SsrQuery {
106 template = replace_in_template(template, var, new_var); 108 template = replace_in_template(template, var, new_var);
107 } 109 }
108 110
109 let template = expr_from_text(&template).syntax().clone(); 111 let template = try_expr_from_text(&template)
112 .ok_or(SsrError("Template is not an expression".into()))?
113 .syntax()
114 .clone();
110 let mut placeholders = FxHashMap::default(); 115 let mut placeholders = FxHashMap::default();
111 116
112 traverse(&template, &mut |n| { 117 traverse(&template, &mut |n| {
@@ -118,7 +123,13 @@ impl FromStr for SsrQuery {
118 } 123 }
119 }); 124 });
120 125
121 let pattern = SsrPattern { pattern: expr_from_text(&pattern).syntax().clone(), vars }; 126 let pattern = SsrPattern {
127 pattern: try_expr_from_text(&pattern)
128 .ok_or(SsrError("Pattern is not an expression".into()))?
129 .syntax()
130 .clone(),
131 vars,
132 };
122 let template = SsrTemplate { template, placeholders }; 133 let template = SsrTemplate { template, placeholders };
123 Ok(SsrQuery { pattern, template }) 134 Ok(SsrQuery { pattern, template })
124 } 135 }
@@ -284,7 +295,6 @@ mod tests {
284 assert_eq!(result.pattern.vars[0].0, "__search_pattern_a"); 295 assert_eq!(result.pattern.vars[0].0, "__search_pattern_a");
285 assert_eq!(result.pattern.vars[1].0, "__search_pattern_b"); 296 assert_eq!(result.pattern.vars[1].0, "__search_pattern_b");
286 assert_eq!(&result.template.template.text(), "bar(__search_pattern_b, __search_pattern_a)"); 297 assert_eq!(&result.template.template.text(), "bar(__search_pattern_b, __search_pattern_a)");
287 dbg!(result.template.placeholders);
288 } 298 }
289 299
290 #[test] 300 #[test]
@@ -335,6 +345,16 @@ mod tests {
335 } 345 }
336 346
337 #[test] 347 #[test]
348 fn parser_invlid_pattern() {
349 assert_eq!(parse_error_text(" ==>> ()"), "Parse error: Pattern is not an expression");
350 }
351
352 #[test]
353 fn parser_invlid_template() {
354 assert_eq!(parse_error_text("() ==>> )"), "Parse error: Template is not an expression");
355 }
356
357 #[test]
338 fn parse_match_replace() { 358 fn parse_match_replace() {
339 let query: SsrQuery = "foo($x:expr) ==>> bar($x)".parse().unwrap(); 359 let query: SsrQuery = "foo($x:expr) ==>> bar($x)".parse().unwrap();
340 let input = "fn main() { foo(1+2); }"; 360 let input = "fn main() { foo(1+2); }";
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index ae8829807..9f6f1cc53 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -112,10 +112,14 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
112 let token = token(op); 112 let token = token(op);
113 expr_from_text(&format!("{}{}", token, expr.syntax())) 113 expr_from_text(&format!("{}{}", token, expr.syntax()))
114} 114}
115pub fn expr_from_text(text: &str) -> ast::Expr { 115fn expr_from_text(text: &str) -> ast::Expr {
116 ast_from_text(&format!("const C: () = {};", text)) 116 ast_from_text(&format!("const C: () = {};", text))
117} 117}
118 118
119pub fn try_expr_from_text(text: &str) -> Option<ast::Expr> {
120 try_ast_from_text(&format!("const C: () = {};", text))
121}
122
119pub fn bind_pat(name: ast::Name) -> ast::BindPat { 123pub fn bind_pat(name: ast::Name) -> ast::BindPat {
120 return from_text(name.text()); 124 return from_text(name.text());
121 125
@@ -239,6 +243,16 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
239 node 243 node
240} 244}
241 245
246fn try_ast_from_text<N: AstNode>(text: &str) -> Option<N> {
247 let parse = SourceFile::parse(text);
248 let node = parse.tree().syntax().descendants().find_map(N::cast)?;
249 let node = node.syntax().clone();
250 let node = unroot(node);
251 let node = N::cast(node).unwrap();
252 assert_eq!(node.syntax().text_range().start(), 0.into());
253 Some(node)
254}
255
242fn unroot(n: SyntaxNode) -> SyntaxNode { 256fn unroot(n: SyntaxNode) -> SyntaxNode {
243 SyntaxNode::new_root(n.green().clone()) 257 SyntaxNode::new_root(n.green().clone())
244} 258}
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index df3622d61..1cc2f6571 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -932,7 +932,10 @@ pub fn handle_document_highlight(
932 932
933pub fn handle_ssr(world: WorldSnapshot, params: req::SsrParams) -> Result<req::SourceChange> { 933pub fn handle_ssr(world: WorldSnapshot, params: req::SsrParams) -> Result<req::SourceChange> {
934 let _p = profile("handle_ssr"); 934 let _p = profile("handle_ssr");
935 world.analysis().structural_search_replace(&params.arg)??.try_conv_with(&world) 935 world
936 .analysis()
937 .structural_search_replace(&params.query, params.parse_only)??
938 .try_conv_with(&world)
936} 939}
937 940
938pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { 941pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> {
diff --git a/crates/rust-analyzer/src/req.rs b/crates/rust-analyzer/src/req.rs
index 156328df8..9e27d3f1c 100644
--- a/crates/rust-analyzer/src/req.rs
+++ b/crates/rust-analyzer/src/req.rs
@@ -218,6 +218,8 @@ impl Request for Ssr {
218} 218}
219 219
220#[derive(Debug, Deserialize, Serialize)] 220#[derive(Debug, Deserialize, Serialize)]
221#[serde(rename_all = "camelCase")]
221pub struct SsrParams { 222pub struct SsrParams {
222 pub arg: String, 223 pub query: String,
224 pub parse_only: bool,
223} 225}