# 機能設計書 69-ファイル監視

## 概要

本ドキュメントは、Lua Language Serverにおける「ファイル監視」機能の設計を記述する。本機能は、ファイルシステムの変更（作成、変更、削除）を監視し、変更があった場合に適切な処理をトリガーする。

### 本機能の処理概要

ファイル監視機能は、ワークスペース内のファイルとライブラリパスを監視し、外部からのファイル変更を検出する。変更を検出するとイベントを発火し、ファイルキャッシュの更新やワークスペースの再スキャンをトリガーする。

**業務上の目的・背景**：開発者はエディタ外でもファイルを編集することがある（Gitの操作、コマンドラインからのファイル作成、外部ツールによる生成など）。これらの変更をリアルタイムで検出し、Language Serverの状態を最新に保つことで、常に正確な補完や診断を提供できる。

**機能の利用シーン**：
- Gitでブランチを切り替えた時のファイル変更検出
- 外部ツールによるコード生成後の自動認識
- ファイル名変更や移動の検出
- 新規ファイル作成の検出
- ファイル削除の検出

**主要な処理内容**：
1. ワークスペースとライブラリのパスを監視対象に追加
2. ファイルシステムの変更イベントを収集
3. 変更イベントを分類（作成、変更、削除）
4. イベントに応じたコールバックを実行
5. 参照カウントベースの監視管理

**関連システム・外部連携**：
- bee.filewatch：ネイティブのファイル監視ライブラリ
- workspace.lua：ワークスペース管理との連携
- files.lua：ファイルキャッシュとの連携
- await.lua：非同期処理との連携

**権限による制御**：本機能に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はバックグラウンドで動作し、専用の画面は存在しない |

## 機能種別

システム連携 / イベント監視

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | Yes | 監視対象のパス | 有効なディレクトリパス |
| recursive | boolean | Yes | 再帰的に監視するか | - |
| filter | function | No | ファイルフィルター関数 | - |

### 入力データソース

- ワークスペースのルートパス
- ライブラリパスの設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| イベント | string | 'create', 'change', 'delete' |
| path | string | 変更されたファイルのパス |

### 出力先

登録されたイベントコールバック関数

## 処理フロー

### 処理シーケンス

```
1. 監視の開始
   ├─ m.watch(path, recursive, filter)を呼び出し
   ├─ 既存の監視があれば参照カウントを増加
   └─ 新規の場合はfw.createで監視を作成
2. イベント収集
   └─ m.update()でイベントを収集
3. イベント分類
   ├─ MODIFY: ファイル内容の変更
   └─ RENAME: ファイルの作成または削除
4. イベント発火
   ├─ 'create': ファイルが存在する場合のRENAME
   ├─ 'delete': ファイルが存在しない場合のRENAME
   └─ 'change': MODIFY
5. コールバック実行
   └─ m._callEvent()で登録されたコールバックを呼び出し
6. 監視の終了
   └─ 返却された関数を呼び出して参照カウントを減少
```

### フローチャート

