Skip to content

Add @nothrow mute comments and --fix autofix - #2

Merged
mirek merged 1 commit into
mainfrom
claude/throwscript-throws-linter-8viyai
Jul 4, 2026
Merged

mirek merged 1 commit into
mainfrom
claude/throwscript-throws-linter-8viyai

Conversation

@mirek

@mirek mirek commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Two features on top of the initial checker (#1):

Muting with @nothrow (eslint-style)

  • // @nothrow or // @nothrow-line — trailing comment mutes that line
  • // @nothrow-next-line — mutes the following line

Semantics depend on what's on the muted line:

  • a throw, a propagating call, or Promise.reject → that throw site is ignored entirely (doesn't need documenting, doesn't count as "using" a documented tag)
  • the function declaration line (// @nothrow-next-line directly above it) → the whole function's missing-@throws report is muted
  • a @throws tag line inside JSDoc → its unused-tag warning is muted

Directives are found by lexing comments with the TypeScript scanner, so @nothrow inside a string literal doesn't trigger. Works in // and /* */ comments; in multi-line comments the directive applies relative to the line it's written on.

--fix

missing-throws diagnostics now carry a text edit (fix field), and throwscript --fix applies them and re-checks:

  • existing multi-line JSDoc → * @throws {Type} lines appended before the closing */
  • single-line /** ... */ → broken open into a multi-line block
  • no JSDoc → fresh block created above the declaration (above the variable statement for arrows), matching surrounding indentation
  • declarations that don't start their own line (inline callbacks) get no fix, since a JSDoc block couldn't be attached unambiguously

Core gains applyFixes(diagnostics) (dedupes identical edits, skips overlaps, returns patched contents per file). Unused-tag warnings are deliberately not auto-fixed. Both packages bumped to 0.2.0.

Test plan

  • pnpm run check green — build, oxlint, 10 core + 6 CLI tests
  • New tests: all mute variants (same-line, -line, -next-line, declaration-level, call-site, tag-line) plus negative controls; fix insertion for no-doc / multi-line-doc / one-line-doc / arrow / indented method / multi-type cases; CLI --fix round-trip on a temp copy
  • Built CLI verified end-to-end: --fix fixed 2 problems, respected a // @nothrow mute, and the re-run exits 0

🤖 Generated with Claude Code

https://claude.ai/code/session_01UG7WqvjcBWuMRj24ssFSrd


Generated by Claude Code

Muting, mirroring eslint's disable comments:
- `// @nothrow` / `// @nothrow-line` trailing a line mutes that line
- `// @nothrow-next-line` mutes the following line
A muted throw site (throw, propagating call, Promise.reject) is ignored
entirely; muting the declaration line suppresses the function's
missing-@throws report, and muting a @throws tag line suppresses its
unused-tag warning. Directives are detected via the TS scanner so
occurrences inside string literals don't trigger.

Autofix: missing-throws diagnostics now carry a text edit that appends
`* @throws {Type}` lines to an existing JSDoc block (breaking open
single-line blocks), or creates a fresh block above the declaration —
above the variable statement for arrows — matching indentation. New
`applyFixes()` in @throwscript/core applies edits with dedupe/overlap
handling; `throwscript --fix` writes the files and re-checks. Fixes are
skipped for declarations that don't start their own line.

Bump both packages to 0.2.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UG7WqvjcBWuMRj24ssFSrd
@mirek
mirek marked this pull request as ready for review July 4, 2026 18:40
Copilot AI review requested due to automatic review settings July 4, 2026 18:40
@mirek
mirek merged commit 99a42ba into main Jul 4, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds two user-facing capabilities to throwscript: eslint-style muting of specific throw/call/tag lines via @nothrow directives, and an autofix mode that can insert missing @throws tags and re-check.

Changes:

  • Implement @nothrow, @nothrow-line, and @nothrow-next-line comment directives to suppress throw-site propagation, missing-@throws errors (at declaration line), and unused-tag warnings (at tag line).
  • Add fix support for missing-throws diagnostics (fix text edit) plus applyFixes(diagnostics) in @throwscript/core.
  • Add CLI --fix mode (writes patched files, re-analyzes) and extend tests/README; bump packages to 0.2.0.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Documents @nothrow muting behavior and --fix autofix mode; notes fix + applyFixes API.
packages/core/test/mute-fix.test.ts Adds core tests covering muting semantics and applyFixes behavior.
packages/core/test/fixtures/muted.ts New fixture exercising muting variants and tag-line muting.
packages/core/test/fixtures/fixable.ts New fixture covering fix insertion cases (no doc, multi-line doc, one-liner, arrow, method, multi-type).
packages/core/src/index.ts Re-exports new API and adds applyFixes(diagnostics) implementation.
packages/core/src/analyzer.ts Adds comment scanning for muted lines, suppresses diagnostics accordingly, and computes missing-throws fixes.
packages/core/package.json Bumps @throwscript/core version to 0.2.0.
packages/cli/test/cli.test.ts Adds CLI tests for --fix round-trip and CLI-level muting behavior.
packages/cli/src/main.ts Adds --fix option, applies fixes and re-checks, updates help/version output.
packages/cli/package.json Bumps throwscript version to 0.2.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/cli/src/main.ts
Comment on lines +156 to 159
if (updated.size > 0) {
fixedCount = fixable.length;
diagnostics = analyze(parsed);
}

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ca0dc70b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ts.isVariableDeclarationList(parent.parent) &&
ts.isVariableStatement(parent.parent.parent)
) {
return parent.parent.parent;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip autofix for multi-declaration arrow statements

When a statement declares multiple arrow/function expressions, e.g. export const a = () => { throw new A(); }, b = () => { throw new B(); };, this returns the same VariableStatement anchor for every declaration. Each diagnostic then emits an insertion at the exact same offset, so --fix stacks multiple JSDoc blocks above one statement; TypeScript only associates the nearest block with the statement, leaving at least one declaration still missing its @throws (or giving all declarations the same tags). This autofix should be skipped or handled specially when the declaration list contains multiple declarations.

Useful? React with 👍 / 👎.

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.

2 participants