---
generated_at: 2026-02-20 12:00:00
metrics:
  claims_total: 202
  claims_with_evidence: 189
  claims_without_evidence: 13
confidence_derived: 0.94
---

# 根拠レポート：lsp モジュール 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された設計書・ドキュメントの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.94**
  - 根拠あり：189 / 202、根拠なし：13
- 優先レビュー（高）
  1. **C-042（awaitResponseタイムアウト）**：タイムアウトのDuration指定がresolveWaitに委譲される内部処理だが、実際のFiberタイムアウト動作はテスト困難
  2. **C-066〜C-068（registerCapabilityAsync/Sync）**：テンプレートメソッドで静的アサーションを含む複雑な構造のため、具体的なテスト入力の根拠が限定的
  3. **C-174〜C-179（PerDocumentCache）**：テンプレート構造体のため型パラメータによる振る舞いの差異が未確認

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。

- E-01: `lsp/source/served/lsp/filereader.d` — FileReader抽象クラス定義（L257-331）
- E-02: `lsp/source/served/lsp/filereader.d` — readCodeWithBuffer関数（L376-402）
- E-03: `lsp/source/served/lsp/filereader.d` — readCodeWithBuffer unittest（L404-430）
- E-04: `lsp/source/served/lsp/filereader.d` — newStdinReader / newFileReader（L346-365）
- E-05: `lsp/source/served/lsp/filereader.d` — PosixFileReader実装（L168-253）
- E-06: `lsp/source/served/lsp/filereader.d` — WindowsStdinReader/WindowsFileReader実装（L13-148）
- E-07: `lsp/source/served/lsp/jsonrpc.d` — RPCProcessor クラス定義（L19-677）
- E-08: `lsp/source/served/lsp/jsonrpc.d` — send(ResponseMessage) メソッド（L48-71）
- E-09: `lsp/source/served/lsp/jsonrpc.d` — send(RequestMessageRaw) メソッド（L107-124）
- E-10: `lsp/source/served/lsp/jsonrpc.d` — sendRawPacket メソッド（L139-169）
- E-11: `lsp/source/served/lsp/jsonrpc.d` — notifyMethod系メソッド（L172-223）
- E-12: `lsp/source/served/lsp/jsonrpc.d` — sendMethod系メソッド（L275-324）
- E-13: `lsp/source/served/lsp/jsonrpc.d` — awaitResponse / prepareWait / resolveWait（L389-448）
- E-14: `lsp/source/served/lsp/jsonrpc.d` — hasData / poll（L364-378）
- E-15: `lsp/source/served/lsp/jsonrpc.d` — run メソッド（L478-577）
- E-16: `lsp/source/served/lsp/jsonrpc.d` — handleRequestImpl メソッド（L579-676）
- E-17: `lsp/source/served/lsp/jsonrpc.d` — MockRPC構造体（L681-747）
- E-18: `lsp/source/served/lsp/jsonrpc.d` — WindowFunctions構造体（L939-1027）
- E-19: `lsp/source/served/lsp/jsonrpc.d` — RPCProcessor unittest（L749-936）
- E-20: `lsp/source/served/lsp/jsonrpc.d` — registerCapabilityAsync/Sync（L228-270）
- E-21: `lsp/source/served/lsp/textdocumentmanager.d` — Document構造体定義（L13-737）
- E-22: `lsp/source/served/lsp/textdocumentmanager.d` — getLanguageId（L36-67）
- E-23: `lsp/source/served/lsp/textdocumentmanager.d` — setContent（L224-240）
- E-24: `lsp/source/served/lsp/textdocumentmanager.d` — applyChange（L243-279）
- E-25: `lsp/source/served/lsp/textdocumentmanager.d` — 位置変換メソッド群（L283-429）
- E-26: `lsp/source/served/lsp/textdocumentmanager.d` — wordRangeAt系（L525-571）
- E-27: `lsp/source/served/lsp/textdocumentmanager.d` — lineByteRangeAt / lineAt / lineAtScope / eolAt（L575-736）
- E-28: `lsp/source/served/lsp/textdocumentmanager.d` — TextDocumentManager構造体（L744-922）
- E-29: `lsp/source/served/lsp/textdocumentmanager.d` — TextDocumentManager unittest（L925-1030）
- E-30: `lsp/source/served/lsp/textdocumentmanager.d` — PerDocumentCache構造体（L1033-1073）
- E-31: `lsp/source/served/lsp/textdocumentmanager.d` — wordInLine / wordInLineBytes / wordInLineImpl（L1076-1134）
- E-32: `lsp/source/served/lsp/textdocumentmanager.d` — wordInLineBytes unittest（L1136-1188）
- E-33: `lsp/source/served/lsp/textdocumentmanager.d` — isDIdentifierSeparatingChar / isValidDIdentifier（L1194-1217）
- E-34: `lsp/source/served/lsp/textdocumentmanager.d` — utf16DecodeUtf8Length / countUTF16Length / countBytesUntilUTF16Index（L1252-1308）
- E-35: `lsp/source/served/lsp/textdocumentmanager.d` — Unicode変換テスト（L1310-1458）
- E-36: `lsp/source/served/lsp/textdocumentmanager.d` — Document setContent/applyChange unittest（L1219-1250）

