From b88c66d8dfdffdaf3204ff17fb4e99444793ff0a Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 8 Feb 2024 10:00:25 -0600 Subject: [PATCH] report syn parse errors to the user --- Cargo.lock | 2 ++ packages/autofmt/src/lib.rs | 7 ------ packages/cli/Cargo.toml | 4 ++++ packages/cli/src/cli/autoformat.rs | 34 ++++++++++++++++++++---------- packages/cli/src/main.rs | 1 - 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 471818cf6..3477f46ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2418,12 +2418,14 @@ dependencies = [ "mlua", "notify", "open", + "prettier-please", "rayon", "reqwest", "rsx-rosetta", "serde", "serde_json", "subprocess", + "syn 2.0.48", "tar", "tauri-bundler", "tempfile", diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs index 953f052b0..e40b873d6 100644 --- a/packages/autofmt/src/lib.rs +++ b/packages/autofmt/src/lib.rs @@ -240,10 +240,3 @@ pub(crate) fn write_ifmt(input: &IfmtInput, writable: &mut impl Write) -> std::f let display = DisplayIfmt(input); write!(writable, "{}", display) } - -/// Call rustfmt to format code, i32 as exitcode -pub fn rustfmt(input: &str) -> Option { - let syntax_tree = syn::parse_file(input).ok()?; - let output = prettyplease::unparse(&syntax_tree); - Some(output) -} diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 82c16e0dc..657c70e0f 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -75,6 +75,10 @@ toml_edit = "0.21.0" # bundling tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] } +# formatting +syn = { version = "2.0" } +prettyplease = { workspace = true } + manganis-cli-support = { workspace = true, features = ["webp", "html"] } dioxus-autofmt = { workspace = true } diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs index 2b8093f75..36072b967 100644 --- a/packages/cli/src/cli/autoformat.rs +++ b/packages/cli/src/cli/autoformat.rs @@ -33,8 +33,7 @@ pub struct Autoformat { } impl Autoformat { - // Todo: autoformat the entire crate - pub async fn autoformat(self) -> Result<()> { + pub fn autoformat(self) -> Result<()> { let Autoformat { check, raw, @@ -46,7 +45,7 @@ impl Autoformat { // Default to formatting the project if raw.is_none() && file.is_none() { - if let Err(e) = autoformat_project(check, split_line_attributes, do_rustfmt).await { + if let Err(e) = autoformat_project(check, split_line_attributes, do_rustfmt) { eprintln!("error formatting project: {}", e); exit(1); } @@ -87,7 +86,7 @@ fn refactor_file(file: String, split_line_attributes: bool, do_rustfmt: bool) -> }; if do_rustfmt { - s = dioxus_autofmt::rustfmt(&s).ok_or_else(|| Error::ParseError("Syntax Error".into()))?; + s = rustfmt(&s)?; } let edits = dioxus_autofmt::fmt_file(&s, indent); @@ -122,8 +121,8 @@ fn format_file(path: impl AsRef, indent: IndentOptions, do_rustfmt: bool) let mut contents = fs::read_to_string(&path)?; let mut if_write = false; if do_rustfmt { - let formatted = dioxus_autofmt::rustfmt(&contents) - .ok_or_else(|| Error::ParseError("Syntax Error".into()))?; + let formatted = rustfmt(&contents) + .map_err(|err| Error::ParseError(format!("Syntax Error:\n{}", err)))?; if contents != formatted { if_write = true; contents = formatted; @@ -150,11 +149,7 @@ fn format_file(path: impl AsRef, indent: IndentOptions, do_rustfmt: bool) /// Runs using rayon for multithreading, so it should be really really fast /// /// Doesn't do mod-descending, so it will still try to format unreachable files. TODO. -async fn autoformat_project( - check: bool, - split_line_attributes: bool, - do_rustfmt: bool, -) -> Result<()> { +fn autoformat_project(check: bool, split_line_attributes: bool, do_rustfmt: bool) -> Result<()> { let files_to_format = get_project_files(); if files_to_format.is_empty() { @@ -238,6 +233,23 @@ fn indentation_for( )) } +/// Format rust code using prettyplease +pub fn rustfmt(input: &str) -> Result { + let syntax_tree = syn::parse_file(input).map_err(format_syn_error)?; + let output = prettyplease::unparse(&syntax_tree); + Ok(output) +} + +fn format_syn_error(err: syn::Error) -> Error { + let start = err.span().start(); + let line = start.line; + let column = start.column; + Error::ParseError(format!( + "Syntax Error in line {} column {}:\n{}", + line, column, err + )) +} + #[tokio::test] async fn test_auto_fmt() { let test_rsx = r#" diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index 0a57735db..dae2deb2c 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -70,7 +70,6 @@ async fn main() -> anyhow::Result<()> { Autoformat(opts) => opts .autoformat() - .await .context(error_wrapper("Error autoformatting RSX")), Check(opts) => opts