Skip to content

Commit a441d5e

Browse files
authored
Read the original file for comparing/detecting newline (#4236)
1 parent a5c06ec commit a441d5e

File tree

7 files changed

+43
-67
lines changed

7 files changed

+43
-67
lines changed

Diff for: src/config/file_lines.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use itertools::Itertools;
44
use std::collections::HashMap;
5-
use std::path::PathBuf;
5+
use std::path::{Path, PathBuf};
66
use std::rc::Rc;
77
use std::{cmp, fmt, iter, str};
88

@@ -26,6 +26,15 @@ pub enum FileName {
2626
Stdin,
2727
}
2828

29+
impl FileName {
30+
pub(crate) fn as_path(&self) -> Option<&Path> {
31+
match self {
32+
FileName::Real(ref path) => Some(path),
33+
_ => None,
34+
}
35+
}
36+
}
37+
2938
impl From<rustc_span::FileName> for FileName {
3039
fn from(name: rustc_span::FileName) -> FileName {
3140
match name {

Diff for: src/emitter.rs

+3-37
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ pub use self::json::*;
55
pub use self::modified_lines::*;
66
pub use self::stdout::*;
77

8-
use std::fs;
98
use std::io::{self, Write};
10-
use std::path::Path;
11-
use std::rc::Rc;
129

1310
use thiserror::Error;
1411

15-
use crate::formatting::ParseSess;
16-
use crate::{config::FileName, FormatReport, FormatResult, NewlineStyle};
12+
use crate::{config::FileName, FormatReport, FormatResult};
1713

1814
pub mod checkstyle;
1915
pub mod diff;
@@ -166,15 +162,14 @@ where
166162

167163
emitter.emit_header(out)?;
168164
for (filename, format_result) in format_report.format_result_as_rc().borrow().iter() {
169-
has_diff |= write_file(None, filename, &format_result, out, &mut *emitter)?.has_diff;
165+
has_diff |= write_file(filename, &format_result, out, &mut *emitter)?.has_diff;
170166
}
171167
emitter.emit_footer(out)?;
172168

173169
Ok(has_diff)
174170
}
175171

176172
pub(crate) fn write_file<T>(
177-
parse_sess: Option<&ParseSess>,
178173
filename: &FileName,
179174
formatted_result: &FormatResult,
180175
out: &mut T,
@@ -183,38 +178,9 @@ pub(crate) fn write_file<T>(
183178
where
184179
T: Write,
185180
{
186-
fn ensure_real_path(filename: &FileName) -> &Path {
187-
match *filename {
188-
FileName::Real(ref path) => path,
189-
_ => panic!("cannot format `{}` and emit to files", filename),
190-
}
191-
}
192-
193-
// SourceFile's in the SourceMap will always have Unix-style line endings
194-
// See: https://github.com/rust-lang/rustfmt/issues/3850
195-
// So if the user has explicitly overridden the rustfmt `newline_style`
196-
// config and `filename` is FileName::Real, then we must check the file system
197-
// to get the original file value in order to detect newline_style conflicts.
198-
// Otherwise, parse session is around (cfg(not(test))) and newline_style has been
199-
// left as the default value, then try getting source from the parse session
200-
// source map instead of hitting the file system. This also supports getting
201-
// original text for `FileName::Stdin`.
202-
let original_text =
203-
if formatted_result.newline_style() != NewlineStyle::Auto && *filename != FileName::Stdin {
204-
Rc::new(fs::read_to_string(ensure_real_path(filename))?)
205-
} else {
206-
match formatted_result.original_text() {
207-
Some(original_snippet) => Rc::new(original_snippet.to_owned()),
208-
None => match parse_sess.and_then(|sess| sess.get_original_snippet(filename)) {
209-
Some(ori) => ori,
210-
None => Rc::new(fs::read_to_string(ensure_real_path(filename))?),
211-
},
212-
}
213-
};
214-
215181
let formatted_file = FormattedFile {
216182
filename,
217-
original_text: original_text.as_str(),
183+
original_text: formatted_result.original_text(),
218184
formatted_text: formatted_result.formatted_text(),
219185
};
220186

Diff for: src/formatting.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,18 @@ use rustc_span::symbol;
77

88
pub(crate) use syntux::session::ParseSess;
99

10-
use self::newline_style::apply_newline_style;
1110
use crate::config::{Config, FileName};
12-
use crate::formatting::modules::Module;
1311
use crate::formatting::{
1412
comment::{CharClasses, FullCodeCharKind},
13+
modules::Module,
14+
newline_style::apply_newline_style,
1515
report::NonFormattedRange,
1616
syntux::parser::{DirectoryOwnership, Parser, ParserError},
1717
utils::count_newlines,
1818
visitor::FmtVisitor,
1919
};
20-
use crate::result::OperationError;
2120
use crate::{
22-
result::{ErrorKind, FormatError},
21+
result::{ErrorKind, FormatError, OperationError},
2322
FormatReport, FormatResult, Input, OperationSetting, Verbosity,
2423
};
2524

@@ -136,7 +135,7 @@ fn format_project(
136135
&module,
137136
&format_report,
138137
original_snippet.clone(),
139-
);
138+
)?;
140139
}
141140
timer = timer.done_formatting();
142141

@@ -159,7 +158,7 @@ fn format_file(
159158
module: &Module<'_>,
160159
report: &FormatReport,
161160
original_snippet: Option<String>,
162-
) {
161+
) -> Result<(), OperationError> {
163162
let snippet_provider = parse_session.snippet_provider(module.as_ref().inner);
164163
let mut visitor =
165164
FmtVisitor::from_parse_sess(&parse_session, config, &snippet_provider, report.clone());
@@ -187,22 +186,33 @@ fn format_file(
187186
report.clone(),
188187
);
189188

190-
apply_newline_style(
191-
config.newline_style(),
192-
&mut visitor.buffer,
193-
snippet_provider.entire_snippet(),
194-
);
189+
// SourceFile's in the SourceMap will always have Unix-style line endings
190+
// See: https://github.com/rust-lang/rustfmt/issues/3850
191+
// So we must check the file system to get the original file value in order
192+
// to detect newline_style conflicts.
193+
// Otherwise, parse session is around (cfg(not(test))) and newline_style has been
194+
// left as the default value, then try getting source from the parse session
195+
// source map instead of hitting the file system.
196+
let original_text = match original_snippet {
197+
Some(snippet) => snippet,
198+
None => std::fs::read_to_string(path.as_path().ok_or(OperationError::IoError(
199+
std::io::Error::from(std::io::ErrorKind::InvalidInput),
200+
))?)?,
201+
};
202+
apply_newline_style(config.newline_style(), &mut visitor.buffer, &original_text);
195203

196204
if visitor.macro_rewrite_failure {
197205
report.add_macro_format_failure(path.clone());
198206
}
199207
let format_result = FormatResult::success(
200208
visitor.buffer.to_owned(),
201209
visitor.skipped_range.borrow().clone(),
202-
original_snippet,
210+
original_text,
203211
config.newline_style(),
204212
);
205213
report.add_format_result(path, format_result);
214+
215+
Ok(())
206216
}
207217

208218
#[derive(Clone, Copy, Debug)]

Diff for: src/formatting/report.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct FormatReport {
2020
/// errors and warning arose while formatting.
2121
#[derive(Debug, Clone, Default)]
2222
pub struct FormatResult {
23-
original_snippet: Option<String>,
23+
original_snippet: String,
2424
formatted_snippet: FormattedSnippet,
2525
format_errors: HashSet<FormatError>,
2626
newline_style: NewlineStyle,
@@ -37,7 +37,7 @@ impl FormatResult {
3737
pub(crate) fn success(
3838
snippet: String,
3939
non_formatted_ranges: Vec<NonFormattedRange>,
40-
original_snippet: Option<String>,
40+
original_snippet: String,
4141
newline_style: NewlineStyle,
4242
) -> Self {
4343
let formatted_snippet = FormattedSnippet {
@@ -67,8 +67,8 @@ impl FormatResult {
6767
self.newline_style.clone()
6868
}
6969

70-
pub fn original_text(&self) -> Option<&str> {
71-
self.original_snippet.as_ref().map(|s| s.as_str())
70+
pub fn original_text(&self) -> &str {
71+
&self.original_snippet
7272
}
7373

7474
pub fn formatted_text(&self) -> &str {
@@ -120,9 +120,7 @@ impl FormatReport {
120120
original_format_result
121121
.format_errors
122122
.extend(format_result.format_errors);
123-
if original_format_result.original_snippet.is_none() {
124-
original_format_result.original_snippet = format_result.original_snippet;
125-
}
123+
original_format_result.original_snippet = format_result.original_snippet;
126124
}
127125

128126
pub(crate) fn append_errors(&self, f: FileName, errors: impl Iterator<Item = FormatError>) {

Diff for: src/formatting/syntux/session.rs

-7
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,6 @@ impl ParseSess {
206206
Rc::clone(source_file.src.as_ref().unwrap()),
207207
)
208208
}
209-
210-
pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option<Rc<String>> {
211-
self.parse_sess
212-
.source_map()
213-
.get_source_file(&file_name.into())
214-
.and_then(|source_file| source_file.src.clone())
215-
}
216209
}
217210

218211
// Methods that should be restricted within the syntux module.

Diff for: src/formatting/visitor.rs

-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ impl SnippetProvider {
6262
}
6363
}
6464

65-
pub(crate) fn entire_snippet(&self) -> &str {
66-
self.big_snippet.as_str()
67-
}
6865
pub(crate) fn start_pos(&self) -> BytePos {
6966
BytePos::from_usize(self.start_pos)
7067
}

Diff for: src/result.rs

+3
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ pub enum OperationError {
120120
/// Parse error occurred while parsing the input.
121121
#[error("failed to parse {input:?}")]
122122
ParseError { input: FileName, is_panic: bool },
123+
/// Io error.
124+
#[error("{0}")]
125+
IoError(#[from] std::io::Error),
123126
}
124127

125128
impl OperationError {

0 commit comments

Comments
 (0)