From 4e4e101eee88905b77f3d7bae9d4d5cc43fb05b6 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 17 Jan 2023 16:24:29 -0800 Subject: [PATCH] fix: dont choke on emojji n exprs --- packages/autofmt/src/expr.rs | 7 +++++-- packages/autofmt/src/lib.rs | 20 ++++--------------- packages/autofmt/src/writer.rs | 16 +++++++++++++-- packages/autofmt/tests/samples.rs | 3 ++- .../autofmt/tests/samples/trailing_expr.rsx | 7 +++++++ 5 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 packages/autofmt/tests/samples/trailing_expr.rsx diff --git a/packages/autofmt/src/expr.rs b/packages/autofmt/src/expr.rs index 3ff133e7f..daf0c36ec 100644 --- a/packages/autofmt/src/expr.rs +++ b/packages/autofmt/src/expr.rs @@ -3,7 +3,7 @@ use std::fmt::{Result, Write}; use proc_macro2::Span; -use crate::Writer; +use crate::{collect_macros::byte_offset, Writer}; impl Writer<'_> { pub fn write_raw_expr(&mut self, placement: Span) -> Result { @@ -16,7 +16,10 @@ impl Writer<'_> { // if the expr is on one line, just write it directly if start.line == end.line { - let row = &self.src[start.line - 1][start.column..end.column].trim(); + // split counting utf8 chars + let start = byte_offset(self.raw_src, start); + let end = byte_offset(self.raw_src, end); + let row = self.raw_src[start..end].trim(); write!(self.out, "{}", row)?; return Ok(()); } diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs index 82cebffed..f1c888ff4 100644 --- a/packages/autofmt/src/lib.rs +++ b/packages/autofmt/src/lib.rs @@ -53,10 +53,7 @@ pub fn fmt_file(contents: &str) -> Vec { return formatted_blocks; } - let mut writer = Writer { - src: contents.lines().collect::>(), - ..Writer::default() - }; + let mut writer = Writer::new(contents); // Dont parse nested macros let mut end_span = LineColumn { column: 0, line: 0 }; @@ -125,10 +122,7 @@ pub fn fmt_file(contents: &str) -> Vec { } pub fn write_block_out(body: CallBody) -> Option { - let mut buf = Writer { - src: vec![""], - ..Writer::default() - }; + let mut buf = Writer::new(""); write_body(&mut buf, &body); @@ -157,10 +151,7 @@ fn write_body(buf: &mut Writer, body: &CallBody) { pub fn fmt_block_from_expr(raw: &str, expr: ExprMacro) -> Option { let body = syn::parse2::(expr.mac.tokens).unwrap(); - let mut buf = Writer { - src: raw.lines().collect(), - ..Writer::default() - }; + let mut buf = Writer::new(raw); write_body(&mut buf, &body); @@ -170,10 +161,7 @@ pub fn fmt_block_from_expr(raw: &str, expr: ExprMacro) -> Option { pub fn fmt_block(block: &str, indent_level: usize) -> Option { let body = syn::parse_str::(block).unwrap(); - let mut buf = Writer { - src: block.lines().collect(), - ..Writer::default() - }; + let mut buf = Writer::new(block); buf.out.indent = indent_level; diff --git a/packages/autofmt/src/writer.rs b/packages/autofmt/src/writer.rs index cdbdbed45..6a0e38d82 100644 --- a/packages/autofmt/src/writer.rs +++ b/packages/autofmt/src/writer.rs @@ -9,8 +9,9 @@ use syn::{spanned::Spanned, Expr, ExprIf}; use crate::buffer::Buffer; -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Writer<'a> { + pub raw_src: &'a str, pub src: Vec<&'a str>, pub cached_formats: HashMap, pub comments: VecDeque, @@ -31,7 +32,18 @@ impl Location { } } -impl Writer<'_> { +impl<'a> Writer<'a> { + pub fn new(raw_src: &'a str) -> Self { + let src = raw_src.lines().collect(); + Self { + raw_src, + src, + cached_formats: HashMap::new(), + comments: VecDeque::new(), + out: Buffer::default(), + } + } + // Expects to be written directly into place pub fn write_ident(&mut self, node: &BodyNode) -> Result { match node { diff --git a/packages/autofmt/tests/samples.rs b/packages/autofmt/tests/samples.rs index 84c48fde2..19e636926 100644 --- a/packages/autofmt/tests/samples.rs +++ b/packages/autofmt/tests/samples.rs @@ -39,5 +39,6 @@ twoway![ t2, reallylong, immediate_expr, - collapse_expr + collapse_expr, + trailing_expr ]; diff --git a/packages/autofmt/tests/samples/trailing_expr.rsx b/packages/autofmt/tests/samples/trailing_expr.rsx new file mode 100644 index 000000000..667b8bb32 --- /dev/null +++ b/packages/autofmt/tests/samples/trailing_expr.rsx @@ -0,0 +1,7 @@ +fn it_works() { + cx.render(rsx! { + div { + span { "Description: ", package.description.as_deref().unwrap_or("❌❌❌❌ missing") } + } + }) +}