blockwatch-cli 0.16.4__tar.gz → 0.16.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/AGENTS.md +4 -8
  2. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/CHANGELOG.md +30 -0
  3. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/CLAUDE.md +4 -8
  4. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/Cargo.lock +1 -1
  5. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/Cargo.toml +1 -1
  6. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/PKG-INFO +1 -1
  7. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/README.md +6 -5
  8. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/ci.md +2 -2
  9. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/cli.md +3 -3
  10. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/symbols.md +223 -20
  11. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/setup.py +1 -1
  12. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/blocks.rs +4 -0
  13. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/c.rs +22 -40
  14. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/c_sharp.rs +47 -100
  15. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/go.rs +16 -18
  16. blockwatch_cli-0.16.6/src/language_parsers/hcl.rs +908 -0
  17. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/java.rs +35 -53
  18. blockwatch_cli-0.16.6/src/language_parsers/json.rs +453 -0
  19. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/kotlin.rs +43 -65
  20. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/mod.rs +26 -0
  21. blockwatch_cli-0.16.6/src/language_parsers/proto.rs +397 -0
  22. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/rust.rs +7 -7
  23. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/swift.rs +46 -76
  24. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/toml.rs +4 -20
  25. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/typescript.rs +7 -12
  26. blockwatch_cli-0.16.6/src/language_parsers/xml.rs +753 -0
  27. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/yaml.rs +9 -22
  28. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/skill.md +50 -6
  29. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/symbols/code.rs +122 -29
  30. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/symbols/mod.rs +548 -643
  31. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/symbol_references.rs +56 -0
  32. blockwatch_cli-0.16.6/tests/testdata/symbol_references/csproj_source.rs +3 -0
  33. blockwatch_cli-0.16.6/tests/testdata/symbol_references/csproj_target.csproj +6 -0
  34. blockwatch_cli-0.16.6/tests/testdata/symbol_references/hcl_source.rs +3 -0
  35. blockwatch_cli-0.16.6/tests/testdata/symbol_references/hcl_target.hcl +8 -0
  36. blockwatch_cli-0.16.6/tests/testdata/symbol_references/nomad_source.rs +3 -0
  37. blockwatch_cli-0.16.6/tests/testdata/symbol_references/nomad_target.nomad +5 -0
  38. blockwatch_cli-0.16.6/tests/testdata/symbol_references/proto_source.rs +3 -0
  39. blockwatch_cli-0.16.6/tests/testdata/symbol_references/proto_target.proto +8 -0
  40. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tf_source.rs +3 -0
  41. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tf_target.tf +8 -0
  42. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tfvars_source.rs +3 -0
  43. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tfvars_target.tfvars +1 -0
  44. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tofu_source.rs +3 -0
  45. blockwatch_cli-0.16.6/tests/testdata/symbol_references/tofu_target.tofu +4 -0
  46. blockwatch_cli-0.16.6/tests/testdata/symbol_references/xml_source.rs +3 -0
  47. blockwatch_cli-0.16.6/tests/testdata/symbol_references/xml_target.xml +12 -0
  48. blockwatch_cli-0.16.4/src/language_parsers/hcl.rs +0 -69
  49. blockwatch_cli-0.16.4/src/language_parsers/json.rs +0 -239
  50. blockwatch_cli-0.16.4/src/language_parsers/json.scm +0 -4
  51. blockwatch_cli-0.16.4/src/language_parsers/proto.rs +0 -71
  52. blockwatch_cli-0.16.4/src/language_parsers/xml.rs +0 -70
  53. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.agents/.claude-plugin/plugin.json +0 -0
  54. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.agents/skills/blockwatch/SKILL.md +0 -0
  55. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.claude-plugin/marketplace.json +0 -0
  56. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/dependabot.yml +0 -0
  57. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/blockwatch.yml +0 -0
  58. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/codeql.yml +0 -0
  59. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/markdownlint.yml +0 -0
  60. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/pypi.yml +0 -0
  61. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/release.yml +0 -0
  62. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/rust.yml +0 -0
  63. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.github/workflows/trusted-checks.yml +0 -0
  64. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.gitignore +0 -0
  65. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.markdownlint-cli2.yaml +0 -0
  66. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.pre-commit-config.yaml +0 -0
  67. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/.pre-commit-hooks.yaml +0 -0
  68. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/LICENSE +0 -0
  69. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/SECURITY.md +0 -0
  70. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/blockwatch.toml +0 -0
  71. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/clippy.toml +0 -0
  72. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/codecov.yml +0 -0
  73. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/demo.gif +0 -0
  74. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/dist-workspace.toml +0 -0
  75. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/agents.md +0 -0
  76. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/README.md +0 -0
  77. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/affects.md +0 -0
  78. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/check-ai.md +0 -0
  79. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/check-lua.md +0 -0
  80. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/keep-sorted.md +0 -0
  81. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/keep-unique.md +0 -0
  82. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/line-count.md +0 -0
  83. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/line-pattern.md +0 -0
  84. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/docs/validators/same-as.md +0 -0
  85. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/pypi/pyproject.toml +0 -0
  86. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/pyproject.toml +0 -0
  87. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/release.toml +0 -0
  88. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/scripts/check_language_count.lua +0 -0
  89. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/scripts/check_latest_gpt_nano_model.lua +0 -0
  90. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/block_parser.rs +0 -0
  91. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/cli.rs +0 -0
  92. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/config.rs +0 -0
  93. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/diff_parser.rs +0 -0
  94. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/explain.rs +0 -0
  95. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/flags.rs +0 -0
  96. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/fs.rs +0 -0
  97. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/bash.rs +0 -0
  98. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/cmake.rs +0 -0
  99. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/cpp.rs +0 -0
  100. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/css.rs +0 -0
  101. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/dart.rs +0 -0
  102. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/dockerfile.rs +0 -0
  103. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/elixir.rs +0 -0
  104. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/graphql.rs +0 -0
  105. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/groovy.rs +0 -0
  106. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/html.rs +0 -0
  107. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/javascript.rs +0 -0
  108. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/lean.rs +0 -0
  109. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/lua.rs +0 -0
  110. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/makefile.rs +0 -0
  111. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/markdown.rs +0 -0
  112. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/mdx.rs +0 -0
  113. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/nix.rs +0 -0
  114. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/ocaml.rs +0 -0
  115. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/php.rs +0 -0
  116. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/python.rs +0 -0
  117. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/ruby.rs +0 -0
  118. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/scala.rs +0 -0
  119. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/sql.rs +0 -0
  120. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/starlark.rs +0 -0
  121. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/language_parsers/tsx.rs +0 -0
  122. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/lib.rs +0 -0
  123. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/main.rs +0 -0
  124. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/path_arguments.rs +0 -0
  125. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/paths_glob.rs +0 -0
  126. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/repo_path.rs +0 -0
  127. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/report.rs +0 -0
  128. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/sarif.rs +0 -0
  129. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/scan.rs +0 -0
  130. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/settings.rs +0 -0
  131. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/symbol_path.rs +0 -0
  132. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/tag_parser.rs +0 -0
  133. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/target_reference.rs +0 -0
  134. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/affects.rs +0 -0
  135. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/check_ai.rs +0 -0
  136. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/check_lua.rs +0 -0
  137. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/keep_sorted.rs +0 -0
  138. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/keep_unique.rs +0 -0
  139. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/line_count.rs +0 -0
  140. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/line_pattern.rs +0 -0
  141. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/mod.rs +0 -0
  142. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/validators/same_as.rs +0 -0
  143. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/violation_address.rs +0 -0
  144. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/src/virtual_blocks.rs +0 -0
  145. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/affects.rs +0 -0
  146. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/check_ai.rs +0 -0
  147. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/check_lua.rs +0 -0
  148. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/common/empty.toml +0 -0
  149. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/common/mod.rs +0 -0
  150. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/config.rs +0 -0
  151. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/encoding.rs +0 -0
  152. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/explain.rs +0 -0
  153. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/general.rs +0 -0
  154. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/keep_sorted.rs +0 -0
  155. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/keep_unique.rs +0 -0
  156. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/line_count.rs +0 -0
  157. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/line_pattern.rs +0 -0
  158. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/list.rs +0 -0
  159. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/path_arguments.rs +0 -0
  160. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/repository_root.rs +0 -0
  161. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/same_as.rs +0 -0
  162. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/sarif.rs +0 -0
  163. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/skill.rs +0 -0
  164. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/suppressions.rs +0 -0
  165. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/cross_file_source.rs +0 -0
  166. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/cross_file_target.md +0 -0
  167. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/custom_ext_source.javascript +0 -0
  168. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/custom_ext_target.javascript +0 -0
  169. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/dangling.md +0 -0
  170. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/missing_symbol.rs +0 -0
  171. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/more_added_than_deleted.py +0 -0
  172. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/multiline_tag_source.rs +0 -0
  173. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/multiline_tag_target.rs +0 -0
  174. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/nested_mapping_source.rs +0 -0
  175. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/nested_mapping_target.yaml +0 -0
  176. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/sibling.md +0 -0
  177. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/symbol_source.rs +0 -0
  178. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/symbol_target.json +0 -0
  179. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/table_source.rs +0 -0
  180. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/table_target.toml +0 -0
  181. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/tag_and_content_source.ts +0 -0
  182. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/tag_and_content_target.ts +0 -0
  183. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/whole_file_source.rs +0 -0
  184. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/affects/whole_file_target.json +0 -0
  185. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_ai/two_blocks.py +0 -0
  186. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/affects.lua +0 -0
  187. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/affects.py +0 -0
  188. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/affects_drift.py +0 -0
  189. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/blocking_io.lua +0 -0
  190. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/blocking_io.py +0 -0
  191. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/echo.lua +0 -0
  192. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/fail.lua +0 -0
  193. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/mode.py +0 -0
  194. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/os.lua +0 -0
  195. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/pathfmt/report_path.lua +0 -0
  196. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/pathfmt/source.py +0 -0
  197. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/pattern.py +0 -0
  198. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/pattern_many_matches.py +0 -0
  199. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/pattern_no_match.py +0 -0
  200. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/success.lua +0 -0
  201. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/check_lua/success_and_failure.py +0 -0
  202. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/config/glob_target/config.toml +0 -0
  203. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/config/glob_target/package.json +0 -0
  204. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/config/glob_target/plugins/blue/package.json +0 -0
  205. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/config/glob_target/plugins/green/package.json +0 -0
  206. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/config/glob_target/plugins/red/package.json +0 -0
  207. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/explain/a.py +0 -0
  208. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/explain/check.lua +0 -0
  209. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/block_selection.py +0 -0
  210. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/custom_file_extension.javascript +0 -0
  211. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/custom_file_extension.python +0 -0
  212. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/disable_enable.py +0 -0
  213. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/paths/invalid.py +0 -0
  214. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/paths/subdir/nested_invalid.py +0 -0
  215. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/paths/valid.py +0 -0
  216. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/general/severity.py +0 -0
  217. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/hidden/.github/workflows/ci.yml +0 -0
  218. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/keep_sorted/orderings.py +0 -0
  219. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/keep_unique/basic_and_pattern.py +0 -0
  220. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/line_count/equality_and_greater_than.py +0 -0
  221. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/line_pattern/forbidden_text.py +0 -0
  222. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/line_pattern/hex_and_word_patterns.py +0 -0
  223. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/list/.hg/.gitkeep +0 -0
  224. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/list/a.py +0 -0
  225. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/list/b.py +0 -0
  226. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/positions/unicode_columns.py +0 -0
  227. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/custom_ext_source.javascript +0 -0
  228. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/custom_ext_target.javascript +0 -0
  229. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/package.json +0 -0
  230. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/paths/alpha/item.txt +0 -0
  231. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/paths/beta/item.txt +0 -0
  232. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/paths_and_block_source.md +0 -0
  233. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/paths_source.md +0 -0
  234. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/sibling.rs +0 -0
  235. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/source.rs +0 -0
  236. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/split_table_source.rs +0 -0
  237. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/split_table_target.toml +0 -0
  238. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/symbol_mismatch_source.rs +0 -0
  239. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/symbol_source.rs +0 -0
  240. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/target.md +0 -0
  241. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/whole_file_mismatch_source.rs +0 -0
  242. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/whole_file_source.rs +0 -0
  243. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/same_as/whole_file_target.json +0 -0
  244. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/sarif/advisory.py +0 -0
  245. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/sarif/clean.py +0 -0
  246. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/sarif/sorted.py +0 -0
  247. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/sarif/unnamed.py +0 -0
  248. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg.txt +0 -0
  249. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg_gone_a.txt +0 -0
  250. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg_gone_b.txt +0 -0
  251. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg_lowercase_trailer.txt +0 -0
  252. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg_malformed.txt +0 -0
  253. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/commit_msg_with_noise.txt +0 -0
  254. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/dangling.py +0 -0
  255. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/sorted.py +0 -0
  256. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/symbol.py +0 -0
  257. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/symbol_target.json +0 -0
  258. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/two_rules.py +0 -0
  259. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/suppressions/unnamed.py +0 -0
  260. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/bzl_source.rs +0 -0
  261. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/bzl_target.bzl +0 -0
  262. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/c_source.rs +0 -0
  263. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/c_target.c +0 -0
  264. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/cpp_source.rs +0 -0
  265. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/cpp_target.cpp +0 -0
  266. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/cs_source.rs +0 -0
  267. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/cs_target.cs +0 -0
  268. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/escapes_source.rs +0 -0
  269. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/escapes_target.json +0 -0
  270. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/filter_source.rs +0 -0
  271. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/filter_target.yaml +0 -0
  272. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/go_source.rs +0 -0
  273. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/go_target.go +0 -0
  274. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/h_source.rs +0 -0
  275. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/h_target.h +0 -0
  276. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/java_source.rs +0 -0
  277. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/java_target.java +0 -0
  278. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/js_source.rs +0 -0
  279. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/js_target.js +0 -0
  280. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/json_source.rs +0 -0
  281. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/json_target.json +0 -0
  282. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/jsonc_source.rs +0 -0
  283. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/jsonc_target.jsonc +0 -0
  284. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/kt_source.rs +0 -0
  285. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/kt_target.kt +0 -0
  286. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/kts_source.rs +0 -0
  287. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/kts_target.kts +0 -0
  288. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/markdown_source.rs +0 -0
  289. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/markdown_target.markdown +0 -0
  290. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/md_source.rs +0 -0
  291. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/md_target.md +0 -0
  292. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/mdx_source.rs +0 -0
  293. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/mdx_target.mdx +0 -0
  294. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/mixed_list_source.rs +0 -0
  295. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/mixed_list_target.json +0 -0
  296. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/py_source.rs +0 -0
  297. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/py_target.py +0 -0
  298. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/rs_source.rs +0 -0
  299. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/rs_target.rs +0 -0
  300. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/swift_source.rs +0 -0
  301. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/swift_target.swift +0 -0
  302. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/toml_source.rs +0 -0
  303. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/toml_target.toml +0 -0
  304. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/ts_source.rs +0 -0
  305. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/ts_target.ts +0 -0
  306. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/tsx_source.rs +0 -0
  307. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/tsx_target.tsx +0 -0
  308. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/yaml_source.rs +0 -0
  309. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/yaml_target.yaml +0 -0
  310. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/yml_source.rs +0 -0
  311. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/symbol_references/yml_target.yml +0 -0
  312. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/affects/pair.py +0 -0
  313. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/clean/counted.py +0 -0
  314. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/clean/noop.py +0 -0
  315. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/clean/notes.txt +0 -0
  316. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/clean/sorted.py +0 -0
  317. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/diff/two_blocks.py +0 -0
  318. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/failing/unsorted.py +0 -0
  319. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/testdata/verbosity/mixed/both_kinds.py +0 -0
  320. {blockwatch_cli-0.16.4 → blockwatch_cli-0.16.6}/tests/verbosity.rs +0 -0
