difftreelog
fix(fmt) multi-line ArgsDesc
in: master
8 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -644,6 +644,8 @@
dependencies = [
"dprint-core",
"hi-doc",
+ "indoc",
+ "insta",
"jrsonnet-rowan-parser",
]
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/main.rs
+++ b/cmds/jrsonnet-fmt/src/main.rs
@@ -1,4 +1,9 @@
-use std::{fs, io};
+use std::{
+ fs,
+ io::{self, Write as _},
+ path::PathBuf,
+ process,
+};
use clap::Parser;
use jrsonnet_formatter::{format, FormatOptions};
crates/jrsonnet-formatter/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-formatter/Cargo.toml
+++ b/crates/jrsonnet-formatter/Cargo.toml
@@ -9,6 +9,8 @@
[dependencies]
dprint-core.workspace = true
hi-doc.workspace = true
+indoc.workspace = true
+insta.workspace = true
jrsonnet-rowan-parser.workspace = true
[lints]
crates/jrsonnet-formatter/src/lib.rsdiffbeforeafterboth1use std::{any::type_name, rc::Rc};23use children::{children_between, trivia_before};4use dprint_core::formatting::{5 condition_helpers::is_multiple_lines, condition_resolvers::true_resolver,6 ConditionResolverContext, LineNumber, PrintItems, PrintOptions,7};8use hi_doc::{Formatting, SnippetBuilder};9use jrsonnet_rowan_parser::{10 nodes::{11 Arg, ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,12 DestructRest, Expr, ExprBase, FieldName, ForSpec, IfSpec, ImportKind, Literal, Member,13 Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix, Text,14 UnaryOperator, Visibility,15 },16 AstNode, AstToken as _, SyntaxToken,17};1819use crate::{20 children::trivia_after,21 comments::{format_comments, CommentLocation},22};2324mod children;25mod comments;26#[cfg(test)]27mod tests;2829pub trait Printable {30 fn print(&self, out: &mut PrintItems);31}3233macro_rules! pi {34 (@i; $($t:tt)*) => {{35 #[allow(unused_mut)]36 let mut o = dprint_core::formatting::PrintItems::new();37 pi!(@s; o: $($t)*);38 o39 }};40 (@s; $o:ident: str($e:expr $(,)?) $($t:tt)*) => {{41 $o.push_string($e.to_owned());42 pi!(@s; $o: $($t)*);43 }};44 (@s; $o:ident: string($e:expr $(,)?) $($t:tt)*) => {{45 $o.push_string($e);46 pi!(@s; $o: $($t)*);47 }};48 (@s; $o:ident: nl $($t:tt)*) => {{49 $o.push_signal(dprint_core::formatting::Signal::NewLine);50 pi!(@s; $o: $($t)*);51 }};52 (@s; $o:ident: tab $($t:tt)*) => {{53 $o.push_signal(dprint_core::formatting::Signal::Tab);54 pi!(@s; $o: $($t)*);55 }};56 (@s; $o:ident: >i $($t:tt)*) => {{57 $o.push_signal(dprint_core::formatting::Signal::StartIndent);58 pi!(@s; $o: $($t)*);59 }};60 (@s; $o:ident: <i $($t:tt)*) => {{61 $o.push_signal(dprint_core::formatting::Signal::FinishIndent);62 pi!(@s; $o: $($t)*);63 }};64 (@s; $o:ident: info($v:expr) $($t:tt)*) => {{65 $o.push_info($v);66 pi!(@s; $o: $($t)*);67 }};68 (@s; $o:ident: if($s:literal, $cond:expr, $($i:tt)*) $($t:tt)*) => {{69 $o.push_condition(dprint_core::formatting::conditions::if_true(70 $s,71 $cond.clone(),72 {73 let mut o = PrintItems::new();74 p!(o, $($i)*);75 o76 },77 ));78 pi!(@s; $o: $($t)*);79 }};80 (@s; $o:ident: if_else($s:literal, $cond:expr, $($i:tt)*)($($e:tt)+) $($t:tt)*) => {{81 $o.push_condition(dprint_core::formatting::conditions::if_true_or(82 $s,83 $cond.clone(),84 {85 let mut o = PrintItems::new();86 p!(o, $($i)*);87 o88 },89 {90 let mut o = PrintItems::new();91 p!(o, $($e)*);92 o93 },94 ));95 pi!(@s; $o: $($t)*);96 }};97 (@s; $o:ident: if_not($s:literal, $cond:expr, $($e:tt)*) $($t:tt)*) => {{98 $o.push_condition(dprint_core::formatting::conditions::if_true_or(99 $s,100 $cond.clone(),101 {102 let o = PrintItems::new();103 o104 },105 {106 let mut o = PrintItems::new();107 p!(o, $($e)*);108 o109 },110 ));111 pi!(@s; $o: $($t)*);112 }};113 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{114 $expr.print($o);115 pi!(@s; $o: $($t)*);116 }};117 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{118 $o.extend($expr);119 pi!(@s; $o: $($t)*);120 }};121 (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{122 if $e {123 pi!(@s; $o: $($then)*);124 }125 pi!(@s; $o: $($t)*);126 }};127 (@s; $o:ident: ifelse ($e:expr)($($then:tt)*)($($else:tt)*) $($t:tt)*) => {{128 if $e {129 pi!(@s; $o: $($then)*);130 } else {131 pi!(@s; $o: $($else)*);132 }133 pi!(@s; $o: $($t)*);134 }};135 (@s; $i:ident:) => {}136}137macro_rules! p {138 ($o:ident, $($t:tt)*) => {139 pi!(@s; $o: $($t)*)140 };141}142pub(crate) use p;143pub(crate) use pi;144145impl<P> Printable for Option<P>146where147 P: Printable,148{149 fn print(&self, out: &mut PrintItems) {150 if let Some(v) = self {151 v.print(out);152 } else {153 p!(154 out,155 string(format!(156 "/*missing {}*/",157 type_name::<P>().replace("jrsonnet_rowan_parser::generated::nodes::", "")158 ),)159 );160 }161 }162}163164impl Printable for SyntaxToken {165 fn print(&self, out: &mut PrintItems) {166 p!(out, string(self.to_string()));167 }168}169170impl Printable for Text {171 fn print(&self, out: &mut PrintItems) {172 p!(out, string(format!("{}", self)));173 }174}175impl Printable for Number {176 fn print(&self, out: &mut PrintItems) {177 p!(out, string(format!("{}", self)));178 }179}180181impl Printable for Name {182 fn print(&self, out: &mut PrintItems) {183 p!(out, { self.ident_lit() });184 }185}186187impl Printable for DestructRest {188 fn print(&self, out: &mut PrintItems) {189 p!(out, str("..."));190 if let Some(name) = self.into() {191 p!(out, { name });192 }193 }194}195196impl Printable for Destruct {197 fn print(&self, out: &mut PrintItems) {198 match self {199 Self::DestructFull(f) => {200 p!(out, { f.name() });201 }202 Self::DestructSkip(_) => p!(out, str("?")),203 Self::DestructArray(a) => {204 p!(out, str("[") >i nl);205 for el in a.destruct_array_parts() {206 match el {207 DestructArrayPart::DestructArrayElement(e) => {208 p!(out, {e.destruct()} str(",") nl);209 }210 DestructArrayPart::DestructRest(d) => {211 p!(out, {d} str(",") nl);212 }213 }214 }215 p!(out, <i str("]"));216 }217 Self::DestructObject(o) => {218 p!(out, str("{") >i nl);219 for item in o.destruct_object_fields() {220 p!(out, { item.field() });221 if let Some(des) = item.destruct() {222 p!(out, str(": ") {des});223 }224 if let Some(def) = item.expr() {225 p!(out, str(" = ") {def});226 }227 p!(out, str(",") nl);228 }229 if let Some(rest) = o.destruct_rest() {230 p!(out, {rest} nl);231 }232 p!(out, <i str("}"));233 }234 }235 }236}237238impl Printable for FieldName {239 fn print(&self, out: &mut PrintItems) {240 match self {241 Self::FieldNameFixed(f) => {242 if let Some(id) = f.id() {243 p!(out, { id });244 } else if let Some(str) = f.text() {245 p!(out, { str });246 } else {247 p!(out, str("/*missing FieldName*/"));248 }249 }250 Self::FieldNameDynamic(d) => {251 p!(out, str("[") {d.expr()} str("]"));252 }253 }254 }255}256257impl Printable for Visibility {258 fn print(&self, out: &mut PrintItems) {259 p!(out, string(self.to_string()));260 }261}262263impl Printable for ObjLocal {264 fn print(&self, out: &mut PrintItems) {265 p!(out, str("local ") {self.bind()});266 }267}268269impl Printable for Assertion {270 fn print(&self, out: &mut PrintItems) {271 p!(out, str("assert ") {self.condition()});272 if self.colon_token().is_some() || self.message().is_some() {273 p!(out, str(": ") {self.message()});274 }275 }276}277278impl Printable for ParamsDesc {279 fn print(&self, out: &mut PrintItems) {280 p!(out, str("(") >i nl);281 for param in self.params() {282 p!(out, { param.destruct() });283 if param.assign_token().is_some() || param.expr().is_some() {284 p!(out, str(" = ") {param.expr()});285 }286 p!(out, str(",") nl);287 }288 p!(out, <i str(")"));289 }290}291impl Printable for ArgsDesc {292 fn print(&self, out: &mut PrintItems) {293 let start = LineNumber::new("start");294 let end = LineNumber::new("end");295 let multi_line = Rc::new(move |condition_context: &mut ConditionResolverContext| {296 is_multiple_lines(condition_context, start, end).map(|v| !v)297 });298 p!(out, str("(") info(start) if("start args", multi_line, >i nl));299 let (children, end_comments) = children_between::<Arg>(300 self.syntax().clone(),301 self.l_paren_token().map(Into::into).as_ref(),302 self.r_paren_token().map(Into::into).as_ref(),303 None,304 );305 let mut args = children.into_iter().peekable();306 while let Some(ele) = args.next() {307 if ele.should_start_with_newline {308 p!(out, nl);309 }310 format_comments(&ele.before_trivia, CommentLocation::AboveItem, out);311 let arg = ele.value;312 if arg.name().is_some() || arg.assign_token().is_some() {313 p!(out, {arg.name()} str(" = "));314 }315 let comma_between = if args.peek().is_some() {316 true_resolver()317 } else {318 multi_line.clone()319 };320 p!(out, {arg.expr()} if("arg comma", comma_between, str(",") if_not("between args", multi_line, str(" "))));321 format_comments(&ele.inline_trivia, CommentLocation::ItemInline, out);322 p!(out, if("between args", multi_line, nl));323 }324 if end_comments.should_start_with_newline {325 p!(out, nl);326 }327 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);328 p!(out, if("end args", multi_line, <i info(end)) str(")"));329 }330}331impl Printable for SliceDesc {332 fn print(&self, out: &mut PrintItems) {333 p!(out, str("["));334 if self.from().is_some() {335 p!(out, { self.from() });336 }337 p!(out, str(":"));338 if self.end().is_some() {339 p!(out, { self.end().map(|e| e.expr()) });340 }341 // Keep only one : in case if we don't need step342 if self.step().is_some() {343 p!(out, str(":") {self.step().map(|e|e.expr())});344 }345 p!(out, str("]"));346 }347}348349impl Printable for Member {350 fn print(&self, out: &mut PrintItems) {351 match self {352 Self::MemberBindStmt(b) => {353 p!(out, { b.obj_local() });354 }355 Self::MemberAssertStmt(ass) => {356 p!(out, { ass.assertion() });357 }358 Self::MemberFieldNormal(n) => {359 p!(out, {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()});360 }361 Self::MemberFieldMethod(m) => {362 p!(out, {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()});363 }364 }365 }366}367368impl Printable for ObjBody {369 fn print(&self, out: &mut PrintItems) {370 match self {371 Self::ObjBodyComp(l) => {372 let (children, mut end_comments) = children_between::<Member>(373 l.syntax().clone(),374 l.l_brace_token().map(Into::into).as_ref(),375 Some(376 &(l.comp_specs()377 .next()378 .expect("at least one spec is defined")379 .syntax()380 .clone())381 .into(),382 ),383 None,384 );385 let trailing_for_comp = end_comments.extract_trailing();386 p!(out, str("{") >i nl);387 for mem in children {388 if mem.should_start_with_newline {389 p!(out, nl);390 }391 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);392 p!(out, {mem.value} str(","));393 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);394 p!(out, nl);395 }396397 if end_comments.should_start_with_newline {398 p!(out, nl);399 }400 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);401402 let (compspecs, end_comments) = children_between::<CompSpec>(403 l.syntax().clone(),404 l.member_comps()405 .last()406 .map(|m| m.syntax().clone())407 .map(Into::into)408 .or_else(|| l.l_brace_token().map(Into::into))409 .as_ref(),410 l.r_brace_token().map(Into::into).as_ref(),411 Some(trailing_for_comp),412 );413 for mem in compspecs {414 if mem.should_start_with_newline {415 p!(out, nl);416 }417 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);418 p!(out, { mem.value });419 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);420 }421 if end_comments.should_start_with_newline {422 p!(out, nl);423 }424 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);425426 p!(out, nl <i str("}"));427 }428 Self::ObjBodyMemberList(l) => {429 let (children, end_comments) = children_between::<Member>(430 l.syntax().clone(),431 l.l_brace_token().map(Into::into).as_ref(),432 l.r_brace_token().map(Into::into).as_ref(),433 None,434 );435 if children.is_empty() && end_comments.is_empty() {436 p!(out, str("{ }"));437 return;438 }439 p!(out, str("{") >i nl);440 for (i, mem) in children.into_iter().enumerate() {441 if mem.should_start_with_newline && i != 0 {442 p!(out, nl);443 }444 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);445 p!(out, {mem.value} str(","));446 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);447 p!(out, nl);448 }449450 if end_comments.should_start_with_newline {451 p!(out, nl);452 }453 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);454 p!(out, <i str("}"));455 }456 }457 }458}459impl Printable for UnaryOperator {460 fn print(&self, out: &mut PrintItems) {461 p!(out, string(self.text().to_string()));462 }463}464impl Printable for BinaryOperator {465 fn print(&self, out: &mut PrintItems) {466 p!(out, string(self.text().to_string()));467 }468}469impl Printable for Bind {470 fn print(&self, out: &mut PrintItems) {471 match self {472 Self::BindDestruct(d) => {473 p!(out, {d.into()} str(" = ") {d.value()});474 }475 Self::BindFunction(f) => {476 p!(out, {f.name()} {f.params()} str(" = ") {f.value()});477 }478 }479 }480}481impl Printable for Literal {482 fn print(&self, out: &mut PrintItems) {483 p!(out, string(self.syntax().to_string()));484 }485}486impl Printable for ImportKind {487 fn print(&self, out: &mut PrintItems) {488 p!(out, string(self.syntax().to_string()));489 }490}491impl Printable for ForSpec {492 fn print(&self, out: &mut PrintItems) {493 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()});494 }495}496impl Printable for IfSpec {497 fn print(&self, out: &mut PrintItems) {498 p!(out, str("if ") {self.expr()});499 }500}501impl Printable for CompSpec {502 fn print(&self, out: &mut PrintItems) {503 match self {504 Self::ForSpec(f) => f.print(out),505 Self::IfSpec(i) => i.print(out),506 }507 }508}509impl Printable for Expr {510 fn print(&self, out: &mut PrintItems) {511 let (stmts, _ending) = children_between::<Stmt>(512 self.syntax().clone(),513 None,514 self.expr_base()515 .as_ref()516 .map(ExprBase::syntax)517 .cloned()518 .map(Into::into)519 .as_ref(),520 None,521 );522 for stmt in stmts {523 p!(out, { stmt.value });524 }525 p!(out, { self.expr_base() });526 let (suffixes, _ending) = children_between::<Suffix>(527 self.syntax().clone(),528 self.expr_base()529 .as_ref()530 .map(ExprBase::syntax)531 .cloned()532 .map(Into::into)533 .as_ref(),534 None,535 None,536 );537 for suffix in suffixes {538 p!(out, { suffix.value });539 }540 }541}542impl Printable for Suffix {543 fn print(&self, out: &mut PrintItems) {544 match self {545 Self::SuffixIndex(i) => {546 if i.question_mark_token().is_some() {547 p!(out, str("?"));548 }549 p!(out, str(".") {i.index()});550 }551 Self::SuffixIndexExpr(e) => {552 if e.question_mark_token().is_some() {553 p!(out, str(".?"));554 }555 p!(out, str("[") {e.index()} str("]"));556 }557 Self::SuffixSlice(d) => {558 p!(out, { d.slice_desc() });559 }560 Self::SuffixApply(a) => {561 p!(out, { a.args_desc() });562 }563 }564 }565}566impl Printable for Stmt {567 fn print(&self, out: &mut PrintItems) {568 match self {569 Self::StmtLocal(l) => {570 let (binds, end_comments) = children_between::<Bind>(571 l.syntax().clone(),572 l.local_kw_token().map(Into::into).as_ref(),573 l.semi_token().map(Into::into).as_ref(),574 None,575 );576 if binds.len() == 1 {577 let bind = &binds[0];578 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);579 p!(out, str("local ") {bind.value});580 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?581 } else {582 p!(out,str("local") >i nl);583 for bind in binds {584 if bind.should_start_with_newline {585 p!(out, nl);586 }587 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);588 p!(out, {bind.value} str(","));589 format_comments(&bind.inline_trivia, CommentLocation::ItemInline, out);590 p!(out, nl);591 }592 if end_comments.should_start_with_newline {593 p!(out, nl);594 }595 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);596 p!(out,<i);597 }598 p!(out,str(";") nl);599 }600 Self::StmtAssert(a) => {601 p!(out, {a.assertion()} str(";") nl);602 }603 }604 }605}606impl Printable for ExprBase {607 fn print(&self, out: &mut PrintItems) {608 match self {609 Self::ExprBinary(b) => {610 p!(out, {b.lhs_work()} str(" ") {b.binary_operator()} str(" ") {b.rhs_work()});611 }612 Self::ExprUnary(u) => p!(out, {u.unary_operator()} {u.rhs()}),613 // Self::ExprSlice(s) => {614 // p!(new: {s.expr()} {s.slice_desc()})615 // }616 // Self::ExprIndex(i) => {617 // p!(new: {i.expr()} str(".") {i.index()})618 // }619 // Self::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")),620 // Self::ExprApply(a) => {621 // let mut pi = p!(new: {a.expr()} {a.args_desc()});622 // if a.tailstrict_kw_token().is_some() {623 // p!(out,str(" tailstrict"));624 // }625 // pi626 // }627 Self::ExprObjExtend(ex) => {628 p!(out, {ex.lhs_work()} str(" ") {ex.rhs_work()});629 }630 Self::ExprParened(p) => {631 p!(out, str("(") {p.expr()} str(")"));632 }633 Self::ExprString(s) => p!(out, { s.text() }),634 Self::ExprNumber(n) => p!(out, { n.number() }),635 Self::ExprArray(a) => {636 p!(out, str("[") >i nl);637 for el in a.exprs() {638 p!(out, {el} str(",") nl);639 }640 p!(out, <i str("]"));641 }642 Self::ExprObject(obj) => {643 p!(out, { obj.obj_body() });644 }645 Self::ExprArrayComp(arr) => {646 p!(out, str("[") {arr.expr()});647 for spec in arr.comp_specs() {648 p!(out, str(" ") {spec});649 }650 p!(out, str("]"));651 }652 Self::ExprImport(v) => {653 p!(out, {v.import_kind()} str(" ") {v.text()});654 }655 Self::ExprVar(n) => p!(out, { n.name() }),656 // Self::ExprLocal(l) => {657 // }658 Self::ExprIfThenElse(ite) => {659 p!(out, str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});660 if ite.else_kw_token().is_some() || ite.else_().is_some() {661 p!(out, str(" else ") {ite.else_().map(|t| t.expr())});662 }663 }664 Self::ExprFunction(f) => p!(out, str("function") {f.params_desc()} nl {f.expr()}),665 // Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),666 Self::ExprError(e) => p!(out, str("error ") {e.expr()}),667 Self::ExprLiteral(l) => {668 p!(out, { l.literal() });669 }670 }671 }672}673674impl Printable for SourceFile {675 fn print(&self, out: &mut PrintItems) {676 let before = trivia_before(677 self.syntax().clone(),678 self.expr()679 .map(|e| e.syntax().clone())680 .map(Into::into)681 .as_ref(),682 );683 let after = trivia_after(684 self.syntax().clone(),685 self.expr()686 .map(|e| e.syntax().clone())687 .map(Into::into)688 .as_ref(),689 );690 format_comments(&before, CommentLocation::AboveItem, out);691 p!(out, {self.expr()} nl);692 format_comments(&after, CommentLocation::EndOfItems, out);693 }694}695696pub struct FormatOptions {697 // 0 for hard tabs698 pub indent: u8,699}700pub fn format(input: &str, opts: &FormatOptions) -> Result<String, SnippetBuilder> {701 let (parsed, errors) = jrsonnet_rowan_parser::parse(input);702 if !errors.is_empty() {703 let mut builder = hi_doc::SnippetBuilder::new(input);704 for error in errors {705 builder706 .error(hi_doc::Text::fragment(707 format!("{:?}", error.error),708 Formatting::default(),709 ))710 .range(711 error.range.start().into()712 ..=(usize::from(error.range.end()) - 1).max(error.range.start().into()),713 )714 .build();715 }716 // let snippet = builder.build();717 return Err(builder);718 // It is possible to recover from this failure, but the output may be broken, as formatter is free to skip719 // ERROR rowan nodes.720 // Recovery needs to be enabled for LSP, though.721 }722 Ok(dprint_core::formatting::format(723 || {724 let mut out = PrintItems::new();725 parsed.print(&mut out);726 out727 },728 PrintOptions {729 indent_width: if opts.indent == 0 {730 // Reasonable max length for both 2 and 4 space sized tabs.731 3732 } else {733 opts.indent734 },735 max_width: 100,736 use_tabs: opts.indent == 0,737 new_line_text: "\n",738 },739 ))740}crates/jrsonnet-formatter/src/snapshots/jrsonnet_fmt__tests__complex_comments_snapshot.snapdiffbeforeafterboth--- a/crates/jrsonnet-formatter/src/snapshots/jrsonnet_fmt__tests__complex_comments_snapshot.snap
+++ /dev/null
@@ -1,53 +0,0 @@
----
-source: cmds/jrsonnet-fmt/src/tests.rs
-expression: "reformat(indoc!(\"{\n\t\t comments: {\n\t\t\t_: '',\n\t\t\t// Plain comment\n\t\t\ta: '',\n\n\t\t\t# Plain comment with empty line before\n\t\t\tb: '',\n\t\t\t/*Single-line multiline comment\n\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/**Single-line multiline doc comment\n\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/**Multiline doc\n\t\t\tComment\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/*\n\n\tMulti-line\n\n\tcomment\n\t\t\t*/\n\t\t\td: '',\n\n\t\t\te: '', // Inline comment\n\n\t\t\tk: '',\n\n\t\t\t// Text after everything\n\t\t },\n\t\t comments2: {\n\t\t\tk: '',\n\t\t\t// Text after everything, but no newline above\n\t\t },\n spacing: {\n a: '',\n\n b: '',\n },\n noSpacing: {\n a: '',\n b: '',\n },\n }\"))"
----
-{
- comments: {
- _: '',
- // Plain comment
- a: '',
-
- # Plain comment with empty line before
- b: '',
- /* Single-line multiline comment */
- c: '',
-
- /**
- * Single-line multiline doc comment
- */
- c: '',
-
- /**
- * Multiline doc
- * Comment
- */
- c: '',
-
- /*
- Multi-line
-
- comment
- */
- d: '',
-
- e: '', // Inline comment
-
- k: '',
-
- // Text after everything
- },
- comments2: {
- k: '',
- // Text after everything, but no newline above
- },
- spacing: {
- a: '',
-
- b: '',
- },
- noSpacing: {
- a: '',
- b: '',
- },
-}
crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__args.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__args.snap
@@ -0,0 +1,36 @@
+---
+source: crates/jrsonnet-formatter/src/tests.rs
+expression: "reformat(indoc!(\"\n\t\t\t{\n\t\t\t\tshort: aaa(1,2,3,4,5),\n\t\t\t\tlong: bbb(123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123),\n\t\t\t\tshort_in_long: bbb(aaa(1,2,3,4,5), 123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123),\n\t\t\t\tlong_in_short: aaa(1,2,3,4,5,bbb(123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123)),\n\t\t\t}\n\t\t\"))"
+---
+{
+ short: aaa(1, 2, 3, 4, 5),
+ long: bbb(
+ 123123123123123123123,
+ 12312312321123123123,
+ 123123123123312123123,
+ 123123123123123123312,
+ 123123123123312321123,
+ ),
+ short_in_long: bbb(
+ aaa(1, 2, 3, 4, 5),
+ 123123123123123123123,
+ 12312312321123123123,
+ 123123123123312123123,
+ 123123123123123123312,
+ 123123123123312321123,
+ ),
+ long_in_short: aaa(
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ bbb(
+ 123123123123123123123,
+ 12312312321123123123,
+ 123123123123312123123,
+ 123123123123123123312,
+ 123123123123312321123,
+ ),
+ ),
+}
crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__complex_comments.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__complex_comments.snap
@@ -0,0 +1,53 @@
+---
+source: crates/jrsonnet-formatter/src/tests.rs
+expression: "reformat(indoc!(\"{\n\t\t comments: {\n\t\t\t_: '',\n\t\t\t// Plain comment\n\t\t\ta: '',\n\n\t\t\t# Plain comment with empty line before\n\t\t\tb: '',\n\t\t\t/*Single-line multiline comment\n\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/**Single-line multiline doc comment\n\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/**Multiline doc\n\t\t\tComment\n\t\t\t*/\n\t\t\tc: '',\n\n\t\t\t/*\n\n\tMulti-line\n\n\tcomment\n\t\t\t*/\n\t\t\td: '',\n\n\t\t\te: '', // Inline comment\n\n\t\t\tk: '',\n\n\t\t\t// Text after everything\n\t\t },\n\t\t comments2: {\n\t\t\tk: '',\n\t\t\t// Text after everything, but no newline above\n\t\t },\n spacing: {\n a: '',\n\n b: '',\n },\n noSpacing: {\n a: '',\n b: '',\n },\n }\"))"
+---
+{
+ comments: {
+ _: '',
+ // Plain comment
+ a: '',
+
+ # Plain comment with empty line before
+ b: '',
+ /* Single-line multiline comment */
+ c: '',
+
+ /**
+ * Single-line multiline doc comment
+ */
+ c: '',
+
+ /**
+ * Multiline doc
+ * Comment
+ */
+ c: '',
+
+ /*
+ Multi-line
+
+ comment
+ */
+ d: '',
+
+ e: '', // Inline comment
+
+ k: '',
+
+ // Text after everything
+ },
+ comments2: {
+ k: '',
+ // Text after everything, but no newline above
+ },
+ spacing: {
+ a: '',
+
+ b: '',
+ },
+ noSpacing: {
+ a: '',
+ b: '',
+ },
+}
crates/jrsonnet-formatter/src/tests.rsdiffbeforeafterboth--- a/crates/jrsonnet-formatter/src/tests.rs
+++ b/crates/jrsonnet-formatter/src/tests.rs
@@ -22,7 +22,7 @@
}
#[test]
-fn complex_comments_snapshot() {
+fn complex_comments() {
insta::assert_snapshot!(reformat(indoc!(
"{
comments: {
@@ -77,3 +77,17 @@
}"
)));
}
+
+#[test]
+fn args() {
+ insta::assert_snapshot!(reformat(indoc!(
+ "
+ {
+ short: aaa(1,2,3,4,5),
+ long: bbb(123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123),
+ short_in_long: bbb(aaa(1,2,3,4,5), 123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123),
+ long_in_short: aaa(1,2,3,4,5,bbb(123123123123123123123,12312312321123123123,123123123123312123123,123123123123123123312,123123123123312321123)),
+ }
+ "
+ )));
+}