git.delta.rocks / jrsonnet / refs/commits / 9ebfdebec2e2

difftreelog

refactor use new rowan-parser in jrsonnet-fmt

Yaroslav Bolyukin2023-09-11parent: #1b82950.patch.diff
in: master

6 files changed

addedCargo.lockdiffbeforeafterboth
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1784 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "ahash"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "annotate-snippets"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36"
+dependencies = [
+ "unicode-width",
+ "yansi-term",
+]
+
+[[package]]
+name = "anstream"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
+dependencies = [
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
+dependencies = [
+ "anstyle",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
+
+[[package]]
+name = "ass-stroke"
+version = "0.1.0"
+dependencies = [
+ "num-traits",
+ "rand 0.8.5",
+ "random_color",
+ "range-map",
+ "smallvec",
+]
+
+[[package]]
+name = "ass-stroke"
+version = "0.1.0"
+source = "git+https://github.com/CertainLach/ass-stroke#c98c0213b9c5f775c0bddaa7b233a38c60859008"
+dependencies = [
+ "num-traits",
+ "rand 0.8.5",
+ "random_color",
+ "range-map",
+ "smallvec",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "backtrace-ext"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
+dependencies = [
+ "backtrace",
+]
+
+[[package]]
+name = "base64"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
+
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_complete"
+version = "4.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5"
+dependencies = [
+ "clap",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
+[[package]]
+name = "console"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "countme"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "dprint-core"
+version = "0.63.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77fb4fc41e8a0217e1c0031c26640126e3ff3aba40a98db8b1db7b4e13bfce29"
+dependencies = [
+ "anyhow",
+ "bumpalo",
+ "indexmap",
+ "rustc-hash",
+ "serde",
+ "unicode-width",
+]
+
+[[package]]
+name = "drop_bomb"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1"
+
+[[package]]
+name = "either"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+
+[[package]]
+name = "encode_unicode"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+
+[[package]]
+name = "errno"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+
+[[package]]
+name = "idna"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indoc"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
+
+[[package]]
+name = "insta"
+version = "1.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a"
+dependencies = [
+ "console",
+ "lazy_static",
+ "linked-hash-map",
+ "similar",
+ "yaml-rust",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "is_ci"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+
+[[package]]
+name = "jrsonnet"
+version = "0.5.0-pre95"
+dependencies = [
+ "ass-stroke 0.1.0 (git+https://github.com/CertainLach/ass-stroke)",
+ "clap",
+ "clap_complete",
+ "jrsonnet-cli",
+ "jrsonnet-evaluator",
+ "jrsonnet-gcmodule",
+ "jrsonnet-parser",
+ "mimallocator",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "jrsonnet-cli"
+version = "0.5.0-pre95"
+dependencies = [
+ "clap",
+ "jrsonnet-evaluator",
+ "jrsonnet-gcmodule",
+ "jrsonnet-parser",
+ "jrsonnet-stdlib",
+]
+
+[[package]]
+name = "jrsonnet-evaluator"
+version = "0.5.0-pre95"
+dependencies = [
+ "annotate-snippets",
+ "anyhow",
+ "async-trait",
+ "bincode",
+ "derivative",
+ "hashbrown 0.13.2",
+ "jrsonnet-gcmodule",
+ "jrsonnet-interner",
+ "jrsonnet-macros",
+ "jrsonnet-parser",
+ "jrsonnet-types",
+ "num-bigint",
+ "pathdiff",
+ "rustc-hash",
+ "serde",
+ "static_assertions",
+ "strsim",
+ "thiserror",
+]
+
+[[package]]
+name = "jrsonnet-fmt"
+version = "0.5.0-pre95"
+dependencies = [
+ "ass-stroke 0.1.0",
+ "clap",
+ "dprint-core",
+ "indoc",
+ "insta",
+ "jrsonnet-rowan-parser",
+ "tempfile",
+ "thiserror",
+]
+
+[[package]]
+name = "jrsonnet-gcmodule"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11fb98940a7f8b419619e98ccbf2e094671a5fdd0e277f05acd373071186d57"
+dependencies = [
+ "jrsonnet-gcmodule-derive",
+ "parking_lot",
+]
+
+[[package]]
+name = "jrsonnet-gcmodule-derive"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bee774b7ba86fc86ee84482cd6732aa860ae3559f9827c65efd75c51e66ac76"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "jrsonnet-interner"
+version = "0.5.0-pre95"
+dependencies = [
+ "hashbrown 0.13.2",
+ "jrsonnet-gcmodule",
+ "rustc-hash",
+ "serde",
+ "structdump",
+]
+
+[[package]]
+name = "jrsonnet-lsp"
+version = "0.5.0-pre95"
+dependencies = [
+ "anyhow",
+ "jrsonnet-evaluator",
+ "jrsonnet-rowan-parser",
+ "lsp-server",
+ "lsp-types",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "jrsonnet-macros"
+version = "0.5.0-pre95"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "jrsonnet-parser"
+version = "0.5.0-pre95"
+dependencies = [
+ "jrsonnet-gcmodule",
+ "jrsonnet-interner",
+ "peg",
+ "serde",
+ "static_assertions",
+ "structdump",
+]
+
+[[package]]
+name = "jrsonnet-rowan-parser"
+version = "0.5.0-pre95"
+dependencies = [
+ "anyhow",
+ "backtrace",
+ "drop_bomb",
+ "indoc",
+ "insta",
+ "logos",
+ "miette",
+ "rowan",
+ "text-size",
+ "thiserror",
+]
+
+[[package]]
+name = "jrsonnet-stdlib"
+version = "0.5.0-pre95"
+dependencies = [
+ "base64",
+ "bincode",
+ "jrsonnet-evaluator",
+ "jrsonnet-gcmodule",
+ "jrsonnet-macros",
+ "jrsonnet-parser",
+ "md5",
+ "num-bigint",
+ "serde",
+ "serde_json",
+ "serde_yaml_with_quirks",
+ "sha1",
+ "sha2",
+ "sha3",
+ "structdump",
+]
+
+[[package]]
+name = "jrsonnet-types"
+version = "0.5.0-pre95"
+dependencies = [
+ "jrsonnet-gcmodule",
+ "peg",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940"
+dependencies = [
+ "cpufeatures",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.147"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+[[package]]
+name = "libjsonnet"
+version = "0.5.0-pre95"
+dependencies = [
+ "jrsonnet-evaluator",
+ "jrsonnet-gcmodule",
+ "jrsonnet-parser",
+ "jrsonnet-stdlib",
+]
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
+
+[[package]]
+name = "lock_api"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "logos"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1"
+dependencies = [
+ "logos-derive",
+]
+
+[[package]]
+name = "logos-derive"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c"
+dependencies = [
+ "beef",
+ "fnv",
+ "proc-macro2",
+ "quote",
+ "regex-syntax",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "lsp-server"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f70570c1c29cf6654029b8fe201a5507c153f0d85be6f234d471d756bc36775a"
+dependencies = [
+ "crossbeam-channel",
+ "log",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "lsp-types"
+version = "0.93.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9be6e9c7e2d18f651974370d7aff703f9513e0df6e464fd795660edc77e6ca51"
+dependencies = [
+ "bitflags 1.3.2",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "url",
+]
+
+[[package]]
+name = "md5"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
+
+[[package]]
+name = "memchr"
+version = "2.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
+
+[[package]]
+name = "memoffset"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "miette"
+version = "5.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e"
+dependencies = [
+ "backtrace",
+ "backtrace-ext",
+ "is-terminal",
+ "miette-derive",
+ "once_cell",
+ "owo-colors",
+ "supports-color",
+ "supports-hyperlinks",
+ "supports-unicode",
+ "terminal_size",
+ "textwrap",
+ "thiserror",
+ "unicode-width",
+]
+
+[[package]]
+name = "miette-derive"
+version = "5.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "mimalloc-sys"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4aa3cefb626f6ae3d0b2f71c5378c89d2b1d4d7bc246b0ca9a7ee61a4daad291"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "mimallocator"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d44fe4ebf6b538fcf39d9975c2b90bb3232d1ba8e8bffeacd004f27b20c577a"
+dependencies = [
+ "mimalloc-sys",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+ "serde",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "object"
+version = "0.32.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
+name = "owo-colors"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
+name = "peg"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a07f2cafdc3babeebc087e499118343442b742cc7c31b4d054682cc598508554"
+dependencies = [
+ "peg-macros",
+ "peg-runtime",
+]
+
+[[package]]
+name = "peg-macros"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a90084dc05cf0428428e3d12399f39faad19b0909f64fb9170c9fdd6d9cd49b"
+dependencies = [
+ "peg-runtime",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "peg-runtime"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa00462b37ead6d11a82c9d568b26682d78e0477dc02d1966c013af80969739"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc",
+ "rand_pcg",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.10",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "random_color"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5f34bd6526786b2ce5141fd37a4084b5da1ebae74595b5b0d05482a7cef7181"
+dependencies = [
+ "rand 0.7.3",
+]
+
+[[package]]
+name = "range-map"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12a5a2d6c7039059af621472a4389be1215a816df61aa4d531cfe85264aee95f"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "rowan"
+version = "0.15.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64449cfef9483a475ed56ae30e2da5ee96448789fb2aa240a04beb6a055078bf"
+dependencies = [
+ "countme",
+ "hashbrown 0.12.3",
+ "memoffset",
+ "rustc-hash",
+ "text-size",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustix"
+version = "0.38.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453"
+dependencies = [
+ "bitflags 2.4.0",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "serde"
+version = "1.0.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_repr"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "serde_yaml_with_quirks"
+version = "0.8.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47c5983eba86eae2d0058c35fb1065ccffb23af7f8965871069269088098321a"
+dependencies = [
+ "indexmap",
+ "ryu",
+ "serde",
+ "yaml-rust",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha3"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
+dependencies = [
+ "digest",
+ "keccak",
+]
+
+[[package]]
+name = "similar"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
+
+[[package]]
+name = "smallvec"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
+
+[[package]]
+name = "smawk"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "structdump"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0570327507bf281d8a6e6b0d4c082b12cb6bcee27efce755aa5efacd44076c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "structdump-derive",
+]
+
+[[package]]
+name = "structdump-derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29cc0b59cfa11f1bceda09a9a7e37e6a6c3138575fd24ade8aa9af6d09aedf28"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "supports-color"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4950e7174bffabe99455511c39707310e7e9b440364a2fcb1cc21521be57b354"
+dependencies = [
+ "is-terminal",
+ "is_ci",
+]
+
+[[package]]
+name = "supports-hyperlinks"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d"
+dependencies = [
+ "is-terminal",
+]
+
+[[package]]
+name = "supports-unicode"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7"
+dependencies = [
+ "is-terminal",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "terminal_size"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "tests"
+version = "0.1.0"
+dependencies = [
+ "jrsonnet-evaluator",
+ "jrsonnet-gcmodule",
+ "jrsonnet-stdlib",
+ "serde",
+]
+
+[[package]]
+name = "text-size"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
+
+[[package]]
+name = "textwrap"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
+dependencies = [
+ "smawk",
+ "unicode-linebreak",
+ "unicode-width",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.31",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "typenum"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+
+[[package]]
+name = "ungrammar"
+version = "1.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
+
+[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "url"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "xshell"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad"
+dependencies = [
+ "xshell-macros",
+]
+
+[[package]]
+name = "xshell-macros"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e"
+
+[[package]]
+name = "xtask"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "ungrammar",
+ "xshell",
+]
+
+[[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "yansi-term"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
+dependencies = [
+ "winapi",
+]
modifiedcmds/jrsonnet-fmt/Cargo.tomldiffbeforeafterboth
--- a/cmds/jrsonnet-fmt/Cargo.toml
+++ b/cmds/jrsonnet-fmt/Cargo.toml
@@ -4,8 +4,11 @@
 edition = "2021"
 
 [dependencies]
-dprint-core = "0.60.0"
+dprint-core = "0.63.2"
 jrsonnet-rowan-parser.workspace = true
 insta = "1.15"
 indoc = "1.0"
 ass-stroke = { path = "/home/lach/build/ass-stroke/crates/ass-stroke", version = "0.1.0" }
+clap = { version = "4.4.2", features = ["derive"] }
+tempfile = "3.8.0"
+thiserror = "1.0.48"
modifiedcmds/jrsonnet-fmt/src/children.rsdiffbeforeafterboth
--- a/cmds/jrsonnet-fmt/src/children.rs
+++ b/cmds/jrsonnet-fmt/src/children.rs
@@ -99,15 +99,19 @@
 	node: SyntaxNode,
 	start: Option<&SyntaxElement>,
 	end: Option<&SyntaxElement>,
+	trailing: Option<ChildTrivia>,
 ) -> (Vec<Child<T>>, EndingComments) {
 	let mut iter = node.children_with_tokens().peekable();
-	while iter.peek() != start {
+	if start.is_some() {
+		while iter.peek() != start {
+			iter.next();
+		}
 		iter.next();
 	}
-	iter.next();
 	children(
 		iter.take_while(|i| Some(i) != end),
-		start.is_none() || end.is_none(),
+		start.is_none() && end.is_none(),
+		trailing,
 	)
 }
 
@@ -165,6 +169,7 @@
 pub fn children<T: AstNode + Debug>(
 	items: impl Iterator<Item = SyntaxElement>,
 	loose: bool,
+	mut trailing: Option<ChildTrivia>,
 ) -> (Vec<Child<T>>, EndingComments) {
 	let mut out = Vec::new();
 	let mut current_child = None::<Child<T>>;
@@ -175,7 +180,12 @@
 
 	for item in items {
 		if let Some(value) = item.as_node().cloned().and_then(T::cast) {
-			let before_trivia = mem::take(&mut next);
+			let before_trivia = if let Some(trailing) = trailing.take() {
+				assert!(next.is_empty());
+				trailing
+			} else {
+				mem::take(&mut next)
+			};
 			let last_child = current_child.replace(Child {
 				// First item should not start with newline
 				should_start_with_newline: had_some
@@ -195,7 +205,10 @@
 		} else if let Some(trivia) = item.as_token().cloned().and_then(Trivia::cast) {
 			let is_single_line_comment = trivia.kind() == TriviaKind::SingleLineHashComment
 				|| trivia.kind() == TriviaKind::SingleLineSlashComment;
-			if started_next
+			if trailing.is_some() {
+				// Someone have already parsed trivia for us
+				continue;
+			} else if started_next
 				|| current_child.is_none()
 				|| trivia.text().contains('\n') && !is_single_line_comment
 			{
@@ -271,4 +284,7 @@
 	pub fn is_empty(&self) -> bool {
 		!self.should_start_with_newline && self.trivia.is_empty()
 	}
+	pub fn extract_trailing(&mut self) -> ChildTrivia {
+		mem::take(&mut self.trivia)
+	}
 }
modifiedcmds/jrsonnet-fmt/src/comments.rsdiffbeforeafterboth
before · cmds/jrsonnet-fmt/src/comments.rs
1use dprint_core::formatting::PrintItems;2use jrsonnet_rowan_parser::{nodes::TriviaKind, AstToken};34use crate::{children::ChildTrivia, p, pi};56pub enum CommentLocation {7	/// Above local, field, other things8	AboveItem,9	/// After item10	ItemInline,11	/// After all items in object12	EndOfItems,13}1415#[must_use]16pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation) -> PrintItems {17	let mut pi = p!(new:);1819	for c in comments {20		let Ok(c) = c else {21			let mut text = c.as_ref().unwrap_err() as &str;22			while !text.is_empty() {23				let pos = text.find(|c| c == '\n' || c == '\t').unwrap_or(text.len());24				let sliced = &text[..pos];25				p!(pi: string(sliced.to_string()));26				text = &text[pos..];27				if! text.is_empty(){28					match text.as_bytes()[0] {29						b'\n' => p!(pi: nl),30						b'\t' => p!(pi: tab),31						_ => unreachable!()32					}33					text = &text[1..];34				}35			}36			continue;37		};38		match c.kind() {39			TriviaKind::Whitespace => {}40			TriviaKind::MultiLineComment => {41				let mut text = c42					.text()43					.strip_prefix("/*")44					.expect("ml comment starts with /*")45					.strip_suffix("*/")46					.expect("ml comment ends with */");47				// doc-style comment, /**48				let doc = if text.starts_with('*') {49					text = &text[1..];50					true51				} else {52					false53				};54				// Is comment starts with text immediatly, i.e /*text55				let mut immediate_start = true;56				let mut lines = text57					.split('\n')58					.map(|l| l.trim_end().to_string())59					.skip_while(|l| {60						if l.is_empty() {61							immediate_start = false;62							true63						} else {64							false65						}66					})67					.collect::<Vec<_>>();68				while lines.last().map(|l| l.is_empty()).unwrap_or(false) {69					lines.pop();70				}71				if lines.len() == 1 && !doc {72					p!(pi: str("/* ") string(lines[0].trim().to_string()) str(" */") nl)73				} else if !lines.is_empty() {74					fn common_ws_prefix<'a>(a: &'a str, b: &str) -> &'a str {75						let offset = a76							.bytes()77							.zip(b.bytes())78							.take_while(|(a, b)| a == b && (a.is_ascii_whitespace() || *a == b'*'))79							.count();80						&a[..offset]81					}82					// First line is not empty, extract ws prefix of it83					let mut common_ws_padding = (if immediate_start && lines.len() > 1 {84						common_ws_prefix(&lines[1], &lines[1])85					} else {86						common_ws_prefix(&lines[0], &lines[0])87					})88					.to_string();89					for line in lines90						.iter()91						.skip(if immediate_start { 2 } else { 1 })92						.filter(|l| !l.is_empty())93					{94						common_ws_padding = common_ws_prefix(&common_ws_padding, line).to_string();95					}96					for line in lines97						.iter_mut()98						.skip(if immediate_start { 1 } else { 0 })99						.filter(|l| !l.is_empty())100					{101						*line = line102							.strip_prefix(&common_ws_padding)103							.expect("all non-empty lines start with this padding")104							.to_string();105					}106107					p!(pi: str("/*"));108					if doc {109						p!(pi: str("*"));110					}111					p!(pi: nl);112					for mut line in lines {113						if doc {114							p!(pi: str(" *"));115						}116						if line.is_empty() {117							p!(pi: nl);118						} else {119							if doc {120								p!(pi: str(" "));121							}122							while let Some(new_line) = line.strip_prefix('\t') {123								if doc {124									p!(pi: str("    "));125								} else {126									p!(pi: tab);127								}128								line = new_line.to_string();129							}130							p!(pi: string(line.to_string()) nl)131						}132					}133					if doc {134						p!(pi: str(" "));135					}136					p!(pi: str("*/") nl)137				}138			}139			// TODO: Keep common padding for multiple continous lines of single-line comments140			// I.e141			// ```142			// #  Line1143			// #    Line2144			// ```145			// Should be reformatted as146			// ```147			// # Line1148			// #   Line2149			// ```150			// But currently comment formatter is not aware of continous comment lines, and reformats it as151			// ```152			// # Line1153			// # Line2154			// ```155			TriviaKind::SingleLineHashComment => {156				if matches!(loc, CommentLocation::ItemInline) {157					p!(pi: str(" "))158				}159				p!(pi: str("# ") string(c.text().strip_prefix('#').expect("hash comment starts with #").trim().to_string()));160				if !matches!(loc, CommentLocation::ItemInline) {161					p!(pi: nl)162				}163			}164			TriviaKind::SingleLineSlashComment => {165				if matches!(loc, CommentLocation::ItemInline) {166					p!(pi: str(" "))167				}168				p!(pi: str("// ") string(c.text().strip_prefix("//").expect("comment starts with //").trim().to_string()));169				if !matches!(loc, CommentLocation::ItemInline) {170					p!(pi: nl)171				}172			}173			// Garbage in - garbage out174			TriviaKind::ErrorCommentTooShort => p!(pi: str("/*/")),175			TriviaKind::ErrorCommentUnterminated => p!(pi: string(c.text().to_string())),176		}177	}178179	pi180}
after · cmds/jrsonnet-fmt/src/comments.rs
1use dprint_core::formatting::PrintItems;2use jrsonnet_rowan_parser::{nodes::TriviaKind, AstToken};34use crate::{children::ChildTrivia, p, pi};56pub enum CommentLocation {7	/// Above local, field, other things8	AboveItem,9	/// After item10	ItemInline,11	/// After all items in object12	EndOfItems,13}1415#[must_use]16pub fn format_comments(comments: &ChildTrivia, loc: CommentLocation) -> PrintItems {17	let mut pi = p!(new:);1819	for c in comments {20		let Ok(c) = c else {21			let mut text = c.as_ref().unwrap_err() as &str;22			while !text.is_empty() {23				let pos = text.find(|c| c == '\n' || c == '\t').unwrap_or(text.len());24				let sliced = &text[..pos];25				p!(pi: string(sliced.to_string()));26				text = &text[pos..];27				if !text.is_empty() {28					match text.as_bytes()[0] {29						b'\n' => p!(pi: nl),30						b'\t' => p!(pi: tab),31						_ => unreachable!(),32					}33					text = &text[1..];34				}35			}36			continue;37		};38		match c.kind() {39			TriviaKind::Whitespace => {}40			TriviaKind::MultiLineComment => {41				let mut text = c42					.text()43					.strip_prefix("/*")44					.expect("ml comment starts with /*")45					.strip_suffix("*/")46					.expect("ml comment ends with */");47				// doc-style comment, /**48				let doc = if text.starts_with('*') {49					text = &text[1..];50					true51				} else {52					false53				};54				// Is comment starts with text immediatly, i.e /*text55				let mut immediate_start = true;56				let mut lines = text57					.split('\n')58					.map(|l| l.trim_end().to_string())59					.skip_while(|l| {60						if l.is_empty() {61							immediate_start = false;62							true63						} else {64							false65						}66					})67					.collect::<Vec<_>>();68				while lines.last().map(|l| l.is_empty()).unwrap_or(false) {69					lines.pop();70				}71				if lines.len() == 1 && !doc {72					if matches!(loc, CommentLocation::ItemInline) {73						p!(pi: str(" "));74					}75					p!(pi: str("/* ") string(lines[0].trim().to_string()) str(" */"))76				} else if !lines.is_empty() {77					fn common_ws_prefix<'a>(a: &'a str, b: &str) -> &'a str {78						let offset = a79							.bytes()80							.zip(b.bytes())81							.take_while(|(a, b)| a == b && (a.is_ascii_whitespace() || *a == b'*'))82							.count();83						&a[..offset]84					}85					// First line is not empty, extract ws prefix of it86					let mut common_ws_padding = (if immediate_start && lines.len() > 1 {87						common_ws_prefix(&lines[1], &lines[1])88					} else {89						common_ws_prefix(&lines[0], &lines[0])90					})91					.to_string();92					for line in lines93						.iter()94						.skip(if immediate_start { 2 } else { 1 })95						.filter(|l| !l.is_empty())96					{97						common_ws_padding = common_ws_prefix(&common_ws_padding, line).to_string();98					}99					for line in lines100						.iter_mut()101						.skip(if immediate_start { 1 } else { 0 })102						.filter(|l| !l.is_empty())103					{104						*line = line105							.strip_prefix(&common_ws_padding)106							.expect("all non-empty lines start with this padding")107							.to_string();108					}109110					p!(pi: str("/*"));111					if doc {112						p!(pi: str("*"));113					}114					p!(pi: nl);115					for mut line in lines {116						if doc {117							p!(pi: str(" *"));118						}119						if line.is_empty() {120							p!(pi: nl);121						} else {122							if doc {123								p!(pi: str(" "));124							}125							while let Some(new_line) = line.strip_prefix('\t') {126								if doc {127									p!(pi: str("    "));128								} else {129									p!(pi: tab);130								}131								line = new_line.to_string();132							}133							p!(pi: string(line.to_string()) nl)134						}135					}136					if doc {137						p!(pi: str(" "));138					}139					p!(pi: str("*/") nl)140				}141			}142			// TODO: Keep common padding for multiple continous lines of single-line comments143			// I.e144			// ```145			// #  Line1146			// #    Line2147			// ```148			// Should be reformatted as149			// ```150			// # Line1151			// #   Line2152			// ```153			// But currently comment formatter is not aware of continous comment lines, and reformats it as154			// ```155			// # Line1156			// # Line2157			// ```158			TriviaKind::SingleLineHashComment => {159				if matches!(loc, CommentLocation::ItemInline) {160					p!(pi: str(" "))161				}162				p!(pi: str("# ") string(c.text().strip_prefix('#').expect("hash comment starts with #").trim().to_string()));163				if !matches!(loc, CommentLocation::ItemInline) {164					p!(pi: nl)165				}166			}167			TriviaKind::SingleLineSlashComment => {168				if matches!(loc, CommentLocation::ItemInline) {169					p!(pi: str(" "))170				}171				p!(pi: str("// ") string(c.text().strip_prefix("//").expect("comment starts with //").trim().to_string()));172				if !matches!(loc, CommentLocation::ItemInline) {173					p!(pi: nl)174				}175			}176			// Garbage in - garbage out177			TriviaKind::ErrorCommentTooShort => p!(pi: str("/*/")),178			TriviaKind::ErrorCommentUnterminated => p!(pi: string(c.text().to_string())),179		}180	}181182	pi183}
modifiedcmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth
--- a/cmds/jrsonnet-fmt/src/main.rs
+++ b/cmds/jrsonnet-fmt/src/main.rs
@@ -1,15 +1,21 @@
-use std::any::type_name;
+use std::{
+	any::type_name,
+	fs,
+	io::{self, Write},
+	path::PathBuf,
+	process,
+};
 
 use children::{children_between, trivia_before};
+use clap::Parser;
 use dprint_core::formatting::{PrintItems, PrintOptions};
 use jrsonnet_rowan_parser::{
 	nodes::{
 		ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,
-		DestructRest, Expr, FieldName, ForSpec, IfSpec, ImportKind, LhsExpr, Literal, Member, Name,
-		Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Text, UnaryOperator,
-		Visibility, VisibilityKind,
+		DestructRest, Expr, ExprBase, FieldName, ForSpec, IfSpec, ImportKind, Literal, Member,
+		Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix, Text,
+		UnaryOperator, Visibility,
 	},
-	rowan::NodeOrToken,
 	AstNode, AstToken, SyntaxToken,
 };
 
@@ -287,7 +293,9 @@
 			Member::MemberFieldNormal(n) => {
 				p!(new: {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()})
 			}
-			Member::MemberFieldMethod(_) => todo!(),
+			Member::MemberFieldMethod(m) => {
+				p!(new: {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()})
+			}
 		}
 	}
 }
@@ -296,7 +304,7 @@
 	fn print(&self) -> PrintItems {
 		match self {
 			ObjBody::ObjBodyComp(l) => {
-				let (children, end_comments) = children_between::<Member>(
+				let (children, mut end_comments) = children_between::<Member>(
 					l.syntax().clone(),
 					l.l_brace_token().map(Into::into).as_ref(),
 					Some(
@@ -307,7 +315,9 @@
 							.clone())
 						.into(),
 					),
+					None,
 				);
+				let trailing_for_comp = end_comments.extract_trailing();
 				let mut pi = p!(new: str("{") >i nl);
 				for mem in children.into_iter() {
 					if mem.should_start_with_newline {
@@ -333,6 +343,7 @@
 						.or_else(|| l.l_brace_token().map(Into::into))
 						.as_ref(),
 					l.r_brace_token().map(Into::into).as_ref(),
+					Some(trailing_for_comp),
 				);
 				for mem in compspecs.into_iter() {
 					if mem.should_start_with_newline {
@@ -347,7 +358,7 @@
 				}
 				p!(pi: items(format_comments(&end_comments.trivia, CommentLocation::EndOfItems)));
 
-				p!(pi: <i str("}"));
+				p!(pi: nl <i str("}"));
 				pi
 			}
 			ObjBody::ObjBodyMemberList(l) => {
@@ -355,6 +366,7 @@
 					l.syntax().clone(),
 					l.l_brace_token().map(Into::into).as_ref(),
 					l.r_brace_token().map(Into::into).as_ref(),
+					None,
 				);
 				if children.is_empty() && end_comments.is_empty() {
 					return p!(new: str("{ }"));
@@ -412,11 +424,6 @@
 		p!(new: string(self.syntax().to_string()))
 	}
 }
-impl Printable for LhsExpr {
-	fn print(&self) -> PrintItems {
-		p!(new: {self.expr()})
-	}
-}
 impl Printable for ForSpec {
 	fn print(&self) -> PrintItems {
 		p!(new: str("for ") {self.bind()} str(" in ") {self.expr()})
@@ -437,62 +444,75 @@
 }
 impl Printable for Expr {
 	fn print(&self) -> PrintItems {
+		let mut o = p!(new:);
+		let (stmts, ending) = children_between::<Stmt>(
+			self.syntax().clone(),
+			None,
+			self.expr_base()
+				.as_ref()
+				.map(ExprBase::syntax)
+				.cloned()
+				.map(Into::into)
+				.as_ref(),
+			None,
+		);
+		for stmt in stmts {
+			p!(o: {stmt.value});
+		}
+		p!(o: {self.expr_base()});
+		let (suffixes, ending) = children_between::<Suffix>(
+			self.syntax().clone(),
+			self.expr_base()
+				.as_ref()
+				.map(ExprBase::syntax)
+				.cloned()
+				.map(Into::into)
+				.as_ref(),
+			None,
+			None,
+		);
+		for suffix in suffixes {
+			p!(o: {suffix.value});
+		}
+		o
+	}
+}
+impl Printable for Suffix {
+	fn print(&self) -> PrintItems {
+		let mut o = p!(new:);
 		match self {
-			Expr::ExprBinary(b) => {
-				p!(new: {b.lhs()} str(" ") {b.binary_operator()} str(" ") {b.rhs()})
-			}
-			Expr::ExprUnary(u) => p!(new: {u.unary_operator()} {u.rhs()}),
-			Expr::ExprSlice(s) => {
-				p!(new: {s.expr()} {s.slice_desc()})
-			}
-			Expr::ExprIndex(i) => {
-				p!(new: {i.expr()} str(".") {i.index()})
-			}
-			Expr::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")),
-			Expr::ExprApply(a) => {
-				let mut pi = p!(new: {a.expr()} {a.args_desc()});
-				if a.tailstrict_kw_token().is_some() {
-					p!(pi: str(" tailstrict"));
+			Suffix::SuffixIndex(i) => {
+				if i.question_mark_token().is_some() {
+					p!(o: str("?"));
 				}
-				pi
-			}
-			Expr::ExprObjExtend(ex) => {
-				p!(new: {ex.lhs_expr()} str(" ") {ex.expr()})
-			}
-			Expr::ExprParened(p) => {
-				p!(new: str("(") {p.expr()} str(")"))
+				p!(o: str(".") {i.index()});
 			}
-			Expr::ExprString(s) => p!(new: {s.text()}),
-			Expr::ExprNumber(n) => p!(new: {n.number()}),
-			Expr::ExprArray(a) => {
-				let mut pi = p!(new: str("[") >i nl);
-				for el in a.exprs() {
-					p!(pi: {el} str(",") nl);
+			Suffix::SuffixIndexExpr(e) => {
+				if e.question_mark_token().is_some() {
+					p!(o: str(".?"));
 				}
-				p!(pi: <i str("]"));
-				pi
+				p!(o: str("[") {e.index()} str("]"))
 			}
-			Expr::ExprObject(o) => {
-				p!(new: {o.obj_body()})
+			Suffix::SuffixSlice(d) => {
+				p!(o: {d.slice_desc()})
 			}
-			Expr::ExprArrayComp(arr) => {
-				let mut pi = p!(new: str("[") {arr.expr()});
-				for spec in arr.comp_specs() {
-					p!(pi: str(" ") {spec});
-				}
-				p!(pi: str("]"));
-				pi
+			Suffix::SuffixApply(a) => {
+				p!(o: {a.args_desc()})
 			}
-			Expr::ExprImport(v) => {
-				p!(new: {v.import_kind()} str(" ") {v.text()})
-			}
-			Expr::ExprVar(n) => p!(new: {n.name()}),
-			Expr::ExprLocal(l) => {
+		}
+		o
+	}
+}
+impl Printable for Stmt {
+	fn print(&self) -> PrintItems {
+		match self {
+			Stmt::StmtLocal(l) => {
 				let mut pi = p!(new:);
 				let (binds, end_comments) = children_between::<Bind>(
 					l.syntax().clone(),
 					l.local_kw_token().map(Into::into).as_ref(),
 					l.semi_token().map(Into::into).as_ref(),
+					None,
 				);
 				if binds.len() == 1 {
 					let bind = &binds[0];
@@ -516,24 +536,69 @@
 					p!(pi: <i);
 				}
 				p!(pi: str(";") nl);
-
-				let expr_comments = trivia_between(
-					l.syntax().clone(),
-					l.semi_token().map(Into::into).as_ref(),
-					l.expr()
-						.map(|e| e.syntax().clone())
-						.map(Into::into)
-						.as_ref(),
-				);
-
-				if expr_comments.should_start_with_newline {
-					p!(pi: nl);
+				pi
+			}
+			Stmt::StmtAssert(a) => {
+				p!(new: {a.assertion()} str(";") nl)
+			}
+		}
+	}
+}
+impl Printable for ExprBase {
+	fn print(&self) -> PrintItems {
+		match self {
+			Self::ExprBinary(b) => {
+				p!(new: {b.lhs_work()} str(" ") {b.binary_operator()} str(" ") {b.rhs_work()})
+			}
+			Self::ExprUnary(u) => p!(new: {u.unary_operator()} {u.rhs()}),
+			// Self::ExprSlice(s) => {
+			// 	p!(new: {s.expr()} {s.slice_desc()})
+			// }
+			// Self::ExprIndex(i) => {
+			// 	p!(new: {i.expr()} str(".") {i.index()})
+			// }
+			// Self::ExprIndexExpr(i) => p!(new: {i.base()} str("[") {i.index()} str("]")),
+			// Self::ExprApply(a) => {
+			// 	let mut pi = p!(new: {a.expr()} {a.args_desc()});
+			// 	if a.tailstrict_kw_token().is_some() {
+			// 		p!(pi: str(" tailstrict"));
+			// 	}
+			// 	pi
+			// }
+			Self::ExprObjExtend(ex) => {
+				p!(new: {ex.lhs_work()} str(" ") {ex.rhs_work()})
+			}
+			Self::ExprParened(p) => {
+				p!(new: str("(") {p.expr()} str(")"))
+			}
+			Self::ExprString(s) => p!(new: {s.text()}),
+			Self::ExprNumber(n) => p!(new: {n.number()}),
+			Self::ExprArray(a) => {
+				let mut pi = p!(new: str("[") >i nl);
+				for el in a.exprs() {
+					p!(pi: {el} str(",") nl);
+				}
+				p!(pi: <i str("]"));
+				pi
+			}
+			Self::ExprObject(obj) => {
+				p!(new: {obj.obj_body()})
+			}
+			Self::ExprArrayComp(arr) => {
+				let mut pi = p!(new: str("[") {arr.expr()});
+				for spec in arr.comp_specs() {
+					p!(pi: str(" ") {spec});
 				}
-				p!(pi: items(format_comments(&expr_comments.trivia, CommentLocation::AboveItem)));
-				p!(pi: {l.expr()});
+				p!(pi: str("]"));
 				pi
 			}
-			Expr::ExprIfThenElse(ite) => {
+			Self::ExprImport(v) => {
+				p!(new: {v.import_kind()} str(" ") {v.text()})
+			}
+			Self::ExprVar(n) => p!(new: {n.name()}),
+			// Self::ExprLocal(l) => {
+			// }
+			Self::ExprIfThenElse(ite) => {
 				let mut pi =
 					p!(new: str("if ") {ite.cond()} str(" then ") {ite.then().map(|t| t.expr())});
 				if ite.else_kw_token().is_some() || ite.else_().is_some() {
@@ -541,10 +606,10 @@
 				}
 				pi
 			}
-			Expr::ExprFunction(f) => p!(new: str("function") {f.params_desc()} str(" ") {f.expr()}),
-			Expr::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),
-			Expr::ExprError(e) => p!(new: str("error ") {e.expr()}),
-			Expr::ExprLiteral(l) => {
+			Self::ExprFunction(f) => p!(new: str("function") {f.params_desc()} nl {f.expr()}),
+			// Self::ExprAssert(a) => p!(new: {a.assertion()} str("; ") {a.expr()}),
+			Self::ExprError(e) => p!(new: str("error ") {e.expr()}),
+			Self::ExprLiteral(l) => {
 				p!(new: {l.literal()})
 			}
 		}
@@ -575,7 +640,11 @@
 	}
 }
 
-fn format(input: &str) -> String {
+struct FormatOptions {
+	// 0 for hard tabs
+	indent: u8,
+}
+fn format(input: &str, opts: &FormatOptions) -> Option<String> {
 	let (parsed, errors) = jrsonnet_rowan_parser::parse(input);
 	if !errors.is_empty() {
 		let mut builder = ass_stroke::SnippetBuilder::new(input);
@@ -593,160 +662,143 @@
 		}
 		let snippet = builder.build();
 		let ansi = ass_stroke::source_to_ansi(&snippet);
-		println!("{ansi}");
+		eprintln!("{ansi}");
+		// It is possible to recover from this failure, but the output may be broken, as formatter is free to skip
+		// ERROR rowan nodes.
+		// Recovery needs to be enabled for LSP, though.
+		//
+		// TODO: Verify how formatter interacts in cases of missing positional values, i.e `if cond then /*missing Expr*/ else residual`.
+		return None;
 	}
-	dprint_core::formatting::format(
+	Some(dprint_core::formatting::format(
 		|| parsed.print(),
 		PrintOptions {
-			indent_width: 2,
+			indent_width: if opts.indent == 0 {
+				// Reasonable max length for both 2 and 4 space sized tabs.
+				3
+			} else {
+				opts.indent
+			},
 			max_width: 100,
-			use_tabs: false,
+			use_tabs: opts.indent == 0,
 			new_line_text: "\n",
 		},
-	)
+	))
 }
-fn main() {
-	let input = r#"
 
+#[derive(Parser)]
+struct Opts {
+	/// Treat input as code, reformat it instead of reading file.
+	#[clap(long, short = 'e')]
+	exec: bool,
+	/// Path to be reformatted if `--exec` if unset, otherwise code itself.
+	input: String,
+	/// Replace code with formatted in-place, instead of printing it to stdout.
+	/// Only applicable if `--exec` is unset.
+	#[clap(long, short = 'i')]
+	in_place: bool,
 
-		# Edit me!
-		local b = import "b.libsonnet";  # comment
-		local a = import "a.libsonnet";
+	/// Exit with error if formatted does not match input
+	#[arg(long)]
+	test: bool,
+	/// Number of spaces to indent with
+	///
+	/// 0 for guess from input (default), and use hard tabs if unable to guess.
+	#[arg(long, default_value = "0")]
+	indent: u8,
+	/// Force hard tab for indentation
+	#[arg(long)]
+	hard_tabs: bool,
 
-		local f(x,y)=x+y;
+	/// Debug option: how many times to call reformatting in case of unstable dprint output resolution.
+	///
+	/// 0 for not retrying to reformat.
+	#[arg(long, default_value = "0")]
+	conv_limit: usize,
+}
 
-		local {a: [b, ..., c], d, ...e} = null;
+#[derive(thiserror::Error, Debug)]
+enum Error {
+	#[error("--in-place is incompatible with --exec")]
+	InPlaceExec,
+	#[error("io: {0}")]
+	Io(#[from] io::Error),
+	#[error("persist: {0}")]
+	Persist(#[from] tempfile::PersistError),
+	#[error("parsing failed, refusing to reformat corrupted input")]
+	ParseError,
+}
 
-		local ass = assert false : false; false;
-
-		local fn = function(a, b, c = 3) 4;
-
-		local comp = [a for b in c if d == e];
-		local ocomp = {[k]: 1 for k in v};
-
-		local ? = skip;
-
-		local ie = a[expr];
-
-		local unary = !a;
-
-		local
-			//   I am comment
-			singleLocalWithItemComment = 1,
-		;
-
-		// Comment between local and expression
-
-		local
-			a = 1, //   Inline
-			// Comment above b
-			b = 4,
-
-			// c needs some space
-			c = 5,
-
-			// Comment after everything
-		;
-
-
-		local Template = {z: "foo"};
-
-		{
-						local
-
-					h = 3,
-					assert self.a == 1
+fn main_result() -> Result<(), Error> {
+	eprintln!("jrsonnet-fmt is a prototype of a jsonnet code formatter, do not expect it to produce meaningful results right now.");
+	eprintln!("It is not expected for its output to match other implementations, it will be completly separate implementation with maybe different name.");
+	let mut opts = Opts::parse();
+	let input = if opts.exec {
+		if opts.in_place {
+			return Err(Error::InPlaceExec);
+		}
+		opts.input.clone()
+	} else {
+		fs::read_to_string(&opts.input)?
+	};
 
-					: "error",
-		"f": ((((((3)))))) ,
-		"g g":
-		f(4,2),
-		arr: [[
-		  1, 2,
-		  ],
-		  3,
-		  {
-			  b: {
-				  c: {
-					  k: [16]
-				  }
-			  }
-		  }
-		  ],
-		  m: a[1::],
-		  m: b[::],
-
-		  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
-			s
-			*/
-			c: '',
-
-			/*
-
-	Multi-line
-
-	comment
-			*/
-			d: '',
-
-			e: '', // Inline comment
-
-			k: '',
-
-			// Text after everything
-		  },
-		  comments2: {
-			k: '',
-			// Text after everything, but no newline above
-		  },
-		  k: if a         == b    then
-
-
-		  2
-
-		  else Template {},
-
-		  compspecs: {
-			obj_with_no_item: {a:1, for i in [1, 2, 3]},
-			obj_with_2_items: {a:1, /*b:2,*/ for i in [1,2,3]},
-		  }
-
-		} + Template
-"#;
+	if opts.indent == 0 {
+		// Sane default.
+		// TODO: Implement actual guessing.
+		opts.hard_tabs = true;
+	}
 
 	let mut iteration = 0;
-	let mut a = input.to_string();
-	let mut b;
+	let mut formatted = input.clone();
+	let mut tmp;
 	// https://github.com/dprint/dprint/pull/423
 	loop {
-		b = format(&a).trim().to_owned();
-		if a == b {
+		let Some(reformatted) = format(
+			&formatted,
+			&FormatOptions {
+				indent: if opts.indent == 0 || opts.hard_tabs {
+					0
+				} else {
+					opts.indent
+				},
+			},
+		) else {
+			return Err(Error::ParseError);
+		};
+		tmp = reformatted.trim().to_owned();
+		if formatted == tmp {
 			break;
 		}
-		println!("{b}");
-		a = b;
+		formatted = tmp;
+		if opts.conv_limit == 0 {
+			break;
+		}
 		iteration += 1;
-		if iteration > 5 {
+		if iteration > opts.conv_limit {
 			panic!("formatting not converged");
-			break;
 		}
 	}
-	println!("{a}");
+	formatted.push('\n');
+	if opts.test && formatted != input {
+		process::exit(1);
+	}
+	if opts.in_place {
+		let path = PathBuf::from(opts.input);
+		let mut temp = tempfile::NamedTempFile::new_in(path.parent().expect(
+			"not failed during read, this path is not a directory, and there is a parent",
+		))?;
+		temp.write_all(formatted.as_bytes())?;
+		temp.flush()?;
+		temp.persist(&path)?;
+	} else {
+		print!("{formatted}")
+	}
+	Ok(())
+}
+
+fn main() {
+	if let Err(e) = main_result() {
+		eprintln!("{e}");
+		process::exit(1);
+	}
 }
modifiedcmds/jrsonnet/src/main.rsdiffbeforeafterboth
--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -37,15 +37,15 @@
 #[derive(Parser)]
 #[clap(next_help_heading = "INPUT")]
 struct InputOpts {
-	/// Treat input as code, evaluate them instead of reading file
+	/// Treat input as code, evaluate it instead of reading file.
 	#[clap(long, short = 'e')]
 	pub exec: bool,
 
-	/// Path to the file to be compiled if `--evaluate` is unset, otherwise code itself
+	/// Path to the file to be compiled if `--exec` is unset, otherwise code itself.
 	pub input: Option<String>,
 
 	/// After executing input, apply specified code.
-	/// Output of the initial input will be accessible using `$`
+	/// Output of the initial input will be accessible using `_`.
 	#[cfg(feature = "exp-apply")]
 	#[clap(long)]
 	pub exp_apply: Vec<String>,