diff --git a/CHANGELOG.md b/CHANGELOG.md index 1229f214..b87f9220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -181,6 +181,15 @@ adheres to [Semantic Versioning](https://semver.org/). next to `HOME` (#692 class 5, 1 Windows failure in run 38008915302). `Path.expanduser` reads `USERPROFILE` on Windows and ignores `HOME`, so `~/state` resolved under the runner's real profile instead of the test root. +- The Kotlin walker tests pinned tree-sitter's error recovery instead of the + walker: their fixture `class A { fun m() {} class B { ... } }` is not valid + Kotlin (declarations need a newline or `;`), so the expected definitions + changed with the grammar release, and bumping tree-sitter-language-pack to + 1.23.1 (#932) failed `unit` on `TestKotlin` (run 42350563661). The fixture is + now valid Kotlin, a test asserts it parses without error, and the pin moves + to `<1.24`, locked at 1.23.1, whose grammar parses a bare `object O { ... }` + as an `object_declaration`: `O` and `O.o` are now reported where 1.22.1 + dropped `O` and left `o` unqualified. - Four `validate_memory` tests write their file references the way the platform writes paths (#692 class 5, 4 Windows failures in run 38008915302). `f"{tmp_path}/a.py"` mixes `\` and `/` on Windows, and the extractor reads diff --git a/pyproject.toml b/pyproject.toml index 2c52be25..a514b27c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -132,7 +132,7 @@ codebase = [ # # # - "tree-sitter-language-pack>=1.12.5,<1.23", + "tree-sitter-language-pack>=1.12.5,<1.24", "networkx>=3.0", # source: ADR-0874 # diff --git a/tests_py/core/test_ast_extractor_walkers.py b/tests_py/core/test_ast_extractor_walkers.py index 34291dbd..d4cd2461 100644 --- a/tests_py/core/test_ast_extractor_walkers.py +++ b/tests_py/core/test_ast_extractor_walkers.py @@ -16,7 +16,7 @@ Every expectation below was measured against the implementation, not predicted, then read back against the source to confirm it is the intended -contract rather than a bug being frozen. Three measured behaviours are +contract rather than a bug being frozen. Two measured behaviours are surprising enough to name explicitly, and are pinned here as *current* behaviour so that changing them becomes a deliberate act with a failing test, not an accident: @@ -24,8 +24,6 @@ * Swift `enum`/`struct` report kind ``class``. tree-sitter-swift parses all three as ``class_declaration``, so ``_SWIFT_KIND_MAP``'s ``enum_declaration`` and ``struct_declaration`` entries never match. -* Kotlin ``object O { ... }`` emits no entry for ``O``, and its members are - attributed to no type (``o``/``function``, not ``O.o``/``method``). * Ruby ``def self.name`` is not emitted at all — it parses as ``singleton_method``, which the walker does not handle. @@ -63,9 +61,17 @@ class Inner { void deep() {} } } """ +# Valid Kotlin: members of `A` sit on their own lines, because Kotlin needs a +# newline or `;` between declarations. The earlier one-line `class A { fun m() +# {} class B {...} }` was a syntax error the walker only read through the +# grammar's error recovery, so its output tracked the grammar release, not the +# walker (tree-sitter-language-pack 1.23.1 recovers differently and lost `A.m`). KOTLIN_SOURCE = b"""interface I { fun x() } object O { fun o() {} } -class A { fun m() {} class B { fun deep() {} } } +class A { + fun m() {} + class B { fun deep() {} } +} fun top() {} """ @@ -158,29 +164,41 @@ def test_full_definition_set_in_document_order(self) -> None: assert _defs("kotlin", KOTLIN_SOURCE, extract_kotlin_definitions) == [ ("I", "interface"), ("I.x", "method"), - ("o", "function"), + ("O", "class"), + ("O.o", "method"), ("A", "class"), ("A.m", "method"), - ("A.deep", "method"), + ("B", "class"), + ("B.deep", "method"), ("top", "function"), ] - def test_object_declaration_emits_no_type_entry(self) -> None: - """Pins the surprise: a bare `object O` yields nothing for O, and its - member is unqualified. Changing this should require editing this - assertion. + def test_fixture_is_valid_kotlin(self) -> None: + """The walker contract is pinned on source the grammar accepts. On a + syntax error the definitions come from error recovery, which changes + between grammar releases (the reason this fixture was rewritten). + """ + from tree_sitter_language_pack import get_parser + + assert not get_parser("kotlin").parse(KOTLIN_SOURCE).root_node.has_error + + def test_bare_object_declaration_emits_a_type_entry(self) -> None: + """`object O { ... }` with no supertype is an `object_declaration` + carrying a `type_identifier` in tree-sitter-language-pack 1.23.1, so O + is reported and its member is qualified. The 1.22.1 grammar parsed it + as an `infix_expression` with an ERROR, which is why an earlier + version of this test pinned "no entry for O". """ from mcp_server.core.ast_extractors_jvm import extract_kotlin_definitions got = _defs("kotlin", KOTLIN_SOURCE, extract_kotlin_definitions) - assert ("O", "class") not in got - assert ("o", "function") in got + assert ("O", "class") in got + assert ("O.o", "method") in got + assert ("o", "function") not in got def test_object_with_a_supertype_does_emit_a_type_entry(self) -> None: - """The contrast that explains the surprise above: with a supertype the - grammar produces a `type_identifier`, so `object_declaration` is a - reachable, observable branch and not dead code. Without this case the - branch's node-type string is unpinned. + """A supertype does not change the shape: still an + `object_declaration` with a `type_identifier`, members qualified. """ from mcp_server.core.ast_extractors_jvm import extract_kotlin_definitions diff --git a/uv.lock b/uv.lock index 87676c3b..f4ae60c4 100644 --- a/uv.lock +++ b/uv.lock @@ -1484,7 +1484,7 @@ requires-dist = [ { name = "sentence-transformers", marker = "extra == 'dev'", specifier = ">=3.0.0" }, { name = "sqlite-vec", marker = "extra == 'sqlite'", specifier = ">=0.1.1" }, { name = "tree-sitter", marker = "extra == 'codebase'", specifier = ">=0.24.0,<0.27" }, - { name = "tree-sitter-language-pack", marker = "extra == 'codebase'", specifier = ">=1.12.5,<1.23" }, + { name = "tree-sitter-language-pack", marker = "extra == 'codebase'", specifier = ">=1.12.5,<1.24" }, ] provides-extras = ["postgresql", "sqlite", "codebase", "viz-tile", "benchmarks", "otel", "dev"] @@ -4787,19 +4787,19 @@ wheels = [ [[package]] name = "tree-sitter-language-pack" -version = "1.22.1" +version = "1.23.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "tree-sitter" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/e0/ac9bb5f5241b8c406da03ff30a457f385fabd489d06e77ef81378d34bc4e/tree_sitter_language_pack-1.22.1.tar.gz", hash = "sha256:e0cba16312890fc7747da5fb5edb7aabfc68aac7db0ebab5212986a67cd01ed4", size = 89948, upload-time = "2026-10-12T18:26:39.348Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/39/995494c7732d945360a75d5cda5f0428f60c2985e45f391c6e3fe8e29a54/tree_sitter_language_pack-1.23.1.tar.gz", hash = "sha256:ebd76299a70d7387932d35bf6ed388e7822445c363526a0e7cc7f31f14d81bf5", size = 70587, upload-time = "2026-11-02T02:05:59.906Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/04/97b69d8ce812bd17cb8180f837bcd17a8ae61362fd1e6f61cf526027f0e1/tree_sitter_language_pack-1.22.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d34a528bdd845d024c42da3fa43495c5d51c66151597ea6e46a1e9d79d863e89", size = 2313359, upload-time = "2026-10-12T18:26:29.718Z" }, - { url = "https://files.pythonhosted.org/packages/4d/5b/5157fef42981eac1e315ab9cfd2e1e7189d53677b68405d171a620b7a52a/tree_sitter_language_pack-1.22.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:b85116c8a8d7bbdca2e1be8068d6c3d4f0ac66e95b3310a6dbdd21fc87332323", size = 2199623, upload-time = "2026-10-12T18:26:31.601Z" }, - { url = "https://files.pythonhosted.org/packages/1a/3c/de8422cd16bbf8aad4da68b5182ad985c8f32c5573d9fa8aa7c527cdce34/tree_sitter_language_pack-1.22.1-cp310-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:852a0129463a94f898dda2aa9616fb19e598d9a0a9d3024ec9dc2bffb3fa7945", size = 2356785, upload-time = "2026-10-12T18:26:33.649Z" }, - { url = "https://files.pythonhosted.org/packages/6b/e1/30683d0d99c9cb7ae0fc23d6c6e8fb0bf9a1ac520fc8fd7cb9d12fe0cd46/tree_sitter_language_pack-1.22.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8a476b71c2f6c71f23b0b63f5ff6f72a8ba2c11901db63c360ebcaf1fc51af5c", size = 2473497, upload-time = "2026-10-12T18:26:35.085Z" }, - { url = "https://files.pythonhosted.org/packages/92/d0/9ebe21280bbe31fe0d7a2885837c616304eabf05fe5f74dfa973b54eccc6/tree_sitter_language_pack-1.22.1-cp310-abi3-win_amd64.whl", hash = "sha256:624d90afb8b210584bdcb871935385035872eeb12b26e41f487c0c8e1cab350b", size = 2257970, upload-time = "2026-10-12T18:26:36.548Z" }, - { url = "https://files.pythonhosted.org/packages/80/76/8bcee4c731ef0e6e610491b3614a45e63aa9550d99e951d9a14fa314da57/tree_sitter_language_pack-1.22.1-cp310-abi3-win_arm64.whl", hash = "sha256:34e4e7a77d02d102abf95c7b088962fcd56825bd48eabbe80f93e1d43665e7ad", size = 2164528, upload-time = "2026-10-12T18:26:38.09Z" }, + { url = "https://files.pythonhosted.org/packages/d9/2c/76333d53e86506e7f74a511d29811e4bb532faad4e2989ad622ce45a8754/tree_sitter_language_pack-1.23.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:81ea85e3cb1d15164a2ecb64fd15e213ab6366977a424d1f74b096b7f06aef10", size = 2289597, upload-time = "2026-11-02T02:05:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3e/63adcac14d4e75f86eb7b5d85e9d2f38e1f1c99144a24a838c296744b039/tree_sitter_language_pack-1.23.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:cc0e6789e7c759fd29da58176c54bf6869cf0936b7d59724f851b108c8adcf6f", size = 2175161, upload-time = "2026-11-02T02:05:52.812Z" }, + { url = "https://files.pythonhosted.org/packages/51/b9/e685126af89ab3a3d2b8efdc52e9ebcdfd7e9f9a8c71c0ce93c26f3a35ee/tree_sitter_language_pack-1.23.1-cp310-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b9597ef3971a4ec842fdf2b51a9fd5210f9c5a38ab35e11bffa3188ddf145411", size = 2334535, upload-time = "2026-11-02T02:05:54.179Z" }, + { url = "https://files.pythonhosted.org/packages/9c/21/c84919f91a07cfb135469d59b37c93b68970bf279bce71d67a18c85ee9bf/tree_sitter_language_pack-1.23.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:0091c27b7f9d625d1181582abafaae8a0f3d0aa9d39c2d2048016ffbb0e17790", size = 2452822, upload-time = "2026-11-02T02:05:55.554Z" }, + { url = "https://files.pythonhosted.org/packages/3b/4d/3f3bfc6fcc4c00ef285e8925b354c13970f36dad55a96f192a088978155c/tree_sitter_language_pack-1.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:3dc50ff0ba575480a437a575947c3e3247dd79b1511811d2741a0790f6dd9fe9", size = 2239402, upload-time = "2026-11-02T02:05:57.274Z" }, + { url = "https://files.pythonhosted.org/packages/01/18/a03f664a0c2a12ced2c72451bfb83958c00951643d60f4046d51ede126d1/tree_sitter_language_pack-1.23.1-cp310-abi3-win_arm64.whl", hash = "sha256:292a63023da2a90541ac63d24fe13bbe5790abf49b450376a2534ac574245d29", size = 2145049, upload-time = "2026-11-02T02:05:58.771Z" }, ] [[package]]