diff --git a/packages/autofmt/src/writer.rs b/packages/autofmt/src/writer.rs index 0f53e2cd3..9b6c3a62d 100644 --- a/packages/autofmt/src/writer.rs +++ b/packages/autofmt/src/writer.rs @@ -3,6 +3,7 @@ use dioxus_rsx::*; use proc_macro2::{LineColumn, Span}; use quote::ToTokens; use std::{ + borrow::Cow, collections::{HashMap, VecDeque}, fmt::{Result, Write}, }; @@ -910,9 +911,14 @@ impl<'a> Writer<'a> { } #[allow(clippy::map_entry)] - fn retrieve_formatted_expr(&mut self, expr: &Expr) -> &str { + fn retrieve_formatted_expr(&mut self, expr: &Expr) -> Cow<'_, str> { let loc = expr.span().start(); + // never cache expressions that are spanless + if loc.line == 1 && loc.column == 0 { + return self.unparse_expr(expr).into(); + } + if !self.cached_formats.contains_key(&loc) { let formatted = self.unparse_expr(expr); self.cached_formats.insert(loc, formatted); @@ -922,6 +928,7 @@ impl<'a> Writer<'a> { .get(&loc) .expect("Just inserted the parsed expr, so it should be in the cache") .as_str() + .into() } fn final_span_of_node(node: &BodyNode) -> Span { diff --git a/packages/autofmt/tests/samples/attributes.rsx b/packages/autofmt/tests/samples/attributes.rsx index 2443f515a..aa32466e4 100644 --- a/packages/autofmt/tests/samples/attributes.rsx +++ b/packages/autofmt/tests/samples/attributes.rsx @@ -7,6 +7,8 @@ rsx! { class: "asd", class: "asd", class: "asd", + src: asset!("/123.png"), + src: asset!("/456.png"), blah: 123, onclick: move |_| { let blah = 120; diff --git a/packages/autofmt/tests/srcless.rs b/packages/autofmt/tests/srcless.rs index afddcff40..cf1ecea34 100644 --- a/packages/autofmt/tests/srcless.rs +++ b/packages/autofmt/tests/srcless.rs @@ -1,17 +1,29 @@ use dioxus_rsx::CallBody; -use proc_macro2::TokenStream as TokenStream2; +use syn::parse_quote; + +macro_rules! test_case { + ( + $path:literal + ) => { + works(include!($path), include_str!($path)) + }; +} /// Ensure we can write RSX blocks without a source file /// /// Useful in code generation use cases where we still want formatted code. #[test] fn write_block_out() { - let src = include_str!("./srcless/basic_expr.rsx"); - - let tokens: TokenStream2 = syn::parse_str(src).unwrap(); - let parsed: CallBody = syn::parse2(tokens).unwrap(); + test_case!("./srcless/basic_expr.rsx"); + test_case!("./srcless/asset.rsx"); +} +fn works(parsed: CallBody, src: &str) { let block = dioxus_autofmt::write_block_out(&parsed).unwrap(); + let src = src + .trim() + .trim_start_matches("parse_quote! {") + .trim_end_matches('}'); // normalize line endings for windows tests to pass pretty_assertions::assert_eq!( diff --git a/packages/autofmt/tests/srcless/asset.rsx b/packages/autofmt/tests/srcless/asset.rsx new file mode 100644 index 000000000..121e918be --- /dev/null +++ b/packages/autofmt/tests/srcless/asset.rsx @@ -0,0 +1,5 @@ +parse_quote! { + img { src: asset!("/assets/logos/123.png") } + img { src: asset!("/assets/logos/456.png") } + img { src: asset!("/assets/logos/789.png") } +} diff --git a/packages/autofmt/tests/srcless/basic_expr.rsx b/packages/autofmt/tests/srcless/basic_expr.rsx index 1c1e21524..80637c935 100644 --- a/packages/autofmt/tests/srcless/basic_expr.rsx +++ b/packages/autofmt/tests/srcless/basic_expr.rsx @@ -1,3 +1,4 @@ +parse_quote! { div { "hi" {children} @@ -37,6 +38,23 @@ let b = 40; let c = 50; }, + src1: asset!("/123.png"), + src2: asset!("/456.png"), + src3: asset!("/789.png"), + src4: asset!("/101112.png", WithOptions), "hi" } + p { + img { + src: asset!("/example-book/assets1/logo.png", ImageAssetOptions::new().with_avif()), + alt: "some_local1", + title: "", + } + img { + src: asset!("/example-book/assets2/logo.png", ImageAssetOptions::new().with_avif()), + alt: "some_local2", + title: "", + } + } div { class: "asd", "Jon" } +}