report syn parse errors to the user

This commit is contained in:
Evan Almloff 2024-02-08 10:00:25 -06:00
parent 65d4f922b4
commit b88c66d8df
5 changed files with 29 additions and 19 deletions

2
Cargo.lock generated
View file

@ -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",

View file

@ -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<String> {
let syntax_tree = syn::parse_file(input).ok()?;
let output = prettyplease::unparse(&syntax_tree);
Some(output)
}

View file

@ -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 }

View file

@ -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<Path>, 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<Path>, 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<String> {
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#"

View file

@ -70,7 +70,6 @@ async fn main() -> anyhow::Result<()> {
Autoformat(opts) => opts
.autoformat()
.await
.context(error_wrapper("Error autoformatting RSX")),
Check(opts) => opts