```mermaid
flowchart TD
    A[監視開始] --> B{既存の監視?}
    B -->|Yes| C[参照カウント++]
    B -->|No| D[fw.create]
    D --> E[監視設定]
    E --> F[m._watchingsに追加]
    C --> G[監視中]
    F --> G

    G --> H[m.update呼び出し]
    H --> I[イベント収集]
    I --> J{イベントあり?}
    J -->|No| H
    J -->|Yes| K[イベント分類]
    K --> L{イベント種類}
    L -->|RENAME| M{ファイル存在?}
    M -->|Yes| N[create発火]
    M -->|No| O[delete発火]
    L -->|MODIFY| P[change発火]
    N --> Q[コールバック実行]
    O --> Q
    P --> Q
    Q --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 参照カウント管理 | 同じパスの監視は参照カウントで管理 | 複数箇所から同じパスを監視 |
| BR-02 | 再帰監視 | recursiveオプションでサブディレクトリも監視 | recursive=true |
| BR-03 | フィルター適用 | filter関数でファイルを選択的に監視 | filter指定時 |
| BR-04 | RENAME判定 | RENAMEイベントはファイル存在で作成/削除を判定 | RENAMEイベント発生時 |
| BR-05 | シンボリックリンク | シンボリックリンクを追跡して監視 | recursive=true |

### 計算ロジック

イベントフラグの計算：
- `MODIFY = 1 << 0` (値: 1)
- `RENAME = 1 << 1` (値: 2)
- イベントはビットOR演算で組み合わされる

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

### 操作別データベース影響一覧

本機能はデータベースを使用しない（メモリ上のイベント処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | パスが存在しない場合は空の関数を返却 | パスの存在を確認 |

### リトライ仕様

リトライは不要（イベントは次のupdate呼び出しで再取得）

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

トランザクション管理は不要（イベント駆動型処理）

## パフォーマンス要件

- イベント収集は100ms以内
- 最大10000イベントを1回で処理
- コールバック呼び出しはasync処理

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

- シンボリックリンクの追跡によるセキュリティリスクの認識
- パスの正規化によるディレクトリトラバーサル防止

## 備考

- filewatch.luaはbee.filewatchのラッパーモジュール
- イベント収集はm.update()を定期的に呼び出す必要がある
- Windows環境では大文字小文字の正規化が行われる

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ファイル監視のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | filewatch.lua | `script/filewatch.lua` | `@class filewatch`の定義（31-32行目） |
| 1-2 | filewatch.lua | `script/filewatch.lua` | イベントフラグの定義（8-9行目） |

**読解のコツ**: 主要なデータ構造：
- `m._watchings`: パス -> 監視情報のマップ
- `m._eventList`: イベントコールバックのリスト
- 各監視情報には`count`（参照カウント）と`watch`（ネイティブ監視）

#### Step 2: 監視の開始と終了を理解する

監視のライフサイクルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | filewatch.lua | `script/filewatch.lua` | `m.watch`関数（41-74行目） |

**主要処理フロー**:
- **42-43行目**: パスが空または非ディレクトリなら空関数を返却
- **45-46行目**: 既存監視の場合は参照カウントを増加
- **47-60行目**: 新規監視の作成と設定
- **62-73行目**: 監視終了用の関数を返却

#### Step 3: イベント処理を理解する

イベントの収集と発火を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | filewatch.lua | `script/filewatch.lua` | `m.update`関数（89-127行目） |
| 3-2 | filewatch.lua | `script/filewatch.lua` | `m._callEvent`関数（81-87行目） |
| 3-3 | filewatch.lua | `script/filewatch.lua` | `m.event`関数（77-79行目） |

**主要処理フロー**:
- **91-108行目**: 全監視からイベントを収集
- **115-125行目**: イベントを分類して発火
  - `RENAME & isExists` -> 'create'
  - `RENAME & !isExists` -> 'delete'
  - `MODIFY` -> 'change'

#### Step 4: workspaceとの連携を理解する

ワークスペースからの監視設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | workspace.lua | `script/workspace/workspace.lua` | `m.awaitPreload`内のfw.watch呼び出し（339行目, 363行目） |
| 4-2 | workspace.lua | `script/workspace/workspace.lua` | `fw.event`コールバック（587-621行目） |

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

```
workspace (ワークスペース管理)
    │
    ├─ m.awaitPreload
    │      ├─ fw.watch (ワークスペースパス)
    │      │      └─ filter関数でignore判定
    │      └─ fw.watch (ライブラリパス)
    │
    └─ fw.event (イベントコールバック登録)
           └─ イベント発生時の処理

filewatch (ファイル監視)
    │
    ├─ m.watch
    │      ├─ 参照カウント管理
    │      └─ bee.filewatch.create
    │
    ├─ m.update (定期呼び出し)
    │      ├─ watch:select (イベント取得)
    │      └─ m._callEvent (コールバック発火)
    │
    └─ m.event
           └─ コールバック登録

bee.filewatch (ネイティブ監視)
    │
    ├─ create
    ├─ add
    ├─ set_recursive
    ├─ set_follow_symlinks
    └─ select
```

### データフロー図

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

ファイルシステム変更
        │
        ▼
  bee.filewatch        ───▶  イベント検出
        │                    (modify/rename)
        ▼
  m.update             ───▶  イベント収集
        │                    ↓
        │                    イベント分類
        │                    ↓
        ▼                    ファイル存在確認
  m._callEvent         ───▶  イベント決定
        │                    (create/change/delete)
        ▼
  コールバック実行     ───▶  ワークスペース更新
        │                    ↓
        ▼                    ファイルキャッシュ更新
  files更新            ───▶  診断再実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| filewatch.lua | `script/filewatch.lua` | ソース | ファイル監視のメイン処理 |
| workspace.lua | `script/workspace/workspace.lua` | ソース | 監視の設定とイベント処理 |
| files.lua | `script/files.lua` | ソース | ファイルキャッシュ連携 |
| await.lua | `script/await.lua` | ソース | 非同期処理 |
| bee.filewatch | (ネイティブ) | ライブラリ | ネイティブファイル監視 |
