Skip to content

fix(go): a type declared on its own keeps its doc comment - #2438

Merged
colbymchenry merged 11 commits into
mainfrom
claude/vigilant-chandrasekhar-072d56
Oct 7, 2026
Merged

colbymchenry merged 11 commits into
mainfrom
claude/vigilant-chandrasekhar-072d56

Conversation

@colbymchenry

@colbymchenry colbymchenry commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Problem

A Go type declared on its own lost its doc comment in both extractors, while one inside a type ( … ) group kept it:

// Foo is documented.
type Foo struct{}      // docstring: none

type (
	// Bar is documented.
	Bar int            // docstring: "Bar is documented."
)

tree-sitter-go wraps every type in a type_declaration, and the comment is that declaration's previous sibling. The node is made from the spec inside it (a type_spec, or a type_alias since #2417), and the spec's only predecessor is the type keyword. So the docstring walk found nothing for any ungrouped struct, interface, defined type or alias.

Fix

  • Read the doc from the declaration (getDeclarationWrapper in languages/go.ts, declaration_wrapper in go.rs). The climb happens when the type_declaration holds exactly one spec (type_spec or type_alias) and nothing precedes that spec inside it.
    • The leading comment of a group with several members stays the group's. A member's own comment beside it is found as before.
    • A group of one (// X … above type ( Lone int )) takes the comment above it, as go doc does, unless its member has a comment of its own. None of the three repos below has such a group.
  • A comment that trails code on the line above is not a doc (new docstringSkipsTrailingComments extractor option, set for Go; preceding_docstring_skipping_trailing in docstring.rs).
    • The spot-check turned this up: reading from the declaration would have handed 7 types the comment at the end of the previous line. For example, prometheus's generated const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package would have become type MetricType int32's doc.
    • A comment that begins after code on its line is now left out, and so is one that begins on the line such a comment ends. That is go/parser's line-comment rule.
    • It applies to every Go declaration, so it also removes such comments from the 7 functions that had already picked one up, e.g. BenchmarkSize ← var GlobalTotal uint64 // Encourage the compiler….

Validation

Indexes of etcd, prometheus and gin built on main (ed199e60, aliases included) and on this branch, with the default kernel route and with CODEGRAPH_KERNEL=0:

repo Go nodes with a docstring gained of which = go doc function docstrings changed
etcd 1,955 → 2,291 336 332 1 trimmed
prometheus 3,889 → 4,786 902 897 1 trimmed, 5 cleared
gin 500 → 569 69 67 —
  • "= go doc" is checked against an independent text oracle: the comment-only lines directly above the declaration line, with no blank line between. The gains include the 14 documented ungrouped aliases (10 etcd, 4 prometheus). The 7 changed function docstrings were all trailing comments of the line above; the 2 trimmed ones now equal go doc.
  • Nothing else changed: nodes (every other column), edges, unresolved refs and files are byte-identical. Kernel and wasm full indexes are identical on both sides.
  • Kernel parity: kernel-parity.mjs --lang go shows 0 diffs on all three repos, with the same deferral counts as main (etcd 40/1105, prometheus 0/736, gin 0/99).

Spot-check

  • No gained docstring takes a license header (the package clause stands between), a group's leading comment, or a comment from the line above.
  • 11 gained docstrings also include a comment separated from the type by a blank line:
    • Most are section banners or file notes: gin's // ==== TextUnmarshaler tests START ====, the /*** CONTENT NEGOTIATION ***/ banner above Negotiate, prometheus's // Filters in this file expect ….
    • Codegraph's docstring walk joins such comments in every language, and Go functions already get them (51 on these repos).
    • One is clearly someone else's: etcd's ReadTx picks up an orphaned copy of Bucket.IsSafeRangeBucket's doc.
    • go doc ignores these comments. Applying its adjacency rule to every Go declaration would drop them, but that changes existing function docstrings too, so it is left out of this PR.

Overlap

Tests

  • __tests__/go-type-doc-comments.test.ts: kernel and wasm, LF and CRLF. On main it fails with 10 wrong values: 8 types have no doc (7 declared on their own, an alias among them, plus a group of one), and Kelvin (a group member) and Next (a function) take the trailing comment of the line above.
  • Rust unit test docstring::tests::skips_the_comments_that_trail_code.
  • __tests__/fixtures/kernel-parity/torture.go gains a documented ungrouped type, a commented group and a trailing comment.
  • Full suite: the parallel run on this loaded box (100% CPU, about 90 node processes from other sessions) failed 194 tests in 72 files on timeouts. A serial rerun of those files with 120 s timeouts passed all but 5. Four of those (mcp-status-freshness, mcp-writer-lock, mpeg-ts-not-typescript) passed when their files ran alone. The fifth, the Python #1820 case in function-ref.test.ts, passed in 151 s once its in-file 60 s limit was raised locally (not committed). None of them involves docstrings.

🤖 Generated with Claude Code

colbymchenry and others added 11 commits October 7, 2026 05:47
tree-sitter-go puts the comment above `type Foo struct{}` before the
`type_declaration`, but the node is made from the spec inside it, so both
extractors found no docstring for an ungrouped struct, interface, defined
type or alias. A type inside a `type ( ... )` group kept its own comment,
which sits beside it in the parentheses.

Go's docstring is now read from the declaration when the declaration
holds one spec and nothing precedes that spec inside it. The leading
comment of a group with several members stays the group's.

Reading from the declaration exposed comments that trail the line above:
`const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto
package` would have become `type MetricType int32`'s doc. For every Go
declaration, a comment that begins after code on its line, and one that
begins on the line such a comment ends, is now left out, as go/parser
reads them. Seven function docstrings on etcd and prometheus lose one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2417 now extracts `type A = B`, so the test covers an ungrouped alias
and an alias that is a member of a commented group.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@colbymchenry
colbymchenry merged commit b635dd4 into main Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant