# 通知設計書 123-hintDeclaredLoc

## 概要

本ドキュメントは、Nimコンパイラの通知種別「hintDeclaredLoc」（No.123）に関する設計仕様を定義する。この通知は、シンボル（変数、型、プロシージャなど）の宣言位置情報をエラーメッセージや警告に付加するためのヒント通知である。Nim 1.5.1以降で導入された。

### 本通知の処理概要

hintDeclaredLocは、Nimコンパイラの診断メッセージの情報量を強化するための機能として設計されたヒント通知である。型ミスマッチエラーやシンボル参照エラーなどの診断メッセージに対して、関連するシンボルがどこで宣言されたかの位置情報（ファイル名、行番号、列番号）を追加表示する。

**業務上の目的・背景**：大規模なNimプロジェクトや複数モジュールにまたがるコードベースでは、同名のシンボルが複数存在することがある。また、型エイリアスやジェネリクスを使用している場合、エラーメッセージだけでは問題の原因となっているシンボルや型がどこで定義されているかを特定することが困難な場合がある。このヒントにより、エラーメッセージに宣言位置情報が付加され、開発者が問題を迅速に特定・修正できるようになる。

**通知の送信タイミング**：`--declaredLocs:on`オプションが有効な場合、または`optDeclaredLocs`がglobalOptionsに含まれている場合に、型ミスマッチや関連するエラー・警告メッセージの一部として送信される。メッセージ生成処理（astmsgs.nim、types.nim等）内で、addDeclaredLoc系関数が呼び出された際に宣言位置情報が追加される。

**通知の受信者**：Nimコンパイラを使用してコードをコンパイルする開発者。特に、型エラーや名前解決エラーのデバッグを行っている開発者。

**通知内容の概要**：シンボルの種類（proc、var、type等）と、そのシンボルが宣言されたソースファイルの位置（ファイル名:行番号:列番号）を角括弧で囲んで出力する。フォーマット例：`[proc declared in /path/to/file.nim(42, 5)]`

**期待されるアクション**：開発者は、宣言位置情報を参考にして、問題の原因となっているシンボルや型の定義を直接参照し、型の不一致や誤った参照を修正することが期待される。

## 通知種別

コンパイラヒント（Hint）- 他のエラー・警告メッセージへの付加情報

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（エラー・警告メッセージの一部として出力） |
| 優先度 | 低（補助情報としてのヒント） |
| リトライ | 無し |

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

コンパイラの標準エラー出力（stderr）または標準出力（stdout、`--stdout`オプション指定時）に対して送信される。`--declaredLocs:on`が指定されている場合に有効となる。デフォルトでは無効。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（デフォルト）/ stdout（`--stdout`指定時） |
| 形式 | エラー・警告メッセージに埋め込まれる追加情報 |

### 本文テンプレート

シンボルの場合：
```
[{シンボル種別} declared in {ファイルパス}({行番号}, {列番号})]
```

型の場合：
```
[{型種別} declared in {ファイルパス}({行番号}, {列番号})]
```

### 出力例

シンボル付加情報：
```
type mismatch:
 got 'string'
 [string declared in /path/to/file.nim(10, 5)]
 but expected 'int'
 [int declared in system.nim(123, 1)]
```

プロシージャヘッダ付加情報：
```
proc foo.bar(x: int): string [proc declared in /path/to/file.nim(42, 1)]
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $1 | 宣言位置情報文字列 | addDeclaredLoc関数で生成 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コンパイル処理 | addDeclaredLoc関数呼び出し | 常に（呼び出された場合） | シンボルまたは型の宣言位置を追加 |
| コンパイル処理 | addDeclaredLocMaybe関数呼び出し | optDeclaredLocs in globalOptions | オプション有効時のみ追加 |
| コンパイル処理 | 型ミスマッチエラー | optDeclaredLocs in globalOptions | typeMismatch関数内で使用 |
| コンパイル処理 | getProcHeader関数 | getDeclarationPath=true | プロシージャヘッダ生成時 |
| コンパイル処理 | addTypeHeader関数 | getDeclarationPath=true | 型ヘッダ生成時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `--declaredLocs:off`（デフォルト） | オプションが無効の場合 |
| sym == nil | シンボルがnilの場合（addDeclaredLocMaybe） |
| `--verbosity:0`、`--verbosity:1`、`--verbosity:2` | NotesVerbosityでverbosity:2以下で除外 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[エラー/警告メッセージ生成] --> B{addDeclaredLocMaybe呼び出し?}
    B -->|No| C[addDeclaredLoc直接呼び出し?]
    B -->|Yes| D{optDeclaredLocs in globalOptions?}
    C -->|No| E[宣言位置情報なしで終了]
    C -->|Yes| F[addDeclaredLoc実行]
    D -->|No| E
    D -->|Yes| F
    F --> G{sym != nil?}
    G -->|No| H[型情報のみ追加]
    G -->|Yes| I[シンボル種別 + 宣言位置を追加]
    H --> J[メッセージに追記]
    I --> J
    J --> K[終了]
    E --> K
```

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

