# 機能設計書 58-構文チェック（Flycheck）

## 概要

本ドキュメントは、Doom Emacsの`checkers/syntax`モジュールが提供する構文チェック機能の設計仕様を記述する。Flycheckまたはflymakeを使用したリアルタイムの構文エラー・警告検出と、エラー表示UIの提供を行う。

### 本機能の処理概要

**業務上の目的・背景**：プログラミングにおいて、構文エラーや潜在的な問題を早期に発見することは、デバッグ時間の削減と品質向上に直結する。コード編集中にリアルタイムでエラーを検出し、視覚的なフィードバックを提供することで、問題を早期に修正できるようにする。

**機能の利用シーン**：
- プログラミング中のリアルタイム構文チェック
- Lintツールによるコード品質チェック
- コンパイル前のエラー検出
- ESCキーでの即時再チェック

**主要な処理内容**：
1. Flycheckによるリアルタイム構文チェック
2. 言語固有のチェッカー（eslint、flake8、gcc等）との連携
3. エラー表示UI（popup-tip、posframe）
4. エラーリストバッファの管理
5. CVE-2024-53920対策（非プロジェクトバッファでのEmacs Lispチェック無効化）

**関連システム・外部連携**：
- flycheck（構文チェックフレームワーク）
- flymake（代替実装、+flymakeフラグ時）
- flycheck-popup-tip（エラーポップアップ）
- flycheck-posframe（チャイルドフレームエラー表示）
- 各言語のリンター/コンパイラ

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | プログラミングバッファ | 主画面 | エラーハイライト、ポップアップ表示 |
| - | *Flycheck errors* | 補助画面 | エラー一覧表示 |

## 機能種別

構文検証 / コード品質チェック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| +flymake | flag | No | flymakeを使用（flycheckの代わり） | modulep!でチェック |
| +childframe | flag | No | posframeでエラー表示 | modulep!でチェック |
| +icons | flag | No | エラーアイコンを使用 | modulep!でチェック |

### 入力データソース

- バッファのソースコード
- 外部リンター/コンパイラの出力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| エラーマーカー | overlay | エラー箇所のハイライト |
| エラー詳細 | string | エラーメッセージのポップアップ/posframe |
| エラーリスト | buffer | エラー一覧バッファ |

### 出力先

- 現在のバッファ（オーバーレイ）
- ポップアップ/posframe
- `*Flycheck errors*`バッファ

## 処理フロー

### 処理シーケンス

```
1. プログラミングバッファを開く
   └─ global-flycheck-mode によりflycheck-modeが有効化
2. バッファ編集
   └─ idle-change-delay後にチェック開始
3. チェッカー実行
   └─ 言語に応じたリンター/コンパイラを呼び出し
4. 結果解析
   └─ エラー/警告をオーバーレイで表示
5. カーソル移動
   └─ エラー箇所でポップアップ/posframe表示
```

### フローチャート

```mermaid
flowchart TD
    A[バッファを開く] --> B{global-flycheck-mode?}
    B -->|Yes| C[flycheck-mode有効化]
    B -->|No| D[flymake-mode有効化]
    C --> E[バッファ編集]
    D --> E
    E --> F{idle-change-delay経過?}
    F -->|Yes| G[チェッカー実行]
    F -->|No| E
    G --> H[結果解析]
    H --> I{エラーあり?}
    I -->|Yes| J[オーバーレイ表示]
    I -->|No| E
    J --> K{カーソルがエラー上?}
    K -->|Yes| L[ポップアップ/posframe表示]
    K -->|No| E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-58-01 | 新行チェック無効 | 改行時のチェックを無効化（過剰チェック防止） | 常時 |
| BR-58-02 | idle-change-delay | 1秒の遅延後にチェック実行 | 常時 |
| BR-58-03 | 表示遅延 | 0.25秒後にエラー表示 | 常時 |
| BR-58-04 | ESCでチェック | ESCキー押下時に即時チェック | doom-escape-hook |
| BR-58-05 | CVE対策 | 非プロジェクトバッファではEmacs Lispチェック無効 | emacs-lispチェッカー |

### 計算ロジック

- チェッカー選択: `flycheck-checker-get`で言語に応じたチェッカーを選択
- プロジェクト判定: `doom-project-p`

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | チェッカー未検出 | リンターが未インストール | 警告表示、チェックスキップ |
| - | タイムアウト | チェッカーが応答しない | タイムアウト後にスキップ |

### リトライ仕様

バッファ再編集時に自動リトライ。

## トランザクション仕様

トランザクション処理は不要。

## パフォーマンス要件

- チェック実行: idle後1秒で開始
- エラー表示: 0.25秒以内

## セキュリティ考慮事項

- CVE-2024-53920対策: マクロ展開時のコード実行脆弱性を防ぐため、非プロジェクトバッファではEmacs Lispチェックを無効化

## 備考

- lsp-ui-modeが有効でlsp-ui-sideline-enableがtrueの場合、flycheck-popup-tipは無効化
- Evilのinsert/replaceステートではposframeを抑制

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: Flycheck基本設定を理解する

まず、Flycheckの基本設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/checkers/syntax/config.el` | flycheck設定（6-59行目） |

**読解のコツ**: `use-package!`でFlycheckをlazy load、`doom-first-buffer`フックで`global-flycheck-mode`を有効化。

**主要処理フロー**:
1. **9行目**: doom-first-bufferフックでglobal-flycheck-modeを有効化
2. **11行目**: emacs-lisp-load-pathをinheritに設定
3. **14行目**: new-lineをcheck-syntax-automaticallyから削除
4. **16行目**: idle-change-delayを1秒に設定
5. **24行目**: display-errors-delayを0.25秒に設定

#### Step 2: CVE対策を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/checkers/syntax/config.el` | CVE対策（26-38行目） |

**主要処理フロー**:
- **29-37行目**: emacs-lispチェッカーにpredicateを設定
- `no-byte-compile`がfalseかつ`doom-project-p`がtrueの場合のみチェック

#### Step 3: ポップアップUI設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.el | `modules/checkers/syntax/config.el` | popup-tip設定（62-80行目） |
| 3-2 | config.el | `modules/checkers/syntax/config.el` | posframe設定（83-118行目） |

**主要処理フロー**:
- **67行目**: +iconsフラグでエラープレフィックスを設定
- **73-80行目**: Evil normalステート時のみポップアップ表示
- **88-94行目**: +iconsフラグでposframeプレフィックス設定
- **113-118行目**: insert/replaceステートでposframeを抑制

#### Step 4: flymake設定を理解する（+flymakeフラグ時）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.el | `modules/checkers/syntax/config.el` | flymake設定（124-145行目） |

**主要処理フロー**:
- **126行目**: prog-mode/text-modeフックでflymake-modeを有効化
- **128行目**: fringe indicatorを右側に配置
- **133-136行目**: CVE対策（flymake版）

### プログラム呼び出し階層図

```
doom-first-buffer-hook
    │
    └─ global-flycheck-mode
           │
           ├─ flycheck-mode (バッファごと)
           │      │
           │      ├─ flycheck-buffer
           │      │      └─ 言語別チェッカー
           │      │
           │      └─ flycheck-display-error-at-point
           │             │
           │             ├─ flycheck-popup-tip-show-popup
           │             │
           │             └─ flycheck-posframe-show-posframe
           │
           └─ flycheck-error-list-mode
                  └─ *Flycheck errors*バッファ
```

### データフロー図

```
[入力]               [処理]                    [出力]

ソースコード ───▶ flycheck-buffer ───▶ リンター呼び出し
                      │                       │
                      ▼                       ▼
              flycheck-parse-output ◀── リンター出力
                      │
                      ▼
              flycheck-report-buffer
                      │
           ┌──────────┼──────────┐
           ▼          ▼          ▼
        overlay    popup-tip   posframe
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/checkers/syntax/config.el` | ソース | メイン設定 |
| packages.el | `modules/checkers/syntax/packages.el` | 設定 | 依存パッケージ定義 |
| autoload.el | `modules/checkers/syntax/autoload.el` | ソース | ヘルパー関数 |
