difftreelog
refactor demote ::, ::: from full tokens to multiple colon tokens
in: master
21 files changed
crates/jrsonnet-formatter/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-formatter/Cargo.toml
+++ b/crates/jrsonnet-formatter/Cargo.toml
@@ -11,6 +11,7 @@
hi-doc.workspace = true
indoc.workspace = true
insta.workspace = true
+jrsonnet-lexer = { version = "0.5.0-pre97", path = "../jrsonnet-lexer" }
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,6 condition_resolvers::true_resolver,7 ir_helpers::{new_line_group, with_indent},8 ConditionResolver, ConditionResolverContext, LineNumber, PrintItems, PrintOptions,9};10use hi_doc::{Formatting, SnippetBuilder};11use jrsonnet_lexer::collect_lexed_str_block;12use jrsonnet_rowan_parser::{13 nodes::{14 Arg, ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,15 DestructRest, Expr, ExprArray, ExprBase, FieldName, ForSpec, IfSpec, ImportKind, Literal,16 Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix,17 Text, TextKind, UnaryOperator, Visibility,18 },19 AstNode, AstToken as _, SyntaxToken,20};2122use crate::{23 children::{trivia_after, Child, EndingComments},24 comments::{format_comments, CommentLocation},25};2627mod children;28mod comments;29mod tests;3031fn with_indent_eoi(cond: ConditionResolver, o: PrintItems, e: EndingComments) -> PrintItems {32 let end_comments_items = {33 let mut items = PrintItems::new();34 if e.should_start_with_newline {35 p!(&mut items, nl);36 }37 format_comments(&e.trivia, CommentLocation::EndOfItems, &mut items);38 items.into_rc_path()39 };40 let items = new_line_group(pi!(@i; items(o) items(end_comments_items.into()))).into_rc_path();4142 let indented = with_indent(pi!(@i; nl items(items.into())));4344 pi!(@i; if_else("indented body", cond, items(indented))(str(" ") items(items.into())))45}4647pub trait Printable {48 fn print(&self, out: &mut PrintItems);49}5051macro_rules! pi {52 (@i; $($t:tt)*) => {{53 #[allow(unused_mut)]54 let mut o = dprint_core::formatting::PrintItems::new();55 pi!(@s; o: $($t)*);56 o57 }};58 (@s; $o:ident: str($e:expr $(,)?) $($t:tt)*) => {{59 $o.push_string($e.to_owned());60 pi!(@s; $o: $($t)*);61 }};62 (@s; $o:ident: string($e:expr $(,)?) $($t:tt)*) => {{63 $o.push_string($e);64 pi!(@s; $o: $($t)*);65 }};66 (@s; $o:ident: nl $($t:tt)*) => {{67 $o.push_signal(dprint_core::formatting::Signal::NewLine);68 pi!(@s; $o: $($t)*);69 }};70 (@s; $o:ident: sonl $($t:tt)*) => {{71 $o.push_signal(dprint_core::formatting::Signal::SpaceOrNewLine);72 pi!(@s; $o: $($t)*);73 }};74 (@s; $o:ident: tab $($t:tt)*) => {{75 $o.push_signal(dprint_core::formatting::Signal::Tab);76 pi!(@s; $o: $($t)*);77 }};78 (@s; $o:ident: >i $($t:tt)*) => {{79 $o.push_signal(dprint_core::formatting::Signal::StartIndent);80 pi!(@s; $o: $($t)*);81 }};82 (@s; $o:ident: <i $($t:tt)*) => {{83 $o.push_signal(dprint_core::formatting::Signal::FinishIndent);84 pi!(@s; $o: $($t)*);85 }};86 (@s; $o:ident: >ii $($t:tt)*) => {{87 $o.push_signal(dprint_core::formatting::Signal::StartIgnoringIndent);88 pi!(@s; $o: $($t)*);89 }};90 (@s; $o:ident: <ii $($t:tt)*) => {{91 $o.push_signal(dprint_core::formatting::Signal::FinishIgnoringIndent);92 pi!(@s; $o: $($t)*);93 }};94 (@s; $o:ident: info($v:expr) $($t:tt)*) => {{95 $o.push_info($v);96 pi!(@s; $o: $($t)*);97 }};98 (@s; $o:ident: ln_anchor($v:expr) $($t:tt)*) => {{99 $o.push_anchor(LineNumberAnchor::new($v));100 pi!(@s; $o: $($t)*);101 }};102 (@s; $o:ident: if($s:literal, $cond:expr, $($i:tt)*) $($t:tt)*) => {{103 $o.push_condition(dprint_core::formatting::conditions::if_true(104 $s,105 $cond.clone(),106 {107 let mut o = PrintItems::new();108 p!(o, $($i)*);109 o110 },111 ));112 pi!(@s; $o: $($t)*);113 }};114 (@s; $o:ident: if_else($s:literal, $cond:expr, $($i:tt)*)($($e:tt)+) $($t:tt)*) => {{115 $o.push_condition(dprint_core::formatting::conditions::if_true_or(116 $s,117 $cond.clone(),118 {119 let mut o = PrintItems::new();120 p!(o, $($i)*);121 o122 },123 {124 let mut o = PrintItems::new();125 p!(o, $($e)*);126 o127 },128 ));129 pi!(@s; $o: $($t)*);130 }};131 (@s; $o:ident: if_not($s:literal, $cond:expr, $($e:tt)*) $($t:tt)*) => {{132 $o.push_condition(dprint_core::formatting::conditions::if_true_or(133 $s,134 $cond.clone(),135 {136 let o = PrintItems::new();137 o138 },139 {140 let mut o = PrintItems::new();141 p!(o, $($e)*);142 o143 },144 ));145 pi!(@s; $o: $($t)*);146 }};147 (@s; $o:ident: {$expr:expr} $($t:tt)*) => {{148 $expr.print($o);149 pi!(@s; $o: $($t)*);150 }};151 (@s; $o:ident: items($expr:expr) $($t:tt)*) => {{152 $o.extend($expr);153 pi!(@s; $o: $($t)*);154 }};155 (@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{156 if $e {157 pi!(@s; $o: $($then)*);158 }159 pi!(@s; $o: $($t)*);160 }};161 (@s; $o:ident: ifelse ($e:expr)($($then:tt)*)($($else:tt)*) $($t:tt)*) => {{162 if $e {163 pi!(@s; $o: $($then)*);164 } else {165 pi!(@s; $o: $($else)*);166 }167 pi!(@s; $o: $($t)*);168 }};169 (@s; $i:ident:) => {}170}171macro_rules! p {172 ($o:ident, $($t:tt)*) => {173 pi!(@s; $o: $($t)*)174 };175 (&mut $o:ident, $($t:tt)*) => {176 let om = &mut $o;177 pi!(@s; om: $($t)*)178 };179}180pub(crate) use p;181pub(crate) use pi;182183impl<P> Printable for Option<P>184where185 P: Printable,186{187 fn print(&self, out: &mut PrintItems) {188 if let Some(v) = self {189 v.print(out);190 } else {191 p!(192 out,193 string(format!(194 "/*missing {}*/",195 type_name::<P>().replace("jrsonnet_rowan_parser::generated::nodes::", "")196 ),)197 );198 }199 }200}201202impl Printable for SyntaxToken {203 fn print(&self, out: &mut PrintItems) {204 p!(out, string(self.to_string()));205 }206}207208impl Printable for Text {209 fn print(&self, out: &mut PrintItems) {210 if matches!(self.kind(), TextKind::StringBlock) {211 let text = self.text();212 let mut text = collect_lexed_str_block(&text[3..])213 .expect("formatting is not performed on code with parsing errors");214215 if text.truncate && text.lines.ends_with(&[""]) {216 text.truncate = false;217 text.lines.pop();218 }219220 p!(out, str("|||"));221 if text.truncate {222 p!(out, str("-"));223 }224 p!(out, nl > i);225 for ele in text.lines {226 if ele.is_empty() {227 p!(out, >ii nl <ii);228 } else {229 p!(out, string(ele.to_string()) nl);230 }231 }232 p!(out, <i str("|||"));233234 return;235 }236 p!(out, string(format!("{}", self)));237 }238}239impl Printable for Number {240 fn print(&self, out: &mut PrintItems) {241 p!(out, string(format!("{}", self)));242 }243}244245impl Printable for Name {246 fn print(&self, out: &mut PrintItems) {247 p!(out, { self.ident_lit() });248 }249}250251impl Printable for DestructRest {252 fn print(&self, out: &mut PrintItems) {253 p!(out, str("..."));254 if let Some(name) = self.into() {255 p!(out, { name });256 }257 }258}259260impl Printable for Destruct {261 fn print(&self, out: &mut PrintItems) {262 match self {263 Self::DestructFull(f) => {264 p!(out, { f.name() });265 }266 Self::DestructSkip(_) => p!(out, str("?")),267 Self::DestructArray(a) => {268 p!(out, str("[") >i nl);269 for el in a.destruct_array_parts() {270 match el {271 DestructArrayPart::DestructArrayElement(e) => {272 p!(out, {e.destruct()} str(",") nl);273 }274 DestructArrayPart::DestructRest(d) => {275 p!(out, {d} str(",") nl);276 }277 }278 }279 p!(out, <i str("]"));280 }281 Self::DestructObject(o) => {282 p!(out, str("{") >i nl);283 for item in o.destruct_object_fields() {284 p!(out, { item.field() });285 if let Some(des) = item.destruct() {286 p!(out, str(": ") {des});287 }288 if let Some(def) = item.expr() {289 p!(out, str(" = ") {def});290 }291 p!(out, str(",") nl);292 }293 if let Some(rest) = o.destruct_rest() {294 p!(out, {rest} nl);295 }296 p!(out, <i str("}"));297 }298 }299 }300}301302impl Printable for FieldName {303 fn print(&self, out: &mut PrintItems) {304 match self {305 Self::FieldNameFixed(f) => {306 if let Some(id) = f.id() {307 p!(out, { id });308 } else if let Some(str) = f.text() {309 p!(out, { str });310 } else {311 p!(out, str("/*missing FieldName*/"));312 }313 }314 Self::FieldNameDynamic(d) => {315 p!(out, str("[") {d.expr()} str("]"));316 }317 }318 }319}320321impl Printable for Visibility {322 fn print(&self, out: &mut PrintItems) {323 p!(out, string(self.to_string()));324 }325}326327impl Printable for ObjLocal {328 fn print(&self, out: &mut PrintItems) {329 p!(out, str("local ") {self.bind()});330 }331}332333impl Printable for Assertion {334 fn print(&self, out: &mut PrintItems) {335 p!(out, str("assert ") {self.condition()});336 if self.colon_token().is_some() || self.message().is_some() {337 p!(out, str(": ") {self.message()});338 }339 }340}341342impl Printable for ParamsDesc {343 fn print(&self, out: &mut PrintItems) {344 p!(out, str("(") >i nl);345 for param in self.params() {346 p!(out, { param.destruct() });347 if param.assign_token().is_some() || param.expr().is_some() {348 p!(out, str(" = ") {param.expr()});349 }350 p!(out, str(",") nl);351 }352 p!(out, <i str(")"));353 }354}355impl Printable for ArgsDesc {356 fn print(&self, out: &mut PrintItems) {357 fn gen_args(children: Vec<Child<Arg>>, multi_line: ConditionResolver) -> PrintItems {358 let mut out = PrintItems::new();359360 let mut args = children.into_iter().peekable();361 while let Some(ele) = args.next() {362 if ele.should_start_with_newline {363 p!(out, nl);364 }365 format_comments(&ele.before_trivia, CommentLocation::AboveItem, &mut out);366 let arg = ele.value;367 if arg.name().is_some() || arg.assign_token().is_some() {368 p!(&mut out, {arg.name()} str(" = "));369 }370 p!(&mut out, { arg.expr() });371 let has_more = args.peek().is_some();372 if has_more {373 p!(out, str(","));374 } else {375 p!(out, if("trailing comma", multi_line, str(",")));376 }377 format_comments(&ele.inline_trivia, CommentLocation::ItemInline, &mut out);378 if has_more {379 p!(out, if_else("arg separator", multi_line, nl)(sonl));380 }381 }382383 out384 }385386 let start = LineNumber::new("args start line");387 let end = LineNumber::new("args end line");388 let multi_line = Rc::new(move |condition_context: &mut ConditionResolverContext| {389 is_multiple_lines(condition_context, start, end)390 });391392 let (children, end_comments) = children_between::<Arg>(393 self.syntax().clone(),394 self.l_paren_token().map(Into::into).as_ref(),395 self.r_paren_token().map(Into::into).as_ref(),396 None,397 );398399 let args_items = new_line_group(gen_args(children, multi_line.clone())).into_rc_path();400 let args_indented = with_indent(pi!(@i; nl items(args_items.into())));401402 p!(out, str("(") info(start));403 p!(out, if_else("args body", multi_line, items(args_indented) nl)(items(args_items.into())));404 if end_comments.should_start_with_newline {405 p!(out, nl);406 }407 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);408 p!(out, str(")") info(end));409 }410}411impl Printable for SliceDesc {412 fn print(&self, out: &mut PrintItems) {413 p!(out, str("["));414 if self.from().is_some() {415 p!(out, { self.from() });416 }417 p!(out, str(":"));418 if self.end().is_some() {419 p!(out, { self.end().map(|e| e.expr()) });420 }421 // Keep only one : in case if we don't need step422 if self.step().is_some() {423 p!(out, str(":") {self.step().map(|e|e.expr())});424 }425 p!(out, str("]"));426 }427}428429impl Printable for Member {430 fn print(&self, out: &mut PrintItems) {431 match self {432 Self::MemberBindStmt(b) => {433 p!(out, { b.obj_local() });434 }435 Self::MemberAssertStmt(ass) => {436 p!(out, { ass.assertion() });437 }438 Self::MemberFieldNormal(n) => {439 p!(out, {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()});440 }441 Self::MemberFieldMethod(m) => {442 p!(out, {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()});443 }444 }445 }446}447448impl Printable for ObjBody {449 #[allow(clippy::too_many_lines)]450 fn print(&self, out: &mut PrintItems) {451 match self {452 Self::ObjBodyComp(l) => {453 let (children, mut end_comments) = children_between::<Member>(454 l.syntax().clone(),455 l.l_brace_token().map(Into::into).as_ref(),456 Some(457 &(l.comp_specs()458 .next()459 .expect("at least one spec is defined")460 .syntax()461 .clone())462 .into(),463 ),464 None,465 );466 let trailing_for_comp = end_comments.extract_trailing();467 p!(out, str("{") >i nl);468 for mem in children {469 if mem.should_start_with_newline {470 p!(out, nl);471 }472 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);473 p!(out, {mem.value} str(","));474 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);475 p!(out, nl);476 }477478 if end_comments.should_start_with_newline {479 p!(out, nl);480 }481 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);482483 let (compspecs, end_comments) = children_between::<CompSpec>(484 l.syntax().clone(),485 l.member_comps()486 .last()487 .map(|m| m.syntax().clone())488 .map(Into::into)489 .or_else(|| l.l_brace_token().map(Into::into))490 .as_ref(),491 l.r_brace_token().map(Into::into).as_ref(),492 Some(trailing_for_comp),493 );494 for mem in compspecs {495 if mem.should_start_with_newline {496 p!(out, nl);497 }498 format_comments(&mem.before_trivia, CommentLocation::AboveItem, out);499 p!(out, { mem.value });500 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, out);501 }502 if end_comments.should_start_with_newline {503 p!(out, nl);504 }505 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);506507 p!(out, nl <i str("}"));508 }509 Self::ObjBodyMemberList(l) => {510 fn gen_members(511 children: Vec<Child<Member>>,512 multi_line: ConditionResolver,513 ) -> PrintItems {514 let mut out = PrintItems::new();515 let mut members = children.into_iter().peekable();516 while let Some(mem) = members.next() {517 if mem.should_start_with_newline {518 p!(out, nl);519 }520 format_comments(&mem.before_trivia, CommentLocation::AboveItem, &mut out);521 p!(&mut out, { mem.value });522 let has_more = members.peek().is_some();523 if has_more {524 p!(out, str(","));525 } else {526 p!(out, if("trailing comma", multi_line, str(",")));527 }528 format_comments(&mem.inline_trivia, CommentLocation::ItemInline, &mut out);529 p!(out, if_else("member separator", multi_line, nl)(sonl));530 }531 out532 }533534 let (children, end_comments) = children_between::<Member>(535 l.syntax().clone(),536 l.l_brace_token().map(Into::into).as_ref(),537 l.r_brace_token().map(Into::into).as_ref(),538 None,539 );540 if children.is_empty() && end_comments.is_empty() {541 p!(out, str("{ }"));542 return;543 }544545 let source_is_multiline = children.iter().any(|c| c.triggers_multiline)546 || end_comments.should_start_with_newline;547548 let start = LineNumber::new("obj start line");549 let end = LineNumber::new("obj end line");550 let multi_line: ConditionResolver = if source_is_multiline {551 true_resolver()552 } else {553 Rc::new(move |ctx: &mut ConditionResolverContext| {554 is_multiple_lines(ctx, start, end)555 })556 };557558 let members_items =559 new_line_group(gen_members(children, multi_line.clone())).into_rc_path();560561 let members = with_indent_eoi(multi_line, members_items.into(), end_comments);562563 p!(out, str("{") info(start));564 p!(out, items(members));565 p!(out, str("}") info(end));566 }567 }568 }569}570impl Printable for UnaryOperator {571 fn print(&self, out: &mut PrintItems) {572 p!(out, string(self.text().to_string()));573 }574}575impl Printable for BinaryOperator {576 fn print(&self, out: &mut PrintItems) {577 p!(out, string(self.text().to_string()));578 }579}580impl Printable for Bind {581 fn print(&self, out: &mut PrintItems) {582 match self {583 Self::BindDestruct(d) => {584 p!(out, {d.into()} str(" = ") {d.value()});585 }586 Self::BindFunction(f) => {587 p!(out, {f.name()} {f.params()} str(" = ") {f.value()});588 }589 }590 }591}592impl Printable for Literal {593 fn print(&self, out: &mut PrintItems) {594 p!(out, string(self.syntax().to_string()));595 }596}597impl Printable for ImportKind {598 fn print(&self, out: &mut PrintItems) {599 p!(out, string(self.syntax().to_string()));600 }601}602impl Printable for ForSpec {603 fn print(&self, out: &mut PrintItems) {604 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()});605 }606}607impl Printable for IfSpec {608 fn print(&self, out: &mut PrintItems) {609 p!(out, str("if ") {self.expr()});610 }611}612impl Printable for CompSpec {613 fn print(&self, out: &mut PrintItems) {614 match self {615 Self::ForSpec(f) => f.print(out),616 Self::IfSpec(i) => i.print(out),617 }618 }619}620impl Printable for Expr {621 fn print(&self, out: &mut PrintItems) {622 let (stmts, _ending) = children_between::<Stmt>(623 self.syntax().clone(),624 None,625 self.expr_base()626 .as_ref()627 .map(ExprBase::syntax)628 .cloned()629 .map(Into::into)630 .as_ref(),631 None,632 );633 for stmt in stmts {634 p!(out, { stmt.value });635 }636 p!(out, { self.expr_base() });637 let (suffixes, _ending) = children_between::<Suffix>(638 self.syntax().clone(),639 self.expr_base()640 .as_ref()641 .map(ExprBase::syntax)642 .cloned()643 .map(Into::into)644 .as_ref(),645 None,646 None,647 );648 for suffix in suffixes {649 p!(out, { suffix.value });650 }651 }652}653impl Printable for Suffix {654 fn print(&self, out: &mut PrintItems) {655 match self {656 Self::SuffixIndex(i) => {657 if i.question_mark_token().is_some() {658 p!(out, str("?"));659 }660 p!(out, str(".") {i.index()});661 }662 Self::SuffixIndexExpr(e) => {663 if e.question_mark_token().is_some() {664 p!(out, str(".?"));665 }666 p!(out, str("[") {e.index()} str("]"));667 }668 Self::SuffixSlice(d) => {669 p!(out, { d.slice_desc() });670 }671 Self::SuffixApply(a) => {672 p!(out, { a.args_desc() });673 }674 }675 }676}677impl Printable for Stmt {678 fn print(&self, out: &mut PrintItems) {679 match self {680 Self::StmtLocal(l) => {681 let (binds, end_comments) = children_between::<Bind>(682 l.syntax().clone(),683 l.local_kw_token().map(Into::into).as_ref(),684 l.semi_token().map(Into::into).as_ref(),685 None,686 );687 if binds.len() == 1 {688 let bind = &binds[0];689 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);690 p!(out, str("local ") {bind.value});691 // TODO: keep end_comments, child.inline_trivia somehow, force multiple locals formatting in case of presence?692 } else {693 p!(out,str("local") >i nl);694 for bind in binds {695 if bind.should_start_with_newline {696 p!(out, nl);697 }698 format_comments(&bind.before_trivia, CommentLocation::AboveItem, out);699 p!(out, {bind.value} str(","));700 format_comments(&bind.inline_trivia, CommentLocation::ItemInline, out);701 p!(out, nl);702 }703 if end_comments.should_start_with_newline {704 p!(out, nl);705 }706 format_comments(&end_comments.trivia, CommentLocation::EndOfItems, out);707 p!(out,<i);708 }709 p!(out,str(";") nl);710 }711 Self::StmtAssert(a) => {712 p!(out, {a.assertion()} str(";") nl);713 }714 }715 }716}717718impl Printable for ExprArray {719 fn print(&self, out: &mut PrintItems) {720 fn gen_elements(children: Vec<Child<Expr>>, multi_line: ConditionResolver) -> PrintItems {721 let mut out = PrintItems::new();722 let mut els = children.into_iter().peekable();723 while let Some(el) = els.next() {724 if el.should_start_with_newline {725 p!(out, nl);726 }727 format_comments(&el.before_trivia, CommentLocation::AboveItem, &mut out);728 p!(&mut out, { el.value });729 let has_more = els.peek().is_some();730 if has_more {731 p!(out, str(","));732 } else {733 p!(out, if("trailing comma", multi_line, str(",")));734 }735 format_comments(&el.inline_trivia, CommentLocation::ItemInline, &mut out);736 p!(out, if_else("element separator", multi_line, nl)(sonl));737 }738 out739 }740741 let (children, end_comments) = children_between::<Expr>(742 self.syntax().clone(),743 self.l_brack_token().map(Into::into).as_ref(),744 self.r_brack_token().map(Into::into).as_ref(),745 None,746 );747 if children.is_empty() && end_comments.is_empty() {748 p!(out, str("[ ]"));749 return;750 }751752 let source_is_multiline =753 children.iter().any(|c| c.triggers_multiline) || end_comments.should_start_with_newline;754755 let start = LineNumber::new("arr start line");756 let end = LineNumber::new("arr end line");757 let multi_line: ConditionResolver = if source_is_multiline {758 true_resolver()759 } else {760 Rc::new(move |ctx: &mut ConditionResolverContext| is_multiple_lines(ctx, start, end))761 };762763 let els_items = new_line_group(gen_elements(children, multi_line.clone())).into_rc_path();764765 let els = with_indent_eoi(multi_line, els_items.into(), end_comments);766767 p!(out, str("[") info(start) items(els) str("]") info(end));768 }769}770771impl Printable for ExprBase {772 fn print(&self, out: &mut PrintItems) {773 match self {774 Self::ExprBinary(b) => {775 p!(out, {b.lhs()} str(" ") {b.binary_operator()} str(" ") {b.rhs()});776 }777 Self::ExprUnary(u) => p!(out, {u.unary_operator()} {u.rhs()}),778 // Self::ExprSlice(s) => {779 // p!(new: {s.expr()} {s.slice_desc()})780 // }781 // Self::ExprIndex(i) => {782 // p!(new: {i.expr()} str(".") {i.index()})783 // }784 // Self::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")),785 // Self::ExprApply(a) => {786 // let mut pi = p!(new: {a.expr()} {a.args_desc()});787 // if a.tailstrict_kw_token().is_some() {788 // p!(out,str(" tailstrict"));789 // }790 // pi791 // }792 Self::ExprObjExtend(ex) => {793 p!(out, {ex.lhs()} str(" ") {ex.rhs()});794 }795 Self::ExprParened(p) => {796 p!(out, str("(") {p.expr()} str(")"));797 }798 Self::ExprString(s) => p!(out, { s.text() }),799 Self::ExprNumber(n) => p!(out, { n.number() }),800 Self::ExprArray(a) => {801 p!(out, { a });802 }803 Self::ExprObject(obj) => {804 p!(out, { obj.obj_body() });805 }806 Self::ExprArrayComp(arr) => {807 p!(out, str("[") {arr.expr()});808 for spec in arr.comp_specs() {809 p!(out, str(" ") {spec});810 }811 p!(out, str("]"));812 }813 Self::ExprImport(v) => {814 p!(out, {v.import_kind()} str(" ") {v.text()});815 }816 Self::ExprVar(n) => p!(out, { n.name() }),817 // Self::ExprLocal(l) => {818 // }819 Self::ExprIfThenElse(ite) => {820 p!(out, str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});821 if ite.else_kw_token().is_some() || ite.else_().is_some() {822 p!(out, str(" else ") {ite.else_().map(|t| t.expr())});823 }824 }825 Self::ExprFunction(f) => p!(out, str("function") {f.params_desc()} nl {f.expr()}),826 // Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),827 Self::ExprError(e) => p!(out, str("error ") {e.expr()}),828 Self::ExprLiteral(l) => {829 p!(out, { l.literal() });830 }831 }832 }833}834835impl Printable for SourceFile {836 fn print(&self, out: &mut PrintItems) {837 let before = trivia_before(838 self.syntax().clone(),839 self.expr()840 .map(|e| e.syntax().clone())841 .map(Into::into)842 .as_ref(),843 );844 let after = trivia_after(845 self.syntax().clone(),846 self.expr()847 .map(|e| e.syntax().clone())848 .map(Into::into)849 .as_ref(),850 );851 format_comments(&before, CommentLocation::AboveItem, out);852 p!(out, {self.expr()} nl);853 format_comments(&after, CommentLocation::EndOfItems, out);854 }855}856857pub struct FormatOptions {858 // 0 for hard tabs, otherwise number of spaces859 pub indent: u8,860}861862#[allow(863 clippy::result_large_err,864 reason = "TODO: there should be an intermediate representation for such reports"865)]866pub fn format(input: &str, opts: &FormatOptions) -> Result<String, SnippetBuilder> {867 let (parsed, errors) = jrsonnet_rowan_parser::parse(input);868 if !errors.is_empty() {869 let mut builder = hi_doc::SnippetBuilder::new(input);870 for error in errors {871 builder872 .error(hi_doc::Text::fragment(873 format!("{:?}", error.error),874 Formatting::default(),875 ))876 .range(877 error.range.start().into()878 ..=(usize::from(error.range.end()) - 1).max(error.range.start().into()),879 )880 .build();881 }882 // let snippet = builder.build();883 return Err(builder);884 // It is possible to recover from this failure, but the output may be broken, as formatter is free to skip885 // ERROR rowan nodes.886 // Recovery needs to be enabled for LSP, though.887 }888 Ok(dprint_core::formatting::format(889 || {890 let mut out = PrintItems::new();891 parsed.print(&mut out);892 out893 },894 PrintOptions {895 indent_width: if opts.indent == 0 {896 // Reasonable max length for both 2 and 4 space sized tabs.897 3898 } else {899 opts.indent900 },901 max_width: 100,902 use_tabs: opts.indent == 0,903 new_line_text: "\n",904 },905 ))906}crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__snapshots@visibilities.jsonnet.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-formatter/src/snapshots/jrsonnet_formatter__tests__snapshots@visibilities.jsonnet.snap
@@ -0,0 +1,6 @@
+---
+source: crates/jrsonnet-formatter/src/tests.rs
+expression: reformat(&input)
+input_file: crates/jrsonnet-formatter/src/tests/visibilities.jsonnet
+---
+{ normal: 1, hide:: 2, unhide::: 3 }
crates/jrsonnet-formatter/src/tests/visibilities.jsonnetdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-formatter/src/tests/visibilities.jsonnet
@@ -0,0 +1 @@
+{normal:1,hide::2,unhide:::3}
crates/jrsonnet-lexer/src/generated/syntax_kinds.rsdiffbeforeafterboth--- a/crates/jrsonnet-lexer/src/generated/syntax_kinds.rs
+++ b/crates/jrsonnet-lexer/src/generated/syntax_kinds.rs
@@ -72,10 +72,6 @@
R_BRACE,
#[token(":")]
COLON,
- #[token("::")]
- COLONCOLON,
- #[token(":::")]
- COLONCOLONCOLON,
#[token(";")]
SEMI,
#[token(".")]
@@ -188,11 +184,10 @@
match self {
OR | NULL_COAELSE | AND | BIT_OR | BIT_XOR | BIT_AND | EQ | NE | LT | GT | LE | GE
| LHS | RHS | PLUS | MINUS | MUL | DIV | MODULO | NOT | BIT_NOT | L_BRACK | R_BRACK
- | L_PAREN | R_PAREN | L_BRACE | R_BRACE | COLON | COLONCOLON | COLONCOLONCOLON
- | SEMI | DOT | DOTDOTDOT | COMMA | DOLLAR | ASSIGN | QUESTION_MARK | TAILSTRICT_KW
- | LOCAL_KW | IMPORTSTR_KW | IMPORTBIN_KW | IMPORT_KW | IF_KW | THEN_KW | ELSE_KW
- | FUNCTION_KW | ERROR_KW | IN_KW | NULL_KW | TRUE_KW | FALSE_KW | SELF_KW
- | SUPER_KW | FOR_KW | ASSERT_KW => true,
+ | L_PAREN | R_PAREN | L_BRACE | R_BRACE | COLON | SEMI | DOT | DOTDOTDOT | COMMA
+ | DOLLAR | ASSIGN | QUESTION_MARK | TAILSTRICT_KW | LOCAL_KW | IMPORTSTR_KW
+ | IMPORTBIN_KW | IMPORT_KW | IF_KW | THEN_KW | ELSE_KW | FUNCTION_KW | ERROR_KW
+ | IN_KW | NULL_KW | TRUE_KW | FALSE_KW | SELF_KW | SUPER_KW | FOR_KW | ASSERT_KW => true,
_ => false,
}
}
@@ -205,6 +200,6 @@
}
}
#[macro_export]
-macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [??] => { $ crate :: SyntaxKind :: NULL_COAELSE } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLONCOLON } ; [:::] => { $ crate :: SyntaxKind :: COLONCOLONCOLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } }
+macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [??] => { $ crate :: SyntaxKind :: NULL_COAELSE } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } }
#[allow(unused_imports)]
pub use T;
crates/jrsonnet-lexer/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-lexer/src/lib.rs
+++ b/crates/jrsonnet-lexer/src/lib.rs
@@ -5,4 +5,6 @@
#[derive(Clone, Copy, Debug)]
pub struct Span(pub u32, pub u32);
+pub use generated::syntax_kinds::SyntaxKind;
pub use lex::{Lexeme, Lexer};
+pub use string_block::{collect_lexed_str_block, CollectStrBlock};
crates/jrsonnet-rowan-parser/jsonnet.ungramdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/jsonnet.ungram
+++ b/crates/jrsonnet-rowan-parser/jsonnet.ungram
@@ -44,8 +44,8 @@
UnaryOperator
rhs:Expr
ExprObjExtend =
- Expr
- Expr
+ lhs:Expr
+ rhs:Expr
ExprParened =
'('
Expr
@@ -209,9 +209,7 @@
| FieldNameDynamic
Visibility =
- ':::'
-| '::'
-| ':'
+ ':' v1:':'? v2:':'?
Literal =
'null'
crates/jrsonnet-rowan-parser/src/generated/nodes.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/generated/nodes.rs
+++ b/crates/jrsonnet-rowan-parser/src/generated/nodes.rs
@@ -228,9 +228,12 @@
pub(crate) syntax: SyntaxNode,
}
impl ExprObjExtend {
- pub fn expr(&self) -> Option<Expr> {
+ pub fn lhs(&self) -> Option<Expr> {
support::children(&self.syntax).next()
}
+ pub fn rhs(&self) -> Option<Expr> {
+ support::children(&self.syntax).nth(1usize)
+ }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -562,7 +565,7 @@
support::token(&self.syntax, T![+])
}
pub fn visibility(&self) -> Option<Visibility> {
- support::token_child(&self.syntax)
+ support::children(&self.syntax).next()
}
pub fn expr(&self) -> Option<Expr> {
support::children(&self.syntax).next()
@@ -570,6 +573,16 @@
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Visibility {
+ pub(crate) syntax: SyntaxNode,
+}
+impl Visibility {
+ pub fn colon_token(&self) -> Option<SyntaxToken> {
+ support::token(&self.syntax, T![:])
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MemberFieldMethod {
pub(crate) syntax: SyntaxNode,
}
@@ -581,7 +594,7 @@
support::children(&self.syntax).next()
}
pub fn visibility(&self) -> Option<Visibility> {
- support::token_child(&self.syntax)
+ support::children(&self.syntax).next()
}
pub fn expr(&self) -> Option<Expr> {
support::children(&self.syntax).next()
@@ -999,19 +1012,6 @@
ImportstrKw,
ImportbinKw,
ImportKw,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Visibility {
- syntax: SyntaxToken,
- kind: VisibilityKind,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum VisibilityKind {
- Coloncoloncolon,
- Coloncolon,
- Colon,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1627,6 +1627,21 @@
&self.syntax
}
}
+impl AstNode for Visibility {
+ fn can_cast(kind: SyntaxKind) -> bool {
+ kind == VISIBILITY
+ }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode {
+ &self.syntax
+ }
+}
impl AstNode for MemberFieldMethod {
fn can_cast(kind: SyntaxKind) -> bool {
kind == MEMBER_FIELD_METHOD
@@ -2640,45 +2655,6 @@
std::fmt::Display::fmt(self.syntax(), f)
}
}
-impl AstToken for Visibility {
- fn can_cast(kind: SyntaxKind) -> bool {
- VisibilityKind::can_cast(kind)
- }
- fn cast(syntax: SyntaxToken) -> Option<Self> {
- let kind = VisibilityKind::cast(syntax.kind())?;
- Some(Visibility { syntax, kind })
- }
- fn syntax(&self) -> &SyntaxToken {
- &self.syntax
- }
-}
-impl VisibilityKind {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- COLONCOLONCOLON | COLONCOLON | COLON => true,
- _ => false,
- }
- }
- pub fn cast(kind: SyntaxKind) -> Option<Self> {
- let res = match kind {
- COLONCOLONCOLON => Self::Coloncoloncolon,
- COLONCOLON => Self::Coloncolon,
- COLON => Self::Colon,
- _ => return None,
- };
- Some(res)
- }
-}
-impl Visibility {
- pub fn kind(&self) -> VisibilityKind {
- self.kind
- }
-}
-impl std::fmt::Display for Visibility {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- std::fmt::Display::fmt(self.syntax(), f)
- }
-}
impl AstToken for Trivia {
fn can_cast(kind: SyntaxKind) -> bool {
TriviaKind::can_cast(kind)
@@ -3015,6 +2991,11 @@
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for Visibility {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for MemberFieldMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs
+++ b/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs
@@ -44,8 +44,6 @@
L_BRACE,
R_BRACE,
COLON,
- COLONCOLON,
- COLONCOLONCOLON,
SEMI,
DOT,
DOTDOTDOT,
@@ -142,6 +140,7 @@
OBJ_LOCAL,
MEMBER_ASSERT_STMT,
MEMBER_FIELD_NORMAL,
+ VISIBILITY,
MEMBER_FIELD_METHOD,
FIELD_NAME_FIXED,
FIELD_NAME_DYNAMIC,
@@ -174,7 +173,6 @@
TEXT,
NUMBER,
IMPORT_KIND,
- VISIBILITY,
TRIVIA,
CUSTOM_ERROR,
#[doc(hidden)]
@@ -186,11 +184,10 @@
match self {
OR | NULL_COAELSE | AND | BIT_OR | BIT_XOR | BIT_AND | EQ | NE | LT | GT | LE | GE
| LHS | RHS | PLUS | MINUS | MUL | DIV | MODULO | NOT | BIT_NOT | L_BRACK | R_BRACK
- | L_PAREN | R_PAREN | L_BRACE | R_BRACE | COLON | COLONCOLON | COLONCOLONCOLON
- | SEMI | DOT | DOTDOTDOT | COMMA | DOLLAR | ASSIGN | QUESTION_MARK | TAILSTRICT_KW
- | LOCAL_KW | IMPORTSTR_KW | IMPORTBIN_KW | IMPORT_KW | IF_KW | THEN_KW | ELSE_KW
- | FUNCTION_KW | ERROR_KW | IN_KW | NULL_KW | TRUE_KW | FALSE_KW | SELF_KW
- | SUPER_KW | FOR_KW | ASSERT_KW => true,
+ | L_PAREN | R_PAREN | L_BRACE | R_BRACE | COLON | SEMI | DOT | DOTDOTDOT | COMMA
+ | DOLLAR | ASSIGN | QUESTION_MARK | TAILSTRICT_KW | LOCAL_KW | IMPORTSTR_KW
+ | IMPORTBIN_KW | IMPORT_KW | IF_KW | THEN_KW | ELSE_KW | FUNCTION_KW | ERROR_KW
+ | IN_KW | NULL_KW | TRUE_KW | FALSE_KW | SELF_KW | SUPER_KW | FOR_KW | ASSERT_KW => true,
_ => false,
}
}
@@ -198,7 +195,7 @@
match self {
SUFFIX | BIND | STMT | OBJ_BODY | COMP_SPEC | EXPR_BASE | MEMBER_COMP | MEMBER
| FIELD_NAME | DESTRUCT | DESTRUCT_ARRAY_PART | BINARY_OPERATOR | UNARY_OPERATOR
- | LITERAL | TEXT | NUMBER | IMPORT_KIND | VISIBILITY | TRIVIA | CUSTOM_ERROR => true,
+ | LITERAL | TEXT | NUMBER | IMPORT_KIND | TRIVIA | CUSTOM_ERROR => true,
_ => false,
}
}
@@ -211,6 +208,6 @@
}
}
#[macro_export]
-macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [??] => { $ crate :: SyntaxKind :: NULL_COAELSE } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLONCOLON } ; [:::] => { $ crate :: SyntaxKind :: COLONCOLONCOLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } }
+macro_rules ! T { [||] => { $ crate :: SyntaxKind :: OR } ; [??] => { $ crate :: SyntaxKind :: NULL_COAELSE } ; [&&] => { $ crate :: SyntaxKind :: AND } ; [|] => { $ crate :: SyntaxKind :: BIT_OR } ; [^] => { $ crate :: SyntaxKind :: BIT_XOR } ; [&] => { $ crate :: SyntaxKind :: BIT_AND } ; [==] => { $ crate :: SyntaxKind :: EQ } ; [!=] => { $ crate :: SyntaxKind :: NE } ; [<] => { $ crate :: SyntaxKind :: LT } ; [>] => { $ crate :: SyntaxKind :: GT } ; [<=] => { $ crate :: SyntaxKind :: LE } ; [>=] => { $ crate :: SyntaxKind :: GE } ; [<<] => { $ crate :: SyntaxKind :: LHS } ; [>>] => { $ crate :: SyntaxKind :: RHS } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [*] => { $ crate :: SyntaxKind :: MUL } ; [/] => { $ crate :: SyntaxKind :: DIV } ; [%] => { $ crate :: SyntaxKind :: MODULO } ; [!] => { $ crate :: SyntaxKind :: NOT } ; [~] => { $ crate :: SyntaxKind :: BIT_NOT } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_BRACE } ; ['}'] => { $ crate :: SyntaxKind :: R_BRACE } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [;] => { $ crate :: SyntaxKind :: SEMI } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [...] => { $ crate :: SyntaxKind :: DOTDOTDOT } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['$'] => { $ crate :: SyntaxKind :: DOLLAR } ; [=] => { $ crate :: SyntaxKind :: ASSIGN } ; [?] => { $ crate :: SyntaxKind :: QUESTION_MARK } ; [tailstrict] => { $ crate :: SyntaxKind :: TAILSTRICT_KW } ; [local] => { $ crate :: SyntaxKind :: LOCAL_KW } ; [importstr] => { $ crate :: SyntaxKind :: IMPORTSTR_KW } ; [importbin] => { $ crate :: SyntaxKind :: IMPORTBIN_KW } ; [import] => { $ crate :: SyntaxKind :: IMPORT_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [then] => { $ crate :: SyntaxKind :: THEN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [function] => { $ crate :: SyntaxKind :: FUNCTION_KW } ; [error] => { $ crate :: SyntaxKind :: ERROR_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [null] => { $ crate :: SyntaxKind :: NULL_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [assert] => { $ crate :: SyntaxKind :: ASSERT_KW } }
#[allow(unused_imports)]
pub use T;
crates/jrsonnet-rowan-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/lib.rs
+++ b/crates/jrsonnet-rowan-parser/src/lib.rs
@@ -21,11 +21,6 @@
pub use language::*;
pub use token_set::SyntaxKindSet;
-use self::{
- ast::support,
- generated::nodes::{Expr, ExprObjExtend},
-};
-
pub fn parse(input: &str) -> (SourceFile, Vec<LocatedSyntaxError>) {
let lexemes = lex::lex(input);
let kinds = lexemes
@@ -44,15 +39,4 @@
},
parse.errors,
)
-}
-impl ExprObjExtend {
- pub fn lhs_work(&self) -> Option<Expr> {
- support::child(self.syntax())
- }
- pub fn rhs_work(&self) -> Option<Expr> {
- let mut children = support::children(self.syntax());
- // skip lhs
- children.next()?;
- children.next()
- }
}
crates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/parser.rs
+++ b/crates/jrsonnet-rowan-parser/src/parser.rs
@@ -406,17 +406,27 @@
m.complete(p, FIELD_NAME_FIXED);
} else {
m.forget(p);
- // ::: it split because in TS it is being handled as : ::
- p.error_with_recovery_set(TS![; : :: '('].with(T![:::]));
+ // Recover with ::, :::
+ p.error_with_recovery_set(TS![; : '(']);
}
}
fn visibility(p: &mut Parser) {
- // ::: it split because in TS it is being handled as : ::
- if p.at_ts(TS![: ::].with(T![:::])) {
+ let m = p.start();
+ if !p.at_ts(TS![:]) {
+ p.error_with_recovery_set(TS![=]);
+ }
+ p.bump();
+ 'colons: {
+ if !p.at_ts(TS![:]) {
+ break 'colons;
+ }
p.bump();
- } else {
- p.error_with_recovery_set(TS![=]);
+ if !p.at_ts(TS![:]) {
+ break 'colons;
+ }
+ p.bump();
}
+ m.complete(p, VISIBILITY);
}
fn assertion(p: &mut Parser) {
let m = p.start();
@@ -472,17 +482,17 @@
visibility(p);
expr(p);
true
- // ::: it split because in TS it is being handled as : ::
- } else if p.at_ts(TS![: ::].with(T![:::])) && p.nth_at(1, T![function]) {
- visibility(p);
- p.bump_assert(T![function]);
- params_desc(p);
- expr(p);
- true
} else {
visibility(p);
- expr(p);
- false
+ if p.at(T![function]) {
+ p.bump_assert(T![function]);
+ params_desc(p);
+ expr(p);
+ true
+ } else {
+ expr(p);
+ false
+ }
};
elems += 1;
@@ -648,15 +658,14 @@
fn slice_desc_or_index(p: &mut Parser) -> bool {
let m = p.start();
p.bump();
- // TODO: do not treat :, ::, ::: as full tokens?
// Start
- if !p.at(T![:]) && !p.at(T![::]) {
+ if !p.at(T![:]) {
expr(p);
}
if p.at(T![:]) {
p.bump();
// End
- if !p.at(T![']']) {
+ if !p.at_ts(TS![']' :]) {
expr(p).wrap(p, SLICE_DESC_END, true);
}
if p.at(T![:]) {
@@ -665,12 +674,6 @@
if !p.at(T![']']) {
expr(p).wrap(p, SLICE_DESC_STEP, true);
}
- }
- } else if p.at(T![::]) {
- p.bump();
- // End
- if !p.at(T![']']) {
- expr(p).wrap(p, SLICE_DESC_END, true);
}
} else {
// It was not a slice
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec.snap
@@ -11,7 +11,8 @@
FIELD_NAME_FIXED@1..2
NAME@1..2
IDENT@1..2 "a"
- COLON@2..3 ":"
+ VISIBILITY@2..3
+ COLON@2..3 ":"
EXPR@3..4
EXPR_NUMBER@3..4
FLOAT@3..4 "1"
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_comma.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_comma.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_comma.snap
@@ -11,7 +11,8 @@
FIELD_NAME_FIXED@1..2
NAME@1..2
IDENT@1..2 "a"
- COLON@2..3 ":"
+ VISIBILITY@2..3
+ COLON@2..3 ":"
EXPR@3..4
EXPR_NUMBER@3..4
FLOAT@3..4 "1"
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_asserts.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_asserts.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_asserts.snap
@@ -21,7 +21,8 @@
FIELD_NAME_FIXED@11..12
NAME@11..12
IDENT@11..12 "a"
- COLON@12..13 ":"
+ VISIBILITY@12..13
+ COLON@12..13 ":"
WHITESPACE@13..14 " "
EXPR@14..15
EXPR_NUMBER@14..15
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems.snap
@@ -11,7 +11,8 @@
FIELD_NAME_FIXED@1..2
NAME@1..2
IDENT@1..2 "a"
- COLON@2..3 ":"
+ VISIBILITY@2..3
+ COLON@2..3 ":"
EXPR@3..4
EXPR_NUMBER@3..4
FLOAT@3..4 "1"
@@ -49,7 +50,8 @@
FIELD_NAME_FIXED@25..26
NAME@25..26
IDENT@25..26 "b"
- COLON@26..27 ":"
+ VISIBILITY@26..27
+ COLON@26..27 ":"
EXPR@27..28
EXPR_NUMBER@27..28
FLOAT@27..28 "1"
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems_w.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems_w.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_compspec_incompatible_with_multiple_elems_w.snap
@@ -11,7 +11,8 @@
FIELD_NAME_FIXED@1..2
NAME@1..2
IDENT@1..2 "a"
- COLON@2..3 ":"
+ VISIBILITY@2..3
+ COLON@2..3 ":"
EXPR@3..4
EXPR_NUMBER@3..4
FLOAT@3..4 "1"
@@ -21,7 +22,8 @@
FIELD_NAME_FIXED@6..7
NAME@6..7
IDENT@6..7 "b"
- COLON@7..8 ":"
+ VISIBILITY@7..8
+ COLON@7..8 ":"
EXPR@8..9
EXPR_NUMBER@8..9
FLOAT@8..9 "1"
@@ -60,7 +62,8 @@
FIELD_NAME_FIXED@31..32
NAME@31..32
IDENT@31..32 "c"
- COLON@32..33 ":"
+ VISIBILITY@32..33
+ COLON@32..33 ":"
EXPR@33..34
EXPR_NUMBER@33..34
FLOAT@33..34 "1"
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_method.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_method.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__obj_method.snap
@@ -19,7 +19,8 @@
NAME@5..6
IDENT@5..6 "x"
R_PAREN@6..7 ")"
- COLON@7..8 ":"
+ VISIBILITY@7..8
+ COLON@7..8 ":"
WHITESPACE@8..9 " "
EXPR@9..10
EXPR_VAR@9..10
@@ -31,7 +32,8 @@
FIELD_NAME_FIXED@13..14
NAME@13..14
IDENT@13..14 "a"
- COLON@14..15 ":"
+ VISIBILITY@14..15
+ COLON@14..15 ":"
WHITESPACE@15..16 " "
FUNCTION_KW@16..24 "function"
PARAMS_DESC@24..27
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__visibilities.snapdiffbeforeafterboth--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__visibilities.snap
@@ -0,0 +1,51 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "{\n\tnormal: 1,\n\thide:: 2,\n\tunhide::: 3,\n}\n"
+---
+SOURCE_FILE@0..41
+ EXPR@0..40
+ EXPR_OBJECT@0..40
+ OBJ_BODY_MEMBER_LIST@0..40
+ L_BRACE@0..1 "{"
+ WHITESPACE@1..3 "\n\t"
+ MEMBER_FIELD_NORMAL@3..12
+ FIELD_NAME_FIXED@3..9
+ NAME@3..9
+ IDENT@3..9 "normal"
+ VISIBILITY@9..10
+ COLON@9..10 ":"
+ WHITESPACE@10..11 " "
+ EXPR@11..12
+ EXPR_NUMBER@11..12
+ FLOAT@11..12 "1"
+ COMMA@12..13 ","
+ WHITESPACE@13..15 "\n\t"
+ MEMBER_FIELD_NORMAL@15..23
+ FIELD_NAME_FIXED@15..19
+ NAME@15..19
+ IDENT@15..19 "hide"
+ VISIBILITY@19..21
+ COLON@19..20 ":"
+ COLON@20..21 ":"
+ WHITESPACE@21..22 " "
+ EXPR@22..23
+ EXPR_NUMBER@22..23
+ FLOAT@22..23 "2"
+ COMMA@23..24 ","
+ WHITESPACE@24..26 "\n\t"
+ MEMBER_FIELD_NORMAL@26..37
+ FIELD_NAME_FIXED@26..32
+ NAME@26..32
+ IDENT@26..32 "unhide"
+ VISIBILITY@32..35
+ COLON@32..33 ":"
+ COLON@33..34 ":"
+ COLON@34..35 ":"
+ WHITESPACE@35..36 " "
+ EXPR@36..37
+ EXPR_NUMBER@36..37
+ FLOAT@36..37 "3"
+ COMMA@37..38 ","
+ WHITESPACE@38..39 "\n"
+ R_BRACE@39..40 "}"
+ WHITESPACE@40..41 "\n"
crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__wrong_field_end.snapdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__wrong_field_end.snap
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__wrong_field_end.snap
@@ -12,7 +12,8 @@
FIELD_NAME_FIXED@3..4
NAME@3..4
IDENT@3..4 "a"
- COLON@4..5 ":"
+ VISIBILITY@4..5
+ COLON@4..5 ":"
WHITESPACE@5..6 " "
EXPR@6..7
EXPR_NUMBER@6..7
@@ -24,7 +25,8 @@
FIELD_NAME_FIXED@10..11
NAME@10..11
IDENT@10..11 "b"
- COLON@11..12 ":"
+ VISIBILITY@11..12
+ COLON@11..12 ":"
WHITESPACE@12..13 " "
EXPR@13..14
EXPR_NUMBER@13..14
crates/jrsonnet-rowan-parser/src/tests.rsdiffbeforeafterboth--- a/crates/jrsonnet-rowan-parser/src/tests.rs
+++ b/crates/jrsonnet-rowan-parser/src/tests.rs
@@ -208,6 +208,14 @@
Trimmed text block
|||
"#
+
+ visibilities => r#"
+ {
+ normal: 1,
+ hide:: 2,
+ unhide::: 3,
+ }
+ "#
);
#[test]
xtask/src/sourcegen/kinds.rsdiffbeforeafterboth--- a/xtask/src/sourcegen/kinds.rs
+++ b/xtask/src/sourcegen/kinds.rs
@@ -240,8 +240,6 @@
"{" => "L_BRACE";
"}" => "R_BRACE";
":" => "COLON";
- "::" => "COLONCOLON";
- ":::" => "COLONCOLONCOLON";
";" => "SEMI";
"." => "DOT";
"..." => "DOTDOTDOT";