difftreelog
feat(fmt) preserve comments in locals
in: master
3 files changed
cmds/jrsonnet-fmt/src/children.rsdiffbeforeafterboth40 }40 }41 let mut iter = node.children_with_tokens().peekable();41 let mut iter = node.children_with_tokens().peekable();42 while iter.peek() != start {42 while iter.peek() != start {43 // println!("Skipped {}");44 dbg!(&iter.next());43 iter.next();45 }44 }46 dbg!(&iter.next());45 iter.next();47 let mut out = Vec::new();46 let mut out = Vec::new();48 for item in iter {47 for item in iter {49 if let Some(trivia) = item.as_token().cloned().and_then(Trivia::cast) {48 if let Some(trivia) = item.as_token().cloned().and_then(Trivia::cast) {59 out58 out60}59}6061pub fn trivia_between(62 node: SyntaxNode,63 start: Option<&SyntaxElement>,64 end: Option<&SyntaxElement>,65) -> ChildTrivia {66 let mut iter = node.children_with_tokens().peekable();67 while iter.peek() != start {68 iter.next();69 }70 iter.next();7172 let loose = start.is_none() || end.is_none();7374 let mut out = Vec::new();75 for item in iter.take_while(|i| Some(i) != end) {76 if let Some(trivia) = item.as_token().cloned().and_then(Trivia::cast) {77 out.push(trivia);78 } else if loose {79 break;80 } else {81 assert!(82 TS![, ;].contains(item.kind()) || item.kind() == ERROR,83 "silently eaten token: {:?}",84 item.kind()85 )86 }87 }88 out89}619062pub fn children_between<T: AstNode + Debug>(91pub fn children_between<T: AstNode + Debug>(63 node: SyntaxNode,92 node: SyntaxNode,cmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth12 EndOfItems,12 EndOfItems,13}13}141415#[must_use]15pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation) -> PrintItems {16pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation) -> PrintItems {16 let mut pi = p!(new:);17 let mut pi = p!(new:);1718cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth13};13};141415use crate::{15use crate::{16 children::{should_start_with_newline, trivia_after},16 children::{should_start_with_newline, trivia_after, trivia_between},17 comments::{format_comments, CommentLocation},17 comments::{format_comments, CommentLocation},18};18};1919436 }436 }437 Expr::ExprVar(n) => p!(new: {n.name()}),437 Expr::ExprVar(n) => p!(new: {n.name()}),438 Expr::ExprLocal(l) => {438 Expr::ExprLocal(l) => {439 let mut pi = p!(new: str("local") >i nl);439 let mut pi = p!(new:);440 let (binds, end_comments) = children_between::<Bind>(441 l.syntax().clone(),442 l.local_kw_token().map(Into::into).as_ref(),443 l.semi_token().map(Into::into).as_ref(),444 );445 if binds.len() == 1 {446 let bind = &binds[0];447 p!(pi: items(format_comments(&bind.before_trivia, CommentLocation::AboveItem)));448 p!(pi: str("local ") {bind.value});449 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?450 } else {451 p!(pi: str("local") >i nl);440 for bind in l.binds() {452 for bind in binds {453 if bind.needs_newline_above() {454 p!(pi: nl);455 }456 p!(pi: items(format_comments(&bind.before_trivia, CommentLocation::AboveItem)));441 p!(pi: {bind} str(",") nl);457 p!(pi: {bind.value} str(";"));442 }458 p!(pi: items(format_comments(&bind.inline_trivia, CommentLocation::ItemInline)) nl);459 }460 // TODO: needs_newline_above end_comments461 p!(pi: items(format_comments(&end_comments, CommentLocation::EndOfItems)));462 p!(pi: <i);463 }464 p!(pi: str(";") nl);465466 let expr_comments = trivia_between(467 l.syntax().clone(),468 l.semi_token().map(Into::into).as_ref(),469 l.expr()470 .map(|e| e.syntax().clone())471 .map(Into::into)472 .as_ref(),473 );474 p!(pi: items(format_comments(&expr_comments, CommentLocation::AboveItem)));475476 // TODO: needs_newline_above expr443 p!(pi: <i str(";") nl {l.expr()});477 p!(pi: {l.expr()});444 pi478 pi445 }479 }446 Expr::ExprIfThenElse(ite) => {480 Expr::ExprIfThenElse(ite) => {487521488fn main() {522fn main() {489 let (parsed, _errors) = jrsonnet_rowan_parser::parse(523 let (parsed, _errors) = jrsonnet_rowan_parser::parse(490 r#"524 r#"491525492526493 # Edit me!527 # Edit me!494 local b = import "b.libsonnet"; # comment528 local b = import "b.libsonnet"; # comment495 local a = import "a.libsonnet";529 local a = import "a.libsonnet";496530497 local f(x,y)=x+y;531 local f(x,y)=x+y;498532499 local {a: [b, ..., c], d, ...e} = null;533 local {a: [b, ..., c], d, ...e} = null;500534501 local ass = assert false : false; false;535 local ass = assert false : false; false;502536503 local fn = function(a, b, c = 3) 4;537 local fn = function(a, b, c = 3) 4;504538505 local comp = [a for b in c if d == e];539 local comp = [a for b in c if d == e];506 local ocomp = {[k]: 1 for k in v};540 local ocomp = {[k]: 1 for k in v};507541508 local ? = skip;542 local ? = skip;509543510 local intr = $intrinsic(test);544 local intr = $intrinsic(test);511 local intrId = $intrinsicId;545 local intrId = $intrinsicId;512 local intrThisFile = $intrinsicThisFile;546 local intrThisFile = $intrinsicThisFile;513547514 local ie = a[expr];548 local ie = a[expr];515549516 local unary = !a;550 local unary = !a;517551518 local Template = {z: "foo"};552 local553 // I am comment554 singleLocalWithItemComment = 1,555 ;556557 // Comment between local and expression558559 local560 a = 1, // Inline561 // Comment above b562 b = 4,563564 // c needs some space565 c = 5,566567 // Comment after everything568 ;569570571 local Template = {z: "foo"};519572520 {573 {521 local574 local522575523 h = 3,576 h = 3,524 assert self.a == 1577 assert self.a == 1525578526 : "error",579 : "error",527 "f": ((((((3)))))) ,580 "f": ((((((3)))))) ,528 "g g":581 "g g":529 f(4,2),582 f(4,2),530 arr: [[583 arr: [[531 1, 2,584 1, 2,532 ],585 ],533 3,586 3,534 {587 {535 b: {588 b: {536 c: {589 c: {537 k: [16]590 k: [16]538 }591 }539 }592 }540 }593 }541 ],594 ],542 m: a[1::],595 m: a[1::],543 m: b[::],596 m: b[::],544597545 comments: {598 comments: {546 _: '',599 _: '',547 // Plain comment600 // Plain comment548 a: '',601 a: '',549602550 # Plain comment with empty line before603 # Plain comment with empty line before551 b: '',604 b: '',552 /*Single-line multiline comment605 /*Single-line multiline comment553606554 */607 */555 c: '',608 c: '',556609557 /**Single-line multiline doc comment610 /**Single-line multiline doc comment558611559 */612 */560 c: '',613 c: '',561614562 /**multiline doc comment615 /**multiline doc comment563 s616 s564 */617 */565 c: '',618 c: '',566619567 /*620 /*568621569 Multi-line622 Multi-line570623571 comment624 comment572 */625 */573 d: '',626 d: '',574627575 e: '', // Inline comment628 e: '', // Inline comment576629577 k: '',630 k: '',578631579 // Text after everything632 // Text after everything580 },633 },581 comments2: {634 comments2: {582 k: '',635 k: '',583 // Text after everything, but no newline above636 // Text after everything, but no newline above584 },637 },585 k: if a == b then638 k: if a == b then586639587640588 2641 2589642590 else Template {}643 else Template {}591 } + Template644 } + Template592645593646594 // Comment after everything647 // Comment after everything595"#,648"#,596 );649 );597650598 // dbg!(errors);651 // dbg!(errors);