Format Document is not idempotent when a line break moves a token that enclosing nodes start at
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- typescript
調査の方向性
The report gives two reproductions but names no formatter files or tests. Read the formatting and indentation logic for tokens moved by inserted line breaks, then inspect pull request #64994, which includes a proposed fix and regression tests for both inputs. Done means formatting either example twice produces the same result.
索引モデルが issue の本文から書いたものです。
説明
🔎 Search Terms
format document, formatter, idempotent, idempotence, indentation, continuation indent, non-null assertion
🕗 Version & Regression Information
- TypeScript 7 at
main4a4b24d5dc96d148641ec6a39c4f5bbf023cbb2f (FormatDocument). - TypeScript 6.0.3's language service (
getFormattingEditsForDocument) behaves the same way.
⏯ Playground Link
Not applicable: run Format Document twice on the code below (indent size 4, smart indentation).
💻 Code
{{0!
("")}}
{{x
+ y}}
🙁 Actual behavior
The first format indents (""), and + y, by 8 spaces; formatting the result again moves them to 12. With an identifier callee, {{x\n("")}}, the first format already gives 12.
When a formatting rule adds a line break before a token, only the dynamic indenter of the token's own node is updated. In the first input that node is the non-null expression 0!; the call 0!("") and its statement start at the same token and moved too, but keep the indentation they inherited while everything was on one line. In the second input, the binary expression's continuation delta is reset although its statement starts at the same x.
🙂 Expected behavior
The first format gives the stable result, and formatting it again changes nothing.
Additional information about the issue
Found by fuzzing the formatter for idempotence in a fork of this repository. A fix with a regression test for both inputs is in #64994.
This report was drafted with Claude Code (Claude Opus 5.5).
- 主要言語
- Go
- スター
- 112k
- フォーク
- 16k
- 平均マージ
- 3日 4時間
- マージ済み PR(30日)
- 145
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/TypeScript のほかの issue
-
API: `tsc.exe` opens a visible console window on Windows when the parent process has no consoleオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
microsoft/TypeScript#65083 ·
メンテナーはふだん 1 日以内に返信
-
TS7 LSP: documentHighlight returns nothing when the file path contains '@'再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンBug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
microsoft/TypeScript#64758 ·
メンテナーはふだん 1 日以内に返信
-
Language server (tsc --lsp) exits with code 1 after `shutdown` and `exit`対応中かも @rajnish-verma-22172 が 11 日前に担当しました。 オープンBug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
microsoft/TypeScript#64742 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Class names `eval` and `arguments` are not reported as invalid strict mode bindings対応中かも @dmety が 24 日前に担当しました。 オープンBug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
microsoft/TypeScript#64661 ·
メンテナーはふだん 1 日以内に返信
-
Non-enum CLI options with multiple values separated by comma and space aren't whitespace trimmed対応中かも @RyanCavanaugh が 25 日前に担当しました。 オープンBug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
microsoft/TypeScript#64618 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
microsoft/TypeScript の issue をすべて見る
似ている issue
-
netrc credential source accepts a password with an embedded CR/LF that every other source rejectsオープンagent-butler-finding bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
jordansmall/spindrift#6268 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 7 日以内に返信
-
kind/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
kmesh-net/kmesh#1979 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
caddyserver/caddy#8314 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100