difftreelog
refactor remove p!(new:) constructor from macros
in: master
2 files changed
cmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/comments.rs
+++ b/cmds/jrsonnet-fmt/src/comments.rs
@@ -12,22 +12,19 @@
EndOfItems,
}
-#[must_use]
-pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation) -> PrintItems {
- let mut pi = p!(new:);
-
+pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation, out: &mut PrintItems) {
for c in comments {
let Ok(c) = c else {
let mut text = c.as_ref().unwrap_err() as &str;
while !text.is_empty() {
let pos = text.find(|c| c == '\n' || c == '\t').unwrap_or(text.len());
let sliced = &text[..pos];
- p!(pi: string(sliced.to_string()));
+ p!(out, string(sliced.to_string()));
text = &text[pos..];
if !text.is_empty() {
match text.as_bytes()[0] {
- b'\n' => p!(pi: nl),
- b'\t' => p!(pi: tab),
+ b'\n' => p!(out, nl),
+ b'\t' => p!(out, tab),
_ => unreachable!(),
}
text = &text[1..];
@@ -70,9 +67,9 @@
}
if lines.len() == 1 && !doc {
if matches!(loc, CommentLocation::ItemInline) {
- p!(pi: str(" "));
+ p!(out, str(" "));
}
- p!(pi: str("/* ") string(lines[0].trim().to_string()) str(" */") nl)
+ p!(out, str("/* ") string(lines[0].trim().to_string()) str(" */") nl)
} else if !lines.is_empty() {
fn common_ws_prefix<'a>(a: &'a str, b: &str) -> &'a str {
let offset = a
@@ -107,36 +104,36 @@
.to_string();
}
- p!(pi: str("/*"));
+ p!(out, str("/*"));
if doc {
- p!(pi: str("*"));
+ p!(out, str("*"));
}
- p!(pi: nl);
+ p!(out, nl);
for mut line in lines {
if doc {
- p!(pi: str(" *"));
+ p!(out, str(" *"));
}
if line.is_empty() {
- p!(pi: nl);
+ p!(out, nl);
} else {
if doc {
- p!(pi: str(" "));
+ p!(out, str(" "));
}
while let Some(new_line) = line.strip_prefix('\t') {
if doc {
- p!(pi: str(" "));
+ p!(out, str(" "));
} else {
- p!(pi: tab);
+ p!(out, tab);
}
line = new_line.to_string();
}
- p!(pi: string(line.to_string()) nl)
+ p!(out, string(line.to_string()) nl)
}
}
if doc {
- p!(pi: str(" "));
+ p!(out, str(" "));
}
- p!(pi: str("*/") nl)
+ p!(out, str("*/") nl)
}
}
// TODO: Keep common padding for multiple continous lines of single-line comments
@@ -157,27 +154,25 @@
// ```
TriviaKind::SingleLineHashComment => {
if matches!(loc, CommentLocation::ItemInline) {
- p!(pi: str(" "))
+ p!(out, str(" "))
}
- p!(pi: str("# ") string(c.text().strip_prefix('#').expect("hash comment starts with #").trim().to_string()));
+ p!(out, str("# ") string(c.text().strip_prefix('#').expect("hash comment starts with #").trim().to_string()));
if !matches!(loc, CommentLocation::ItemInline) {
- p!(pi: nl)
+ p!(out, nl)
}
}
TriviaKind::SingleLineSlashComment => {
if matches!(loc, CommentLocation::ItemInline) {
- p!(pi: str(" "))
+ p!(out, str(" "))
}
- p!(pi: str("// ") string(c.text().strip_prefix("//").expect("comment starts with //").trim().to_string()));
+ p!(out, str("// ") string(c.text().strip_prefix("//").expect("comment starts with //").trim().to_string()));
if !matches!(loc, CommentLocation::ItemInline) {
- p!(pi: nl)
+ p!(out, nl)
}
}
// Garbage in - garbage out
- TriviaKind::ErrorCommentTooShort => p!(pi: str("/*/")),
- TriviaKind::ErrorCommentUnterminated => p!(pi: string(c.text().to_string())),
+ TriviaKind::ErrorCommentTooShort => p!(out, str("/*/")),
+ TriviaKind::ErrorCommentUnterminated => p!(out, string(c.text().to_string())),
}
}
-
- pi
}
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth16 Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix, Text,16 Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix, Text,17 UnaryOperator, Visibility,17 UnaryOperator, Visibility,18 },18 },19 AstNode, AstToken, SyntaxToken,19 AstNode, AstToken as _, SyntaxToken,20};20};212122use crate::{22use crate::{30mod tests;30mod tests;313132pub trait Printable {32pub trait Printable {33 fn print(&self) -> PrintItems;33 fn print(&self, out: &mut PrintItems);34}34}353536macro_rules! pi {36macro_rules! pi {65 pi!(@s; $o: $($t)*);65 pi!(@s; $o: $($t)*);66 }};66 }};67 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{67 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{68 $o.extend($expr.print());68 $expr.print($o);69 pi!(@s; $o: $($t)*);69 pi!(@s; $o: $($t)*);70 }};70 }};71 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{71 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{89 (@s; $i:ident:) => {}89 (@s; $i:ident:) => {}90}90}91macro_rules! p {91macro_rules! p {92 (new: $($t:tt)*) => {92 ($o:ident, $($t:tt)*) => {93 pi!(@i; $($t)*)94 };95 ($o:ident: $($t:tt)*) => {96 pi!(@s; $o: $($t)*)93 pi!(@s; $o: $($t)*)97 };94 };98}95}103where100where104 P: Printable,101 P: Printable,105{102{106 fn print(&self) -> PrintItems {103 fn print(&self, out: &mut PrintItems) {107 if let Some(v) = self {104 if let Some(v) = self {108 v.print()105 v.print(out)109 } else {106 } else {110 p!(new: string(107 p!(111 format!(108 out,109 string(format!(112 "/*missing {}*/",110 "/*missing {}*/",113 type_name::<P>().replace("jrsonnet_rowan_parser::generated::nodes::", "")111 type_name::<P>().replace("jrsonnet_rowan_parser::generated::nodes::", "")114 ),112 ),)115 ))113 )116 }114 }117 }115 }118}116}119117120impl Printable for SyntaxToken {118impl Printable for SyntaxToken {121 fn print(&self) -> PrintItems {119 fn print(&self, out: &mut PrintItems) {122 p!(new: string(self.to_string()))120 p!(out, string(self.to_string()))123 }121 }124}122}125123126impl Printable for Text {124impl Printable for Text {127 fn print(&self) -> PrintItems {125 fn print(&self, out: &mut PrintItems) {128 p!(new: string(format!("{}", self)))126 p!(out, string(format!("{}", self)))129 }127 }130}128}131impl Printable for Number {129impl Printable for Number {132 fn print(&self) -> PrintItems {130 fn print(&self, out: &mut PrintItems) {133 p!(new: string(format!("{}", self)))131 p!(out, string(format!("{}", self)))134 }132 }135}133}136134137impl Printable for Name {135impl Printable for Name {138 fn print(&self) -> PrintItems {136 fn print(&self, out: &mut PrintItems) {139 p!(new: {self.ident_lit()})137 p!(out, { self.ident_lit() })140 }138 }141}139}142140143impl Printable for DestructRest {141impl Printable for DestructRest {144 fn print(&self) -> PrintItems {142 fn print(&self, out: &mut PrintItems) {145 let mut pi = p!(new: str("..."));143 p!(out, str("..."));146 if let Some(name) = self.into() {144 if let Some(name) = self.into() {147 p!(pi: {name});145 p!(out, { name });148 }146 }149 pi150 }147 }151}148}152149153impl Printable for Destruct {150impl Printable for Destruct {154 fn print(&self) -> PrintItems {151 fn print(&self, out: &mut PrintItems) {155 let mut pi = p!(new:);156 match self {152 match self {157 Destruct::DestructFull(f) => {153 Destruct::DestructFull(f) => {158 p!(pi: {f.name()})154 p!(out, { f.name() })159 }155 }160 Destruct::DestructSkip(_) => p!(pi: str("?")),156 Destruct::DestructSkip(_) => p!(out, str("?")),161 Destruct::DestructArray(a) => {157 Destruct::DestructArray(a) => {162 p!(pi: str("[") >i nl);158 p!(out, str("[") >i nl);163 for el in a.destruct_array_parts() {159 for el in a.destruct_array_parts() {164 match el {160 match el {165 DestructArrayPart::DestructArrayElement(e) => {161 DestructArrayPart::DestructArrayElement(e) => {166 p!(pi: {e.destruct()} str(",") nl)162 p!(out, {e.destruct()} str(",") nl)167 }163 }168 DestructArrayPart::DestructRest(d) => {164 DestructArrayPart::DestructRest(d) => {169 p!(pi: {d} str(",") nl)165 p!(out, {d} str(",") nl)170 }166 }171 }167 }172 }168 }173 p!(pi: <i str("]"));169 p!(out, <i str("]"));174 }170 }175 Destruct::DestructObject(o) => {171 Destruct::DestructObject(o) => {176 p!(pi: str("{") >i nl);172 p!(out, str("{") >i nl);177 for item in o.destruct_object_fields() {173 for item in o.destruct_object_fields() {178 p!(pi: {item.field()});174 p!(out, { item.field() });179 if let Some(des) = item.destruct() {175 if let Some(des) = item.destruct() {180 p!(pi: str(": ") {des})176 p!(out, str(": ") {des})181 }177 }182 if let Some(def) = item.expr() {178 if let Some(def) = item.expr() {183 p!(pi: str(" = ") {def});179 p!(out, str(" = ") {def});184 }180 }185 p!(pi: str(",") nl);181 p!(out, str(",") nl);186 }182 }187 if let Some(rest) = o.destruct_rest() {183 if let Some(rest) = o.destruct_rest() {188 p!(pi: {rest} nl)184 p!(out, {rest} nl)189 }185 }190 p!(pi: <i str("}"));186 p!(out, <i str("}"));191 }187 }192 }188 }193 pi194 }189 }195}190}196191197impl Printable for FieldName {192impl Printable for FieldName {198 fn print(&self) -> PrintItems {193 fn print(&self, out: &mut PrintItems) {199 match self {194 match self {200 FieldName::FieldNameFixed(f) => {195 FieldName::FieldNameFixed(f) => {201 if let Some(id) = f.id() {196 if let Some(id) = f.id() {202 p!(new: {id})197 p!(out, { id })203 } else if let Some(str) = f.text() {198 } else if let Some(str) = f.text() {204 p!(new: {str})199 p!(out, { str })205 } else {200 } else {206 p!(new: str("/*missing FieldName*/"))201 p!(out, str("/*missing FieldName*/"))207 }202 }208 }203 }209 FieldName::FieldNameDynamic(d) => {204 FieldName::FieldNameDynamic(d) => {210 p!(new: str("[") {d.expr()} str("]"))205 p!(out, str("[") {d.expr()} str("]"))211 }206 }212 }207 }213 }208 }214}209}215210216impl Printable for Visibility {211impl Printable for Visibility {217 fn print(&self) -> PrintItems {212 fn print(&self, out: &mut PrintItems) {218 p!(new: string(self.to_string()))213 p!(out, string(self.to_string()))219 }214 }220}215}221216222impl Printable for ObjLocal {217impl Printable for ObjLocal {223 fn print(&self) -> PrintItems {218 fn print(&self, out: &mut PrintItems) {224 p!(new: str("local ") {self.bind()})219 p!(out, str("local ") {self.bind()})225 }220 }226}221}227222228impl Printable for Assertion {223impl Printable for Assertion {229 fn print(&self) -> PrintItems {224 fn print(&self, out: &mut PrintItems) {230 let mut pi = p!(new: str("assert ") {self.condition()});225 p!(out, str("assert ") {self.condition()});231 if self.colon_token().is_some() || self.message().is_some() {226 if self.colon_token().is_some() || self.message().is_some() {232 p!(pi: str(": ") {self.message()})227 p!(out, str(": ") {self.message()})233 }228 }234 pi235 }229 }236}230}237231238impl Printable for ParamsDesc {232impl Printable for ParamsDesc {239 fn print(&self) -> PrintItems {233 fn print(&self, out: &mut PrintItems) {240 let mut pi = p!(new: str("(") >i nl);234 p!(out, str("(") >i nl);241 for param in self.params() {235 for param in self.params() {242 p!(pi: {param.destruct()});236 p!(out, { param.destruct() });243 if param.assign_token().is_some() || param.expr().is_some() {237 if param.assign_token().is_some() || param.expr().is_some() {244 p!(pi: str(" = ") {param.expr()})238 p!(out, str(" = ") {param.expr()})245 }239 }246 p!(pi: str(",") nl)240 p!(out, str(",") nl)247 }241 }248 p!(pi: <i str(")"));242 p!(out, <i str(")"));249 pi250 }243 }251}244}252impl Printable for ArgsDesc {245impl Printable for ArgsDesc {253 fn print(&self) -> PrintItems {246 fn print(&self, out: &mut PrintItems) {254 let mut pi = p!(new: str("(") >i nl);247 p!(out, str("(") >i nl);255 for arg in self.args() {248 for arg in self.args() {256 if arg.name().is_some() || arg.assign_token().is_some() {249 if arg.name().is_some() || arg.assign_token().is_some() {257 p!(pi: {arg.name()} str(" = "));250 p!(out, {arg.name()} str(" = "));258 }251 }259 p!(pi: {arg.expr()} str(",") nl)252 p!(out, {arg.expr()} str(",") nl)260 }253 }261 p!(pi: <i str(")"));254 p!(out, <i str(")"));262 pi263 }255 }264}256}265impl Printable for SliceDesc {257impl Printable for SliceDesc {266 fn print(&self) -> PrintItems {258 fn print(&self, out: &mut PrintItems) {267 let mut pi = p!(new: str("["));259 p!(out, str("["));268 if self.from().is_some() {260 if self.from().is_some() {269 p!(pi: {self.from()});261 p!(out, { self.from() });270 }262 }271 p!(pi: str(":"));263 p!(out, str(":"));272 if self.end().is_some() {264 if self.end().is_some() {273 p!(pi: {self.end().map(|e|e.expr())})265 p!(out, { self.end().map(|e| e.expr()) })274 }266 }275 // Keep only one : in case if we don't need step267 // Keep only one : in case if we don't need step276 if self.step().is_some() {268 if self.step().is_some() {277 p!(pi: str(":") {self.step().map(|e|e.expr())});269 p!(out, str(":") {self.step().map(|e|e.expr())});278 }270 }279 p!(pi: str("]"));271 p!(out, str("]"));280 pi281 }272 }282}273}283274284impl Printable for Member {275impl Printable for Member {285 fn print(&self) -> PrintItems {276 fn print(&self, out: &mut PrintItems) {286 match self {277 match self {287 Member::MemberBindStmt(b) => {278 Member::MemberBindStmt(b) => {288 p!(new: {b.obj_local()})279 p!(out, { b.obj_local() })289 }280 }290 Member::MemberAssertStmt(ass) => {281 Member::MemberAssertStmt(ass) => {291 p!(new: {ass.assertion()})282 p!(out, { ass.assertion() })292 }283 }293 Member::MemberFieldNormal(n) => {284 Member::MemberFieldNormal(n) => {294 p!(new: {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()})285 p!(out, {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()})295 }286 }296 Member::MemberFieldMethod(m) => {287 Member::MemberFieldMethod(m) => {297 p!(new: {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()})288 p!(out, {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()})298 }289 }299 }290 }300 }291 }301}292}302293303impl Printable for ObjBody {294impl Printable for ObjBody {304 fn print(&self) -> PrintItems {295 fn print(&self, out: &mut PrintItems) {305 match self {296 match self {306 ObjBody::ObjBodyComp(l) => {297 ObjBody::ObjBodyComp(l) => {307 let (children, mut end_comments) = children_between::<Member>(298 let (children, mut end_comments) = children_between::<Member>(318 None,309 None,319 );310 );320 let trailing_for_comp = end_comments.extract_trailing();311 let trailing_for_comp = end_comments.extract_trailing();321 let mut pi = p!(new: str("{") >i nl);312 p!(out, str("{") >i nl);322 for mem in children.into_iter() {313 for mem in children.into_iter() {323 if mem.should_start_with_newline {314 if mem.should_start_with_newline {324 p!(pi: nl);315 p!(out, nl);325 }316 }326 p!(pi: items(format_comments(&mem.before_trivia, CommentLocation::AboveItem)));317 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);327 p!(pi: {mem.value} str(","));318 p!(out, {mem.value} str(","));328 p!(pi: items(format_comments(&mem.inline_trivia, CommentLocation::ItemInline)));319 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);329 p!(pi: nl)320 p!(out, nl)330 }321 }331322332 if end_comments.should_start_with_newline {323 if end_comments.should_start_with_newline {333 p!(pi: nl);324 p!(out, nl);334 }325 }335 p!(pi: items(format_comments(&end_comments.trivia, CommentLocation::EndOfItems)));326 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);336327337 let (compspecs, end_comments) = children_between::<CompSpec>(328 let (compspecs, end_comments) = children_between::<CompSpec>(338 l.syntax().clone(),329 l.syntax().clone(),347 );338 );348 for mem in compspecs.into_iter() {339 for mem in compspecs.into_iter() {349 if mem.should_start_with_newline {340 if mem.should_start_with_newline {350 p!(pi: nl);341 p!(out, nl);351 }342 }352 p!(pi: items(format_comments(&mem.before_trivia, CommentLocation::AboveItem)));343 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);353 p!(pi: {mem.value});344 p!(out, { mem.value });354 p!(pi: items(format_comments(&mem.inline_trivia, CommentLocation::ItemInline)));345 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);355 }346 }356 if end_comments.should_start_with_newline {347 if end_comments.should_start_with_newline {357 p!(pi: nl);348 p!(out, nl);358 }349 }359 p!(pi: items(format_comments(&end_comments.trivia, CommentLocation::EndOfItems)));350 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);360351361 p!(pi: nl <i str("}"));352 p!(out, nl <i str("}"));362 pi363 }353 }364 ObjBody::ObjBodyMemberList(l) => {354 ObjBody::ObjBodyMemberList(l) => {365 let (children, end_comments) = children_between::<Member>(355 let (children, end_comments) = children_between::<Member>(369 None,359 None,370 );360 );371 if children.is_empty() && end_comments.is_empty() {361 if children.is_empty() && end_comments.is_empty() {372 return p!(new: str("{ }"));362 p!(out, str("{ }"));363 return;373 }364 }374 let mut pi = p!(new: str("{") >i nl);365 p!(out, str("{") >i nl);375 for (i, mem) in children.into_iter().enumerate() {366 for (i, mem) in children.into_iter().enumerate() {376 if mem.should_start_with_newline && i != 0 {367 if mem.should_start_with_newline && i != 0 {377 p!(pi: nl);368 p!(out, nl);378 }369 }379 p!(pi: items(format_comments(&mem.before_trivia, CommentLocation::AboveItem)));370 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);380 p!(pi: {mem.value} str(","));371 p!(out, {mem.value} str(","));381 p!(pi: items(format_comments(&mem.inline_trivia, CommentLocation::ItemInline)));372 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);382 p!(pi: nl)373 p!(out, nl)383 }374 }384375385 if end_comments.should_start_with_newline {376 if end_comments.should_start_with_newline {386 p!(pi: nl);377 p!(out, nl);387 }378 }388 p!(pi: items(format_comments(&end_comments.trivia, CommentLocation::EndOfItems)));379 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);389 p!(pi: <i str("}"));380 p!(out, <i str("}"));390 pi391 }381 }392 }382 }393 }383 }394}384}395impl Printable for UnaryOperator {385impl Printable for UnaryOperator {396 fn print(&self) -> PrintItems {386 fn print(&self, out: &mut PrintItems) {397 p!(new: string(self.text().to_string()))387 p!(out, string(self.text().to_string()))398 }388 }399}389}400impl Printable for BinaryOperator {390impl Printable for BinaryOperator {401 fn print(&self) -> PrintItems {391 fn print(&self, out: &mut PrintItems) {402 p!(new: string(self.text().to_string()))392 p!(out, string(self.text().to_string()))403 }393 }404}394}405impl Printable for Bind {395impl Printable for Bind {406 fn print(&self) -> PrintItems {396 fn print(&self, out: &mut PrintItems) {407 match self {397 match self {408 Bind::BindDestruct(d) => {398 Bind::BindDestruct(d) => {409 p!(new: {d.into()} str(" = ") {d.value()})399 p!(out, {d.into()} str(" = ") {d.value()})410 }400 }411 Bind::BindFunction(f) => {401 Bind::BindFunction(f) => {412 p!(new: {f.name()} {f.params()} str(" = ") {f.value()})402 p!(out, {f.name()} {f.params()} str(" = ") {f.value()})413 }403 }414 }404 }415 }405 }416}406}417impl Printable for Literal {407impl Printable for Literal {418 fn print(&self) -> PrintItems {408 fn print(&self, out: &mut PrintItems) {419 p!(new: string(self.syntax().to_string()))409 p!(out, string(self.syntax().to_string()))420 }410 }421}411}422impl Printable for ImportKind {412impl Printable for ImportKind {423 fn print(&self) -> PrintItems {413 fn print(&self, out: &mut PrintItems) {424 p!(new: string(self.syntax().to_string()))414 p!(out, string(self.syntax().to_string()))425 }415 }426}416}427impl Printable for ForSpec {417impl Printable for ForSpec {428 fn print(&self) -> PrintItems {418 fn print(&self, out: &mut PrintItems) {429 p!(new: str("for ") {self.bind()} str(" in ") {self.expr()})419 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()})430 }420 }431}421}432impl Printable for IfSpec {422impl Printable for IfSpec {433 fn print(&self) -> PrintItems {423 fn print(&self, out: &mut PrintItems) {434 p!(new: str("if ") {self.expr()})424 p!(out, str("if ") {self.expr()})435 }425 }436}426}437impl Printable for CompSpec {427impl Printable for CompSpec {438 fn print(&self) -> PrintItems {428 fn print(&self, out: &mut PrintItems) {439 match self {429 match self {440 CompSpec::ForSpec(f) => f.print(),430 CompSpec::ForSpec(f) => f.print(out),441 CompSpec::IfSpec(i) => i.print(),431 CompSpec::IfSpec(i) => i.print(out),442 }432 }443 }433 }444}434}445impl Printable for Expr {435impl Printable for Expr {446 fn print(&self) -> PrintItems {436 fn print(&self, out: &mut PrintItems) {447 let mut o = p!(new:);448 let (stmts, ending) = children_between::<Stmt>(437 let (stmts, _ending) = children_between::<Stmt>(449 self.syntax().clone(),438 self.syntax().clone(),450 None,439 None,451 self.expr_base()440 self.expr_base()457 None,446 None,458 );447 );459 for stmt in stmts {448 for stmt in stmts {460 p!(o: {stmt.value});449 p!(out, { stmt.value });461 }450 }462 p!(o: {self.expr_base()});451 p!(out, { self.expr_base() });463 let (suffixes, ending) = children_between::<Suffix>(452 let (suffixes, _ending) = children_between::<Suffix>(464 self.syntax().clone(),453 self.syntax().clone(),465 self.expr_base()454 self.expr_base()466 .as_ref()455 .as_ref()472 None,461 None,473 );462 );474 for suffix in suffixes {463 for suffix in suffixes {475 p!(o: {suffix.value});464 p!(out, { suffix.value });476 }465 }477 o478 }466 }479}467}480impl Printable for Suffix {468impl Printable for Suffix {481 fn print(&self) -> PrintItems {469 fn print(&self, out: &mut PrintItems) {482 let mut o = p!(new:);483 match self {470 match self {484 Suffix::SuffixIndex(i) => {471 Suffix::SuffixIndex(i) => {485 if i.question_mark_token().is_some() {472 if i.question_mark_token().is_some() {486 p!(o: str("?"));473 p!(out, str("?"));487 }474 }488 p!(o: str(".") {i.index()});475 p!(out, str(".") {i.index()});489 }476 }490 Suffix::SuffixIndexExpr(e) => {477 Suffix::SuffixIndexExpr(e) => {491 if e.question_mark_token().is_some() {478 if e.question_mark_token().is_some() {492 p!(o: str(".?"));479 p!(out, str(".?"));493 }480 }494 p!(o: str("[") {e.index()} str("]"))481 p!(out, str("[") {e.index()} str("]"))495 }482 }496 Suffix::SuffixSlice(d) => {483 Suffix::SuffixSlice(d) => {497 p!(o: {d.slice_desc()})484 p!(out, { d.slice_desc() })498 }485 }499 Suffix::SuffixApply(a) => {486 Suffix::SuffixApply(a) => {500 p!(o: {a.args_desc()})487 p!(out, { a.args_desc() })501 }488 }502 }489 }503 o504 }490 }505}491}506impl Printable for Stmt {492impl Printable for Stmt {507 fn print(&self) -> PrintItems {493 fn print(&self, out: &mut PrintItems) {508 match self {494 match self {509 Stmt::StmtLocal(l) => {495 Stmt::StmtLocal(l) => {510 let mut pi = p!(new:);511 let (binds, end_comments) = children_between::<Bind>(496 let (binds, end_comments) = children_between::<Bind>(512 l.syntax().clone(),497 l.syntax().clone(),513 l.local_kw_token().map(Into::into).as_ref(),498 l.local_kw_token().map(Into::into).as_ref(),516 );501 );517 if binds.len() == 1 {502 if binds.len() == 1 {518 let bind = &binds[0];503 let bind = &binds[0];519 p!(pi: items(format_comments(&bind.before_trivia, CommentLocation::AboveItem)));504 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);520 p!(pi: str("local ") {bind.value});505 p!(out, str("local ") {bind.value});521 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?506 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?522 } else {507 } else {523 p!(pi: str("local") >i nl);508 p!(out,str("local") >i nl);524 for bind in binds {509 for bind in binds {525 if bind.should_start_with_newline {510 if bind.should_start_with_newline {526 p!(pi: nl);511 p!(out, nl);527 }512 }528 p!(pi: items(format_comments(&bind.before_trivia, CommentLocation::AboveItem)));513 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);529 p!(pi: {bind.value} str(","));514 p!(out, {bind.value} str(","));530 p!(pi: items(format_comments(&bind.inline_trivia, CommentLocation::ItemInline)) nl);515 format_comments(&bind.inline_trivia, CommentLocation::ItemInline, out);531 }516 }532 if end_comments.should_start_with_newline {517 if end_comments.should_start_with_newline {533 p!(pi: nl)518 p!(out, nl)534 }519 }535 p!(pi: items(format_comments(&end_comments.trivia, CommentLocation::EndOfItems)));520 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);536 p!(pi: <i);521 p!(out,<i);537 }522 }538 p!(pi: str(";") nl);523 p!(out,str(";") nl);539 pi540 }524 }541 Stmt::StmtAssert(a) => {525 Stmt::StmtAssert(a) => {542 p!(new: {a.assertion()} str(";") nl)526 p!(out, {a.assertion()} str(";") nl)543 }527 }544 }528 }545 }529 }546}530}547impl Printable for ExprBase {531impl Printable for ExprBase {548 fn print(&self) -> PrintItems {532 fn print(&self, out: &mut PrintItems) {549 match self {533 match self {550 Self::ExprBinary(b) => {534 Self::ExprBinary(b) => {551 p!(new: {b.lhs_work()} str(" ") {b.binary_operator()} str(" ") {b.rhs_work()})535 p!(out, {b.lhs_work()} str(" ") {b.binary_operator()} str(" ") {b.rhs_work()})552 }536 }553 Self::ExprUnary(u) => p!(new: {u.unary_operator()} {u.rhs()}),537 Self::ExprUnary(u) => p!(out, {u.unary_operator()} {u.rhs()}),554 // Self::ExprSlice(s) => {538 // Self::ExprSlice(s) => {555 // p!(new: {s.expr()} {s.slice_desc()})539 // p!(new: {s.expr()} {s.slice_desc()})556 // }540 // }561 // Self::ExprApply(a) => {545 // Self::ExprApply(a) => {562 // let mut pi = p!(new: {a.expr()} {a.args_desc()});546 // let mut pi = p!(new: {a.expr()} {a.args_desc()});563 // if a.tailstrict_kw_token().is_some() {547 // if a.tailstrict_kw_token().is_some() {564 // p!(pi: str(" tailstrict"));548 // p!(out,str(" tailstrict"));565 // }549 // }566 // pi550 // pi567 // }551 // }568 Self::ExprObjExtend(ex) => {552 Self::ExprObjExtend(ex) => {569 p!(new: {ex.lhs_work()} str(" ") {ex.rhs_work()})553 p!(out, {ex.lhs_work()} str(" ") {ex.rhs_work()})570 }554 }571 Self::ExprParened(p) => {555 Self::ExprParened(p) => {572 p!(new: str("(") {p.expr()} str(")"))556 p!(out, str("(") {p.expr()} str(")"))573 }557 }574 Self::ExprString(s) => p!(new: {s.text()}),558 Self::ExprString(s) => p!(out, { s.text() }),575 Self::ExprNumber(n) => p!(new: {n.number()}),559 Self::ExprNumber(n) => p!(out, { n.number() }),576 Self::ExprArray(a) => {560 Self::ExprArray(a) => {577 let mut pi = p!(new: str("[") >i nl);561 p!(out, str("[") >i nl);578 for el in a.exprs() {562 for el in a.exprs() {579 p!(pi: {el} str(",") nl);563 p!(out, {el} str(",") nl);580 }564 }581 p!(pi: <i str("]"));565 p!(out, <i str("]"));582 pi583 }566 }584 Self::ExprObject(obj) => {567 Self::ExprObject(obj) => {585 p!(new: {obj.obj_body()})568 p!(out, { obj.obj_body() })586 }569 }587 Self::ExprArrayComp(arr) => {570 Self::ExprArrayComp(arr) => {588 let mut pi = p!(new: str("[") {arr.expr()});571 p!(out, str("[") {arr.expr()});589 for spec in arr.comp_specs() {572 for spec in arr.comp_specs() {590 p!(pi: str(" ") {spec});573 p!(out, str(" ") {spec});591 }574 }592 p!(pi: str("]"));575 p!(out, str("]"));593 pi594 }576 }595 Self::ExprImport(v) => {577 Self::ExprImport(v) => {596 p!(new: {v.import_kind()} str(" ") {v.text()})578 p!(out, {v.import_kind()} str(" ") {v.text()})597 }579 }598 Self::ExprVar(n) => p!(new: {n.name()}),580 Self::ExprVar(n) => p!(out, { n.name() }),599 // Self::ExprLocal(l) => {581 // Self::ExprLocal(l) => {600 // }582 // }601 Self::ExprIfThenElse(ite) => {583 Self::ExprIfThenElse(ite) => {602 let mut pi =584 p!(out, str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});603 p!(new: str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});604 if ite.else_kw_token().is_some() || ite.else_().is_some() {585 if ite.else_kw_token().is_some() || ite.else_().is_some() {605 p!(pi: str(" else ") {ite.else_().map(|t| t.expr())})586 p!(out, str(" else ") {ite.else_().map(|t| t.expr())})606 }587 }607 pi608 }588 }609 Self::ExprFunction(f) => p!(new: str("function") {f.params_desc()} nl {f.expr()}),589 Self::ExprFunction(f) => p!(out, str("function") {f.params_desc()} nl {f.expr()}),610 // Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),590 // Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),611 Self::ExprError(e) => p!(new: str("error ") {e.expr()}),591 Self::ExprError(e) => p!(out, str("error ") {e.expr()}),612 Self::ExprLiteral(l) => {592 Self::ExprLiteral(l) => {613 p!(new: {l.literal()})593 p!(out, { l.literal() })614 }594 }615 }595 }616 }596 }617}597}618598619impl Printable for SourceFile {599impl Printable for SourceFile {620 fn print(&self) -> PrintItems {600 fn print(&self, out: &mut PrintItems) {621 let mut pi = p!(new:);622 let before = trivia_before(601 let before = trivia_before(623 self.syntax().clone(),602 self.syntax().clone(),624 self.expr()603 self.expr()633 .map(Into::into)612 .map(Into::into)634 .as_ref(),613 .as_ref(),635 );614 );636 p!(pi: items(format_comments(&before, CommentLocation::AboveItem)));615 format_comments(&before, CommentLocation::AboveItem, out);637 p!(pi: {self.expr()} nl);616 p!(out, {self.expr()} nl);638 p!(pi: items(format_comments(&after, CommentLocation::EndOfItems)));617 format_comments(&after, CommentLocation::EndOfItems, out)639 pi640 }618 }641}619}642620671 return None;649 return None;672 }650 }673 Some(dprint_core::formatting::format(651 Some(dprint_core::formatting::format(674 || parsed.print(),652 || {653 let mut out = PrintItems::new();654 parsed.print(&mut out);655 out656 },675 PrintOptions {657 PrintOptions {676 indent_width: if opts.indent == 0 {658 indent_width: if opts.indent == 0 {677 // Reasonable max length for both 2 and 4 space sized tabs.659 // Reasonable max length for both 2 and 4 space sized tabs.726 #[error("persist: {0}")]708 #[error("persist: {0}")]727 Persist(#[from] tempfile::PersistError),709 Persist(#[from] tempfile::PersistError),728 #[error("parsing failed, refusing to reformat corrupted input")]710 #[error("parsing failed, refusing to reformat corrupted input")]729 ParseError,711 Parse,730}712}731713732fn main_result() -> Result<(), Error> {714fn main_result() -> Result<(), Error> {763 },745 },764 },746 },765 ) else {747 ) else {766 return Err(Error::ParseError);748 return Err(Error::Parse);767 };749 };768 tmp = reformatted.trim().to_owned();750 tmp = reformatted.trim().to_owned();769 if formatted == tmp {751 if formatted == tmp {