@@ -235,22 +235,18 @@ The main modules:
235
235
  Some languages also have symbols. Such a language has a `SymbolsParser`, which its `parser()` passes to
236
236
  `.with_symbols(...)`:
237
237
 
238
- - JSON uses a `QuerySymbolsParser`, built from a tree-sitter query (`.scm`) and a `NodeDecoder`.
238
+ - JSON, YAML and XML walk their syntax trees themselves, and refuse a file with a syntax error.
239
239
  - TOML finds its symbols with `toml_edit`. What a TOML key means depends on the order of the headers, not on how the
240
240
  syntax tree is nested.
241
- - YAML walks its syntax tree itself. An alias has a position in a sequence but can't be addressed, and a query can't
242
- express that.
243
241
  - Markdown finds its sections with the `markdown` crate, the same parser that finds its comments.
244
242
 
245
243
  Each language's tests list every symbol it finds. When you give a language symbols, also document its paths in
246
244
  `docs/symbols.md` and in the "Symbols" section of the skill, `src/skill.md`. A test in `language_parsers/mod.rs` and the
247
245
  repository's own blocks keep the list of file types with symbols, and each language's section, in sync with the
248
246
  code.
249
- - `src/symbols.rs` — `Symbol`, the `SymbolsParser` trait, and `resolve`, which finds the symbol a path refers to.
250
- `QuerySymbolsParser` runs a language's query and finds every addressable `Symbol` in one walk of the tree, with its
251
- path, its definition range and its decoded value. It suits a language whose structure is its syntax tree. It rejects
252
- a file with a syntax error, instead of resolving a path through tree-sitter's error recovery. It doesn't check the
253
- query itself.
247
+ - `src/symbols/mod.rs` — `Symbol`, the `SymbolsParser` trait, and `resolve`, which finds the symbol a path refers to.
248
+ `ensure_no_syntax_error` refuses a file with a syntax error, instead of resolving a path through tree-sitter's error
249
+ recovery.
254
250
  - `src/validators/` — one file for each validator (`affects`, `check_ai`, `check_lua`, `keep_sorted`, `keep_unique`,
255
251
  `line_count`, `line_pattern`, `same_as`). Each file exports a `detect` function. `Validator::detect` in