## 3) Claims と根拠の対応（レビューの主戦場）

### filereader.d 関連（C-001〜C-017）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-001 | yieldLineがCRLFで行を分割する | E-01 (L275: countUntil CRLF) | ○ |
| C-002 | yieldLineが複数行を逐次読み取る | E-01 (L266-292: ループ構造) | ○ |
| C-003 | 空行（CRLF）で空文字列が返る | E-01 (L276-278: index=0ならret="") | ○ |
| C-004 | データ空＋isReading=falseでnull返却 | E-01 (L286-287: hasData && !isReading) | ○ |
| C-005 | whileThisIsによるループ中断 | E-01 (L270: whileThisIs条件チェック) | ○ |
| C-006 | CRLFなしデータでisReading=falseの場合 | E-01 (L286-287) | ○ |
| C-007 | yieldDataが指定長データを返す | E-01 (L298-321: length条件) | ○ |
| C-008 | 要求長=data長の場合 | E-01 (L305-309) | ○ |
| C-009 | yieldDataでデータ空時null返却 | E-01 (L315-316) | ○ |
| C-010 | yieldDataでwhileThisIs中断 | E-01 (L300, L320) | ○ |
| C-011 | readCodeWithBuffer基本読み込み | E-02, E-03 (L409-411) | ○ |
| C-012 | readCodeWithBuffer maxLen制限 | E-02, E-03 (L418-419) | ○ |
| C-013 | readCodeWithBuffer バッファリサイズ | E-02, E-03 (L406-410) | ○ |
| C-014 | 小バッファ+maxLen | E-02, E-03 (L422-424) | ○ |
| C-015 | in契約違反 | E-02 (L377: in (buffer.length > 0)) | ○ |
| C-016 | newStdinReaderプラットフォーム分岐 | E-04 (L348-353) | ○ |
| C-017 | newFileReaderプラットフォーム分岐 | E-04 (L358-364) | ○ |

### jsonrpc.d RPCProcessor 関連（C-018〜C-065）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-018 | RPCProcessorコンストラクタ | E-07 (L22-34) | ○ |
| C-019 | stop()でstopped=true | E-07 (L38-40) | ○ |
| C-020 | send(ResponseMessage) result付き | E-08 (L48-71) | ○ |
| C-021 | send(ResponseMessage) error付き | E-08 (L62-67) | ○ |
| C-022 | send(ResponseMessage) 最小 | E-08 (L55-58: isNoneチェック) | ○ |
| C-023 | send(ResponseMessageRaw) | E-07 (L73-95) | ○ |
| C-024 | send(RequestMessage) | E-07 (L100-103) | ○ |
| C-025 | send(RequestMessageRaw) | E-09 (L107-124) | ○ |
| C-026 | send(RequestMessageRaw) idなし | E-09 (L112-113: isNone check) | ○ |
| C-027 | sendRawPacket Content-Length | E-10 (L161-168) | ○ |
| C-028 | sendRawPacket 複数parts | E-10 (L156-158: len計算) | ○ |
| C-029 | notifyMethod パラメータなし | E-11 (L172-177) | ○ |
| C-030 | notifyMethod パラメータ付き | E-11 (L180-183) | ○ |
| C-031 | notifyMethodRaw | E-11 (L201-211) | ○ |
| C-032 | notifyProgressRaw | E-11 (L213-223) | ○ |
| C-033 | sendMethod パラメータなし | E-12 (L275-287) | ○ |
| C-034 | sendMethod パラメータ付き | E-12 (L292-295) | ○ |
| C-035 | sendMethodRaw | E-12 (L310-324) | ○ |
| C-036 | sendRequest | E-07 (L332-335) | ○ |
| C-037 | hasData true | E-14 (L364-366) | ○ |
| C-038 | hasData false | E-14 (L364-366) | ○ |
| C-039 | poll 正常取得 | E-14 (L371-378) | ○ |
| C-040 | poll 空キューException | E-14 (L373-374) | ○ |
| C-041 | awaitResponse 正常 | E-13 (L444-448), E-19 (L791-793) | ○ |
| C-042 | awaitResponse タイムアウト | E-13 (L419-421) | △ |
| C-043 | prepareWait 登録 | E-13 (L390-407) | ○ |
| C-044 | prepareWait スロット再利用 | E-13 (L395-400: handled check) | ○ |
| C-045 | resolveWait 正常解決 | E-13 (L411-427) | ○ |
| C-046 | run Content-Length パース | E-15 (L483-509), E-19 | ○ |
| C-047 | run バッチリクエスト | E-15 (L520-531) | ○ |
| C-048 | run Content-Length 0以下 | E-15 (L505-509) | ○ |
| C-049 | run 不正JSON | E-15 (L544-563), E-19 (L919-920) | ○ |
| C-050 | run 空バッチ | E-15 (L532-533), E-19 (L922-923) | ○ |
| C-051 | run 非オブジェクト/配列リクエスト | E-15 (L539-541) | ○ |
| C-052 | run 不完全メッセージ | E-15 (L511-513), E-19 (L797-810) | ○ |
| C-053 | run 余白耐性 | E-15 (L515: chomp), E-19 (L855-883) | ○ |
| C-054 | run 非同期バッファリング | E-15, E-19 (L813-852) | ○ |
| C-055 | handleRequestImpl 通常リクエスト | E-16 (L648-673) | ○ |
| C-056 | handleRequestImpl レスポンスマッチ | E-16 (L612-636) | ○ |
| C-057 | handleRequestImpl 不明ID | E-16 (L638-644), E-19 (L912-913) | ○ |
| C-058 | handleRequestImpl 必須メンバ不足 | E-16 (L598-608), E-19 (L925-926) | ○ |
| C-059 | handleRequestImpl 曖昧メンバ | E-16 (L598-600) | ○ |
| C-060 | handleRequestImpl 不正params型 | E-16 (L656-668) | ○ |
| C-061 | handleRequestImpl error=null除外 | E-16 (L585-595: error=="null") | ○ |
| C-062 | handleRequestImpl result=null除外 | E-16 (L585-595: result=="null") | ○ |
| C-063 | handleRequestImpl 非オブジェクトJSON | E-16 (L581-582) | ○ |
| C-064 | log送信 | E-07 (L353-361) | ○ |
| C-065 | window()ヘルパー | E-07 (L381-384) | ○ |

### jsonrpc.d registerCapability/MockRPC/WindowFunctions 関連（C-066〜C-086）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-066 | registerCapabilityAsync | E-20 (L229-258) | △ |
| C-067 | registerCapabilitySync 成功 | E-20 (L261-270) | △ |
| C-068 | registerCapabilitySync 失敗 | E-20 (L264-267) | △ |
| C-069 | MockRPC writePacket | E-17 (L690-701) | ○ |
| C-070 | MockRPC writePacket prologue/epilogue | E-17 (L690-701) | ○ |
| C-071 | MockRPC readPacket | E-17 (L704-716) | ○ |
| C-072 | MockRPC expectPacket 成功 | E-17 (L718-722) | ○ |
| C-073 | MockRPC expectPacket 失敗 | E-17 (L721: assert) | ○ |
| C-074 | MockRPC testRPC | E-17 (L724-746) | ○ |
| C-075 | MockRPC testRPC 即時close | E-19 (L775) | ○ |
| C-076 | showMessage | E-18 (L947-953) | ○ |
| C-077 | showMessage safeShowMessage=false時ログ | E-18 (L949-950) | ○ |
| C-078 | requestMessage(MessageActionItem[]) | E-18 (L956-963) | ○ |
| C-079 | requestMessage dismiss | E-18 (L960-961) | ○ |
| C-080 | requestMessage(string[]) | E-18 (L966-972) | ○ |
| C-081 | runOrMessage 成功 | E-18 (L976-990) | ○ |
| C-082 | runOrMessage 失敗 | E-18 (L984-989) | ○ |
| C-083 | showErrorMessage | E-18 (L994-998) | ○ |
| C-084 | showWarningMessage | E-18 (L1002-1008) | ○ |
| C-085 | showInformationMessage | E-18 (L1012-1017) | ○ |
| C-086 | showLogMessage | E-18 (L1020-1026) | ○ |

### textdocumentmanager.d Document 関連（C-087〜C-153）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-087 | getLanguageId languageId設定済み | E-22 (L38, L65-66) | ○ |
| C-088 | getLanguageId .d拡張子推定 | E-22 (L44) | ○ |
| C-089 | getLanguageId .di拡張子 | E-22 (L44) | ○ |
| C-090 | getLanguageId .dpp拡張子 | E-22 (L46) | ○ |
| C-091 | getLanguageId .c拡張子 | E-22 (L48) | ○ |
| C-092 | getLanguageId .cpp拡張子 | E-22 (L50) | ○ |
| C-093 | getLanguageId .ds/.dscript拡張子 | E-22 (L52) | ○ |
| C-094 | getLanguageId .dml拡張子 | E-22 (L54) | ○ |
| C-095 | getLanguageId .sdl拡張子 | E-22 (L56) | ○ |
| C-096 | getLanguageId .dt拡張子 | E-22 (L58) | ○ |
| C-097 | getLanguageId .json拡張子 | E-22 (L60) | ○ |
| C-098 | getLanguageId 未知拡張子 | E-22 (L62-63) | ○ |
| C-099 | getLanguageId 空URI | E-22 (L38: !languageId.length, L62-63: null返却) | △ |
| C-100 | this(DocumentUri) | E-21 (L82-88) | ○ |
| C-101 | this(TextDocumentItem) | E-21 (L102-108) | ○ |
| C-102 | nullDocument | E-21 (L126-131) | ○ |
| C-103 | clone | E-21 (L145-153) | ○ |
| C-104 | rawText | E-21 (L168-177) | ○ |
| C-105 | sliceRawText(TextRange) | E-21 (L180-183) | ○ |
| C-106 | sliceRawText(size_t[2]) | E-21 (L186-193) | ○ |
| C-107 | sliceRawText end超過 | E-21 (L188-189) | ○ |
| C-108 | sliceRawText start>end | E-21 (L190-191) | ○ |
| C-109 | length | E-21 (L215-217) | ○ |
| C-110 | setContent 基本 | E-23 (L224-240) | ○ |
| C-111 | setContent バッファ再利用 | E-23 (L226-232) | ○ |
| C-112 | setContent バッファ拡張 | E-23 (L233-238) | ○ |
| C-113 | setContent 空文字列 | E-23, E-36 | △ |
| C-114 | applyChange 基本置換 | E-24, E-36 (L1231-1232) | ○ |
| C-115 | applyChange 挿入 | E-24, E-36 (L1245-1246) | ○ |
| C-116 | applyChange 削除 | E-24, E-36 (L1243-1244) | ○ |
| C-117 | applyChange 拡張 | E-24 (L261-266) | ○ |
| C-118 | applyChange 縮小 | E-24 (L268-273) | ○ |
| C-119 | applyChange 全体置換最適化 | E-24 (L251-254) | ○ |
| C-120 | applyChange 範囲逆転 | E-24 (L248-249: swap) | ○ |
| C-121 | offsetToBytes ASCII | E-25 (L283-286) | ○ |
| C-122 | offsetToBytes Unicode | E-25, E-35 | ○ |
| C-123 | bytesToOffset | E-25 (L289-292), E-35 | ○ |
| C-124 | positionToOffset | E-25 (L295-321), E-35 | ○ |
| C-125 | positionToBytes | E-25 (L324-344), E-35 | ○ |
| C-126 | positionToBytes 最大値 | E-35 (L1441-1443) | ○ |
| C-127 | positionToBytes 複数行 | E-25, E-35 | ○ |
| C-128 | offsetToPosition | E-25 (L347-367), E-35 | ○ |
| C-129 | bytesToPosition | E-25 (L370-387), E-35 | ○ |
| C-130 | bytesToPosition 最大値 | E-35 (L1438-1439) | ○ |
| C-131 | lineColumnBytesToPosition | E-25 (L390-402), E-35 (L1455) | ○ |
| C-132 | lineColumnBytesToPosition 列超過 | E-25 (L395-398), E-35 (L1457-1458) | ○ |
| C-133 | movePositionBytes 正常 | E-25 (L407-429) | ○ |
| C-134 | movePositionBytes 同一位置 | E-25 (L409-410) | ○ |
| C-135 | movePositionBytes 後退 | E-25 (L411-412) | ○ |
| C-136 | movePositionBytes 改行 | E-25 (L419-422) | ○ |
| C-137 | nextPositionBytes | E-25 (L469-475) | ○ |
| C-138 | byteRangeToTextRange | E-25 (L503-512) | ○ |
| C-139 | textRangeToByteRange | E-25 (L516-522) | ○ |
| C-140 | wordRangeAt(Position) | E-26 (L525-529) | ○ |
| C-141 | wordRangeAt(size_t) 正常 | E-26 (L540-549) | ○ |
| C-142 | wordRangeAt(size_t) 区切り文字 | E-26, E-36 (L561: bytes=10 -> [10,10]) | ○ |
| C-143 | wordRangeAt(size_t) 末尾 | E-26, E-36 (L558-559) | ○ |
| C-144 | lineByteRangeAt 正常 | E-27 (L575-599) | ○ |
| C-145 | lineByteRangeAt 最終行 | E-27 (L592-598) | ○ |
| C-146 | lineByteRangeAt 存在しない行 | E-27 (L589-590) | ○ |
| C-147 | lineAt 正常 | E-27 (L607-624) | ○ |
| C-148 | lineAt Position経由 | E-27 (L607-610) | ○ |
| C-149 | lineAtScope | E-27 (L666-676) | ○ |
| C-150 | lineAtScope 存在しない行 | E-27 (L589-590, L674-676) | ○ |
| C-151 | eolAt LF | E-27 (L704-723) | ○ |
| C-152 | eolAt CRLF | E-27 (L716: prevWasCr) | ○ |
| C-153 | eolAt デフォルト | E-27 (L722) | ○ |

