# 機能設計書 36-非推奨機能 (deprecated)

## 概要

本ドキュメントは、Lua Language Serverにおける「非推奨機能検出機能」の設計詳細を記載したものである。`@deprecated`アノテーションまたは`@version`アノテーションにより非推奨とマークされたAPI・関数の使用を検出し、開発者に警告する診断機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
ソフトウェアの進化に伴い、一部のAPIや関数は非推奨となり、将来のバージョンで削除される可能性がある。また、特定のLuaバージョンでのみ利用可能なAPIも存在する。本機能は、非推奨APIの使用や、現在の設定バージョンでサポートされていないAPIの使用を検出し、開発者に警告することで、将来の互換性問題を未然に防止する。

**機能の利用シーン**：
- 新しいLuaバージョンへの移行時
- サードパーティライブラリの更新時
- レガシーコードのモダナイゼーション

**主要な処理内容**：
1. 対象ファイルのASTを取得する
2. getglobal/getfield/getindex/getmethodノードを走査する
3. `vm.getDeprecated`で非推奨情報を取得する
4. `@version`の場合は有効なバージョンと現在の設定を比較する
5. `@deprecated`の場合はコメントを含めてメッセージを生成する
6. DiagnosticTag.Deprecatedを付与して報告する

**関連システム・外部連携**：
- LSP (Language Server Protocol)クライアント（VSCode等のエディタ）との連携
- 診断結果はLSPの`textDocument/publishDiagnostics`通知で送信される

**権限による制御**：
- 設定`Lua.diagnostics.disable`で本診断を無効化可能
- 設定`Lua.diagnostics.globals`で特定のグローバル変数を除外可能
- 設定`Lua.runtime.special`で特殊関数を除外可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | 診断情報 | 補助機能 | 非推奨APIの使用を検出 |

## 機能種別

バリデーション / 静的解析 / 診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | 診断対象ファイルのURI | 有効なファイルURIであること |
| callback | function | Yes | 診断結果を受け取るコールバック関数 | - |

### 入力データソース

- ファイルシステムから読み込まれたLuaソースコード
- `files.getState(uri)`から取得されるAST情報
- `config.get(uri, 'Lua.diagnostics.globals')`から除外グローバル変数
- `config.get(uri, 'Lua.runtime.special')`から特殊関数設定
- `config.get(uri, 'Lua.runtime.version')`からランタイムバージョン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| start | integer | エラー位置の開始オフセット |
| finish | integer | エラー位置の終了オフセット |
| tags | table | DiagnosticTag.Deprecatedを含む配列 |
| message | string | 診断メッセージ（非推奨理由やバージョン情報を含む） |
| data | table | バージョン情報を含む追加データ |

### 出力先

- LSPクライアントへの診断通知（`textDocument/publishDiagnostics`）
- エディタ上でのインライン警告表示（取り消し線）

## 処理フロー

### 処理シーケンス

