Attach doc comments across Sorbet sig blocks in tags query - #12
Open
tarebyte wants to merge 1 commit into
Open
Conversation
A Sorbet `sig` block sits between a method's doc comment and its definition, so the comment is not adjacent to the definition and `#select-adjacent!` discarded it. Every documented method in a `sig`-annotated codebase lost its doc string in code navigation output. Add a method pattern that matches an intervening `sig` call and anchors doc adjacency on that call. It precedes the general pattern because tree-sitter-tags keeps the match from the earliest pattern when several match the same node, so no duplicate tags are produced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac21705f-befb-4606-9c83-657e3e9ea0dc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
queries/tags.scmattaches a method's documentation with#select-adjacent!, which keeps a comment only while it sits on the row immediately above the anchor node. A Sorbet signature between the comment and the definition breaks that adjacency:tree-sitter tagstagsaddbut reports no docs for it.This affects the comment-then-
sig-then-deforder only. Writing the signature above the comment already works onmaster, so this is not every documented method in a Sorbet codebase — it is the conventional ordering.Change
Adds one pattern that allows a single
sigcall between the comment and the definition and anchors adjacency on thesigitself. It coverssig { },sig do … end,sig(:final) { }andT::Sig::WithoutRuntime.sig { }, for bothmethodandsingleton_method.The pattern is placed before the general method pattern because
tree-sitter-tagsdeduplicates by name range and keeps the match from the earliest pattern.The
sigidentifier has to be captured to be matched with#eq?, andtree-sitter-tagsrejects capture names outside its known set —@_sigand similar are errors — so it is captured as@reference.call. The existing generic call pattern already emits asigreference, and deduplication means no second one is added.No grammar change: a signature is an ordinary Ruby block and already parses as a
call.Known limits
Both are asserted in the Rust test so that changing either is deliberate.
tree-sitter-tagsanchors#select-adjacent!on the last node captured for the named capture, so with two signatures the anchor is the one nearest the definition and the comment is two rows away. Capturing only the first signature is not expressible, because the extra signatures would need a capture name and every valid name has other side effects.private defis unaffected by this PR and still loses its comment. The definition is an argument toprivate, not a sibling of the comment. This is independent of Sorbet — a documentedprivate defloses its comment onmastertoo, with or without a signature.Validation
test/tags/sorbet.rb, picked up bytree-sitter testastags: sorbet.rb (4 assertions). That harness compares only tag names and spans, so it is a guard against the new pattern changing what gets tagged; it cannot observe docs and does not fail onmaster.bindings/rust/lib.rsdrivestree-sitter-tagsdirectly and asserts the doc strings. It is the test that actually demonstrates the fix: againstmaster's query it fails withleft: Some(None),right: Some(Some("Converts to a string.")).examples/ruby_specfiles before and after: 274,521 tags on both sides, differing in exactly one line.That one line is
cvar_c | methodbecomingcvar_c | call, both at(0, 0). It comes from the(setter (identifier) @ignore)pattern.Tag::ignoredhardcodessyntax_type_id: 0, and adding@reference.callearlier in the file movescallinto index zero. The underlying tag is an ignored sentinel thattree-sitter-tagsleaks into its output rather than a real tag, but it is consumer-visible —tree-sitter tagsprintsmethodonmasterandcallon this branch. No non-ignored tag changed.The corpus comparison is a regression check only.
examples/ruby_speccontains no line-leading Sorbetsig, so it does not exercise the new pattern.tree-sitter-tagsis added as a dev-dependency;cargo tree -e normaldoes not include it.Cargo.lockalso picks up a transitivememchrbump from 2.7.4 to 2.8.3.Relationship to tree-sitter#175
This does not resolve that issue and is not a partial fix for it. tree-sitter#175 asks for dedicated AST nodes for Sorbet signatures; the maintainers answered that signatures are ordinary Ruby and belong in post-processing or a derived grammar. This PR changes only the tags query and adds no nodes. The doc-comment bug is a separate defect that happens to be triggered by the same syntax; it is not mentioned in tree-sitter#175.
Merge note
This and #5 both add tests to the same module in
bindings/rust/lib.rsand will conflict; whichever lands second needs the other's test block re-applied.