11//! structural search replace
22
33use crate :: source_change:: SourceFileEdit ;
4+ use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
5+ use ra_ide_db:: symbol_index:: SymbolsDatabase ;
46use ra_ide_db:: RootDatabase ;
5- use ra_syntax:: ast:: make:: expr_from_text ;
7+ use ra_syntax:: ast:: make:: try_expr_from_text ;
68use ra_syntax:: ast:: { AstToken , Comment } ;
79use ra_syntax:: { AstNode , SyntaxElement , SyntaxNode } ;
810use ra_text_edit:: { TextEdit , TextEditBuilder } ;
911use rustc_hash:: FxHashMap ;
1012use std:: collections:: HashMap ;
1113use std:: str:: FromStr ;
1214
13- pub use ra_db:: { SourceDatabase , SourceDatabaseExt } ;
14- use ra_ide_db:: symbol_index:: SymbolsDatabase ;
15-
1615#[ derive( Debug , PartialEq ) ]
1716pub struct SsrError ( String ) ;
1817
@@ -26,14 +25,17 @@ impl std::error::Error for SsrError {}
2625
2726pub fn parse_search_replace (
2827 query : & str ,
28+ parse_only : bool ,
2929 db : & RootDatabase ,
3030) -> Result < Vec < SourceFileEdit > , SsrError > {
3131 let mut edits = vec ! [ ] ;
3232 let query: SsrQuery = query. parse ( ) ?;
33+ if parse_only {
34+ return Ok ( edits) ;
35+ }
3336 for & root in db. local_roots ( ) . iter ( ) {
3437 let sr = db. source_root ( root) ;
3538 for file_id in sr. walk ( ) {
36- dbg ! ( db. file_relative_path( file_id) ) ;
3739 let matches = find ( & query. pattern , db. parse ( file_id) . tree ( ) . syntax ( ) ) ;
3840 if !matches. matches . is_empty ( ) {
3941 edits. push ( SourceFileEdit { file_id, edit : replace ( & matches, & query. template ) } ) ;
@@ -106,7 +108,10 @@ impl FromStr for SsrQuery {
106108 template = replace_in_template ( template, var, new_var) ;
107109 }
108110
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 ( ) ;
110115 let mut placeholders = FxHashMap :: default ( ) ;
111116
112117 traverse ( & template, & mut |n| {
@@ -118,7 +123,13 @@ impl FromStr for SsrQuery {
118123 }
119124 } ) ;
120125
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+ } ;
122133 let template = SsrTemplate { template, placeholders } ;
123134 Ok ( SsrQuery { pattern, template } )
124135 }
@@ -284,7 +295,6 @@ mod tests {
284295 assert_eq ! ( result. pattern. vars[ 0 ] . 0 , "__search_pattern_a" ) ;
285296 assert_eq ! ( result. pattern. vars[ 1 ] . 0 , "__search_pattern_b" ) ;
286297 assert_eq ! ( & result. template. template. text( ) , "bar(__search_pattern_b, __search_pattern_a)" ) ;
287- dbg ! ( result. template. placeholders) ;
288298 }
289299
290300 #[ test]
@@ -334,6 +344,16 @@ mod tests {
334344 ) ;
335345 }
336346
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+
337357 #[ test]
338358 fn parse_match_replace ( ) {
339359 let query: SsrQuery = "foo($x:expr) ==>> bar($x)" . parse ( ) . unwrap ( ) ;
0 commit comments