Credence.Syntax.NoDocWithDoBlock (credence v0.8.0)

Copy Markdown

Repairs a documentation attribute written with a stray do block.

LLMs repeatedly emit @doc "..." do — gluing a do onto a @doc attribute. A documentation attribute (@doc, @moduledoc, @typedoc) never takes a do block, and the dangling do has no matching end, so the module fails to parse (missing terminator: end). It is always a mistake, so this is a REPAIR: drop the trailing do, which rebalances the block structure and leaves the attribute and its value untouched.

The match is anchored to a documentation attribute whose value is a complete double-quoted string literal immediately followed by a bare do at end of line. That is the canonical LLM mistake (@doc "..." do), and a string-literal doc with a do-block never compiles — so the only thing this can match is the bug. A normal @doc "...", a def f do, or a value whose string merely contains the word "do" (which ends in a quote, not do) are never touched.

Deliberately left alone (narrowed out): a documentation attribute whose value is an expression ending in do, e.g. a multi-line conditional doc

@doc (if prod? do
        "..."
      else
        "..."
      end)

This is valid, compiling code. Because the syntax phase runs every rule's fix whenever the source fails to parse for any reason, a line-by-line regex broad enough to catch @doc (... do would also strip the do from this valid block when some unrelated part of the file fails to parse. Anchoring to a complete string literal keeps the repair to the provably-bug shape.

Bad (won't parse — missing terminator: end)

@doc "top_n_items/2" do
def find_top_n(map, n), do: Enum.take(map, n)

Good

@doc "top_n_items/2"
def find_top_n(map, n), do: Enum.take(map, n)