```
1. ファイル状態の取得
   └─ files.getState(uri)でAST付きの状態を取得
2. 除外設定の取得
   └─ config.get(uri, 'Lua.diagnostics.globals')
   └─ config.get(uri, 'Lua.runtime.special')
3. 参照ノードの走査
   └─ guide.eachSourceTypes(ast.ast, types, callback)
4. getglobalの除外判定
   └─ dglobals[key]またはrspecial[key]の場合はスキップ
5. 非推奨情報の取得
   └─ vm.getDeprecated(src, true)
6. バージョン情報の処理
   └─ doc.versionの場合、有効バージョンを取得
7. 非推奨コメントの処理
   └─ doc.deprecatedの場合、コメントを追加
8. 診断結果の報告
   └─ Deprecatedタグ付きで報告
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ファイル状態を取得]
    B --> C{状態が存在するか?}
    C -->|No| D[終了]
    C -->|Yes| E[除外設定を取得]
    E --> F[参照ノードを走査]
    F --> G{getglobalか?}
    G -->|Yes| H{除外対象か?}
    H -->|Yes| I[次のノードへ]
    H -->|No| J[await.delay]
    G -->|No| J
    J --> K[vm.getDeprecated取得]
    K --> L{非推奨か?}
    L -->|No| I
    L -->|Yes| M[await.delay]
    M --> N{doc.versionか?}
    N -->|Yes| O[有効バージョン取得]
    O --> P{有効バージョンあり?}
    P -->|No| I
    P -->|Yes| Q[バージョンメッセージ生成]
    N -->|No| R{doc.deprecatedか?}
    R -->|Yes| S[コメント取得]
    S --> T[診断報告]
    Q --> T
    R -->|No| T
    T --> I
    I --> U{全ノード完了?}
    U -->|No| F
    U -->|Yes| D
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | 対象ノードタイプ | getglobal/getfield/getindex/getmethod | types配列 |
| BR-36-02 | グローバル除外 | Lua.diagnostics.globalsに含まれるグローバル変数は除外 | getglobalノード |
| BR-36-03 | 特殊関数除外 | Lua.runtime.specialに含まれる関数は除外 | getglobalノード |
| BR-36-04 | バージョン判定 | doc.versionの場合、validVersionsと現在のruntime.versionを比較 | @versionアノテーション |
| BR-36-05 | コメント付加 | doc.deprecatedの場合、アノテーションコメントをメッセージに追加 | @deprecatedアノテーション |
| BR-36-06 | Deprecatedタグ | 診断にはDiagnosticTag.Deprecatedを付与 | 取り消し線表示用 |

### 計算ロジック

#### バージョン互換性判定

```lua
-- doc.versionの処理
if deprecated.type == 'doc.version' then
    local validVersions = vm.getValidVersions(deprecated)
    if not validVersions then
        return -- 全バージョンで有効
    end
    local versions = {}
    for version, valid in pairs(validVersions) do
        if valid then
            versions[#versions+1] = version
        end
    end
    table.sort(versions)
    if #versions > 0 then
        message = message .. '(' ..
            lang.script('DIAG_DEFINED_VERSION',
                table.concat(versions, '/'),
                config.get(uri, 'Lua.runtime.version')
            ) .. ')'
    end
end
```

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル状態なし | files.getState(uri)がnilを返す場合 | 処理を中断して正常終了 |

### リトライ仕様

リトライは行わない。ファイルが再度編集された際に自動的に再診断される。

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

該当なし（読み取り専用処理）

## パフォーマンス要件

- 単一ファイルの診断は通常0.5秒以内に完了すること
- `await.delay()`により非同期処理のブロッキングを防止

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

- ユーザーコードの読み取りのみを行い、ファイルシステムへの書き込みは行わない
- 外部ネットワークへのアクセスは行わない

## 備考

- `DiagnosticTag.Deprecated`により、エディタ上で該当コードに取り消し線が表示される
- バージョン情報は設定`Lua.runtime.version`との比較に使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | define.lua | `script/proto/define.lua` | DiagnosticTag.Deprecatedの定義（32行目） |

**読解のコツ**: `@deprecated`と`@version`は異なるアノテーションタイプで、それぞれ処理が異なる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | deprecated.lua | `script/core/diagnostics/deprecated.lua` | メイン診断関数 |

**主要処理フロー**:
1. **10行目**: types配列で対象ノードタイプを定義
2. **13-16行目**: ファイル状態取得
3. **18-19行目**: 除外設定の取得
4. **21-33行目**: getglobalの除外判定
5. **35-40行目**: vm.getDeprecatedで非推奨情報取得
6. **44-65行目**: doc.versionの処理
7. **66-70行目**: doc.deprecatedの処理
8. **72-80行目**: 診断報告

#### Step 3: バージョン判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | deprecated.lua | `script/core/diagnostics/deprecated.lua` | doc.version処理 |

**主要処理フロー**:
- **46行目**: deprecated.type == 'doc.version'で判定
- **47行目**: vm.getValidVersions(deprecated)で有効バージョン取得
- **51-56行目**: 有効バージョンをリスト化
- **57行目**: table.sort(versions)でソート
- **58-64行目**: バージョン情報付きメッセージ生成

#### Step 4: VMの非推奨判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | vm.lua | `script/vm/vm.lua` | getDeprecated, getValidVersions |

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

```
script/core/diagnostics/init.lua (診断エントリー)
    │
    ├─ require('core.diagnostics.deprecated')
    │      │
    │      ├─ files.getState(uri)
    │      │
    │      ├─ config.get(uri, 'Lua.diagnostics.globals')
    │      ├─ config.get(uri, 'Lua.runtime.special')
    │      │
    │      ├─ guide.eachSourceTypes(ast.ast, types, callback)
    │      │      │
    │      │      ├─ await.delay()
    │      │      │
    │      │      ├─ vm.getDeprecated(src, true)
    │      │      │      └─ deprecated情報を取得
    │      │      │
    │      │      └─ vm.getValidVersions(deprecated)
    │      │             └─ 有効バージョン情報
    │      │
    │      └─ callback(result)
    │             └─ DiagnosticTag.Deprecated付き
    │
    └─ LSP診断通知
```

### データフロー図

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

Luaソースコード ───▶ パーサー(AST生成) ───▶ AST
      +                                     │
LuaDocアノテーション                         ▼
(@deprecated/@version)  guide.eachSourceTypes(types)
                                              │
                                              ▼
                        vm.getDeprecated(src, true)
                                              │
                               ┌──────────────┴──────────────┐
                               │                              │
                               ▼                              ▼
                        doc.version                    doc.deprecated
                               │                              │
                               ▼                              ▼
                    vm.getValidVersions()         deprecated.comment
                               │                              │
                               ▼                              ▼
                    バージョン比較              コメント取得
                               │                              │
                               └──────────────┬──────────────┘
                                              │
                                              ▼
                              診断メッセージ生成 ───▶ LSP診断通知
                                              │      （Deprecatedタグ）
                                              ▼
                                        エディタ表示
                                        （取り消し線）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| deprecated.lua | `script/core/diagnostics/deprecated.lua` | ソース | 非推奨機能診断のメインロジック |
| init.lua | `script/core/diagnostics/init.lua` | ソース | 診断処理のエントリーポイント |
| define.lua | `script/proto/define.lua` | ソース | DiagnosticTag定義 |
| vm.lua | `script/vm/vm.lua` | ソース | getDeprecated, getValidVersions |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作 |
| files.lua | `script/files.lua` | ソース | ファイル状態管理 |
| config.lua | `script/config/config.lua` | ソース | 設定値取得 |
| await.lua | `script/await.lua` | ソース | 非同期処理ユーティリティ |
| utility.lua | `script/utility.lua` | ソース | arrayToHashなど |
| language.lua | `script/language.lua` | ソース | 診断メッセージ定義 |
