Skip to content
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
25 changes: 6 additions & 19 deletions crates/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ pub enum ParenExprMode {
}

impl ParenExprMode {
const UNSUPPORTED_REF_EXPR: &str = "`(@&...)` only supports simple path and field expressions";

pub const fn is_ref(self) -> bool {
matches!(self, Self::Ref)
}
Expand All @@ -213,7 +215,7 @@ impl ParenExprMode {
if is_supported(expr) {
Ok(())
} else {
Err(Error::new_spanned(expr, "unsupported borrow expression"))
Err(Error::new_spanned(expr, Self::UNSUPPORTED_REF_EXPR))
}
}

Expand Down Expand Up @@ -264,19 +266,9 @@ impl ParenExprMode {

if mode.is_ref() {
match &body {
ParenExprBody::Expr(expr) => {
Self::validate_ref_expr(expr).map_err(|err| {
Error::new(
err.span(),
"`(@&...)` only supports simple path and field expressions",
)
})?;
}
ParenExprBody::Expr(expr) => Self::validate_ref_expr(expr)?,
ParenExprBody::Unit | ParenExprBody::Tuple(_) => {
return Err(Error::new_spanned(
&body,
"`(@&...)` only supports simple path and field expressions",
));
return Err(Error::new_spanned(&body, Self::UNSUPPORTED_REF_EXPR));
}
}
}
Expand Down Expand Up @@ -307,12 +299,7 @@ impl Parse for BorrowExpr<Expr> {
};

if mode.is_ref() {
ParenExprMode::validate_ref_expr(&expr).map_err(|err| {
Error::new(
err.span(),
"`(@&...)` only supports simple path and field expressions",
)
})?;
ParenExprMode::validate_ref_expr(&expr)?;
}

Ok(Self {
Expand Down
28 changes: 24 additions & 4 deletions crates/cargo-cheers/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn run(
buf
};

let mut formatted_buf = try_fmt_file(&buf, &format_options).unwrap_or(buf);
let mut formatted_buf = format_reporting_errors(buf, "<stdin>", &format_options);

if rustfmt {
formatted_buf = run_rustfmt(&formatted_buf, &rustfmt_args).unwrap_or(formatted_buf);
Expand All @@ -132,19 +132,39 @@ pub fn run(
Some(files) => {
for file in get_file_paths(files)? {
let source = std::fs::read_to_string(&file)?;
let mut formatted_source =
try_fmt_file(&source, &format_options).unwrap_or(source);
let mut formatted_source = format_reporting_errors(
source.clone(),
&file.display().to_string(),
&format_options,
);

if rustfmt {
formatted_source = run_rustfmt(&formatted_source, &rustfmt_args)
.unwrap_or(formatted_source);
}

fs::write(file, &formatted_source)?;
if formatted_source != source {
fs::write(file, &formatted_source)?;
}
}
}
}

Ok(())
}
}

fn format_reporting_errors(source: String, name: &str, options: &FormatOptions) -> String {
match try_fmt_file(&source, options) {
Ok(formatted) => {
for error in formatted.macro_errors {
eprintln!("{name}: {error:#}");
}
formatted.source
}
Err(error) => {
eprintln!("{name}: {error:#}");
source
}
}
}
7 changes: 4 additions & 3 deletions crates/cargo-cheers/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ pub fn format_source(
source: &mut Rope,
macros: Vec<MaudMacro<'_>>,
options: &FormatOptions,
) -> String {
) -> (String, Vec<anyhow::Error>) {
let mut edits = Vec::new();
let mut errors = Vec::new();

for maud_mac in macros {
let mac = maud_mac.macro_;
Expand All @@ -57,7 +58,7 @@ pub fn format_source(
range: start_byte..end_byte,
new_text,
}),
Err(e) => eprintln!("{e}"),
Err(e) => errors.push(e.context(format!("line {}", start.line))),
}
}

Expand All @@ -74,7 +75,7 @@ pub fn format_source(
last_offset += new_text.len() as isize - (end as isize - start as isize);
}

source.to_string()
(source.to_string(), errors)
}

fn format_macro(mac: &MaudMacro, source: &Rope, options: &FormatOptions) -> Result<String> {
Expand Down
15 changes: 12 additions & 3 deletions crates/cargo-cheers/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,22 @@ pub use format::FormatOptions;

use crate::{fmt::FmtArgs, subsecond::SubsecondArgs};

pub fn try_fmt_file(source: &str, options: &format::FormatOptions) -> Result<String> {
pub struct FormattedFile {
pub source: String,
/// Macros that failed to parse and were left as written.
pub macro_errors: Vec<anyhow::Error>,
}

pub fn try_fmt_file(source: &str, options: &format::FormatOptions) -> Result<FormattedFile> {
let ast = syn::parse_file(source).context("Failed to parse source")?;
let rope = Rope::from(source);
let (mut rope, macros) = collect::collect_macros_from_file(&ast, rope, &options.macro_names);
let formatted_processed = format::format_source(&mut rope, macros, options);
let (source, macro_errors) = format::format_source(&mut rope, macros, options);

Ok(formatted_processed)
Ok(FormattedFile {
source,
macro_errors,
})
}

#[derive(Parser)]
Expand Down
Loading
Loading