# 通知設計書 71-非推奨関数使用警告

## 概要

本ドキュメントは、Julia言語の`@deprecate`マクロおよび`depwarn()`関数によって生成される非推奨関数使用警告の通知設計を定義する。

### 本通知の処理概要

非推奨（deprecated）となったAPIを開発者が使用した場合に、代替APIへの移行を促す警告メッセージをログ出力する通知機能である。

**業務上の目的・背景**：Juliaの進化に伴い、古いAPIは新しいAPIに置き換えられる。非推奨関数の使用を検出し開発者に通知することで、コードの安全なマイグレーションを促進し、将来のバージョンでのAPI削除による突然のビルド失敗を未然に防ぐ。この仕組みはJuliaの後方互換性ポリシーの中核を成すものであり、非推奨のAPIは一般的に次のメジャーリリースで完全に削除される。

**通知の送信タイミング**：`@deprecate`マクロで定義された非推奨関数が呼び出されたとき、または`depwarn()`が明示的に呼び出されたときに通知が生成される。Juliaの`--depwarn`オプションの設定に応じて挙動が変わり、`--depwarn=yes`で警告表示、`--depwarn=error`で例外送出、`--depwarn=no`（デフォルト）で抑制される。ただし`Pkg.test()`実行時はデフォルトで警告が有効化される。

**通知の受信者**：非推奨関数を呼び出したJuliaコードの開発者。ログシステムを通じてコンソール（stderr）に出力される。

**通知内容の概要**：非推奨となった関数名、代替として推奨される関数名、および呼び出し元の位置情報（ファイル名・行番号）が通知される。

**期待されるアクション**：開発者は通知に記載された代替関数に移行し、非推奨APIの使用を排除すること。

## 通知種別

ログ出力（CoreLogging.Warn レベル / `_group=:depwarn`）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（関数呼び出し時に即座に評価） |
| 優先度 | 中（`--depwarn`フラグに応じて動的に変更） |
| リトライ | なし |

### 送信先決定ロジック

通知はJuliaの標準ログシステム（`CoreLogging`）を通じて出力される。`depwarn()`の`maxlog=1`設定により、同一呼び出し箇所からの重複警告は抑制され、各コールサイトにつき最初の1回のみ通知される（`funcsym`が`nothing`の場合は毎回通知）。

## 通知テンプレート

### メール通知の場合

該当なし（ログ出力のみ）

### 本文テンプレート

```
`{旧関数シグネチャ}` is deprecated, use `{新関数シグネチャ}` instead.
```

`@deprecate`マクロ以外で`depwarn()`を直接呼び出す場合は、任意のメッセージ文字列が指定される。

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| 該当なし | - | - | - |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| oldcall | 非推奨関数のシグネチャ文字列 | `@deprecate`マクロの第1引数 | Yes |
| newcall | 代替関数のシグネチャ文字列 | `@deprecate`マクロの第2引数 | Yes |
| _module | 呼び出し元モジュール | バックトレースから動的取得 | Yes |
| _file | 呼び出し元ファイル名 | バックトレースから動的取得 | Yes |
| _line | 呼び出し元行番号 | バックトレースから動的取得 | Yes |
| caller | 呼び出し元のスタックフレーム情報 | `firstcaller()`関数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | `@deprecate`で定義された関数の実行 | `--depwarn=yes`または`force=true` | 非推奨関数の呼び出し時 |
| API呼び出し | `depwarn()`の明示的呼び出し | `--depwarn=yes`または`force=true` | プログラマによる直接利用 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `--depwarn=no`（デフォルト） | `force=false`の場合、ログレベルが`BelowMinLevel`に設定され実質的に抑制される |
| `maxlog=1` | 同一`(frame, funcsym)`ペアに対して最初の1回のみ通知（`funcsym`が`nothing`の場合はこの制限なし） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[非推奨関数呼び出し] --> B[@deprecateマクロ展開]
    B --> C[depwarn関数呼び出し]
    C --> D[_depwarn内部関数]
    D --> E{--depwarnオプション確認}
    E -->|depwarn==2| F[ErrorException送出]
    E -->|depwarn==1 or force| G[Warnレベルでログ出力]
    E -->|depwarn==0 and !force| H[BelowMinLevelで出力抑制]
    G --> I[backtrace取得]
    I --> J[firstcaller特定]
    J --> K[@logmsgでログ記録]
    K --> L[終了]
    F --> L
    H --> L
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| 該当なし | - | ログ出力のみのためDB参照なし |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| 該当なし | - | ログ出力のみのためDB更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ErrorException | `--depwarn=error`設定時 | 非推奨関数の呼び出しが例外として送出される |
| スタックトレース取得失敗 | バックトレース情報が不完全な場合 | `firstcaller`が`(C_NULL, StackTraces.UNKNOWN)`を返す |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（`maxlog=1`により自然に制限） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（関数呼び出し時に即座に通知）

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

