Skip to content

✨ sphinx-codelinks: TypeScript and JavaScript comment type (moved from sphinx-codelinks#82) - #2166

Merged
chrisjsewell merged 28 commits into
masterfrom
feat/codelinks-typescript
Oct 9, 2026
Merged

chrisjsewell merged 28 commits into
masterfrom
feat/codelinks-typescript

Conversation

@ubmarco

@ubmarco ubmarco commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

What

packages/sphinx-codelinks: moves useblocks/sphinx-codelinks#82 (TypeScript and JavaScript comment type, by @arnoox) into the monorepo with the recipe from #1871, and addresses that PR's open review on top.

comment_type = "ts" analyses .ts, .tsx, .mts, .cts, .js, .jsx, .mjs and .cjs. The grammar is chosen per file: TypeScript for .ts/.mts/.cts, where a <T>x cast is legal, and TSX for every other suffix, which also reads JSX. Legacy one-line <!-- comments (classic scripts only) are read too. For this comment type exclude defaults to the usual build-output directories.

The move: the branch was 24 commits, 3 of them merges of main, and #1898 measured five conflict stops on the old main. So it comes across as two commits with their authors kept: Arnaud Riess's work up to the 2026-08-07 merge, and Marco Heinemann's follow-ups. Both were filtered with the import's git filter-repo rule, which puts them on the commit the import merged, and cherry-picked onto master. The full history stays at useblocks/sphinx-codelinks#82. The conflicts against master were resolved in place:

  • The changelog entry moved to docs/changelog.rst, written for the release.
  • The docs hunks moved to docs/components/.
  • The audited AGENTS.md and the @AGENTS.md CLAUDE.md are kept; the PR's own CLAUDE.md is dropped.
  • test_analyse_oneline_needs takes the PR's case dicts with master's get_multiline_needs.
  • uv.lock gains only the tree-sitter-typescript entries.

Then four commits (six, the takeover counted: a 📚 commit linking the changelog entry to this pull request follows the third, and a 🧪 commit pinning a @need-ids: line in a JSDoc block follows the fourth):

  1. 🧪 The TypeScript cases are re-captured in the production-shape corpus of 🧪 sphinx-codelinks: snapshot the real extraction output, with marker scope association (moved from sphinx-codelinks#100) #2128. Multi-line needs work in TypeScript with no code change, now pinned by two cases.
  2. 👌 Scope association covers TypeScript's declarations (the review below).
  3. 👌 The one-row block, JSX and <!-- --> markers.
  4. 👌 A JSDoc tag line is a jsdoc_tag warning, not a need.

The merge of master: master moved by one commit since this branch was cut, 132607bb (#2168: src-trace renders multi-line needs). It is merged in (023dd70b), not rebased, so the eight commits above are unchanged. Two files conflicted. In docs/changelog.rst the multi-line needs bullet takes master's text with this branch's language list, and the TypeScript bullet follows master's new src-trace bullet. In tests/data/extraction/multiline_needs.yaml master's four language cases and this branch's two sit side by side after bash_hash_run. Nothing else moved: against master the diff is this branch's own (+2974/−149) plus the takeover's commits below. A // run and a JSDoc block — the two shapes the corpus pins — now render through src-trace: test_typescript_blocks_render.

The review round (two reviews of the takeover; every commit after the merge): export declare … binds the declaration it holds (find_next_scope looks one container deeper, pinned red first by typescript_export_declare), and a declare-prefixed const, let or var is a scope, as it holds no value (pinned red first by typescript_declare_const_binds, which now holds one of each); JSDoc's @modifies and TypeScript's JSX pragmas jsx, jsxFrag, jsxImportSource and jsxRuntime join the shared tag list (112 names); the grammar choice, the scope predicates, the C++ side of the jsdoc_tag gate, <!-- runs and discover -e get the pins they lacked, each shown red under the wrong version it catches, but for the <!-- pin, which records today's behaviour; the narrowed rule's question to the one-line parser (jsdoc_tag_asks_the_one_line_parser, with ; as the separator) and every JSX pragma of the tag list are pinned too; the docs say what was measured (the exclude default's width, the discover.rst example, [[ rather than @need as the suggested start sequence, where <!-- is valid); and, in a commit of its own, the jsdoc_tag rule is narrowed (item 15).

Closes #1890

Why

The review of useblocks/sphinx-codelinks#82, open at the move. The first round (five threads) was fixed on that branch before it moved.

  1. The TSX grammar is not a superset of TypeScript's. Fixed on that branch: the grammar is chosen per suffix. oneline.yaml type_assertion_oneliner_typescript now pins it through production wiring: under TSX, the marker after the cast is lost.
  2. Interfaces, enums, type aliases, abstract classes and generator functions bound to the next unrelated function. They are scopes now. So are function signatures, modules, namespaces and interface/abstract method signatures.
  3. TS_FUNCTION_VALUE_TYPES was too narrow. Generator functions and class expressions count, seen through as, satisfies, !, <T> and parentheses.
  4. The demo marker field order. Fixed on that branch.
  5. Nothing pinned the production grammar choice. The test fixtures now build their parsers through init_tree_sitter. The declarative cases go through production wiring, and their tagged_scope differs under the wrong grammar.
  6. JavaScript's assignment forms and anonymous default exports. module.exports = function () {}, Foo.prototype.bar = … and export default () => {} bind.
  7. Class-field arrow functions bound to the class. A class field holding a function binds to the field.
  8. .d.ts declarations had no scope. declare … is searched like export …, so ambient declarations bind. .d.ts files stay discovered.
  9. TypeScript-only rules hardcoded in the shared traversal. They now live in two per-language tables, SCOPE_CONTAINER_TYPES and SCOPE_PREDICATES. A comment type without a SCOPE_NODE_TYPES entry has no scopes, not C++'s.
  10. Six copies of one query. The five grammars (six, the takeover counted: C/C++, C#, YAML, Go, JSONC and Bash) whose comments are one comment node share SIMPLE_COMMENT_QUERY. TypeScript's query differs, since it also captures html_comment.
  11. Five unsynchronised edits per language. test_every_comment_type_is_wired fails when a CommentType member misses a table, rather than failing as a KeyError in discovery.
  12. The one-row {/* @… */} and /* @… */ forms failed. They work since 🐛 sphinx-codelinks: physical marker columns, need-ref spans, and Epydoc field tags in docstrings are not needs #2129 (the closing */ is no marker text) and are pinned now. The docs no longer call them unsupported.
  13. The CLAUDE.md described an architecture that does not exist. Dropped in the move.
  14. The changelog heading. The entry is under Unreleased.
  15. Every JSDoc tag line warned (the takeover's change to the rule, measured: one ordinary eight-line JSDoc comment with no comma anywhere gave six jsdoc_tag warnings, enough to fail a -W build, while the same text in /* */ gave none). As docstring_tag was narrowed for Python, a line of a JSDoc comment is now a jsdoc_tag warning, and never a need, only when the one-line start sequence is @, nothing alphanumeric precedes it, a listed tag directly follows it and ends at a space, a tab, {, } or the line end, and the one-line parser would otherwise have read the line as a marker or warned about it. @param a the augend stays silent; @param a the first, thing still warns. Under [[, [[param a, b]] is a need. The rule is written once, in jsdoc.yaml's header. It is its own commit, so it can be dropped.

Follow-up findings on that PR:

  • html_comment markers were dropped. Fixed on that branch, and a one-row <!-- … --> now drops its --> as a block comment drops */.
  • @need-ids: in a JSDoc block also produced a phantom need. Fixed on master by ✨ sphinx-codelinks: attach @need-ids references to the needs they name, during the build #2049: a reference-marker line is no one-line need.
  • Generated output was scanned as source. Fixed on that branch by the per-comment-type exclude default.
  • JSDoc tags with a comma became needs: @param a First, second gave a need with the id second. Now a jsdoc_tag warning applies, following the docstring_tag rule of 🐛 sphinx-codelinks: physical marker columns, need-ref spans, and Epydoc field tags in docstrings are not needs #2129. A line of a JSDoc comment whose start sequence is directly followed by a JSDoc tag warns and yields no need (narrowed by the takeover to the lines the one-line parser would have read, under @: item 15). A JSDoc comment is one opened by exactly /**, under comment_type = "ts". The tag must end at a space, a tab, {, } or the line's end. The tag list covers JSDoc's block tags, TSDoc's, TypeScript's and the inline tags; matching is case-sensitive. The warning says to choose a start sequence JSDoc does not use. /* */, // and /*** */ comments are untouched, and so is C++ Doxygen.

Tests

  • scope.yaml: 23 TypeScript and JavaScript cases (30 since the takeover's typescript_export_declare, typescript_declare_const_binds, and one case per scope predicate and for the abstract method signature), one association each, among them every declaration kind above.
  • oneline.yaml: 7 TypeScript-family cases: the three moved ones plus the one-row block, JSX inline, <!-- --> and cast cases (8 with the takeover's jsx_text_oneliner_tsx: JSX text is no comment, so .tsx → TSX is pinned).
  • multiline_needs.yaml: a // run and a JSDoc block (4 with the takeover's two <!-- pins: a run of <!-- lines holds no block, and a <!-- row ends a // run).
  • jsdoc.yaml (new, 6 cases; 7 with the @need-ids: case, the takeover counted; 10 with its jsdoc_more_tags, doxygen_in_cpp_is_no_jsdoc and jsdoc_tag_asks_the_one_line_parser): tag lines warn and the non-tag marker is a need. It also covers where a tag ends, case sensitivity, comments that are no JSDoc, JavaScript, and a start sequence JSDoc does not use.
  • test_jsdoc_tag: the tag shape, the same table as ubCode's.
  • test_every_comment_type_is_wired.
  • The PR's own unit, discovery and CLI tests.
  • test_multiline_needs_render.py::test_typescript_blocks_render (the takeover's): a ts project beside the fixture's src, a // run with an RST body in a .ts file and a JSDoc block with a MyST body in a .tsx file, each traced on an RST page. Each need is recorded at its directive with its body's doctype and its links, its local URL is at the block's open line, its body renders the role link and the list, and the build warns nothing. With get_multiline_needs off for the project both needs are absent and the test fails.
  • The takeover's units: test_ts_grammar_key (.ts, .mts, .cts, .d.ts in any case → TypeScript; the rest → TSX); test_a_ts_and_a_tsx_file_in_one_run_each_get_their_grammar (one analysis, both orders); test_discover_cli_excludes_replace_the_ts_default; and the default-exclude test asserts what discovery lists, build/, out/, coverage/ and a .d.ts included.
  • At the tip: poe test-codelinks 1051 passed, 0 skipped, on Sphinx 9.1 and on Sphinx 7.4 / Python 3.11; poe docs-codelinks builds with no warning; poe import-check-codelinks imports the wheel with tree-sitter 0.25.2 and tree-sitter-typescript 0.23.2 resolved from PyPI.

The corpus is shared with ubCode, whose parity test replays every case above (useblocks/ubcode#2764, re-vendored from this branch the same day; see ubCode below).

ubCode

The twin is useblocks/ubcode#2764 (Marco's, taken over the same day and merged onto main). It re-vendors the shared corpus (SOURCE.md) from this branch while it is open and at this pull request's squash commit once it merges, and its parity test replays the TypeScript cases of oneline.yaml, scope.yaml, jsdoc.yaml and multiline_needs.yaml. The jsdoc_tag rule (the tag list, the end class, the exactly-/** rule, and since the review round the @-only and would-have-been-read clauses) is written once, here, in jsdoc.yaml's header, and ubCode implements the same text. From the re-vendor the twin also mirrors the two-level container walk (export declare …), the ambient-variable arm of the declaration predicate (a declare-prefixed const, let or var is a scope) and the 112-name tag list. js_html_row_breaks_a_line_run in multiline_needs.yaml was written for the reference by ubCode's review of the twin.

Checklist

  • I wrote this change myself and have read every line of it; it was not generated automatically from an issue.
  • I ran the package's tests (uv run poe test-codelinks) and they pass.
  • Documentation is updated where behaviour or options change.
  • The package's docs/changelog.rst has an entry under Unreleased.
  • uv run poe lint and uv run poe typecheck pass.

Arnaud Riess and others added 5 commits October 9, 2026 14:16
The original work of useblocks/sphinx-codelinks#82, squashed from its branch
(issue/69-typescript-support) up to the 2026-08-07 merge of main:
`comment_type = "ts"`, parsed with tree-sitter-typescript's TSX grammar,
discovery of `.ts` and `.tsx`, scope node types for TypeScript (an exported
declaration and a function-valued `const` bind), and tests.

The full commit history stays reachable at
useblocks/sphinx-codelinks#82.
The follow-up commits of useblocks/sphinx-codelinks#82 (2026-08-07 to
2026-08-19), squashed: the comment type covers `.mts`, `.cts`, `.js`, `.jsx`,
`.mjs` and `.cjs`; the grammar is chosen per file suffix (TSX only for
`.tsx`, `.jsx` and the JavaScript family, so a `<T>x` cast in a `.ts` file
no longer swallows the rest of the file); legacy `<!-- ... -->` comments are
captured; generated output is excluded from discovery by default for this
comment type; declarative extraction fixtures for the TypeScript family;
the FE_TS feature with its impl markers; docs.

The full commit history stays reachable at
useblocks/sphinx-codelinks#82.
The moved branch predates #2128, so its three oneline
cases are re-captured as the real extraction output (data and `[warnings]`
snapshot each), and the harness maps `js` like `typescript` and `tsx`. Since
#2129 a block comment's `*/` is not marker text, so the
cases' notes no longer warn about it.

Multi-line needs work in TypeScript `//` runs and JSDoc blocks with no code
change (prefix stripping goes by the comment's kind); two shared cases pin it,
and the language lists say so.
…s declarations

Review of useblocks/sphinx-codelinks#82: a marker above a declaration kind
the scope table did not name walked on to the next unrelated function. Now:

- interfaces, enums, type aliases, abstract classes, generator functions,
  function signatures (overloads, `declare function`), modules, namespaces
  and interface/abstract method signatures are scopes;
- a `const`/`let`/`var`, a class field, an assignment (`module.exports =
  function () {}`, `Foo.prototype.bar = …`) and an anonymous default export
  are scopes when they hold a function, generator or class, seen through
  `as`, `satisfies`, `!`, `<T>` and parentheses;
- `declare …` and an expression statement are searched like `export …`.

The TypeScript-only rules move out of the shared traversal into two
per-language tables, SCOPE_CONTAINER_TYPES and SCOPE_PREDICATES; a comment
type without a SCOPE_NODE_TYPES entry has no scopes rather than C++'s.
The five grammars whose comments are one `comment` node share one query,
the test fixtures build their parsers through init_tree_sitter (so the TSX
fixture tests the grammar analysis picks), and a test fails when a comment
type misses one of the tables. scope.yaml pins every TypeScript and
JavaScript association.
…ript

Since #2129 a block comment's closing `*/` is not
marker text, so the one-row forms useblocks/sphinx-codelinks#82 documented
as unsupported now work: `/* @t, ID, impl */` and the JSX comment
`{/* @t, ID, impl */}`. A legacy `<!-- … -->` comment's `-->` is not marker
text either. oneline.yaml pins the three, and a `.ts` case with a `<T>x`
cast pins, through production wiring, that `.ts` parses with the
TypeScript grammar (under TSX every marker after the cast is lost).
The feature page says what is supported now.
@github-actions github-actions Bot added the pkg: sphinx-codelinks Concerns the sphinx-codelinks package (packages/sphinx-codelinks) label Oct 9, 2026
@read-the-docs-community

read-the-docs-community Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

@codecov

codecov Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.26087% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.37%. Comparing base (132607b) to head (dfbbf27).

Files with missing lines Patch % Lines
...nks/src/sphinx_codelinks/analyse/oneline_parser.py 93.75% 1 Missing ⚠️
...nx-codelinks/src/sphinx_codelinks/analyse/utils.py 98.11% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2166      +/-   ##
==========================================
+ Coverage   93.35%   93.37%   +0.01%     
==========================================
  Files         140      140              
  Lines       20974    21059      +85     
==========================================
+ Hits        19581    19664      +83     
- Misses       1393     1395       +2     
Flag Coverage Δ
ai-index 100.00% <ø> (ø)
codelinks 96.22% <98.26%> (+0.03%) ⬆️
mounts 94.27% <ø> (ø)
pytests 92.50% <ø> (ø)
reports 94.68% <ø> (ø)
ub-test-reports 90.93% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The last open finding of useblocks/sphinx-codelinks#82: with the default `@`
start sequence, `@param a First operand, the augend` in a JSDoc comment
became a need with the id `the augend`. As the Python docstring rule of
#2129 does for Epydoc fields, a line of a JSDoc comment (opened by exactly
`/**`, under `comment_type = "ts"`) whose start sequence is directly followed
by a JSDoc tag ending at a space, a tab, `{`, `}` or the line's end is a
`jsdoc_tag` warning and yields no need; the warning says to choose a start
sequence JSDoc does not use. The tag list covers JSDoc's block tags, TSDoc's,
TypeScript's and the inline tags; matching is case-sensitive. `/* */`, `//`
and `/*** */` comments are untouched, and so is C++ Doxygen.

The new shared `jsdoc.yaml` pins it, and `test_jsdoc_tag` the tag shape.
ubmarco and others added 16 commits October 9, 2026 15:25
… pinned

A shared case for the shape ubCode's review (useblocks/ubcode#2764) found fragile in both engines: the `*` leader before `@need-ids:`. Both ids are references; the line is neither a need nor a `jsdoc_tag` warning.
…ace, pinned

#2168 renders multi-line needs whatever the language; the branch pinned TypeScript blocks at extraction only. `test_typescript_blocks_render` adds a `ts` project beside the fixture's `src`: a `//` run in a `.ts` file with an RST body and a JSDoc block in a `.tsx` file with a MyST body, each traced on an RST page. Each need is recorded at its directive with the body's doctype and its links, its local URL at the block's open line, and its body renders the role link and the list.
…, pinned (red)

`export declare function render(): void;` is the shape tsc writes into every `.d.ts`: an `ambient_declaration` inside an `export_statement`. The scope search looks one container deep, so the marker above it binds the next function instead. The shared case `typescript_export_declare` in `scope.yaml` pins the declaration; red until the search goes one container deeper.
… and C++ reads no JSDoc, pinned (`jsdoc_more_tags` red)

Two shared cases in `jsdoc.yaml`. `jsdoc_more_tags`: `@jsxImportSource react, dom` and `@modifies state, cache` in a JSDoc comment are `jsdoc_tag` warnings, not needs; red until the tag list has them. `doxygen_in_cpp_is_no_jsdoc`: under `comment_type = "cpp"` a `/** */` comment's `@see Retry policy, IMPL_RETRY, impl` line is a need, so ubCode's parity replay sees the `ts`-only gate too (until now only a Sphinx-level test held it).
…hit it

Under the TypeScript grammar the `//` and `/* */` in a `.tsx` file's JSX text read as comments and become needs; under TSX they are text. Until now only a `has_error` unit test held `.tsx` → TSX, and nothing held the per-file choice in a run over several files, the `.lower()` or the `.mts`/`.cts` suffixes.

- `oneline.yaml` `jsx_text_oneliner_tsx`: one need, `IMPL_TSX_LOGIN`, its scope one line, and no `FAKE_*` (shared, so ubCode's replay holds it too).
- `test_a_ts_and_a_tsx_file_in_one_run_each_get_their_grammar`: one `SourceAnalyse` over `a.ts` (a marker after a `<T>` cast) and `b.tsx` (JSX text holding `// @Fake, FAKE_ID, impl`), in both orders.
- `test_ts_grammar_key`: `.ts`, `.mts`, `.cts`, `.d.ts` in any case → TypeScript; `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` → TSX.
…method signature, pinned

Four of the five predicates that make a declaration a scope only when it holds a function had no case, nor had `abstract_method_signature`: removing any of them left the suite green. Five shared cases in `scope.yaml`, one association each: `var limit = 3;`, a plain class field, `count = 1;` and `export default 42;` before a function or method do not take the marker, and an abstract method signature does.
…inned

A legacy `<!--` comment runs to the end of its line, and the stripping table knows `//`, `#` and `/* */` only, so a block written in `<!--` lines is never opened: no need, no warning. That silence is now written into the shared corpus: `js_html_comment_run_is_no_block` in `multiline_needs.yaml`, and the header's sentence on runs says `"<!--" comments hold no block`.
`test_default_exclude_skips_generated_output` compared the configuration with the constant it was built from, so no change to the constant could fail it, and the test tree held only `dist/` and `node_modules/`. The tree now has `build/`, `out/`, `coverage/` and a declaration file `types/x.d.ts`, and the test asserts what discovery lists: the five output directories absent, `lib/` and `types/x.d.ts` present. A CLI test passes `-e '**/*.test.ts'` under `--comment-type ts`: the test file is dropped and `dist/app.js` is listed, as an explicit list replaces the default.
The scope search looked one container deep: past `export_statement` but not into the `ambient_declaration` inside it, the shape tsc writes into every `.d.ts`. So `export declare function render(): void;` had no scope, and in a `.ts` its marker bound the next function. When a container's child is itself a container other than `block`, its children are searched too. `typescript_export_declare` turns green; nothing else moves.
…join the shared tag list

`@modifies state, cache` in a JSDoc comment became a need with the id `cache`: `modifies` is a JSDoc block tag the list lacked, as were TypeScript's JSX pragmas `jsx`, `jsxFrag`, `jsxImportSource` and `jsxRuntime`. The list, shared with ubCode, now has 112 names. `jsdoc_more_tags` turns green.
…ngelog line

Three test docstrings named findings of the old repository's review ("Regression guard for D2", "the D1 defect") that no reader here can resolve; they now say what each test pins. The `IMPL_TS_3` source marker sat above the `TYPE_SCRIPT_QUERY` constant and bound forward to `ts_grammar_key`; it moves into the TypeScript branch of `init_tree_sitter`, beside the Go and Bash ones. The multi-line needs bullet of the changelog loses its 106-character line.
- `exclude`'s default: `build/` and `out/` are excluded wherever they occur, so a hand-written `src/build/` is not analysed; the five names are all it knows, so a `tsc` `declarationDir` or `outDir` elsewhere is the project's to add; and a `:directory:` scope matches the patterns relative to its own directory. The changelog says "any directory of those five names, wherever it sits".
- `discover.rst`'s TypeScript example no longer sets an `exclude` that silently replaced the default, and says why it leaves it out.
- The suggested start sequence is `[[`: `@need` is the multi-line open word, and a configuration error once multi-line needs are on. `@` also starts `// @ts-ignore`, `// @ts-expect-error` and the decorators inside an `@example`.
- `<!--`: legacy and one line long, valid only in classic scripts (TypeScript and ES modules reject it), read as a one-line comment, never holding a multi-line need.
- Both tag bullets name the characters where ubCode's notion of alphanumeric differs: combining marks, circled letters, and letters newer than the interpreter's Unicode tables.
- `FE_TS` covers multi-line annotations too.
…een read

Every JSDoc tag line was a `jsdoc_tag` warning, comma or not: one ordinary eight-line JSDoc comment with no comma anywhere gave six warnings, enough to fail a `-W` build, while the protection only matters where a line would otherwise have become a need. As `docstring_tag` was narrowed for Python, a line of a JSDoc comment is now a `jsdoc_tag` warning, and never a need, when all hold: the one-line start sequence is `@`, JSDoc's own sigil (under any other, the check does not run and `[[param a, b]]` is the marker its author wrote); nothing alphanumeric precedes the `@`; a tag of the shared list directly follows it and ends at a space, a tab, `{`, `}` or the line end; and the one-line parser would otherwise have read the line as a marker or warned about it. `@param a the augend` and `@returns the sum` stay silent.

The rule is written once, in `jsdoc.yaml`'s header, which ubCode mirrors. `jsdoc_tags` and `jsdoc_tag_end` lose the warnings of their comma-less tag lines; `jsdoc_with_other_start_sequence` gains ` * [[param a, b]]`, a need. The changelog, `oneline.rst` and the configuration note state the rule and its consequence.
`export declare const handle: () => void;` is what tsc writes into a `.d.ts` for a function-valued const, its JSDoc copied along. An ambient variable holds no value, so the plain-const rule (a `const` is a scope only when it holds a function) skips it, and since the search reaches nested containers its marker binds the next declaration. The shared case `typescript_declare_const_binds` in `scope.yaml` pins the const; red until an ambient variable counts as a scope.
…inned

Under the default style "the one-line parser would read the line" and "the line holds a comma" coincide, so a check on the comma, or on markers alone, passed every case. `jsdoc_tag_asks_the_one_line_parser` in `jsdoc.yaml` sets `;` as the field separator: `@param a; b` warns, `@param a, b` stays silent, and `@param a; b; c; d; e` (too many fields, a parser warning) warns too.
`jsdoc_more_tags` held `@jsxImportSource` and `@modifies` only: removing `jsx`, `jsxFrag` or `jsxRuntime` from the list left every case green, so a typo in either tool would never show in the parity replay. The case gains `@jsx h, x`, `@jsxFrag Fragment, x` and `@jsxRuntime automatic, x`, each a `jsdoc_tag` warning.
A `const`/`let`/`var` declaration is a scope only when it holds a function, so that a plain `const flag = true;` does not take the marker of the function after it. An ambient one (`declare const handle: () => void;`, what tsc writes into a `.d.ts` for a function-valued const) holds no value and is itself the declared thing, so it is now a scope whatever its type. `typescript_declare_const_binds` turns green; nothing else moves.
- "choose a start sequence other than `@` … and no JSDoc line is ever read" said the opposite of the next sentence: under `[[` a JSDoc line is read, as a marker where it holds `[[`. The three copies (changelog, `oneline.rst`, the configuration note) now say the check never runs.
- A `declarationDir` duplicates every marker a JSDoc comment holds; an `outDir` duplicates every marker.
- The `TYPE_SCRIPT_QUERY` comment: `<!--` comments are legacy one-line comments, valid in classic scripts only.
- `jsdoc.yaml`'s header says "opened by exactly `/**`" once.
…row ends a `//` run

- `typescript_declare_const_binds` held `export declare const` only, so the arm could narrow to `const`/`let` with every case green. It gains `export declare let fn: (a: number) => void;` and `declare var version: string;`, each binding its own marker. Its comment says what the arm covers: a `declare`-prefixed `const`, `let` or `var`; a variable inside a `declare namespace`, `module` or `global` body, or a bare `export const x: T;` in a `.d.ts`, still binds the next declaration.
- `js_html_row_breaks_a_line_run` in `multiline_needs.yaml`, written for the reference by ubCode's review: a `<!--` row between two `//` rows is no line comment, so it ends the run, and the open line above it is `multiline_need_unterminated`.
- `_declares_function`'s docstring said "an ambient one" in general; the arm covers a `declare`-prefixed `const`, `let` or `var` only. A variable inside a `declare namespace`, `module` or `global` body, or a bare `export const x: T;` in a `.d.ts`, is no scope and binds the next declaration.
- The `jsdoc_tag` bullet and the configuration note suggest `[[` or `@@`, and say that under `[[` ECMAScript's internal-slot notation in a JSDoc line is read as a marker: `[[Prototype]]` alone is a `too_few_fields` warning, `[[Prototype]], [[Extensible]]` a need.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: sphinx-codelinks Concerns the sphinx-codelinks package (packages/sphinx-codelinks)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Add TypeScript language support

2 participants