256
252
  `validators/mod.rs` calls them from one `match`.
@@ -12,6 +12,36 @@ Releases up to and including v0.3.11 predate this file. Their notes live on the
12
12
 
13
13
  ## [Unreleased] - ReleaseDate
14
14
 
15
+ ## [0.16.6] - 2026-11-04
16
+
17
+ ### Added
18
+
19
+ - Symbols in XML files: `.xml`, the MSBuild files (`.csproj`, `.fsproj`, `.vbproj`, `.vcxproj`, `.props`,
20
+ `.targets`), `.xaml`, `.xsd`, `.xsl` and `.xslt`. `pom.xml#/project/version` points at the text of an element, and
21
+ `#/Project/@Sdk` at the value of an attribute. A filter picks one of several elements with one name:
22
+ `#/project/dependencies/~[artifactId=guava]/version`. See [XML](docs/symbols.md#xml).
23
+ - A filter picks one of several items that share a path, such as two `ingress` blocks in HCL:
24
+ `#/resource/aws_security_group/web/~[from_port=443]/to_port`. Before, the path was ambiguous. See
25
+ [Picking an item by a key's value](docs/symbols.md#picking-an-item-by-a-keys-value).
26
+
27
+ ### Fixed
28
+
29
+ - A filter over several items that share a path could read a key of another item, when only that item had the key.
30
+ - A filter could pick the wrong item when an item had a syntax error or a string that blockwatch can't decode. Now
31
+ such a path stops the run, as a path to that item does.
32
+
33
+ ## [0.16.5] - 2026-11-03
34
+
35
+ ### Added
36
+
37
+ - Symbols in Protocol Buffers files (`.proto`). `item.proto#/Item/Color/RED` points at the number of an enum value,
38
+ and `#/Item/name` at the number of a field. Each message, enum and service is a symbol, and so is each field, oneof,
39
+ enum value and rpc in it. The package is not part of a path, and options are not symbols. See
40
+ [Protocol Buffers](docs/symbols.md#protocol-buffers).
41
+ - Symbols in HCL files: Terraform and OpenTofu (`.tf`, `.tofu`, `.tfvars`), Nomad (`.nomad`), and `.hcl` files such
42
+ as Terragrunt's. See [HCL](docs/symbols.md#hcl).
43
+ - blockwatch now checks the tags in Nomad job files (`.nomad`). Before, it skipped them.
44
+
15
45
  ## [0.16.4] - 2026-11-03
16
46
 
17
47
  ### Added
@@ -235,22 +235,18 @@ The main modules:
235
235
  Some languages also have symbols. Such a language has a `SymbolsParser`, which its `parser()` passes to
236
236
  `.with_symbols(...)`:
237
237
 
238
- - JSON uses a `QuerySymbolsParser`, built from a tree-sitter query (`.scm`) and a `NodeDecoder`.
238
+ - JSON, YAML and XML walk their syntax trees themselves, and refuse a file with a syntax error.
239
239
  - TOML finds its symbols with `toml_edit`. What a TOML key means depends on the order of the headers, not on how the
240
240
  syntax tree is nested.
241
- - YAML walks its syntax tree itself. An alias has a position in a sequence but can't be addressed, and a query can't
242
- express that.
243
241
  - Markdown finds its sections with the `markdown` crate, the same parser that finds its comments.
244
242
 
245
243
  Each language's tests list every symbol it finds. When you give a language symbols, also document its paths in
246
244
  `docs/symbols.md` and in the "Symbols" section of the skill, `src/skill.md`. A test in `language_parsers/mod.rs` and the
247
245
  repository's own blocks keep the list of file types with symbols, and each language's section, in sync with the
248
246
  code.
249
- - `src/symbols.rs` — `Symbol`, the `SymbolsParser` trait, and `resolve`, which finds the symbol a path refers to.
250
- `QuerySymbolsParser` runs a language's query and finds every addressable `Symbol` in one walk of the tree, with its
251
- path, its definition range and its decoded value. It suits a language whose structure is its syntax tree. It rejects
252
- a file with a syntax error, instead of resolving a path through tree-sitter's error recovery. It doesn't check the
253
- query itself.
247
+ - `src/symbols/mod.rs` — `Symbol`, the `SymbolsParser` trait, and `resolve`, which finds the symbol a path refers to.
248
+ `ensure_no_syntax_error` refuses a file with a syntax error, instead of resolving a path through tree-sitter's error
249
+ recovery.
254
250
  - `src/validators/` — one file for each validator (`affects`, `check_ai`, `check_lua`, `keep_sorted`, `keep_unique`,
255
251
  `line_count`, `line_pattern`, `same_as`). Each file exports a `detect` function. `Validator::detect` in
256
252
  `validators/mod.rs` calls them from one `match`.
@@ -274,7 +274,7 @@ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
274
274
 
275
275
  [[package]]
276
276
  name = "blockwatch"
277
- version = "0.16.4"
277
+ version = "0.16.6"
278
278
  dependencies = [
279
279
  "anyhow",
280
280
  "assert-json-diff",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "blockwatch"
3
- version = "0.16.4"
3
+ version = "0.16.6"
4
4
  edition = "2024"
5
5
  repository = "https://github.com/mennanov/blockwatch"
6
6
  description = "Language agnostic linter that keeps your code and documentation in sync and valid"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockwatch-cli
3
- Version: 0.16.4
3
+ Version: 0.16.6
4
4
  Summary: Language agnostic linter that keeps your code and documentation in sync and valid
5
5
  Keywords: linter,sync,drift,comments,agents
6
6
  Home-Page: https://github.com/mennanov/blockwatch
@@ -89,9 +89,10 @@ Two validators work across files:
89
89
  - `same-as` fails when a block and its target hold different values. It needs no diff.
90
90
 
91
91
  Both can point to a block, a whole file, a specific value in a file like `package.json#/version`, a section of a
92
- Markdown file, or a constant in a Go, C, C++, Python, Rust, TypeScript, JavaScript, Java, C#, Kotlin or Swift file (see
93
- [Symbols](docs/symbols.md)). The other validators check a single block on their own: the things you'd otherwise have to
94
- nitpick in code review.
92
+ Markdown file, an element or attribute in an XML file such as `pom.xml` or a `.csproj`, a constant in a Go, C, C++,
93
+ Python, Rust, TypeScript, JavaScript, Java, C#, Kotlin or Swift file, a field in a Protocol Buffers file, or a value in
94
+ a Terraform or other HCL file (see [Symbols](docs/symbols.md)). The other validators check a single block on their
95
+ own: the things you'd otherwise have to nitpick in code review.
95
96
 
96
97
  <!-- <block name="available-validators"
97
98
  same-as="src/validators/mod.rs:validator-registry, docs/validators/README.md:validators-index"
@@ -219,7 +220,7 @@ exclusions, and custom extension mappings.
219
220
 
220
221
  ```yaml
221
222
  - repo: https://github.com/mennanov/blockwatch
222
- rev: v0.16.4 # Use latest release
223
+ rev: v0.16.6 # Use latest release
223
224
  hooks:
224
225
  - id: blockwatch
225
226
  ```
@@ -258,7 +259,7 @@ For plain git hooks, local pre-commit setups, and sandboxing untrusted Lua scrip
258
259
  - Go (with `go.mod`, `go.sum` and `go.work` support)
259
260
  - GraphQL (`.graphql`, `.graphqls`, `.gql`)
260
261
  - Groovy (with `.gradle` and `Jenkinsfile` support)
261
- - HCL (Terraform and OpenTofu: `.tf`, `.tfvars`, `.tofu`, `.hcl`)
262
+ - HCL (Terraform and OpenTofu: `.tf`, `.tfvars`, `.tofu`, `.hcl`; Nomad: `.nomad`)
262
263
  - HTML (with `.xhtml` support)
263
264
  - JSON (`.json`, `.jsonc`, `.webmanifest`)
264
265
  - Java
@@ -19,7 +19,7 @@ To use [pre-commit](https://pre-commit.com), add the hook to `.pre-commit-config
19
19
 
20
20
  ```yaml
21
21
  - repo: https://github.com/mennanov/blockwatch
22
- rev: v0.16.4 # Use latest release
22
+ rev: v0.16.6 # Use latest release
23
23
  hooks:
24
24
  - id: blockwatch
25
25
  ```
@@ -59,7 +59,7 @@ The `blockwatch` hook runs before the commit message exists, so it cannot see a
59
59
 
60
60
  ```yaml
61
61
  - repo: https://github.com/mennanov/blockwatch
62
- rev: v0.16.4 # Use latest release
62
+ rev: v0.16.6 # Use latest release
63
63
  hooks:
64
64
  - id: blockwatch-commit-msg
65
65
  ```
@@ -557,15 +557,15 @@ Nothing else about the run changes: the same violations are found, and the exit
557
557
  "tool": {
558
558
  "driver": {
559
559
  "name": "blockwatch",
560
- "version": "0.16.4",
561
- "semanticVersion": "0.16.4",
560
+ "version": "0.16.6",
561
+ "semanticVersion": "0.16.6",
562
562
  "informationUri": "https://github.com/mennanov/blockwatch",
563
563
  "rules": [
564
564
  {
565
565
  "id": "keep-sorted",
566
566
  "name": "keep-sorted",
567
567
  "shortDescription": { "text": "Requires the lines of a block to stay in order." },
568
- "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.4/docs/validators/keep-sorted.md"
568
+ "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.6/docs/validators/keep-sorted.md"
569
569
  }
570
570
  ]
571
571
  }
@@ -24,23 +24,26 @@ declares, instead of tags in a comment.
24
24
  <!-- <block name="extensions-with-symbols" same-as="src/language_parsers/mod.rs:extensions-with-symbols"
25
25
  same-as-pattern="`\.?(?P<value>[A-Za-z.]+)`"> -->
26
26
 
27
- | Language | Files | Paths |
28
- |------------|--------------------------------------------------------------------------------|---------------------------------------------------------|
29
- | JSON | `.json`, `.jsonc`, `.webmanifest` | [JSON](#json) |
30
- | TOML | `.toml`, `Pipfile` | [TOML](#toml) |
31
- | YAML | `.yaml`, `.yml`, `.cff` | [YAML](#yaml) |
32
- | Markdown | `.md`, `.markdown`, `.mdx` | [Markdown](#markdown) |
33
- | Go | `.go` | [Go](#go) |
34
- | C, C++ | `.c`, `.h`, `.cc`, `.cpp`, `.cxx`, `.hh`, `.hpp`, `.hxx` | [C and C++](#c-and-c) |
35
- | Python | `.py`, `.pyi`, `.pyw` | [Python and Starlark](#python-and-starlark) |
36
- | Starlark | `.bzl`, `.bazel`, `.bzlmod`, `.star`, `BUILD`, `BUCK`, `WORKSPACE`, `Tiltfile` | [Python and Starlark](#python-and-starlark) |
37
- | Rust | `.rs` | [Rust](#rust) |
38
- | TypeScript | `.ts`, `.mts`, `.cts`, `.d.ts`, `.tsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
39
- | JavaScript | `.js`, `.mjs`, `.cjs`, `.jsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
40
- | Java | `.java` | [Java](#java) |
41
- | C# | `.cs` | [C#](#c) |
42
- | Kotlin | `.kt`, `.kts` | [Kotlin](#kotlin) |
43
- | Swift | `.swift` | [Swift](#swift) |
27
+ | Language | Files | Paths |
28
+ |------------------|-------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|
29
+ | JSON | `.json`, `.jsonc`, `.webmanifest` | [JSON](#json) |
30
+ | TOML | `.toml`, `Pipfile` | [TOML](#toml) |
31
+ | YAML | `.yaml`, `.yml`, `.cff` | [YAML](#yaml) |
32
+ | Markdown | `.md`, `.markdown`, `.mdx` | [Markdown](#markdown) |
33
+ | XML | `.xml`, `.csproj`, `.fsproj`, `.vbproj`, `.vcxproj`, `.props`, `.targets`, `.xaml`, `.xsd`, `.xsl`, `.xslt` | [XML](#xml) |
34
+ | Go | `.go` | [Go](#go) |
35
+ | C, C++ | `.c`, `.h`, `.cc`, `.cpp`, `.cxx`, `.hh`, `.hpp`, `.hxx` | [C and C++](#c-and-c) |
36
+ | Python | `.py`, `.pyi`, `.pyw` | [Python and Starlark](#python-and-starlark) |
37
+ | Starlark | `.bzl`, `.bazel`, `.bzlmod`, `.star`, `BUILD`, `BUCK`, `WORKSPACE`, `Tiltfile` | [Python and Starlark](#python-and-starlark) |
38
+ | Rust | `.rs` | [Rust](#rust) |
39
+ | TypeScript | `.ts`, `.mts`, `.cts`, `.d.ts`, `.tsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
40
+ | JavaScript | `.js`, `.mjs`, `.cjs`, `.jsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
41
+ | Java | `.java` | [Java](#java) |
42
+ | C# | `.cs` | [C#](#c) |
43
+ | Kotlin | `.kt`, `.kts` | [Kotlin](#kotlin) |
44
+ | Swift | `.swift` | [Swift](#swift) |
45
+ | Protocol Buffers | `.proto` | [Protocol Buffers](#protocol-buffers) |
46
+ | HCL (Terraform) | `.tf`, `.tofu`, `.tfvars`, `.hcl`, `.nomad` | [HCL](#hcl) |
44
47
 
45
48
  <!-- </block> -->
46
49
 
@@ -95,6 +98,12 @@ services:
95
98
  - **A filter picks a map entry too.** In `{"a": {"name": "x"}}`, `#/~[name=x]` is `#/a`.
96
99
  - **A path can hold several filters**, such as `#/groups/~[name=api]/services/~[name=web]/port`. A filter can come
97
100
  first, in a file that is a list: `#/~[name=web]`.
101
+ - **When several items share a path, the rest of the path looks only inside the item the filter picked.** For
102
+ example, two `ingress` blocks in an HCL resource share a path.
103
+ `#/resource/aws_security_group/web/~[from_port=443]/to_port` is the `to_port` of the block whose `from_port` is
104
+ `443`.
105
+ - **A filter that reaches an unreadable path stops the run**, as that path does. An item blockwatch can't read, such
106
+ as one with a syntax error, also stops a filter that compares its key, because that item could match too.
98
107
  - **The value starts after the first `=` and ends at the last `]`,** so it can hold both. The key can't hold `=`.
99
108
  Inside a filter, escape the key and the value like any key: `/` as `~1`, `,` as `%2C`, and so on.
100
109
 
@@ -245,14 +254,78 @@ Clone the repository.
245
254
 
246
255
  <!-- </block> -->
247
256
 
257
+ ## XML
258
+
259
+ `.xml` files have symbols, and so do the MSBuild files (`.csproj`, `.fsproj`, `.vbproj`, `.vcxproj`, `.props`,
260
+ `.targets`), `.xaml`, `.xsd`, `.xsl` and `.xslt`.
261
+
262
+ <!-- <block name="xml-paths"> -->
263
+
264
+ Every element and every attribute is a symbol. A path is each element's name, from the root element down. An attribute
265
+ is `@` and its name, under its element:
266
+
267
+ ```xml
268
+ <project xmlns="http://maven.apache.org/POM/4.0.0">
269
+ <version>1.4.2</version>
270
+ <dependencies>
271
+ <dependency>
272
+ <artifactId>junit</artifactId>
273
+ <version>5.10.0</version>
274
+ </dependency>
275
+ <dependency scope="test">
276
+ <artifactId>guava</artifactId>
277
+ <version>33.0.0-jre</version>
278
+ </dependency>
279
+ </dependencies>
280
+ <description>
281
+ Tools &amp; helpers
282
+ </description>
283
+ </project>
284
+ ```
285
+
286
+ | Path | Points at |
287
+ |------------------------------------------------------|---------------------------------|
288
+ | `#/project/version` | `1.4.2` |
289
+ | `#/project/dependencies` | the whole element |
290
+ | `#/project/dependencies/dependency/version` | a violation: two elements match |
291
+ | `#/project/dependencies/~[artifactId=guava]/version` | `33.0.0-jre` |
292
+ | `#/project/dependencies/~[artifactId=guava]/@scope` | `test` |
293
+ | `#/project/description` | `Tools & helpers` |
294
+
295
+ - **Elements with one name under one parent share a path**, such as the two `dependency` elements above. A path through
296
+ them is a violation, so pick one with a [filter](#picking-an-item-by-a-keys-value). Its key can be a child element,
297
+ such as `artifactId`, or an attribute. In a `.csproj` file, `#/Project/ItemGroup/~[@Include=Serilog]/@Version` is
298
+ the `Version` of the `PackageReference` whose `Include` is `Serilog`. A position, such as
299
+ `#/project/modules/module/1`, is not found.
300
+ - **A prefix is part of the name, as written.** Escape its `:` as `%3A`: `#/manifest/application/@android%3Aname`.
301
+ Namespaces play no part, and `xmlns` attributes are not symbols. Names compare as written, case included.
302
+ - **An element without child elements is its text.** Entities and character references are decoded, CDATA stays as
303
+ written, and comments are left out. The white space around the text is removed, but the line breaks and indents
304
+ inside it stay. `<a/>` and `<a></a>` are empty strings.
305
+ - **An element with child elements has no value.** It gives its whole text, tags included, even when it also holds
306
+ text.
307
+ - **An attribute is its decoded value.** Each tab and line break in it becomes a space, as XML requires. The white
308
+ space around it stays.
309
+ - **An entity that the DOCTYPE declares stops the run for its path**, because it can stand for any text, even
310
+ elements. So does a reference to a character that XML forbids, such as `&#0;`.
311
+ - **The XML declaration, the DOCTYPE, comments and processing instructions are not symbols.**
312
+ - **An element covers its start tag, its content and its end tag.** An attribute covers `name="value"`. A comment
313
+ above an element is not part of it.
314
+ - **A syntax error anywhere stops the run**, and so does an empty file. A few valid files stop it too, because of the
315
+ parser: a DOCTYPE without white space before its `]`, as in `[<!ENTITY e "x">]`, and a processing instruction with
316
+ data, such as `<?pi x?>`, inside an element.
317
+
318
+ <!-- </block> -->
319
+
248
320
  ## Code files
249
321
 
250
322
  <!-- <block name="code-files"> -->
251
323
 
252
324
  In a code file, each top-level name is a symbol: a constant, a variable, a type, a function or a macro. Its path is
253
325
  `#/NAME`.
254
- With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`. In Java, C#, Kotlin and Swift, the
255
- members of a type are symbols too, under the type's name: `Config.java#/Config/MAX_PORTS`.
326
+ With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`. In Java, C#, Kotlin, Swift and Protocol
327
+ Buffers, the members of a type are symbols too, under the type's name: `Config.java#/Config/MAX_PORTS`. In HCL, each
328
+ block, attribute and object key is a symbol: `main.tf#/variable/region/default`.
256
329
 
257
330
  - **A value is the initializer as written.** blockwatch never works it out: `20 * 1024 * 1024` stays as it is, and so
258
331
  does `0x10`. Use `same-as-pattern` to take the part you need.
@@ -266,7 +339,8 @@ members of a type are symbols too, under the type's name: `Config.java#/Config/M
266
339
  with a name from the text that the parser had to skip. Other names in the file still resolve. The message shows
267
340
  where the error is.
268
341
  - **A path to a string that blockwatch can't decode stops the run.** Other paths in the file still resolve.
269
- - **Members are not symbols yet**, such as a method or a field, except in Java, C#, Kotlin and Swift.
342
+ - **Members are not symbols yet**, such as a method or a field, except in Java, C#, Kotlin, Swift, Protocol Buffers
343
+ and HCL.
270
344
 
271
345
  <!-- </block> -->
272
346
 
@@ -724,6 +798,135 @@ extension Config {
724
798
 
725
799
  <!-- </block> -->
726
800
 
801
+ ## Protocol Buffers
802
+
803
+ <!-- <block name="proto-paths"> -->
804
+
805
+ ```protobuf
806
+ syntax = "proto3";
807
+
808
+ package shop.v1;
809
+
810
+ option go_package = "shop/v1";
811
+
812
+ message Item {
813
+ string name = 1;
814
+ map<string, int32> counts = 2;
815
+ enum Color {
816
+ COLOR_UNSPECIFIED = 0;
817
+ RED = 1;
818
+ BLUE = -2;
819
+ }
820
+ oneof price {
821
+ int64 cents = 3;
822
+ }
823
+ }
824
+
825
+ service Items {
826
+ rpc Get(Item) returns (Item);
827
+ }
828
+ ```
829
+
830
+ | Path | Points at |
831
+ |----------------------|------------------------------|
832
+ | `#/Item` | the whole message |
833
+ | `#/Item/name` | `1` |
834
+ | `#/Item/counts` | `2` |
835
+ | `#/Item/Color` | the whole enum |
836
+ | `#/Item/Color/RED` | `1` |
837
+ | `#/Item/Color/BLUE` | `-2` |
838
+ | `#/Item/price` | the whole oneof |
839
+ | `#/Item/cents` | `3` |
840
+ | `#/Items/Get` | the whole rpc |
841
+
842
+ - **Each message, enum and service is a symbol, at any depth, and so is each field, map field, oneof, enum value and
843
+ rpc in it.** A proto2 group, such as `optional group Result = 4 { ... }` in `Item`, is a symbol too, with its
844
+ fields under it: `#/Item/Result/code`. It has no value, though it has a number.
845
+ - **The package is not part of a path.** A file has only one, so `#/Item` is enough.
846
+ - **An enum value sits under its enum:** `#/Item/Color/RED`.
847
+ - **A field's value is its number, and an enum value's value is its number.** Both stay as written: `0x3` stays `0x3`,
848
+ and `- 2` stays `- 2`. Options after the number don't change it: `BLUE = -2 [deprecated = true]` is `-2`.
849
+ - **A oneof's fields sit in its message**, as code reads them: `#/Item/cents`, not `#/Item/price/cents`.
850
+ - **An extension field sits where its `extend` is written**, not in the message it extends.
851
+ `extend Other { int32 tag = 100; }` at the top of the file gives `#/tag`, and inside `Item` it gives `#/Item/tag`.
852
+ - **A definition covers its whole statement**, with its label, its options and its `;`, but not the comments above it.
853
+ - **Options are not symbols**, and neither are `syntax`, `package`, `import`, `extend` blocks, `reserved` and
854
+ `extensions`. To check an option such as `go_package`, wrap it in a `[[block]]` entry with a `target-pattern`.
855
+ - **A syntax error stops the run for the definition that holds it, and for each message around it.** The other
856
+ definitions still resolve.
857
+
858
+ <!-- </block> -->
859
+
860
+ ## HCL
861
+
862
+ Terraform, OpenTofu, Terragrunt, Nomad and Packer files are HCL.
863
+
864
+ <!-- <block name="hcl-paths"> -->
865
+
866
+ ```hcl
867
+ terraform {
868
+ required_providers {
869
+ aws = {
870
+ source = "hashicorp/aws"
871
+ version = "~> 5.0"
872
+ }
873
+ }
874
+ }
875
+
876
+ variable "region" {
877
+ default = "us-east-1"
878
+ }
879
+
880
+ locals {
881
+ name = "app-${var.env}"
882
+ tags = { Team = "core", "cost center" = 42 }
883
+ }
884
+
885
+ resource "aws_instance" "web" {
886
+ ami = data.aws_ami.ubuntu.id
887
+ count = (3)
888
+ user_data = <<-EOT
889
+ #!/bin/sh
890
+ echo hi
891
+ EOT
892
+ }
893
+ ```
894
+
895
+ | Path | Points at |
896
+ |----------------------------------------------|-------------------------------------------|
897
+ | `#/terraform/required_providers/aws/version` | `~> 5.0` |
898
+ | `#/variable/region` | the whole block |
899
+ | `#/variable/region/default` | `us-east-1` |
900
+ | `#/locals/name` | `"app-${var.env}"`, as written |
901
+ | `#/locals/tags` | the whole object, as written |
902
+ | `#/locals/tags/cost center` | `42` |
903
+ | `#/resource/aws_instance/web/ami` | `data.aws_ami.ubuntu.id` |
904
+ | `#/resource/aws_instance/web/count` | `3` |
905
+ | `#/resource/aws_instance/web/user_data` | `#!/bin/sh` and `echo hi`, each on a line |
906
+
907
+ - **Each block is a symbol, at any depth, and so is each attribute and each key of an object.** A block's path is its
908
+ type, then each of its labels: `#/resource/aws_instance/web`. In a `.tfvars` file, each attribute sits at the top:
909
+ `#/region`.
910
+ - **A path with only some of a block's labels points at nothing.** `#/resource/aws_instance` is no symbol.
911
+ - **A block written twice in one body makes its path a violation**, such as two `ingress` blocks in a resource. Two
912
+ `locals` blocks make `#/locals` a violation, but `#/locals/name` still resolves when only one of them sets `name`.
913
+ A filter picks one of the blocks: `#/resource/aws_security_group/web/~[from_port=443]/to_port`.
914
+ - **A key of an object is a segment when it is a name, a plain string, `true` or `false`**, such as `Team` or
915
+ `"cost center"`. A key written as a number or an expression, such as `3` or `(var.k)`, is not. The items of a list
916
+ are not symbols.
917
+ - **A label or key with an escape, such as `"a\"b"`, gives no symbol**, and neither does anything under it.
918
+ - **A value is the expression as written**, without parentheses around it: `count = (3)` is `3`.
919
+ - **Strings follow HCL's escapes.** `"caf\u00e9"` is `café`, `$${` is `${`, and `%%{` is `%{`. A heredoc is its text,
920
+ with each line end. A `<<-` heredoc loses the indent that HCL removes. A string or heredoc with `${...}` or `%{...}`
921
+ stays as written. blockwatch doesn't turn text into Unicode NFC, as HCL does. A path to an escape that stands for no
922
+ character, such as `"\uD800"`, stops the run.
923
+ - **A block covers its type, labels and body.** An attribute or a key covers its name and its value. Comments above
924
+ them are not part of them.
925
+ - **A syntax error stops the run for the definition that holds it, and for each block around it.** After an error, the
926
+ parser can read the rest of the file wrongly, so a later path may not resolve.
927
+
928
+ <!-- </block> -->
929
+
727
930
  ---
728
931
 
729
932
  [← Return to README](../README.md)
@@ -6,7 +6,7 @@ setup(
6
6
  name='blockwatch-pre-commit-placeholder',
7
7
  version='0.0.0',
8
8
  # <block name="blockwatch-cli-version" same-as-pattern="blockwatch-cli==(?P<value>\d+\.\d+\.\d+)">
9
- install_requires=['blockwatch-cli==0.16.4'],
9
+ install_requires=['blockwatch-cli==0.16.6'],
10
10
  # </block>
11
11
  # Without it, setuptools takes the directories under src/ for Python packages.
12
12
  packages=[],
@@ -899,6 +899,10 @@ mod supported_languages_tests {
899
899
  "tofu.tofu".to_string(),
900
900
  "# <block>\nregion = \"eu-central-1\"\n# </block>".to_string(),
901
901
  ),
902
+ (
903
+ "nomad.nomad".to_string(),
904
+ "# <block>\ndatacenters = [\"dc1\"]\n# </block>".to_string(),
905
+ ),
902
906
  (
903
907
  "htm.htm".to_string(),
904
908
  "<!-- <block> -->\n<div>Content</div>\n<!-- </block> -->".to_string(),
@@ -45,6 +45,7 @@ impl SymbolsParser for CSymbolsParser {
45
45
  &definitions,
46
46
  &decode_string,
47
47
  None,
48
+ &[],
48
49
  ))
49
50
  }
50
51
  }
@@ -163,12 +164,7 @@ fn top_level_definitions<'tree>(
163
164
  }
164
165
  "alias_declaration" => node
165
166
  .child_by_field_name("name")
166
- .map(|name| Definition {
167
- parents: Vec::new(),
168
- names: vec![name],
169
- range: start..node.end_byte(),
170
- value: None,
171
- })
167
+ .map(|name| Definition::new(Vec::new(), name, start..node.end_byte(), None))
172
168
  .into_iter()
173
169
  .collect(),
174
170
  _ => Vec::new(),
@@ -208,16 +204,12 @@ fn declaration_definitions(declaration: Node<'_>, start: usize) -> Vec<Definitio
208
204
  if value.is_none() && (is_function || is_extern) {
209
205
  continue;
210
206
  }
211
- definitions.push(Definition {
212
- parents: Vec::new(),
213
- names: vec![name],
214
- range: if alone {
215
- start..declaration.end_byte()
216
- } else {
217
- declarator.byte_range()
218
- },
219
- value: value.map(Value::Initializer),
220
- });
207
+ let range = if alone {
208
+ start..declaration.end_byte()
209
+ } else {
210
+ declarator.byte_range()
211
+ };
212
+ definitions.push(Definition::new(Vec::new(), name, range, value));
221
213
  }
222
214
  definitions
223
215
  }
@@ -264,24 +256,19 @@ fn typedef_definitions<'tree>(
264
256
  /// identifier, such as `Foo::bar` or `operator==`.
265
257
  fn function_definition(function: Node<'_>, start: usize) -> Option<Definition<'_>> {
266
258
  let (name, _) = declared_name(function.child_by_field_name("declarator")?)?;
267
- Some(Definition {
268
- parents: Vec::new(),
269
- names: vec![name],
270
- range: start..function.end_byte(),
271
- value: None,
272
- })
259
+ Some(Definition::new(
260
+ Vec::new(),
261
+ name,
262
+ start..function.end_byte(),
263
+ None,
264
+ ))
273
265
  }
274
266
 
275
267
  /// The definitions of `specifier`, a struct, union, class or enum type that starts at `start`:
276
268
  /// the type's name when it has a body, and the enumerators of a plain `enum`.
277
269
  fn type_definitions(specifier: Node<'_>, start: usize) -> Vec<Definition<'_>> {
278
270
  let mut definitions: Vec<Definition> = defined_type_name(specifier)
279
- .map(|name| Definition {
280
- parents: Vec::new(),
281
- names: vec![name],
282
- range: start..specifier.end_byte(),
283
- value: None,
284
- })
271
+ .map(|name| Definition::new(Vec::new(), name, start..specifier.end_byte(), None))
285
272
  .into_iter()
286
273
  .collect();
287
274
  definitions.extend(enumerators(specifier));
@@ -312,14 +299,12 @@ fn enumerators(specifier: Node<'_>) -> Vec<Definition<'_>> {
312
299
  body.named_children(&mut cursor)
313
300
  .filter(|child| child.kind() == "enumerator")
314
301
  .filter_map(|enumerator| {
315
- Some(Definition {
316
- parents: Vec::new(),
317
- names: vec![enumerator.child_by_field_name("name")?],
318
- range: enumerator.byte_range(),
319
- value: enumerator
320
- .child_by_field_name("value")
321
- .map(Value::Initializer),
322
- })
302
+ Some(Definition::new(
303
+ Vec::new(),
304
+ enumerator.child_by_field_name("name")?,
305
+ enumerator.byte_range(),
306
+ enumerator.child_by_field_name("value"),
307
+ ))
323
308
  })
324
309
  .collect()
325
310
  }
@@ -464,7 +449,6 @@ fn macro_value<'tree>(
464
449
  /// Returns an error if an escape is not one C has, stands for no character, doesn't fit in a
465
450
  /// byte, or makes bytes that are not UTF-8 text.
466
451
  fn decode_string(node: &Node, source: &str) -> anyhow::Result<Option<String>> {
467
- let mut cursor = node.walk();
468
452
  match node.kind() {
469
453
  "concatenated_string" => code::decode_concatenated(node, source, &decode_string),
470
454
  // The prefix and the opening quote make one token, such as `u8"`.
@@ -473,9 +457,7 @@ fn decode_string(node: &Node, source: &str) -> anyhow::Result<Option<String>> {
473
457
  _ => Ok(None),
474
458
  },
475
459
  "raw_string_literal" => match node.child(0).map(|open| open.kind()) {
476
- Some("R\"" | "u8R\"") => Ok(node
477
- .children(&mut cursor)
478
- .find(|child| child.kind() == "raw_string_content")
460
+ Some("R\"" | "u8R\"") => Ok(code::child(*node, "raw_string_content")
479
461
  .map(|content| node_text(&content, source).to_string())),
480
462
  _ => Ok(None),
481
463
  },