Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: non-doc comments within rsx #4

Merged
merged 11 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions formatter/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ impl<'ast> Visit<'ast> for ViewMacroVisitor<'ast> {
.iter()
.filter(|v| v.line == span_line && v.column < span_start)
.map(|v| v.column)
.min();
.min()
.unwrap_or(
self.ident_stack
.iter()
.rev()
.find(|v| v.column < span_start)
.map(|i| i.column)
.unwrap_or(0),
);

if let Some(view_mac) = ViewMacro::try_parse(ident, node) {
if let Some(view_mac) = ViewMacro::try_parse(Some(ident), node) {
self.macros.push(view_mac);
}
}
Expand Down
4 changes: 3 additions & 1 deletion formatter/src/formatter/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rstml::node::{KeyedAttribute, NodeAttribute};
use syn::Expr;
use syn::{spanned::Spanned, Expr};

use crate::{formatter::Formatter, AttributeValueBraceStyle as Braces};

impl Formatter<'_> {
pub fn attribute(&mut self, attribute: &NodeAttribute) {
self.write_comments(attribute.span().start().line - 1);

match attribute {
NodeAttribute::Attribute(k) => self.keyed_attribute(k),
NodeAttribute::Block(b) => self.node_block(b),
Expand Down
20 changes: 18 additions & 2 deletions formatter/src/formatter/expr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use syn::{Block, Expr, ExprBlock, ExprLit, LitStr};
use syn::{spanned::Spanned, Block, Expr, ExprBlock, ExprLit, LitStr};

use crate::{formatter::Formatter, view_macro::ViewMacroFormatter};

Expand Down Expand Up @@ -93,10 +93,26 @@ impl Formatter<'_> {
return;
}

let start_line = expr.span().start().line;
let end_line = expr.span().end().line;

let comments = self
.comments
.iter()
.filter_map(|(line, _comment)| {
let line = *line;
if line >= start_line && line <= end_line {
Some((line, *_comment))
} else {
None
}
})
.collect();

leptosfmt_prettyplease::unparse_expr(
expr,
self.printer,
Some(&ViewMacroFormatter::new(self.settings)),
Some(&ViewMacroFormatter::new(self.settings, comments)),
);
}
}
Expand Down
14 changes: 9 additions & 5 deletions formatter/src/formatter/mac.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use leptosfmt_pretty_printer::Printer;
use proc_macro2::{token_stream, Span, TokenStream, TokenTree};
use rstml::node::Node;
Expand Down Expand Up @@ -44,13 +46,12 @@ impl Formatter<'_> {
cx,
global_class,
nodes,
span,
..
} = view_mac;

let indent = parent_ident
.map(|i| i + self.settings.tab_spaces)
.unwrap_or(span.start().column);
.unwrap_or(0);

self.printer.cbox(indent as isize);

Expand Down Expand Up @@ -121,9 +122,12 @@ fn extract_global_class(
Some((tokens, global_class))
}