### 参照テーブル一覧

本通知はコンパイラ内部のデータ構造を参照するため、外部データベースは使用しない。

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| PSym | シンボル情報（変数、型、プロシージャなど） | info, kind, name等を参照 |
| PType | 型情報 | sym, kindを参照 |
| TLineInfo | ソースコード位置情報 | fileIndex, line, colを参照 |
| ConfigRef.globalOptions | コンパイラオプション | optDeclaredLocsの有効性確認 |

### テーブル別参照項目詳細

#### PSym型

| 参照項目 | 用途 | 取得条件 |
|---------|------|---------|
| info | 宣言位置情報（TLineInfo） | シンボルが存在する場合 |
| kind | シンボル種別（skVar, skProc等） | toHumanStrで文字列化 |
| name | シンボル名 | 必要に応じて参照 |

#### PType型

| 参照項目 | 用途 | 取得条件 |
|---------|------|---------|
| sym | 型のシンボル情報 | sym != nilの場合に位置情報取得 |
| kind | 型種別（tyInt, tyString等） | toHumanStrで文字列化 |

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | - | 本通知は補助情報であり、エラーではない |

### リトライ仕様

該当なし

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | なし（各メッセージに対して必要に応じて付加） |

### 配信時間帯

制限なし（コンパイル実行時に随時出力）

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

- 本通知はソースコードのファイルパスと行番号を出力するため、ソースコード構造が推測される可能性がある
- CI/CDログで公開される場合、プロジェクト構造の一部が露出する
- 機密性の高いプロジェクトでは、本オプションの使用に注意が必要

## 備考

- Nim 1.5.1で導入された機能
- `--declaredLocs:on`オプションで有効化（デフォルト無効）
- `nimHasDeclaredLocs`シンボルが定義されており、コンパイル時に機能の有無を確認可能
- NotesVerbosity定義により、verbosity:2以下では除外される
- 型ミスマッチエラーでは、actualStr == formalStrの場合（同名の異なる型の場合）に自動的に有効化される
- ソースコードコメントに「xxx figure out how to resolve `tyGenericParam`」とあり、ジェネリックパラメータの解決に関する改善が検討されている

---

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

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

### 推奨読解順序

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

まず、宣言位置情報に関連するデータ構造とオプションを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lineinfos.nim | `compiler/lineinfos.nim` | TMsgKind列挙型のhintDeclaredLoc定義（117行目）、「# since 1.5.1」コメント |
| 1-2 | lineinfos.nim | `compiler/lineinfos.nim` | MsgKindToStr配列のhintDeclaredLocエントリ（246行目）、メッセージテンプレートは「$1」 |
| 1-3 | options.nim | `compiler/options.nim` | optDeclaredLocs定義（96行目）、グローバルオプション |

**読解のコツ**: hintDeclaredLocのメッセージテンプレートは「$1」であり、実際の出力内容はaddDeclaredLoc関数で構築される。

#### Step 2: コア関数を理解する

宣言位置情報を追加するコア関数群を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | astmsgs.nim | `compiler/astmsgs.nim` | addDeclaredLoc関数（10-11行目）、シンボル用 |
| 2-2 | astmsgs.nim | `compiler/astmsgs.nim` | addDeclaredLocMaybe関数（13-15行目）、オプションチェック付き |
| 2-3 | astmsgs.nim | `compiler/astmsgs.nim` | addDeclaredLoc関数（17-25行目）、型用 |
| 2-4 | astmsgs.nim | `compiler/astmsgs.nim` | addTypeNodeDeclaredLoc関数（27-31行目）、型ノード用 |

