Skip to content
This repository was archived by the owner on Nov 24, 2023. It is now read-only.

Apply suggestion #63

Merged
merged 3 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ language: rust
rust:
- nightly
- stable
before_script:
- if [ $TRAVIS_RUST_VERSION == nightly ]; then cargo install clippy --git https://github.com/rust-lang-nursery/rust-clippy.git --force; fi
script:
- cargo build
- if [ $TRAVIS_RUST_VERSION == nightly ]; then cargo test -- --nocapture ; fi
Expand Down
57 changes: 57 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate serde_derive;
extern crate serde_json;

use std::collections::HashSet;
use std::error::Error;

pub mod diagnostics;
use diagnostics::{Diagnostic, DiagnosticSpan};
Expand Down Expand Up @@ -165,3 +166,59 @@ pub fn collect_suggestions<S: ::std::hash::BuildHasher>(diagnostic: &Diagnostic,
})
}
}

pub fn apply_suggestion(file_content: &mut String, suggestion: &Replacement) -> String {
use std::cmp::max;

let mut new_content = String::new();

// Add the lines before the section we want to replace
new_content.push_str(&file_content.lines()
.take(max(suggestion.snippet.line_range.start.line - 1, 0) as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");

// Parts of line before replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.start.line - 1)
.unwrap_or("")
.chars()
.take(suggestion.snippet.line_range.start.column - 1)
.collect::<String>());

// Insert new content! Finally!
new_content.push_str(&suggestion.replacement);

// Parts of line after replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.end.line - 1)
.unwrap_or("")
.chars()
.skip(suggestion.snippet.line_range.end.column - 1)
.collect::<String>());

// Add the lines after the section we want to replace
new_content.push_str("\n");
new_content.push_str(&file_content.lines()
.skip(suggestion.snippet.line_range.end.line as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");

new_content
}

pub fn apply_suggestions(code: &str, suggestions: &[Suggestion]) -> String {
let mut fixed = code.to_string();

for sug in suggestions.iter().rev() {
for sol in &sug.solutions {
for r in &sol.replacements {
fixed = apply_suggestion(&mut fixed, r);
}
}
}

fixed
}
40 changes: 2 additions & 38 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,44 +398,8 @@ fn indent(size: u32, s: &str) -> String {
/// This function is as stupid as possible. Make sure you call for the replacemnts in one file in
/// reverse order to not mess up the lines for replacements further down the road.
fn apply_suggestion(suggestion: &Replacement) -> Result<(), ProgramError> {
use std::cmp::max;

let file_content = try!(read_file_to_string(&suggestion.snippet.file_name));
let mut new_content = String::new();

// Add the lines before the section we want to replace
new_content.push_str(&file_content.lines()
.take(max(suggestion.snippet.line_range.start.line - 1, 0) as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");

// Parts of line before replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.start.line - 1)
.unwrap_or("")
.chars()
.take(suggestion.snippet.line_range.start.column - 1)
.collect::<String>());

// Insert new content! Finally!
new_content.push_str(&suggestion.replacement);

// Parts of line after replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.end.line - 1)
.unwrap_or("")
.chars()
.skip(suggestion.snippet.line_range.end.column - 1)
.collect::<String>());

// Add the lines after the section we want to replace
new_content.push_str("\n");
new_content.push_str(&file_content.lines()
.skip(suggestion.snippet.line_range.end.line as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");
let mut file_content = try!(read_file_to_string(&suggestion.snippet.file_name));
let new_content = rustfix::apply_suggestion(&mut file_content, suggestion);

let mut file = try!(File::create(&suggestion.snippet.file_name));
let new_content = new_content.as_bytes();
Expand Down
60 changes: 3 additions & 57 deletions tests/everything.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ use std::collections::HashSet;
use std::process::Output;
use tempdir::TempDir;

use rustfix::Replacement;
use rustfix::{Replacement, apply_suggestions};

fn compile(file: &Path) -> Result<Output, Box<Error>> {
let tmp = TempDir::new("rustfix-tests")?;
let better_call_clippy = cmd!(
"clippy-driver", "rustc", file,
"rustc", file,
"--error-format=pretty-json", "-Zunstable-options", "--emit=metadata",
"--crate-name=rustfix_test",
"--out-dir", tmp.path()
Expand Down Expand Up @@ -75,48 +75,6 @@ fn read_file(path: &Path) -> Result<String, Box<Error>> {
Ok(buffer)
}

fn apply_suggestion(file_content: &mut String, suggestion: &Replacement) -> Result<String, Box<Error>> {
use std::cmp::max;

let mut new_content = String::new();

// Add the lines before the section we want to replace
new_content.push_str(&file_content.lines()
.take(max(suggestion.snippet.line_range.start.line - 1, 0) as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");

// Parts of line before replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.start.line - 1)
.unwrap_or("")
.chars()
.take(suggestion.snippet.line_range.start.column - 1)
.collect::<String>());

// Insert new content! Finally!
new_content.push_str(&suggestion.replacement);

// Parts of line after replacement
new_content.push_str(&file_content.lines()
.nth(suggestion.snippet.line_range.end.line - 1)
.unwrap_or("")
.chars()
.skip(suggestion.snippet.line_range.end.column - 1)
.collect::<String>());

// Add the lines after the section we want to replace
new_content.push_str("\n");
new_content.push_str(&file_content.lines()
.skip(suggestion.snippet.line_range.end.line as usize)
.collect::<Vec<_>>()
.join("\n"));
new_content.push_str("\n");

Ok(new_content)
}

fn test_rustfix_with_file<P: AsRef<Path>>(file: P) -> Result<(), Box<Error>> {
let file: &Path = file.as_ref();
let json_file = file.with_extension("json");
Expand All @@ -141,19 +99,7 @@ fn test_rustfix_with_file<P: AsRef<Path>>(file: P) -> Result<(), Box<Error>> {
"got unexpected suggestions from clippy",
);

let mut fixed = code.clone();

for sug in suggestions.into_iter().rev() {
trace!("{:?}", sug);
for sol in sug.solutions {
trace!("{:?}", sol);
for r in sol.replacements {
debug!("replaced.");
trace!("{:?}", r);
fixed = apply_suggestion(&mut fixed, &r)?;
}
}
}
let fixed = apply_suggestions(&code, &suggestions);

if std::env::var("RUSTFIX_TEST_RECORD_FIXED_RUST").is_ok() {
use std::io::Write;
Expand Down
3 changes: 0 additions & 3 deletions tests/fixtures/const_static_lifetime.fixed.rs

This file was deleted.

111 changes: 0 additions & 111 deletions tests/fixtures/const_static_lifetime.json

This file was deleted.

3 changes: 0 additions & 3 deletions tests/fixtures/const_static_lifetime.rs

This file was deleted.

7 changes: 0 additions & 7 deletions tests/fixtures/explicit_iter_loop.fixed.rs

This file was deleted.

Loading