@@ -114,19 +114,22 @@ pub fn gen_changelog_lint_list(lints: Vec<Lint>) -> Vec<String> {
114114
115115/// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`.
116116pub fn gen_deprecated ( lints : & [ Lint ] ) -> Vec < String > {
117- lints. iter ( )
118- . filter_map ( |l| {
119- l. clone ( ) . deprecation . and_then ( |depr_text| {
120- Some (
121- format ! (
122- " store.register_removed(\n \" {}\" ,\n \" {}\" ,\n );" ,
123- l. name,
124- depr_text
117+ itertools:: flatten (
118+ lints
119+ . iter ( )
120+ . filter_map ( |l| {
121+ l. clone ( ) . deprecation . and_then ( |depr_text| {
122+ Some (
123+ vec ! [
124+ " store.register_removed(" . to_string( ) ,
125+ format!( " \" {}\" ," , l. name) ,
126+ format!( " \" {}\" ," , depr_text) ,
127+ " );" . to_string( )
128+ ]
125129 )
126- )
130+ } )
127131 } )
128- } )
129- . collect ( )
132+ ) . collect ( )
130133}
131134
132135/// Gathers all files in `src/clippy_lints` and gathers all lints inside
@@ -168,23 +171,33 @@ fn lint_files() -> impl Iterator<Item=walkdir::DirEntry> {
168171 . filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
169172}
170173
174+ /// Whether a file has had its text changed or not
175+ #[ derive( PartialEq , Debug ) ]
176+ pub struct FileChange {
177+ pub changed : bool ,
178+ pub new_lines : String ,
179+ }
180+
171181/// Replace a region in a file delimited by two lines matching regexes.
172182///
173183/// `path` is the relative path to the file on which you want to perform the replacement.
174184///
175185/// See `replace_region_in_text` for documentation of the other options.
176186#[ allow( clippy:: expect_fun_call) ]
177- pub fn replace_region_in_file < F > ( path : & str , start : & str , end : & str , replace_start : bool , replacements : F ) where F : Fn ( ) -> Vec < String > {
187+ pub fn replace_region_in_file < F > ( path : & str , start : & str , end : & str , replace_start : bool , write_back : bool , replacements : F ) -> FileChange where F : Fn ( ) -> Vec < String > {
178188 let mut f = fs:: File :: open ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
179189 let mut contents = String :: new ( ) ;
180190 f. read_to_string ( & mut contents) . expect ( "Something went wrong reading the file" ) ;
181- let replaced = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
182-
183- let mut f = fs:: File :: create ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
184- f. write_all ( replaced. as_bytes ( ) ) . expect ( "Unable to write file" ) ;
185- // Ensure we write the changes with a trailing newline so that
186- // the file has the proper line endings.
187- f. write_all ( b"\n " ) . expect ( "Unable to write file" ) ;
191+ let file_change = replace_region_in_text ( & contents, start, end, replace_start, replacements) ;
192+
193+ if write_back {
194+ let mut f = fs:: File :: create ( path) . expect ( & format ! ( "File not found: {}" , path) ) ;
195+ f. write_all ( file_change. new_lines . as_bytes ( ) ) . expect ( "Unable to write file" ) ;
196+ // Ensure we write the changes with a trailing newline so that
197+ // the file has the proper line endings.
198+ f. write_all ( b"\n " ) . expect ( "Unable to write file" ) ;
199+ }
200+ file_change
188201}
189202
190203/// Replace a region in a text delimited by two lines matching regexes.
@@ -213,18 +226,18 @@ pub fn replace_region_in_file<F>(path: &str, start: &str, end: &str, replace_sta
213226/// || {
214227/// vec!["a different".to_string(), "text".to_string()]
215228/// }
216- /// );
229+ /// ).new_lines ;
217230/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
218231/// ```
219- pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> String where F : Fn ( ) -> Vec < String > {
232+ pub fn replace_region_in_text < F > ( text : & str , start : & str , end : & str , replace_start : bool , replacements : F ) -> FileChange where F : Fn ( ) -> Vec < String > {
220233 let lines = text. lines ( ) ;
221234 let mut in_old_region = false ;
222235 let mut found = false ;
223236 let mut new_lines = vec ! [ ] ;
224237 let start = Regex :: new ( start) . unwrap ( ) ;
225238 let end = Regex :: new ( end) . unwrap ( ) ;
226239
227- for line in lines {
240+ for line in lines. clone ( ) {
228241 if in_old_region {
229242 if end. is_match ( & line) {
230243 in_old_region = false ;
@@ -248,7 +261,11 @@ pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_sta
248261 // is incorrect.
249262 eprintln ! ( "error: regex `{:?}` not found. You may have to update it." , start) ;
250263 }
251- new_lines. join ( "\n " )
264+
265+ FileChange {
266+ changed : lines. ne ( new_lines. clone ( ) ) ,
267+ new_lines : new_lines. join ( "\n " )
268+ }
252269}
253270
254271#[ test]
@@ -292,17 +309,11 @@ declare_deprecated_lint! {
292309
293310#[ test]
294311fn test_replace_region ( ) {
295- let text = r#"
296- abc
297- 123
298- 789
299- def
300- ghi"# ;
301- let expected = r#"
302- abc
303- hello world
304- def
305- ghi"# ;
312+ let text = "\n abc\n 123\n 789\n def\n ghi" ;
313+ let expected = FileChange {
314+ changed : true ,
315+ new_lines : "\n abc\n hello world\n def\n ghi" . to_string ( )
316+ } ;
306317 let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , false , || {
307318 vec ! [ "hello world" . to_string( ) ]
308319 } ) ;
@@ -311,22 +322,30 @@ ghi"#;
311322
312323#[ test]
313324fn test_replace_region_with_start ( ) {
314- let text = r#"
315- abc
316- 123
317- 789
318- def
319- ghi"# ;
320- let expected = r#"
321- hello world
322- def
323- ghi"# ;
325+ let text = "\n abc\n 123\n 789\n def\n ghi" ;
326+ let expected = FileChange {
327+ changed : true ,
328+ new_lines : "\n hello world\n def\n ghi" . to_string ( )
329+ } ;
324330 let result = replace_region_in_text ( text, r#"^\s*abc$"# , r#"^\s*def"# , true , || {
325331 vec ! [ "hello world" . to_string( ) ]
326332 } ) ;
327333 assert_eq ! ( expected, result) ;
328334}
329335
336+ #[ test]
337+ fn test_replace_region_no_changes ( ) {
338+ let text = "123\n 456\n 789" ;
339+ let expected = FileChange {
340+ changed : false ,
341+ new_lines : "123\n 456\n 789" . to_string ( )
342+ } ;
343+ let result = replace_region_in_text ( text, r#"^\s*123$"# , r#"^\s*456"# , false , || {
344+ vec ! [ ]
345+ } ) ;
346+ assert_eq ! ( expected, result) ;
347+ }
348+
330349#[ test]
331350fn test_usable_lints ( ) {
332351 let lints = vec ! [
@@ -377,14 +396,19 @@ fn test_gen_changelog_lint_list() {
377396fn test_gen_deprecated ( ) {
378397 let lints = vec ! [
379398 Lint :: new( "should_assert_eq" , "group1" , "abc" , Some ( "has been superseeded by should_assert_eq2" ) , "module_name" ) ,
399+ Lint :: new( "another_deprecated" , "group2" , "abc" , Some ( "will be removed" ) , "module_name" ) ,
380400 Lint :: new( "should_assert_eq2" , "group2" , "abc" , None , "module_name" )
381401 ] ;
382402 let expected: Vec < String > = vec ! [
383- r#" store.register_removed(
384- "should_assert_eq",
385- "has been superseeded by should_assert_eq2",
386- );"# . to_string( )
387- ] ;
403+ " store.register_removed(" ,
404+ " \" should_assert_eq\" ," ,
405+ " \" has been superseeded by should_assert_eq2\" ," ,
406+ " );" ,
407+ " store.register_removed(" ,
408+ " \" another_deprecated\" ," ,
409+ " \" will be removed\" ," ,
410+ " );"
411+ ] . into_iter ( ) . map ( String :: from) . collect ( ) ;
388412 assert_eq ! ( expected, gen_deprecated( & lints) ) ;
389413}
390414
0 commit comments