Переглянути джерело

report syn parse errors to the user

Evan Almloff 1 рік тому
батько
коміт
b88c66d8df

+ 2 - 0
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",

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

+ 4 - 0
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 }

+ 23 - 11
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<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#"

+ 0 - 1
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