Repository navigation
refactor(ast): tidy the doc-placement helpers #1615
Description
Two small cleanups in the doc-comment code that PR #1609 (#1597) added. Neither changes behaviour.
1. Rust-only parameters on a shared hook.
Checker::holds_doc_comment_in_body(ancestor, ancestors, below, comment, code)takescommentandcodeonly for Rust's inner-doc exception: a//!//*!opening a function body is that function's own#![doc].- The trait default and the Java, Kotlin, Groovy and PHP overrides all bind them as
_comment/_code. documents_where_it_sitspassesSome(comment)for the two nearest ancestors andNoneinside the memoised fold, so the contract also depends on depth.
Options:
- Decide the inner-doc exception in Rust's own comment path. The byte test plus
rust_inner_doc_opens_bodyneed only the comment and its two nearest ancestors. The hook then shrinks to(ancestor, ancestors, below). - Alternatively, give the exception a dedicated hook that defaults to
false.
Either way, the shared hook stops carrying one language's parameters.
2. Two backward scans per Python docstring run.
python_documentation_string_run (big-code-analysis-ast/src/lang_helpers/python.rs) walks siblings_before once to find the run's first string, then calls python_is_documentation_string, which walks siblings_before again to find the statement before the run. One pass can find both: the first non-string, non-comment sibling ends the run and is the statement documented_by tests.
How to check.
make pre-commit, andmake bench-scaling, which coversloc/python-additional-docstringsandloc/rust-nested-doc-mods.- No snapshot or metric value should move. Confirm by diffing the loc JSON over the corpora before and after.
Resolution
Commit: on fix/batch-2026-10-17 98f98956 (refactor(ast): tidy the doc-placement helpers).
1. Rust-only parameters on the shared hook. Taken the dedicated-hook route: Checker::holds_doc_comment_in_body is now (ancestor, ancestors, below), and Rust's inner-doc exception lives in a new #[doc(hidden)] hook Checker::doc_comment_opens_body(function, body, comment, code) -> bool (default false; only Rust overrides it). documents_where_it_sits asks it for the two nearest ancestors only, never inside the memoised fold_down, so the per-ancestor cache stays comment-independent. The Java/Kotlin/Groovy/PHP overrides drop their _comment/_code binds. A Rust-local wrapper was rejected: the LineComment arm calls documents_where_it_sits directly but the BlockComment (/*!) arm reaches it through shared.rs::add_comment_lines, so a wrapper would have had to change both arms and repeat the two-ancestor walk.
2. Two backward scans per Python docstring run. python_documentation_string_run and python_is_documentation_string share one private documentation_run_start, which walks siblings_before once and returns both the run's first string and the statement before it.
No metric moved. Pre- and post-fix binaries compared over 29,438 files (DeepSpeech, pdf.js, serde, tests/, src/, big-code-analysis-ast/src/) for the loc family: 0 diffs. No corpus snapshot changed. make bench-scaling: all 58 probes within bound; loc/rust-nested-doc-mods exponent 1.00, loc/python-additional-docstrings 1.01 (bound 1.50).
Tests added: two PEP 257 rows (a docstring run with comments before and inside it, after an assignment and after a call — each catches a mutant nothing else did), and a //!-in-closure-body row in rust_inner_doc_comment_opening_a_fn_body_documents_it (catches dropping the function_item kind check; found by the audit-tests pass). The existing /*! block-form row already guards the BlockComment arm. One deliberate non-test: dropping the body field comparison only changes fn f(/*! x */ a), which is rustc E0753 and left undecided per grammar-dispatch rule 6.
Premise correction: the CHANGELOG reference to the hook is at ~:109, not ~:69 as the plan said; reworded in place to name both hooks. .bca-baseline.toml: checker.rs file-level ploc/sloc +1 % (the new hook's signature and doc), and six stale nargs = 5 entries for the five-argument hook removed.
Gate: BCA_GATE: pass (gate=pre-commit).
Activity
dekobon commentedon Oct 18, 2026
Resolution
Commit: on
fix/batch-2026-10-1798f98956(refactor(ast): tidy the doc-placement helpers).1. Rust-only parameters on the shared hook. Taken the dedicated-hook route:
Checker::holds_doc_comment_in_bodyis now(ancestor, ancestors, below), and Rust's inner-doc exception lives in a new#[doc(hidden)]hookChecker::doc_comment_opens_body(function, body, comment, code) -> bool(defaultfalse; only Rust overrides it).documents_where_it_sitsasks it for the two nearest ancestors only, never inside the memoisedfold_down, so the per-ancestor cache stays comment-independent. The Java/Kotlin/Groovy/PHP overrides drop their_comment/_codebinds. A Rust-local wrapper was rejected: theLineCommentarm callsdocuments_where_it_sitsdirectly but theBlockComment(/*!) arm reaches it throughshared.rs::add_comment_lines, so a wrapper would have had to change both arms and repeat the two-ancestor walk.2. Two backward scans per Python docstring run.
python_documentation_string_runandpython_is_documentation_stringshare one privatedocumentation_run_start, which walkssiblings_beforeonce and returns both the run's first string and the statement before it.No metric moved. Pre- and post-fix binaries compared over 29,438 files (DeepSpeech, pdf.js, serde,
tests/,src/,big-code-analysis-ast/src/) for thelocfamily: 0 diffs. No corpus snapshot changed.make bench-scaling: all 58 probes within bound;loc/rust-nested-doc-modsexponent 1.00,loc/python-additional-docstrings1.01 (bound 1.50).Tests added: two PEP 257 rows (a docstring run with comments before and inside it, after an assignment and after a call — each catches a mutant nothing else did), and a
//!-in-closure-body row inrust_inner_doc_comment_opening_a_fn_body_documents_it(catches dropping thefunction_itemkind check; found by the audit-tests pass). The existing/*!block-form row already guards theBlockCommentarm. One deliberate non-test: dropping thebodyfield comparison only changesfn f(/*! x */ a), which is rustc E0753 and left undecided per grammar-dispatch rule 6.Premise correction: the CHANGELOG reference to the hook is at ~:109, not ~:69 as the plan said; reworded in place to name both hooks.
.bca-baseline.toml:checker.rsfile-levelploc/sloc+1 % (the new hook's signature and doc), and six stalenargs = 5entries for the five-argument hook removed.Gate:
BCA_GATE: pass (gate=pre-commit).refactor(ast): tidy the doc-placement helpers
docs(changelog): record the LOC and doc-comment fixes
refactor(ast): tidy the doc-placement helpers
docs(changelog): record the LOC and doc-comment fixes
refactor(ast): tidy the doc-placement helpers
docs(changelog): record the LOC and doc-comment fixes
dekobon commentedon Oct 20, 2026
Pull request: #1650.