**主要処理フロー**:
1. **10-11行目**: シンボル用addDeclaredLoc - `" [$1 declared in $2]"` フォーマットで出力
2. **13-15行目**: addDeclaredLocMaybe - optDeclaredLocsチェック後にaddDeclaredLoc呼び出し
3. **17-25行目**: 型用addDeclaredLoc - 型の種別とシンボル位置を出力

#### Step 3: 使用箇所を理解する

addDeclaredLoc系関数の使用箇所を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | types.nim | `compiler/types.nim` | typeMismatch関数（1520-1541行目）、型ミスマッチ時の使用 |
| 3-2 | types.nim | `compiler/types.nim` | getProcHeader関数（148-167行目）、プロシージャヘッダ生成 |
| 3-3 | types.nim | `compiler/types.nim` | addTypeHeader関数（144-146行目）、型ヘッダ生成 |
| 3-4 | semcall.nim | `compiler/semcall.nim` | オーバーロード候補表示（299行目） |

**主要処理フロー**:
- **1525行目**: actualStr == formalStrの場合に自動的にverbose=trueとなり宣言位置が追加
- **1533行目**: actual型の宣言位置を追加
- **1536行目**: formal型の宣言位置を追加

#### Step 4: オプション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | commands.nim | `compiler/commands.nim` | declaredlocsオプション処理（1091-1092行目） |
| 4-2 | lineinfos.nim | `compiler/lineinfos.nim` | computeNotesVerbosity関数（266行目）でhintDeclaredLocがverbosity:2で除外 |
| 4-3 | condsyms.nim | `compiler/condsyms.nim` | nimHasDeclaredLocsシンボル定義（127行目） |

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

```
localError / typeMismatch / etc.
    │
    ├─ addDeclaredLocMaybe (astmsgs.nim:13-15)
    │      │
    │      └─ [optDeclaredLocs in globalOptions の場合]
    │              │
    │              └─ addDeclaredLoc (astmsgs.nim:10-11 or 17-25)
    │                      │
    │                      ├─ sym.kind.toHumanStr → シンボル種別
    │                      └─ toFileLineCol(conf, sym.info) → 位置情報
    │
    └─ getProcHeader / addTypeHeader (types.nim)
            │
            └─ addDeclaredLoc (astmsgs.nim)
```

### データフロー図

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

PSym / PType ───▶ addDeclaredLoc / addDeclaredLocMaybe
                        │
                        ├─ sym.kind → toHumanStr → "proc" / "var" / "type" 等
                        │
                        └─ sym.info → toFileLineCol → "file.nim(10, 5)"
                                │
                                ▼
                        " [proc declared in file.nim(10, 5)]"
                                │
                                ▼
                        エラー/警告メッセージに追記 ───▶ コンソール出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lineinfos.nim | `compiler/lineinfos.nim` | ソース | TMsgKind定義、NotesVerbosity設定 |
| astmsgs.nim | `compiler/astmsgs.nim` | ソース | addDeclaredLoc系関数の定義 |
| options.nim | `compiler/options.nim` | ソース | optDeclaredLocsオプション定義 |
| types.nim | `compiler/types.nim` | ソース | 型関連エラーメッセージ生成、getProcHeader、addTypeHeader |
| commands.nim | `compiler/commands.nim` | ソース | --declaredLocsオプション処理 |
| condsyms.nim | `compiler/condsyms.nim` | ソース | nimHasDeclaredLocsシンボル定義 |
| msgs.nim | `compiler/msgs.nim` | ソース | toFileLineCol関数 |
| semcall.nim | `compiler/semcall.nim` | ソース | オーバーロード候補表示での使用 |
| linter.nim | `compiler/linter.nim` | ソース | スタイルチェックでの使用 |
| semobjconstr.nim | `compiler/semobjconstr.nim` | ソース | オブジェクトコンストラクタでの使用 |
