feat: add Elixir comment and doc-attribute extraction - #1151
Open
C-Sinclair wants to merge 1 commit into
Open
Conversation
Elixir has no documentation comment syntax. Its published API documentation lives in `@moduledoc`, `@doc`, `@typedoc` and `@shortdoc` attributes holding a string or heredoc -- that is what `mix docs` renders and what a reader of a module reads first -- so a comment-only pass would see the asides and none of the documentation. Both are extracted. Comments keep the usual `text.comment.line` and `text.comment.block` scopes; the attributes get a `doc` meta scope, so `text.comment.doc.block` can be held to a different standard, or excluded, independently of an implementation note. The queries capture `quoted_content` -- the body of the string -- rather than the string itself, which leaves the delimiters out without a Delims pattern having to remove them. That matters for the single-quoted `@doc "..."` form, where stripping the delimiter by regex would also strip any quote written inside the prose. The attribute name is what decides whether a node is documentation, and the prose is a different node, so the query needs to test one node and capture another. Query captures named with a leading underscore are now skipped rather than linted, which is the convention tree-sitter itself uses for internal captures; without it the only testable node is the one you extract. `@doc false` and `@doc since: "1.0.0"` carry no prose, and the queries require a string or sigil argument, so neither matches. The grammar is already vendored in go-tree-sitter, so this adds no dependency.
C-Sinclair
marked this pull request as ready for review
August 21, 2026 12:29
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.
Adds Elixir (
.ex,.exs) to the tree-sitter comment extractors.Why the doc attributes, not just the comments
Elixir has no documentation comment syntax. Its published API documentation lives in module attributes holding a string or a heredoc:
That is what
mix docsrenders and what a reader of a module reads first, so extracting only#comments would see the asides and none of the documentation.Both are extracted. Comments keep the usual scopes; the attributes get a
docmeta scope, sotext.comment.doc.blockcan be held to a different standard than an implementation note, or excluded on its own viaIgnoredScopes.@moduledoc,@doc,@typedocand@shortdocare covered;@doc falseand@doc since: "1.0.0"carry no prose and the queries require a string or sigil argument, so neither matches.Predicate-only captures
The attribute name is what decides whether a node is documentation, and the prose is a different node — so the query has to test one node and capture another.
#match?can only test a captured node, so this needs a capture that is tested but not linted.query.gonow skips captures whose name begins with_, which is the convention tree-sitter itself uses for internal captures. Without it, the query has to capture the whole@moduledoc """..."""and take the delimiters off withDelims— which for the single-quoted@doc "..."form would also strip any quote written inside the prose.With it, the queries capture
quoted_content(the body of the string) and the extracted text needs no delimiter stripping at all.Delimsis just#.This is a small behaviour change to shared code: any existing query using an
_-prefixed capture name would stop having that capture linted. I could find none in-tree, and linting a capture that exists for a predicate looks like the unintended reading, but flag it in case you'd rather have it behind a language flag.Notes
github.com/smacker/go-tree-sitter/elixiris already vendored, so this adds no dependency..heex(Phoenix HTML templates) is deliberately left alone — no grammar for it in the set, and mapping it onto HTML would reduce it to<!-- -->comments.Tests
testdata/comments/{in,out}/8.ex,9.exs— extraction fixtures covering heredoc docs, the single-quoted form, sigil docs (~S"""), a line-comment run, a trailing comment, and the prose-free attributes.testdata/e2e/lint.yaml— anelixircase againsttestdata/fixtures/formats/test.ex; all seven reported columns are exact.TestPredicateOnlyCaptureandTestDocAttributesWithoutProseincomments_test.go.go test ./internal/...is green.Happy to split the
query.gochange into its own commit or PR if you'd prefer to take them separately.