# 機能設計書 98-属性チェック

## 概要

本ドキュメントは、F#コンパイラにおける属性チェック（Attribute Checking）機能について記述する。属性（Attribute）の妥当性検証、ObsoleteAttribute等の特殊属性の処理、および属性引数の評価を行う。

### 本機能の処理概要

**業務上の目的・背景**：属性はメタデータとしてコード要素に付与され、コンパイラの動作変更、ランタイム動作の制御、ドキュメント生成等に利用される。属性チェック機能は、属性の正しい使用を検証し、ObsoleteやExperimental等の属性に基づく警告・エラーを生成する。

**機能の利用シーン**：
- Obsolete属性による非推奨警告の表示
- Experimental属性による実験的機能の警告
- CompilerMessage属性によるコンパイラメッセージの表示
- カスタム属性の妥当性検証
- 属性引数の評価と検証

**主要な処理内容**：
1. Obsolete属性のチェック - 非推奨APIの使用警告
2. Experimental属性のチェック - 実験的機能の警告
3. CompilerMessage属性のチェック - カスタムコンパイラメッセージ
4. 属性引数の評価 - 定数式の評価
5. 属性の適用先検証 - AttributeUsage属性に基づく検証

**関連システム・外部連携**：名前解決（NameResolution.fs）から呼び出され、型やメンバーの使用時に属性をチェックする。IDEのIntelliSenseで非推奨マークの表示にも利用される。

**権限による制御**：該当なし（コンパイラ内部機能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | IDE統合 | 参照画面 | Obsolete警告、取り消し線表示 |

## 機能種別

属性検証

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g | TcGlobals | Yes | グローバルコンパイラ設定 | - |
| attribs | Attribs | Yes | 検証対象の属性リスト | - |
| m | range | Yes | ソースコード上の位置 | - |

### 入力データソース

型チェッカー、名前解決からの属性情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | OperationResult<unit> | 検証結果（警告/エラーを含む） |

### 出力先

コンパイラ診断出力

## 処理フロー

### 処理シーケンス

```
1. 属性の取得
   ├─ F#属性（Attrib型）
   └─ IL属性（ILAttribute型）

2. Obsolete属性チェック
   ├─ メッセージの取得
   ├─ IsError フラグの確認
   └─ DiagnosticId/UrlFormat の取得

3. Experimental属性チェック
   ├─ メッセージの取得
   └─ 警告の生成

4. CompilerMessage属性チェック
   ├─ メッセージとコードの取得
   ├─ IsError/IsHidden フラグの確認
   └─ 警告/エラーの生成

5. 属性引数の評価
   ├─ 定数式の評価
   └─ 型チェック
```

### フローチャート

```mermaid
flowchart TD
    A[属性付き要素の使用] --> B{属性チェック}
    B --> C[Obsolete属性?]
    C -->|Yes| D{IsError?}
    D -->|Yes| E[エラー生成]
    D -->|No| F[警告生成]
    C -->|No| G[Experimental属性?]
    G -->|Yes| H[警告生成]
    G -->|No| I[CompilerMessage属性?]
    I -->|Yes| J[メッセージ生成]
    I -->|No| K[チェック完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-98-1 | ObsoleteError | IsError=trueの場合はエラー | Obsolete属性 |
| BR-98-2 | ObsoleteWarning | IsError=falseの場合は警告 | Obsolete属性 |
| BR-98-3 | ExperimentalPreview | --langversion:previewで抑制可能 | Experimental属性 |
| BR-98-4 | CompilerMessageHidden | IsHiddenの場合はIntelliSenseから隠す | CompilerMessage属性 |

### 計算ロジック

該当なし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FS0044 | Obsolete | Obsolete属性付き要素の使用 | 代替APIを使用 |
| FS0052 | Experimental | Experimental属性付き要素の使用 | --langversion:previewを使用 |
| - | CompilerMessage | CompilerMessage属性 | 属性指定のコードで報告 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

属性チェックのオーバーヘッドは無視できる程度であること

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

該当なし

## 備考

`#nowarn "44"`でObsolete警告を抑制できる。`--warnaserror:44`でエラーに昇格できる。

---

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

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

### 推奨読解順序

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

属性情報を保持する型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AttributeChecking.fs | `src/Compiler/Checking/AttributeChecking.fs` | AttribInfo型、各種チェック関数 |

**主要な型定義**:
- **77-126行目**: AttribInfo - 属性情報を抽象化するラッパー型
- **27-52行目**: evalILAttribElem, evalFSharpAttribArg - 属性引数の評価

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

属性チェックの主要な関数を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AttributeChecking.fs | `src/Compiler/Checking/AttributeChecking.fs` | CheckFSharpAttributes, CheckILAttributes |

**主要処理フロー**:
- **278-318行目**: CheckILObsoleteAttributes - IL属性のObsoleteチェック
- **335-362行目**: CheckObsoleteAttributes - F#属性のObsoleteチェック
- **385-400行目**: CheckFSharpExperimentalAttribute - Experimentalチェック
- **412-420行目**: CheckFSharpAttributes - F#属性の総合チェック

#### Step 3: 呼び出し元を理解する

属性チェックがどこから使われるかを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | 名前解決時の属性チェック呼び出し |
| 3-2 | CheckExpressions.fs | `src/Compiler/Checking/CheckExpressions.fs` | 式チェック時の属性チェック呼び出し |

**読解のコツ**:
- AttribInfoはF#属性（FSAttribInfo）とIL属性（ILAttribInfo）を統一的に扱う
- trackErrorsコンピュテーション式で複数のチェックを連鎖
- DiagnosticId/UrlFormatはF# 5.0以降で追加された診断拡張

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

```
NameResolution.fs / CheckExpressions.fs
    │
    └─ AttributeChecking.fs
           │
           ├─ CheckFSharpAttributes
           │      ├─ CheckObsoleteAttributes
           │      ├─ CheckCompilerMessageAttribute
           │      ├─ CheckFSharpExperimentalAttribute
           │      └─ CheckUnverifiableAttribute
           │
           ├─ CheckILAttributes
           │      ├─ CheckILObsoleteAttributes
           │      └─ CheckILExperimentalAttributes
           │
           └─ AttribInfo
                  ├─ FSAttribInfo: F#属性
                  ├─ ILAttribInfo: IL属性
                  ├─ TyconRef: 属性の型参照
                  ├─ ConstructorArguments: コンストラクタ引数
                  └─ NamedArguments: 名前付き引数
```

### データフロー図

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

属性付き要素 ───▶ AttributeChecking ───▶ 診断メッセージ
(Type/Member)          │
                       ▼
              ┌──────────────────┐
              │ Obsolete確認      │
              │ Experimental確認  │
              │ CompilerMessage確認│
              └──────────────────┘
                       │
                       ▼
              ┌──────────────────┐
              │ FS0044: Obsolete │
              │ FS0052: Experimental│
              │ カスタムメッセージ │
              └──────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AttributeChecking.fs | `src/Compiler/Checking/AttributeChecking.fs` | ソース | 属性チェック実装 |
| AttributeChecking.fsi | `src/Compiler/Checking/AttributeChecking.fsi` | ソース | 公開シグネチャ |
| NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | ソース | 呼び出し元 |
| CheckExpressions.fs | `src/Compiler/Checking/CheckExpressions.fs` | ソース | 呼び出し元 |
| TcGlobals.fs | `src/Compiler/Checking/TcGlobals.fs` | ソース | 組み込み属性の定義 |