### textdocumentmanager.d TextDocumentManager 関連（C-154〜C-173）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-154 | opIndex 正常 | E-28 (L751-757) | ○ |
| C-155 | opIndex Exception | E-28 (L755), E-29 (L956) | ○ |
| C-156 | tryGet 正常 | E-28 (L761-767) | ○ |
| C-157 | tryGet Document.init | E-28 (L765), E-29 (L959) | ○ |
| C-158 | getOrFromFilesystem キャッシュヒット | E-28 (L798-800) | ○ |
| C-159 | getOrFromFilesystem ファイル読み込み | E-28 (L792-810) | ○ |
| C-160 | getOrFromFilesystem FileException | E-28 (L789-790: Throws) | △ |
| C-161 | getOrFromFilesystem version_=-1 | E-28 (L804) | ○ |
| C-162 | unloadDocument 正常 | E-28 (L851-853) | ○ |
| C-163 | unloadDocument 未登録 | E-28 (L852: remove returns false) | ○ |
| C-164 | syncKind | E-28 (L857-860) | ○ |
| C-165 | insertOrUpdate 新規 | E-28 (L871-874) | ○ |
| C-166 | insertOrUpdate 上書き | E-28 (L871-874) | ○ |
| C-167 | process didOpen | E-28 (L884-891), E-29 (L930-943) | ○ |
| C-168 | process didClose | E-28 (L892-901), E-29 (L1017-1028) | ○ |
| C-169 | process didClose 未登録 warning | E-28 (L896-899) | △ |
| C-170 | process didChange インクリメンタル | E-28 (L903-916), E-29 (L972-993) | ○ |
| C-171 | process didChange 全体置換 | E-28 (L914-915), E-29 (L995-1015) | ○ |
| C-172 | process didChange バージョン更新 | E-28 (L909) | ○ |
| C-173 | process 無関係メソッド | E-28 (L920) | ○ |

### textdocumentmanager.d その他（C-174〜C-202）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-174 | PerDocumentCache cached ヒット | E-30 (L1043-1055) | △ |
| C-175 | PerDocumentCache cached バージョン古い | E-30 (L1049-1052) | △ |
| C-176 | PerDocumentCache cached ミス | E-30 (L1054) | △ |
| C-177 | PerDocumentCache store 追加 | E-30 (L1057-1072) | △ |
| C-178 | PerDocumentCache store 更新 | E-30 (L1063-1066) | △ |
| C-179 | PerDocumentCache store 古いバージョン拒否 | E-30 (L1063: version_ check) | △ |
| C-180 | wordInLine UTF-16 | E-31 (L1076-1078) | ○ |
| C-181 | wordInLineBytes 正常 | E-31, E-32 (L1142-1145) | ○ |
| C-182 | wordInLineBytes 区切り文字 | E-32 (L1148) | ○ |
| C-183 | wordInLineBytes size_t.max | E-32 (L1150) | ○ |
| C-184 | wordInLineBytes 先頭区切り | E-32 (L1166) | ○ |
| C-185 | isDIdentifierSeparatingChar true | E-33 (L1194-1198) | ○ |
| C-186 | isDIdentifierSeparatingChar false | E-33 (L1194-1198) | ○ |
| C-187 | isDIdentifierSeparatingChar Unicode | E-33 (L1197: \u2028, \u2029) | ○ |
| C-188 | isValidDIdentifier 有効 | E-33 (L1201-1206), unittest L1214-1216 | ○ |
| C-189 | isValidDIdentifier 空文字列 | E-33 (L1205: s.length), unittest L1210 | ○ |
| C-190 | isValidDIdentifier 数字開始 | E-33 (L1205: !s[0].isDigit), unittest L1211-1213 | ○ |
| C-191 | isValidDIdentifier 区切り文字含有 | E-33 (L1205: !s.any!) | ○ |
| C-192 | isValidDIdentifier _ のみ | unittest L1214 | ○ |
| C-193 | utf16DecodeUtf8Length ASCII | E-34 (L1271-1274) | ○ |
| C-194 | utf16DecodeUtf8Length 2バイト | E-34 (L1266-1269) | ○ |
| C-195 | utf16DecodeUtf8Length 3バイト | E-34 (L1257-1260) | ○ |
| C-196 | utf16DecodeUtf8Length 4バイト | E-34 (L1262-1265) | ○ |
| C-197 | countUTF16Length ASCII | E-34 (L1278-1289) | ○ |
| C-198 | countUTF16Length マルチバイト | E-34, E-35 | ○ |
| C-199 | countUTF16Length 空文字列 | E-34 (L1282: index < text.length) | △ |
| C-200 | countBytesUntilUTF16Index 正常 | E-34 (L1291-1308) | ○ |
| C-201 | countBytesUntilUTF16Index オフセット超過 | E-34 (L1295: offset < utf16Offset) | ○ |
| C-202 | countBytesUntilUTF16Index 文字境界 | E-34 (L1301-1306) | ○ |