pub fn format_macro(mac: &ViewMacro, settings: &FormatterSettings) -> String {
pub fn format_macro(mac: &ViewMacro, settings: &FormatterSettings, source: Option<&str>) -> String {
let mut printer = Printer::new(settings.into());
let mut formatter = Formatter::new(*settings, &mut printer);
let mut formatter = match source {
Some(source) => Formatter::with_source(*settings, &mut printer, source),
None => Formatter::new(*settings, &mut printer, HashMap::new()),
};

formatter.view_macro(mac);
printer.eof()
Expand All @@ -139,7 +143,7 @@ mod tests {
macro_rules! view_macro {
($($tt:tt)*) => {{
let mac: Macro = syn::parse2(quote! { $($tt)* }).unwrap();
format_macro(&ViewMacro::try_parse(None, &mac).unwrap(), &Default::default())
format_macro(&ViewMacro::try_parse(None, &mac).unwrap(), &Default::default(), None)
}}
}

Expand Down
50 changes: 48 additions & 2 deletions formatter/src/formatter/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use leptosfmt_pretty_printer::{Printer, PrinterSettings};

mod attribute;
Expand Down Expand Up @@ -56,10 +58,54 @@ impl From<&FormatterSettings> for PrinterSettings {
pub struct Formatter<'a> {
pub printer: &'a mut leptosfmt_pretty_printer::Printer,
pub settings: FormatterSettings,
last_line_check: Option<usize>,
comments: HashMap<usize, &'a str>,
}

impl<'a> Formatter<'a> {
pub fn new(settings: FormatterSettings, printer: &'a mut Printer) -> Self {
Self { printer, settings }
pub fn new(
settings: FormatterSettings,
printer: &'a mut Printer,
comments: HashMap<usize, &'a str>,
) -> Self {
Self {
printer,
settings,
comments,
last_line_check: None,
}
}

pub fn with_source(
settings: FormatterSettings,
printer: &'a mut Printer,
source: &'a str,
) -> Self {
Self {
printer,
settings,
comments: source
.lines()
.enumerate()
.filter_map(|(i, l)| l.split("//").nth(1).map(|l| (i, l)))
.collect(),
last_line_check: None,
}
}

pub fn write_comments(&mut self, line_index: usize) {
let last = self.last_line_check.unwrap_or(0);

self.last_line_check = Some(line_index);

let comments = (last..=line_index)
.filter_map(|l| self.comments.remove(&l))
.peekable();

for comment in comments {
self.printer.word("//");
self.printer.word(comment.to_string());
self.printer.hardbreak();
}
}
}
6 changes: 4 additions & 2 deletions formatter/src/formatter/node.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rstml::node::{Node, NodeBlock, NodeComment, NodeDoctype, NodeName, NodeText, RawText};
use syn::{spanned::Spanned};
use syn::spanned::Spanned;

use crate::formatter::Formatter;

impl Formatter<'_> {
pub fn node(&mut self, node: &Node) {
self.write_comments(node.span().start().line - 1);

match node {
Node::Element(ele) => self.element(ele),
Node::Text(text) => self.node_text(text),
Expand All @@ -13,7 +15,7 @@ impl Formatter<'_> {
Node::Doctype(doctype) => self.doctype(doctype),
Node::Block(block) => self.node_block(block),
Node::Fragment(frag) => self.fragment(frag),
}
};
}

pub fn comment(&mut self, comment: &NodeComment) {
Expand Down
115 changes: 105 additions & 10 deletions formatter/src/source_file.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{io, ops::Range};

use crop::Rope;

use syn::spanned::Spanned;
use thiserror::Error;

Expand Down Expand Up @@ -38,16 +39,16 @@ fn format_source<'a>(
macros: Vec<ViewMacro<'a>>,
settings: FormatterSettings,
) -> Result<String, FormatError> {
let mut source: Rope = source.parse().unwrap();
let mut rope: Rope = source.parse().unwrap();
let mut edits = Vec::new();

for view_mac in macros {
let mac = view_mac.inner();
let start = mac.path.span().start();
let end = mac.delimiter.span().close().end();
let start_byte = line_column_to_byte(&source, start);
let end_byte = line_column_to_byte(&source, end);
let new_text = format_macro(&view_mac, &settings);
let start_byte = line_column_to_byte(&rope, start);
let end_byte = line_column_to_byte(&rope, end);
let new_text = format_macro(&view_mac, &settings, Some(source));

edits.push(TextEdit {
range: start_byte..end_byte,
Expand All @@ -61,14 +62,14 @@ fn format_source<'a>(
let end = edit.range.end;
let new_text = edit.new_text;

source.replace(
rope.replace(
(start as isize + last_offset) as usize..(end as isize + last_offset) as usize,
&new_text,
);
last_offset += new_text.len() as isize - (end as isize - start as isize);
}

Ok(source.to_string())
Ok(rope.to_string())
}

fn line_column_to_byte(source: &Rope, point: proc_macro2::LineColumn) -> usize {
Expand Down Expand Up @@ -101,6 +102,58 @@ mod tests {
</div>
};
}

"###);
}

#[test]
fn with_comments() {
let source = indoc! {r#"
fn main() {
view! { cx ,
// Top level comment
<div>
// This is one beautiful message
<span>"hello"</span> // at the end of the line
<div>// at the end of the line
// double
// comments
<span>"hello"</span> </div>
<For
// a function that returns the items we're iterating over; a signal is fine
each= move || {errors.clone().into_iter().enumerate()}
// a unique key for each item as a reference
key=|(index, _error)| *index // yeah
/>
</div> };
}
"#};

let result = format_file_source(source, Default::default()).unwrap();
insta::assert_snapshot!(result, @r###"
fn main() {
view! { cx,
// Top level comment
<div>
// This is one beautiful message
// at the end of the line
<span>"hello"</span>
// at the end of the line
<div>
// double
// comments
<span>"hello"</span>
</div>
<For
// a function that returns the items we're iterating over; a signal is fine
each=move || { errors.clone().into_iter().enumerate() }
// a unique key for each item as a reference
// yeah
key=|(index, _error)| *index
/>
</div>
};
}
"###);
}

Expand All @@ -115,8 +168,8 @@ mod tests {

<span>{a}</span>
}
}</span></div> };
}
}</span></div> };
}
"#};

let result = format_file_source(source, Default::default()).unwrap();
Expand All @@ -131,8 +184,50 @@ mod tests {
}
</span>
</div>
};
}
};
}
"###);
}

#[test]
fn nested_with_comments() {
let source = indoc! {r#"
fn main() {
view! { cx ,
// parent div
<div>

// parent span
<span>{
let a = 12;

view! { cx,
// wow, a span
<span>{a}</span>
}
}</span></div> };
}
"#};

let result = format_file_source(source, Default::default()).unwrap();
insta::assert_snapshot!(result, @r###"
fn main() {
view! { cx,
// parent div
<div>
// parent span
<span>
{
let a = 12;
view! { cx,
// wow, a span
<span>{a}</span>
}
}
</span>
</div>
};
}
"###);
}

Expand Down
4 changes: 3 additions & 1 deletion formatter/src/test_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use leptosfmt_pretty_printer::Printer;
use rstml::node::{Node, NodeAttribute, NodeComment, NodeDoctype, NodeElement, NodeFragment};

Expand Down Expand Up @@ -105,7 +107,7 @@ pub fn get_doctype(mut nodes: Vec<Node>, doctype_index: usize) -> NodeDoctype {

pub fn format_with(settings: FormatterSettings, run: impl FnOnce(&mut Formatter)) -> String {
let mut printer = Printer::new((&settings).into());
let mut formatter = Formatter::new(settings, &mut printer);
let mut formatter = Formatter::new(settings, &mut printer, HashMap::new());
run(&mut formatter);
printer.eof()
}
Loading