- 通知メッセージにはソースコードのファイルパスと行番号が含まれるため、外部に公開されるログではパス情報の漏洩に注意が必要
- `depwarn()`はバックトレース取得を行うため、高頻度呼び出し時にパフォーマンスへの影響がある（`@invokelatest`で緩和済み）

## 備考

- Julia 1.5以降、`--depwarn`のデフォルト値は`no`に変更された。テスト実行時（`Pkg.test()`）はデフォルトで有効化される
- `@deprecate`マクロは関数定義とエクスポートも同時に行う。第3引数`export_old`で制御可能
- Julia 1.9以降、`@deprecate`はキーワード引数の転送にも対応
- `@nospecializeinfer`属性により型推論の特殊化が抑制され、コンパイル時間への影響が軽減されている

---

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

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

### 推奨読解順序

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

非推奨警告システムは`CoreLogging`のログ機構と`JLOptions`構造体（`--depwarn`フラグ）に依存している。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | options.jl | `base/options.jl` | `JLOptions`構造体の`depwarn`フィールド（0=no, 1=yes, 2=error） |
| 1-2 | logging.jl | `base/logging/logging.jl` | `CoreLogging`モジュールのログレベル定義（`Warn`, `BelowMinLevel`） |

**読解のコツ**: `JLOptions().depwarn`の値が通知の挙動全体を制御する。`0`=抑制、`1`=警告、`2`=エラーの3状態を把握すること。

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

`@deprecate`マクロと`depwarn()`関数が通知の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | deprecated.jl | `base/deprecated.jl` | `@deprecate`マクロ（177行目）による非推奨関数定義パターン |
| 2-2 | deprecated.jl | `base/deprecated.jl` | `depwarn()`関数（252行目）がログメッセージ生成の中核 |

**主要処理フロー**:
1. **177行目**: `@deprecate`マクロが非推奨関数を定義し、内部で`depwarn()`を呼び出すコードを生成
2. **215行目**: 生成されたメッセージ「`oldcall` is deprecated, use `newcall` instead.」
3. **252行目**: `depwarn()`が`@invokelatest`で`_depwarn`を呼び出し（バックエッジ回避）

#### Step 3: 内部処理を理解する

`_depwarn`関数がログレベル判定とバックトレース解析を行う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | deprecated.jl | `base/deprecated.jl` | `_depwarn()`関数（259行目）：ログレベル判定とメッセージ出力 |
| 3-2 | deprecated.jl | `base/deprecated.jl` | `firstcaller()`関数（290-316行目）：バックトレースから呼び出し元を特定 |

**主要処理フロー**:
- **261-263行目**: `JLOptions().depwarn`の値チェック。`2`なら`ErrorException`を送出
- **265行目**: `force`または`depwarn==1`なら`Warn`レベル、それ以外は`BelowMinLevel`
- **266-287行目**: `@logmsg`マクロでログ出力。`_id=(frame,funcsym)`で重複制御

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

```
@deprecate マクロ (deprecated.jl:177)
    |
    +-- 非推奨関数定義コード生成
           |
           +-- depwarn(msg, funcsym) (deprecated.jl:252)
                  |
                  +-- @invokelatest _depwarn(msg, funcsym, force)
                         |
                         +-- JLOptions().depwarn チェック
                         |      +-- ==2: throw(ErrorException)
                         |      +-- ==1/force: Warn レベル
                         |      +-- ==0/!force: BelowMinLevel
                         |
                         +-- backtrace() (deprecated.jl:271)
                         +-- firstcaller(bt, funcsym) (deprecated.jl:292)
                         +-- @logmsg(...) (deprecated.jl:266)
```

### データフロー図

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

非推奨関数呼び出し ──────> @deprecate展開コード ──────> depwarn()
                                                          |
--depwarn フラグ ────────> JLOptions().depwarn ────────> ログレベル判定
                                                          |
バックトレース ──────────> firstcaller() ──────────────> 呼び出し元情報
                                                          |
                                                     @logmsg ──> stderr/ログハンドラ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| deprecated.jl | `base/deprecated.jl` | ソース | `@deprecate`マクロ、`depwarn()`、`_depwarn()`、`firstcaller()`の定義 |
| options.jl | `base/options.jl` | ソース | `JLOptions`構造体（`depwarn`フィールド）の定義 |
| logging.jl | `base/logging/logging.jl` | ソース | `CoreLogging`モジュールのログレベルとログマクロの定義 |
| stacktraces.jl | `base/stacktraces.jl` | ソース | `StackTraces.lookup()`、`StackTraces.UNKNOWN`の定義 |