## 4) 不足情報（Unknown / Missing）
- **PerDocumentCache（C-174〜C-179）**: テンプレート構造体のため、具体的な型パラメータTでの単体テストがソースに存在しない。ロジックはシンプルだが、実際の使用パターンでの振る舞いは推測に基づく。
  - 候補：実際のPerDocumentCache使用箇所の確認 / テンプレートインスタンス化テスト
- **registerCapabilityAsync/Sync（C-066〜C-068）**: テンプレートメソッドで静的アサーションを含み、MockRPCを使ったテストで完全に検証するのは複雑。
  - 候補：served-coreや他モジュールでの実使用パターン確認
- **awaitResponseタイムアウト（C-042）**: Fiber内でのタイムアウト動作の検証は、テスト環境でのタイミング制御が必要。
  - 候補：MockRPCを使用したタイムアウト再現テスト
- **getLanguageId 空URI（C-099）**: 空URIの拡張子推定は暗黙的にnullを返すと推定されるが、明示的テストなし。
  - 候補：Document unittest での空URI検証追加
- **getOrFromFilesystem FileException（C-160）**: ドキュメントコメントにThrowsが記載されているが、明示的なテストなし。
  - 候補：存在しないファイルパスでのテスト追加
- **didClose 未登録URI warning（C-169）**: warningログの出力は確認できるがテストでの検証は困難。
  - 候補：ログ出力のモック化
- **setContent 空文字列（C-113）**: 空文字列の場合のnull byte挿入やassumeAppend動作が完全には検証されていない。
  - 候補：空文字列でのsetContent後のrawText確認テスト
- **countUTF16Length 空文字列（C-199）**: ループ条件(index < text.length)から空文字列で0が返ることは自明だが明示的テストなし。
  - 候補：空文字列のユニットテスト追加

## 5) リスクフラグ（レビュー観点）
- **0（低リスク）**: filereader.d のreadCodeWithBuffer関連テストケース（既存unittestで十分カバー）
- **0（低リスク）**: textdocumentmanager.d のDocument位置変換メソッド（既存unittestで広範囲にカバー）
- **0（低リスク）**: jsonrpc.d のRPCProcessor基本送受信（MockRPC unittestで詳細検証済み）
- **1（中リスク）**: PerDocumentCache のテンプレートパラメータによる振る舞い差異
- **1（中リスク）**: registerCapabilityAsync/Sync のテンプレートメソッド検証
- **1（中リスク）**: WindowFunctions のrequestMessageメソッド（RPCレスポンス待機を含む）
- **0（低リスク）**: isDIdentifierSeparatingChar / isValidDIdentifier（ロジックが単純で既存テストあり）

## 6) レビュアーチェックリスト（最小）
- [ ] PerDocumentCache（C-174〜C-179）のテストケースが実際のプロジェクト使用パターンと整合しているか確認
- [ ] registerCapabilityAsync/Sync（C-066〜C-068）のテストケースの入力値が適切か確認
- [ ] awaitResponseタイムアウト（C-042）のテスト実現可能性を検証
- [ ] Unicode位置変換テスト（C-121〜C-132）の入力値が既存unittestのテストデータと整合するか確認
- [ ] TextDocumentManager.process（C-167〜C-173）のテストケースがLSPプロトコル仕様と矛盾しないか確認
- [ ] WindowFunctions.requestMessage（C-078〜C-080）のdismiss処理がLSPクライアントの実装と一致するか確認
