diff --git a/.gitignore b/.gitignore index 4fffb2f..ea8c4bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ /target -/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ddd168d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1047 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" + +[[package]] +name = "ascii" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "codemap" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24" + +[[package]] +name = "codemap-diagnostic" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba0e6be8e2774e750f9e90625b490249715bece38a12f9d09e82477caba5028" +dependencies = [ + "atty", + "codemap", + "termcolor", +] + +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "terminal_size", + "winapi", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "fastrand" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +dependencies = [ + "instant", +] + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "html-escape" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e7479fa1ef38eb49fb6a42c426be515df2d063f06cb8efd3e50af073dbc26c" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "insta" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4126dd76ebfe2561486a1bd6738a33d2029ffb068a99ac446b7f8c77b2e58dbc" +dependencies = [ + "console", + "once_cell", + "serde", + "serde_json", + "serde_yaml", + "similar", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "js-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +dependencies = [ + "wasm-bindgen", +] + +[[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.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rust_sitter" +version = "0.1.0" +dependencies = [ + "insta", + "rust_sitter_macro", + "tempfile", + "tree-sitter", +] + +[[package]] +name = "rust_sitter_example" +version = "0.1.0" +dependencies = [ + "cc", + "codemap", + "codemap-diagnostic", + "insta", + "rust_sitter", + "rust_sitter_tool", + "tempdir", + "tree-sitter", + "tree-sitter-cli", +] + +[[package]] +name = "rust_sitter_macro" +version = "0.1.0" +dependencies = [ + "insta", + "proc-macro2", + "quote", + "syn", + "tempfile", +] + +[[package]] +name = "rust_sitter_tool" +version = "0.1.0" +dependencies = [ + "insta", + "serde", + "serde_json", + "syn", + "syn-inline-mod", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "semver" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" + +[[package]] +name = "serde" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "similar" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" + +[[package]] +name = "smallbitvec" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ce4f9dc4a41b4c3476cc925f1efb11b66df373a8fde5d4b8915fa91b5d995e" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-inline-mod" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b670f535364c67358ecffb60b9f2579f9b45d3c71e8cca6d45d22ee0fadaa7eb" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand", + "remove_dir_all", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[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 = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny_http" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce51b50006056f590c9b7c3808c3bd70f0d1101666629713866c227d6e58d39" +dependencies = [ + "ascii", + "chrono", + "chunked_transfer", + "log", + "url", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tree-sitter" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "549a9faf45679ad50b7f603253635598cf5e007d8ceb806a23f95355938f76a0" +dependencies = [ + "cc", + "regex", +] + +[[package]] +name = "tree-sitter-cli" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab14de5f4c74f5115872ede7ec7089cb0208762f61cac0b4899faf415d04dcd" +dependencies = [ + "ansi_term", + "anyhow", + "atty", + "clap", + "difference", + "dirs", + "glob", + "html-escape", + "indexmap", + "lazy_static", + "log", + "regex", + "regex-syntax", + "rustc-hash", + "semver", + "serde", + "serde_json", + "smallbitvec", + "tiny_http", + "toml", + "tree-sitter", + "tree-sitter-config", + "tree-sitter-highlight", + "tree-sitter-loader", + "tree-sitter-tags", + "walkdir", + "webbrowser", + "which", +] + +[[package]] +name = "tree-sitter-config" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fec4cb27f052ead2246631b332dba0cb6af9a54ce012badee59c4b0ded5e03" +dependencies = [ + "anyhow", + "dirs", + "serde", + "serde_json", +] + +[[package]] +name = "tree-sitter-highlight" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "042342584c5a7a0b833d9fc4e2bdab3f9868ddc6c4b339a1e01451c6720868bc" +dependencies = [ + "regex", + "thiserror", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-loader" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b17eef4833c7c139abed66d562dfa23228e97e647597baf246fd56c21bbfaf" +dependencies = [ + "anyhow", + "cc", + "dirs", + "libloading", + "once_cell", + "regex", + "serde", + "serde_json", + "tree-sitter", + "tree-sitter-highlight", + "tree-sitter-tags", +] + +[[package]] +name = "tree-sitter-tags" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb3f1376219530a37a809751ecf65aa35fd8b9c1c4ab6d4faf5f6a9eeda2c05" +dependencies = [ + "memchr", + "regex", + "thiserror", + "tree-sitter", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" + +[[package]] +name = "unicode-normalization" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" + +[[package]] +name = "web-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a" +dependencies = [ + "web-sys", + "widestring", + "winapi", +] + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + +[[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-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[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 = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/example/build.rs b/example/build.rs index bef96a5..bb846d6 100644 --- a/example/build.rs +++ b/example/build.rs @@ -14,13 +14,8 @@ fn main() { let grammar_file = dir.path().join("parser.c"); let mut f = File::create(grammar_file).unwrap(); - f.write_all( - generate::generate_parser_for_grammar(grammar) - .unwrap() - .1 - .as_bytes(), - ) - .unwrap(); + let (grammar_name, grammar_c) = generate::generate_parser_for_grammar(grammar).unwrap(); + f.write_all(grammar_c.as_bytes()).unwrap(); drop(f); let header_dir: PathBuf = dir.path().join("tree_sitter"); @@ -34,6 +29,6 @@ fn main() { cc::Build::new() .include(&dir) .file(dir.path().join("parser.c")) - .compile("grammar"); + .compile(&grammar_name); }); } diff --git a/example/src/main.rs b/example/src/main.rs index 18d5f8a..c0f2e8e 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -31,6 +31,29 @@ pub mod arithmetic_grammar { } } +#[rust_sitter::grammar("repetitions")] +pub mod repetitions { + #[rust_sitter::language] + #[derive(Debug)] + #[allow(dead_code)] + pub struct NumberList { + numbers: Vec, + } + + #[derive(Debug)] + #[allow(dead_code)] + pub struct Number { + #[rust_sitter::leaf(pattern = r"\d+", transform = |v| v.parse().unwrap())] + v: i32, + } + + #[rust_sitter::extra] + struct Whitespace { + #[rust_sitter::leaf(pattern = r"\s")] + _whitespace: (), + } +} + fn convert_parse_error_to_diagnostics( file_span: &codemap::Span, error: &ParseError, @@ -113,7 +136,7 @@ fn main() { #[cfg(test)] mod tests { - use super::arithmetic_grammar; + use super::*; #[test] fn arithmetic_grammar() { @@ -131,4 +154,10 @@ mod tests { insta::assert_debug_snapshot!(arithmetic_grammar::parse("a1")); insta::assert_debug_snapshot!(arithmetic_grammar::parse("1a")); } + + #[test] + fn repetitions_grammar() { + insta::assert_debug_snapshot!(repetitions::parse("1")); + insta::assert_debug_snapshot!(repetitions::parse("1 2")); + } } diff --git a/example/src/snapshots/rust_sitter_example__tests__arithmetic_grammar-8.snap b/example/src/snapshots/rust_sitter_example__tests__arithmetic_grammar-8.snap index 768aa73..125d3d6 100644 --- a/example/src/snapshots/rust_sitter_example__tests__arithmetic_grammar-8.snap +++ b/example/src/snapshots/rust_sitter_example__tests__arithmetic_grammar-8.snap @@ -5,10 +5,10 @@ expression: "arithmetic_grammar::parse(\"1 - 2 -\")" Err( [ ParseError { - reason: FailedNode( - [], + reason: MissingToken( + "Expression_Number_0", ), - start: 6, + start: 7, end: 7, }, ], diff --git a/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar-2.snap b/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar-2.snap new file mode 100644 index 0000000..da2f15b --- /dev/null +++ b/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar-2.snap @@ -0,0 +1,16 @@ +--- +source: example/src/main.rs +expression: "repetitions::parse(\"1 2\")" +--- +Ok( + NumberList { + numbers: [ + Number { + v: 1, + }, + Number { + v: 2, + }, + ], + }, +) diff --git a/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar.snap b/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar.snap new file mode 100644 index 0000000..87323c4 --- /dev/null +++ b/example/src/snapshots/rust_sitter_example__tests__repetitions_grammar.snap @@ -0,0 +1,13 @@ +--- +source: example/src/main.rs +expression: "repetitions::parse(\"1\")" +--- +Ok( + NumberList { + numbers: [ + Number { + v: 1, + }, + ], + }, +) diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 25fbb6e..4614f91 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -28,6 +28,20 @@ impl Parse for NameValueExpr { } } +enum ParamOrField { + Param(Expr), + Field(FieldValue), +} + +impl ToTokens for ParamOrField { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match self { + ParamOrField::Param(expr) => expr.to_tokens(tokens), + ParamOrField::Field(field) => field.to_tokens(tokens), + } + } +} + fn gen_field(path: String, leaf: Field, out: &mut Vec) { let extract_ident = Ident::new(&format!("extract_{}", path), Span::call_site()); let leaf_type = leaf.ty; @@ -87,8 +101,29 @@ fn gen_field(path: String, leaf: Field, out: &mut Vec) { Box::new(#leaf_type::extract(node, source)) }, ) + } else if type_segment.ident == "Vec" { + let leaf_type = + if let PathArguments::AngleBracketed(p) = &type_segment.arguments { + p.args.first().unwrap().clone() + } else { + panic!("Expected angle bracketed path"); + }; + + let field_name = leaf.ident.unwrap().to_string(); + + ( + vec![syn::parse_quote! { + let mut cursor = node.walk(); + }], + syn::parse_quote! { + node + .children_by_field_name(#field_name, &mut cursor) + .map(|n| #leaf_type::extract(n, source)) + .collect::>() + }, + ) } else { - panic!("Unexpected leaf type"); + panic!("Unexpected leaf type: {}", leaf_type.to_token_stream()); } } else { panic!("Unexpected leaf type"); @@ -128,27 +163,52 @@ fn gen_struct_or_variant( let extract_ident = Ident::new(&format!("extract_{}", path), Span::call_site()); - if let Some(variant_ident) = variant_ident { - let children_parsed = fields - .iter() - .enumerate() - .map(|(i, field)| { - let ident_str = field - .ident - .as_ref() - .map(|v| v.to_string()) - .unwrap_or(format!("{}", i)); - let ident = Ident::new( - &format!("extract_{}_{}", path.clone(), ident_str), - Span::call_site(), - ); + let children_parsed = fields + .iter() + .enumerate() + .map(|(i, field)| { + let ident_str = field + .ident + .as_ref() + .map(|v| v.to_string()) + .unwrap_or(format!("{}", i)); + let ident = Ident::new( + &format!("extract_{}_{}", path.clone(), ident_str), + Span::call_site(), + ); + + let is_vec = if let Type::Path(p) = &field.ty { + let type_segment = p.path.segments.first().unwrap(); + type_segment.ident == "Vec" + } else { + false + }; + let expr = if is_vec { + syn::parse_quote! { + #ident(node, source) + } + } else { syn::parse_quote! { #ident(node.child_by_field_name(#ident_str).unwrap(), source) } - }) - .collect::>(); + }; + + if field.ident.is_none() { + ParamOrField::Param(expr) + } else { + let field_name = field.ident.as_ref().unwrap(); + ParamOrField::Field(FieldValue { + attrs: vec![], + member: Member::Named(field_name.clone()), + colon_token: Some(Token![:](Span::call_site())), + expr, + }) + } + }) + .collect::>(); + if let Some(variant_ident) = variant_ident { out.push(syn::parse_quote! { #[allow(non_snake_case)] fn #extract_ident(node: tree_sitter::Node, source: &[u8]) -> #containing_type { @@ -158,32 +218,6 @@ fn gen_struct_or_variant( } }); } else { - let children_parsed = fields - .iter() - .enumerate() - .map(|(i, field)| { - let ident_str = field - .ident - .as_ref() - .map(|v| v.to_string()) - .unwrap_or(format!("{}", i)); - let ident = Ident::new( - &format!("extract_{}_{}", path.clone(), ident_str), - Span::call_site(), - ); - - let field_name = field.ident.as_ref().unwrap(); - FieldValue { - attrs: vec![], - member: Member::Named(field_name.clone()), - colon_token: Some(Token![:](Span::call_site())), - expr: syn::parse_quote! { - #ident(node.child_by_field_name(#ident_str).unwrap(), source) - }, - } - }) - .collect::>(); - out.push(syn::parse_quote! { #[allow(non_snake_case)] fn #extract_ident(node: tree_sitter::Node, source: &[u8]) -> #containing_type { @@ -222,12 +256,13 @@ fn expand_grammar(input: ItemMod) -> ItemMod { let root_type = new_contents .iter() .find_map(|item| match item { - Item::Enum(e) => { - if e.attrs + Item::Enum(ItemEnum { ident, attrs, .. }) + | Item::Struct(ItemStruct { ident, attrs, .. }) => { + if attrs .iter() .any(|attr| attr.path == syn::parse_quote!(rust_sitter::language)) { - Some(e.ident.clone()) + Some(ident.clone()) } else { None } @@ -313,7 +348,6 @@ fn expand_grammar(input: ItemMod) -> ItemMod { #[allow(non_snake_case)] fn extract(node: tree_sitter::Node, source: &[u8]) -> Self { #(#impl_body)* - #extract_ident(node, source) } } @@ -358,7 +392,7 @@ fn expand_grammar(input: ItemMod) -> ItemMod { Err(errors) } else { use rust_sitter::Extract; - Ok(#root_type::extract(root_node.child(0).unwrap(), input.as_bytes())) + Ok(#root_type::extract(root_node, input.as_bytes())) } } }); @@ -545,4 +579,32 @@ mod tests { .to_string() )); } + + #[test] + fn struct_repeat() { + insta::assert_display_snapshot!(rustfmt_code( + &expand_grammar(parse_quote! { + #[rust_sitter::grammar("test")] + mod ffi { + #[rust_sitter::language] + pub struct NumberList { + numbers: Vec, + } + + pub struct Number { + #[rust_sitter::leaf(pattern = r"\d+", transform = |v| v.parse().unwrap())] + v: i32 + } + + #[rust_sitter::extra] + struct Whitespace { + #[rust_sitter::leaf(pattern = r"\s")] + _whitespace: (), + } + } + }) + .to_token_stream() + .to_string() + )); + } } diff --git a/macro/src/snapshots/rust_sitter_macro__tests__enum_prec_left.snap b/macro/src/snapshots/rust_sitter_macro__tests__enum_prec_left.snap index 5b22966..4d845fc 100644 --- a/macro/src/snapshots/rust_sitter_macro__tests__enum_prec_left.snap +++ b/macro/src/snapshots/rust_sitter_macro__tests__enum_prec_left.snap @@ -74,10 +74,7 @@ mod ffi { Err(errors) } else { use rust_sitter::Extract; - Ok(Expression::extract( - root_node.child(0).unwrap(), - input.as_bytes(), - )) + Ok(Expression::extract(root_node, input.as_bytes())) } } } diff --git a/macro/src/snapshots/rust_sitter_macro__tests__enum_recursive.snap b/macro/src/snapshots/rust_sitter_macro__tests__enum_recursive.snap index 6da7dde..3d157e5 100644 --- a/macro/src/snapshots/rust_sitter_macro__tests__enum_recursive.snap +++ b/macro/src/snapshots/rust_sitter_macro__tests__enum_recursive.snap @@ -68,10 +68,7 @@ mod ffi { Err(errors) } else { use rust_sitter::Extract; - Ok(Expression::extract( - root_node.child(0).unwrap(), - input.as_bytes(), - )) + Ok(Expression::extract(root_node, input.as_bytes())) } } } diff --git a/macro/src/snapshots/rust_sitter_macro__tests__enum_transformed_fields.snap b/macro/src/snapshots/rust_sitter_macro__tests__enum_transformed_fields.snap index 7d2e216..cfe30ed 100644 --- a/macro/src/snapshots/rust_sitter_macro__tests__enum_transformed_fields.snap +++ b/macro/src/snapshots/rust_sitter_macro__tests__enum_transformed_fields.snap @@ -49,10 +49,7 @@ mod ffi { Err(errors) } else { use rust_sitter::Extract; - Ok(Expression::extract( - root_node.child(0).unwrap(), - input.as_bytes(), - )) + Ok(Expression::extract(root_node, input.as_bytes())) } } } diff --git a/macro/src/snapshots/rust_sitter_macro__tests__struct_extra.snap b/macro/src/snapshots/rust_sitter_macro__tests__struct_extra.snap index 78cf1ce..69333a2 100644 --- a/macro/src/snapshots/rust_sitter_macro__tests__struct_extra.snap +++ b/macro/src/snapshots/rust_sitter_macro__tests__struct_extra.snap @@ -72,10 +72,7 @@ mod ffi { Err(errors) } else { use rust_sitter::Extract; - Ok(Expression::extract( - root_node.child(0).unwrap(), - input.as_bytes(), - )) + Ok(Expression::extract(root_node, input.as_bytes())) } } } diff --git a/macro/src/snapshots/rust_sitter_macro__tests__struct_repeat.snap b/macro/src/snapshots/rust_sitter_macro__tests__struct_repeat.snap new file mode 100644 index 0000000..8b1c14a --- /dev/null +++ b/macro/src/snapshots/rust_sitter_macro__tests__struct_repeat.snap @@ -0,0 +1,98 @@ +--- +source: macro/src/lib.rs +expression: "rustfmt_code(&expand_grammar(parse_quote! {\n #[rust_sitter :: grammar(\"test\")] mod ffi\n {\n #[rust_sitter :: language] pub struct NumberList\n { numbers : Vec < Number >, } pub struct Number\n {\n #[rust_sitter ::\n leaf(pattern = r\"\\d+\", transform = | v |\n v.parse().unwrap())] v : i32\n } #[rust_sitter :: extra] struct Whitespace\n {\n #[rust_sitter :: leaf(pattern = r\"\\s\")] _whitespace : (),\n }\n }\n }).to_token_stream().to_string())" +--- +mod ffi { + pub struct NumberList { + numbers: Vec, + } + impl rust_sitter::Extract for NumberList { + #[allow(non_snake_case)] + fn extract(node: tree_sitter::Node, source: &[u8]) -> Self { + #[allow(non_snake_case)] + #[allow(clippy::unused_unit)] + fn extract_NumberList_numbers(node: tree_sitter::Node, source: &[u8]) -> Vec { + let mut cursor = node.walk(); + node.children_by_field_name("numbers", &mut cursor) + .map(|n| Number::extract(n, source)) + .collect::>() + } + #[allow(non_snake_case)] + fn extract_NumberList(node: tree_sitter::Node, source: &[u8]) -> NumberList { + NumberList { + numbers: extract_NumberList_numbers(node, source), + } + } + extract_NumberList(node, source) + } + } + pub struct Number { + v: i32, + } + impl rust_sitter::Extract for Number { + #[allow(non_snake_case)] + fn extract(node: tree_sitter::Node, source: &[u8]) -> Self { + #[allow(non_snake_case)] + #[allow(clippy::unused_unit)] + fn extract_Number_v(node: tree_sitter::Node, source: &[u8]) -> i32 { + fn make_transform() -> impl Fn(&str) -> i32 { + |v| v.parse().unwrap() + } + make_transform()(node.utf8_text(source).unwrap()) + } + #[allow(non_snake_case)] + fn extract_Number(node: tree_sitter::Node, source: &[u8]) -> Number { + Number { + v: extract_Number_v(node.child_by_field_name("v").unwrap(), source), + } + } + extract_Number(node, source) + } + } + struct Whitespace { + _whitespace: (), + } + impl rust_sitter::Extract for Whitespace { + #[allow(non_snake_case)] + fn extract(node: tree_sitter::Node, source: &[u8]) -> Self { + #[allow(non_snake_case)] + #[allow(clippy::unused_unit)] + fn extract_Whitespace__whitespace(node: tree_sitter::Node, source: &[u8]) -> () { + () + } + #[allow(non_snake_case)] + fn extract_Whitespace(node: tree_sitter::Node, source: &[u8]) -> Whitespace { + Whitespace { + _whitespace: extract_Whitespace__whitespace( + node.child_by_field_name("_whitespace").unwrap(), + source, + ), + } + } + extract_Whitespace(node, source) + } + } + extern "C" { + fn tree_sitter_test() -> tree_sitter::Language; + } + fn language() -> tree_sitter::Language { + unsafe { tree_sitter_test() } + } + pub fn parse( + input: &str, + ) -> core::result::Result> { + let mut parser = tree_sitter::Parser::new(); + parser.set_language(language()).unwrap(); + let tree = parser.parse(input, None).unwrap(); + let root_node = tree.root_node(); + if root_node.has_error() { + let mut errors = vec![]; + rust_sitter::errors::collect_parsing_errors(&root_node, input.as_bytes(), &mut errors); + Err(errors) + } else { + use rust_sitter::Extract; + Ok(NumberList::extract(root_node, input.as_bytes())) + } + } +} + diff --git a/tool/src/lib.rs b/tool/src/lib.rs index 7b48b0d..e0e02cc 100644 --- a/tool/src/lib.rs +++ b/tool/src/lib.rs @@ -102,6 +102,30 @@ fn gen_field(path: String, leaf: Field, out: &mut Map) -> Value { "type": "SYMBOL", "name": leaf_type.path.segments.first().unwrap().ident.to_string(), }) + } else if type_segment.ident == "Vec" { + let leaf_type = if let PathArguments::AngleBracketed(p) = &type_segment.arguments { + p.args.first().unwrap().clone() + } else { + panic!("Expected angle bracketed path"); + }; + + let leaf_type = if let GenericArgument::Type(Type::Path(t)) = leaf_type { + t + } else { + panic!("Expected type"); + }; + + json!({ + "type": "REPEAT", + "content": { + "type": "FIELD", + "name": leaf.ident.unwrap().to_string(), + "content": { + "type": "SYMBOL", + "name": leaf_type.path.segments.first().unwrap().ident.to_string(), + } + } + }) } else { panic!("Unexpected leaf type"); } @@ -167,6 +191,9 @@ fn gen_struct_or_variant( fn generate_grammar(module: &ItemMod) -> Value { let mut rules_map = Map::new(); + // for some reason, source_file must be the first key for things to work + rules_map.insert("source_file".to_string(), json!({})); + let mut extras_list = vec![]; let grammar_name = module @@ -195,12 +222,13 @@ fn generate_grammar(module: &ItemMod) -> Value { let root_type = contents .iter() .find_map(|item| match item { - Item::Enum(e) => { - if e.attrs + Item::Enum(ItemEnum { ident, attrs, .. }) + | Item::Struct(ItemStruct { ident, attrs, .. }) => { + if attrs .iter() .any(|attr| attr.path == syn::parse_quote!(rust_sitter::language)) { - Some(e.ident.clone()) + Some(ident.clone()) } else { None } @@ -210,19 +238,6 @@ fn generate_grammar(module: &ItemMod) -> Value { .expect("Each parser must have the root type annotated with `#[rust_sitter::language]`") .to_string(); - rules_map.insert( - "source_file".to_string(), - json!({ - "type": "ALIAS", - "named": false, - "value": &root_type, - "content": { - "type": "SYMBOL", - "name": &root_type - } - }), - ); - contents.iter().for_each(|c| { let (symbol, attrs) = match c { Item::Enum(e) => { @@ -279,6 +294,11 @@ fn generate_grammar(module: &ItemMod) -> Value { } }); + rules_map.insert( + "source_file".to_string(), + rules_map.get(&root_type).unwrap().clone(), + ); + json!({ "name": grammar_name, "rules": rules_map, diff --git a/tool/src/snapshots/rust_sitter_tool__tests__enum_prec_left.snap b/tool/src/snapshots/rust_sitter_tool__tests__enum_prec_left.snap index 474a79c..51801ae 100644 --- a/tool/src/snapshots/rust_sitter_tool__tests__enum_prec_left.snap +++ b/tool/src/snapshots/rust_sitter_tool__tests__enum_prec_left.snap @@ -2,4 +2,4 @@ source: tool/src/lib.rs expression: generate_grammar(&m) --- -{"name":"test","rules":{"source_file":{"type":"ALIAS","named":false,"value":"Expression","content":{"type":"SYMBOL","name":"Expression"}},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression_Sub_1":{"type":"STRING","value":"-"},"Expression_Sub":{"type":"PREC_LEFT","value":1,"content":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression"}},{"type":"FIELD","name":"1","content":{"type":"SYMBOL","name":"Expression_Sub_1"}},{"type":"FIELD","name":"2","content":{"type":"SYMBOL","name":"Expression"}}]}},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Sub"}]}},"extras":[]} +{"name":"test","rules":{"source_file":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Sub"}]},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression_Sub_1":{"type":"STRING","value":"-"},"Expression_Sub":{"type":"PREC_LEFT","value":1,"content":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression"}},{"type":"FIELD","name":"1","content":{"type":"SYMBOL","name":"Expression_Sub_1"}},{"type":"FIELD","name":"2","content":{"type":"SYMBOL","name":"Expression"}}]}},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Sub"}]}},"extras":[]} diff --git a/tool/src/snapshots/rust_sitter_tool__tests__enum_recursive.snap b/tool/src/snapshots/rust_sitter_tool__tests__enum_recursive.snap index 40160a8..3ef4731 100644 --- a/tool/src/snapshots/rust_sitter_tool__tests__enum_recursive.snap +++ b/tool/src/snapshots/rust_sitter_tool__tests__enum_recursive.snap @@ -2,4 +2,4 @@ source: tool/src/lib.rs expression: generate_grammar(&m) --- -{"name":"test","rules":{"source_file":{"type":"ALIAS","named":false,"value":"Expression","content":{"type":"SYMBOL","name":"Expression"}},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression_Neg_0":{"type":"STRING","value":"-"},"Expression_Neg":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Neg_0"}},{"type":"FIELD","name":"1","content":{"type":"SYMBOL","name":"Expression"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Neg"}]}},"extras":[]} +{"name":"test","rules":{"source_file":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Neg"}]},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression_Neg_0":{"type":"STRING","value":"-"},"Expression_Neg":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Neg_0"}},{"type":"FIELD","name":"1","content":{"type":"SYMBOL","name":"Expression"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"},{"type":"SYMBOL","name":"Expression_Neg"}]}},"extras":[]} diff --git a/tool/src/snapshots/rust_sitter_tool__tests__enum_transformed_fields.snap b/tool/src/snapshots/rust_sitter_tool__tests__enum_transformed_fields.snap index 0cc0c32..cc92734 100644 --- a/tool/src/snapshots/rust_sitter_tool__tests__enum_transformed_fields.snap +++ b/tool/src/snapshots/rust_sitter_tool__tests__enum_transformed_fields.snap @@ -2,4 +2,4 @@ source: tool/src/lib.rs expression: generate_grammar(&m) --- -{"name":"test","rules":{"source_file":{"type":"ALIAS","named":false,"value":"Expression","content":{"type":"SYMBOL","name":"Expression"}},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]}},"extras":[]} +{"name":"test","rules":{"source_file":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]}},"extras":[]} diff --git a/tool/src/snapshots/rust_sitter_tool__tests__grammar_with_extras.snap b/tool/src/snapshots/rust_sitter_tool__tests__grammar_with_extras.snap index 30c9d3c..ccda665 100644 --- a/tool/src/snapshots/rust_sitter_tool__tests__grammar_with_extras.snap +++ b/tool/src/snapshots/rust_sitter_tool__tests__grammar_with_extras.snap @@ -2,4 +2,4 @@ source: tool/src/lib.rs expression: generate_grammar(&m) --- -{"name":"test","rules":{"source_file":{"type":"ALIAS","named":false,"value":"Expression","content":{"type":"SYMBOL","name":"Expression"}},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]},"Whitespace__whitespace":{"type":"PATTERN","value":"\\s"},"Whitespace":{"type":"SEQ","members":[{"type":"FIELD","name":"_whitespace","content":{"type":"SYMBOL","name":"Whitespace__whitespace"}}]}},"extras":[{"type":"SYMBOL","name":"Whitespace"}]} +{"name":"test","rules":{"source_file":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]},"Expression_Number_0":{"type":"PATTERN","value":"\\d+"},"Expression_Number":{"type":"SEQ","members":[{"type":"FIELD","name":"0","content":{"type":"SYMBOL","name":"Expression_Number_0"}}]},"Expression":{"type":"CHOICE","members":[{"type":"SYMBOL","name":"Expression_Number"}]},"Whitespace__whitespace":{"type":"PATTERN","value":"\\s"},"Whitespace":{"type":"SEQ","members":[{"type":"FIELD","name":"_whitespace","content":{"type":"SYMBOL","name":"Whitespace__whitespace"}}]}},"extras":[{"type":"SYMBOL","name":"Whitespace"}]}