From 6bbb45b97f12ae1628ddc82d6047beb3efa46315 Mon Sep 17 00:00:00 2001 From: Robert DeLanghe <1240090+bdelanghe@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:03:07 -0400 Subject: [PATCH 1/2] chore(deps): upgrade tree-sitter stack to 0.26 / rust 0.24 / html 0.23 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tree-sitter 0.22 → 0.26.10 tree-sitter-rust 0.21 → 0.24.2 tree-sitter-html 0.20 → 0.23.2 Both grammar call sites updated: language() fn → LANGUAGE.into(), which is the canonical API since the 0.23 grammar series. All 97 unit tests and 5 cucumber tests pass unchanged. Co-Authored-By: Claude Sonnet 4.6 --- Cargo.lock | 55 ++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 6 +++--- src/html.rs | 2 +- src/printer.rs | 2 +- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89240f4..9989f5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,6 +278,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.14" @@ -453,6 +459,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "heck" version = "0.4.1" @@ -487,6 +499,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "inflections" version = "1.1.1" @@ -803,6 +825,7 @@ version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ + "indexmap", "itoa", "memchr", "serde", @@ -839,6 +862,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + [[package]] name = "strsim" version = "0.11.1" @@ -966,32 +995,42 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.22.6" +version = "0.26.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca" +checksum = "3c343ed63e3f5c64d1acdecb5d2c13d4e169cb5fde0052106ebaa6c6f27f9e55" dependencies = [ "cc", "regex", + "regex-syntax 0.8.11", + "serde_json", + "streaming-iterator", + "tree-sitter-language", ] [[package]] name = "tree-sitter-html" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8766b5ad3721517f8259e6394aefda9c686aebf7a8c74ab8624f2c3b46902fd5" +checksum = "261b708e5d92061ede329babaaa427b819329a9d427a1d710abb0f67bbef63ee" dependencies = [ "cc", - "tree-sitter", + "tree-sitter-language", ] +[[package]] +name = "tree-sitter-language" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" + [[package]] name = "tree-sitter-rust" -version = "0.21.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "277690f420bf90741dea984f3da038ace46c4fe6047cba57a66822226cde1c93" +checksum = "439e577dbe07423ec2582ac62c7531120dbfccfa6e5f92406f93dd271a120e45" dependencies = [ "cc", - "tree-sitter", + "tree-sitter-language", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4bd1bad..dc08fb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,9 @@ repository = "https://github.com/bounded-systems/git-ast" # its `Map` is a `BTreeMap` (keys sorted) with deterministic scalar formatting — # exactly the value-level normalization a canonical form needs. [dependencies] -tree-sitter = "0.22" -tree-sitter-rust = "0.21" -tree-sitter-html = "0.20" +tree-sitter = "0.26" +tree-sitter-rust = "0.24" +tree-sitter-html = "0.23" serde_json = "1" # The Gherkin suite (tests/features/*.feature) executes the README's claims diff --git a/src/html.rs b/src/html.rs index 4daf1ec..af36c4e 100644 --- a/src/html.rs +++ b/src/html.rs @@ -25,7 +25,7 @@ use crate::Error; fn parse(source: &[u8]) -> Result { let mut parser = Parser::new(); parser - .set_language(&tree_sitter_html::language()) + .set_language(&tree_sitter_html::LANGUAGE.into()) .map_err(|e| Error::Parsing(format!("loading HTML grammar: {e}")))?; parser .parse(source, None) diff --git a/src/printer.rs b/src/printer.rs index f2d355f..1008eb3 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -66,7 +66,7 @@ pub fn canonicalize(source: &[u8]) -> Result, Error> { fn parse(source: &[u8]) -> Result { let mut parser = Parser::new(); parser - .set_language(&tree_sitter_rust::language()) + .set_language(&tree_sitter_rust::LANGUAGE.into()) .map_err(|e| Error::Parsing(format!("loading Rust grammar: {e}")))?; let tree = parser .parse(source, None) From f85f36e4c9d7e1db7391f6778e92be6eae83aa53 Mon Sep 17 00:00:00 2001 From: Robert DeLanghe <1240090+bdelanghe@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:08:47 -0400 Subject: [PATCH 2/2] style: rustfmt html.rs (CI fmt check) --- src/html.rs | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/html.rs b/src/html.rs index af36c4e..65796fb 100644 --- a/src/html.rs +++ b/src/html.rs @@ -175,7 +175,8 @@ fn extract_attr_value(node: Node, src: &[u8]) -> String { // use `node` again in the fallback path. let found: Option = { let mut c = node.walk(); - let x = node.named_children(&mut c) + let x = node + .named_children(&mut c) .find(|n| n.kind() == "attribute_value") .and_then(|n| n.utf8_text(src).ok()) .map(str::to_string); @@ -425,8 +426,7 @@ fn element_to_def(node: Node, src: &[u8]) -> Option { let mut cursor = node.walk(); let children: Vec = node.children(&mut cursor).collect(); drop(cursor); - let (tag_node, has_body) = if let Some(&st) = - children.iter().find(|n| n.kind() == "start_tag") + let (tag_node, has_body) = if let Some(&st) = children.iter().find(|n| n.kind() == "start_tag") { (st, true) } else if let Some(&sc) = children.iter().find(|n| n.kind() == "self_closing_tag") { @@ -443,7 +443,11 @@ fn element_to_def(node: Node, src: &[u8]) -> Option { .get("role") .and_then(|r| aria_kind(r)) .or_else(|| implicit_role(&tag_name))?; - let text = if has_body { collect_text(node, src) } else { String::new() }; + let text = if has_body { + collect_text(node, src) + } else { + String::new() + }; let name = accessible_name(&attrs, &text).unwrap_or_default(); Some(make_def(kind, &name, &tag_name, &attrs)) } @@ -488,12 +492,7 @@ fn self_closing_to_def(node: Node, src: &[u8]) -> Option { /// so two elements that differ only in label share the same shape. const NAME_ATTRS: &[&str] = &["aria-label", "title", "alt"]; -fn make_def( - kind: &'static str, - name: &str, - tag: &str, - attrs: &BTreeMap, -) -> Def { +fn make_def(kind: &'static str, name: &str, tag: &str, attrs: &BTreeMap) -> Def { let attr_str: String = attrs .iter() .map(|(k, v)| format!("{k}={v}")) @@ -571,7 +570,10 @@ mod tests { #[test] fn values_double_quoted() { let out = canon(r#"link"#); - assert!(out.contains(r#"href="/page""#), "single quotes not converted: {out}"); + assert!( + out.contains(r#"href="/page""#), + "single quotes not converted: {out}" + ); } #[test] @@ -599,7 +601,10 @@ mod tests { fn script_and_style_preserved_verbatim() { let src = ""; let out = canon(src); - assert!(out.contains("var x={b:1,a:2};"), "script was modified: {out}"); + assert!( + out.contains("var x={b:1,a:2};"), + "script was modified: {out}" + ); } // ── inspect ─────────────────────────────────────────────────────────────── @@ -704,7 +709,11 @@ mod tests { fn subtree_hashes_nonempty_for_semantic_elements() { let ds = defs(r#""#); for d in &ds { - assert!(!d.subtree_hashes.is_empty(), "no subtree hashes for {}", d.kind); + assert!( + !d.subtree_hashes.is_empty(), + "no subtree hashes for {}", + d.kind + ); } } }