# 機能設計書 135-ファイルバナー追加

## 概要

本ドキュメントは、Roslynの「ファイルバナー追加（AddFileBanner）」機能の設計を記述する。この機能は、ソースファイルの先頭に著作権表示やライセンス情報などのコメントバナーを追加するリファクタリング機能である。

### 本機能の処理概要

この機能は、プロジェクト内の他のファイルからコメントバナー（ファイルヘッダー）をコピーし、現在編集中のファイルの先頭に追加する。これにより、プロジェクト全体でバナーの一貫性を保つことができる。

**業務上の目的・背景**：
企業やオープンソースプロジェクトでは、ソースファイルの先頭に著作権表示やライセンス情報を記載することが一般的である。新規ファイル作成時や既存ファイルへのバナー追加時に、他ファイルからバナーをコピーする手作業は面倒でミスが発生しやすい。本機能により、一貫したバナーを自動的に追加できる。

**機能の利用シーン**：
- 新規ファイル作成後のバナー追加
- 既存ファイルへのバナー追加
- プロジェクト全体へのバナー一括適用（FixAll）
- コード整形操作の一部として

**主要な処理内容**：
1. 現在ファイルにバナーがないことを確認
2. 同一プロジェクト内の他ファイルからバナーを検索
3. バナーテンプレートの取得（ファイル名のプレースホルダー置換）
4. ファイル先頭へのバナー追加
5. FixAllによるプロジェクト/ソリューション全体への適用

**関連システム・外部連携**：
- EditorConfig：file_header_template設定（設定がある場合はこの機能は無効化）
- IFileBannerFactsService：バナー取得サービス

**権限による制御**：
特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタウィンドウ | 主画面 | Quick Actionsメニューからの実行 |

## 機能種別

コードリファクタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| span | TextSpan | Yes | 選択範囲 | 空のspanまたは先頭位置 |

### 入力データソース

- 対象ドキュメント
- 同一プロジェクト内の他ドキュメント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| banner | ImmutableArray<SyntaxTrivia> | 追加するバナートリビア |
| updatedDocument | Document | バナー追加後のドキュメント |

### 出力先

- 編集後のドキュメント

## 処理フロー

### 処理シーケンス

```
1. ComputeRefactoringsAsync呼び出し
   └─ span.IsEmptyと先頭位置チェック
2. EditorConfig確認
   └─ FileHeaderTemplateが設定されていないことを確認
3. 既存バナー確認
   └─ HasExistingBannerでチェック
4. 他ファイルからバナー検索
   └─ プロジェクト内ファイルを走査
5. CodeAction登録
   └─ バナー発見時にリファクタリング提案
6. CopyBannerAsync実行（ユーザー選択時）
   └─ バナーをコピーして追加
```

### フローチャート

```mermaid
flowchart TD
    A[リファクタリング開始] --> B{span.IsEmpty?}
    B -->|No| Z[終了]
    B -->|Yes| C{FileHeaderTemplate設定あり?}
    C -->|Yes| Z
    C -->|No| D{既存バナーあり?}
    D -->|Yes| Z
    D -->|No| E[他ファイルからバナー検索]
    E --> F{バナー発見?}
    F -->|No| Z
    F -->|Yes| G{GeneratedCode?}
    G -->|Yes| E
    G -->|No| H[CodeAction登録]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-135-01 | EditorConfig優先 | file_header_template設定時はこの機能を無効化 | formattingOptions.FileHeaderTemplateが空でない |
| BR-135-02 | 生成コード除外 | 自動生成ファイルからはバナーを取得しない | IsGeneratedCode == true |
| BR-135-03 | ファイル名置換 | バナー内のファイル名を現在ファイル名に置換 | バナーにファイル名が含まれる場合 |
| BR-135-04 | 先頭位置のみ | ファイル先頭トークンと交差する場合のみ実行 | firstToken.FullSpan.IntersectsWith(position) |

### 計算ロジック

ファイル名プレースホルダー:
- `{filename}`をプレースホルダーとして使用
- ソースファイル名で置換して適用

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

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

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バナー未発見 | プロジェクト内にバナー付きファイルがない | リファクタリングを提案しない |
| - | IO例外 | ファイルパス取得失敗 | IOUtilities.PerformIOで安全に処理 |

### リトライ仕様

リトライは行わない。

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

SyntaxEditorによる原子的な変更適用。

## パフォーマンス要件

- SyntaxEditorBasedCodeRefactoringProviderとして実装
- TryGetSyntaxRootで既存のSyntaxTreeを優先使用（パース回避）
- IsCommentStartCharacterで早期フィルタリング

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

特になし。

## 備考

- FixAllスコープ：Project, Solution
- 新規ドキュメント作成時の自動フォーマットプロバイダーも提供

---

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

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

### 推奨読解順序

#### Step 1: ヘルパークラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AddFileBannerHelpers.cs | `src/Features/Core/Portable/AddFileBanner/` | CopyBannerAsyncメソッド |

**読解のコツ**: ファイル名プレースホルダーの置換ロジックを確認する。

#### Step 2: リファクタリングプロバイダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractAddFileBannerCodeRefactoringProvider.cs | `src/Features/Core/Portable/AddFileBanner/` | リファクタリングプロバイダー基底クラス |

**主要処理フロー**:
1. **33-89行目**: ComputeRefactoringsAsyncでリファクタリング判定
2. **41-46行目**: FileHeaderTemplate設定時の早期リターン
3. **56行目**: HasExistingBannerで既存バナー確認
4. **72-88行目**: 他ファイルからバナー検索
5. **91-96行目**: HasExistingBanner実装
6. **98-107行目**: GetEquivalenceKeyでバナーをキーに変換
7. **148-169行目**: RefactorAllAsyncでFixAll処理

#### Step 3: 新規ドキュメントフォーマットプロバイダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractAddFileBannerNewDocumentFormattingProvider.cs | `src/Features/Core/Portable/AddFileBanner/` | 新規ドキュメント作成時の自動バナー追加 |

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

```
AbstractAddFileBannerCodeRefactoringProvider
    │
    ├─ ComputeRefactoringsAsync
    │      ├─ GetDocumentFormattingOptionsAsync
    │      ├─ HasExistingBanner
    │      │      └─ IFileBannerFactsService.GetFileBanner
    │      └─ TryGetBannerAsync
    │             └─ IFileBannerFactsService.GetFileBanner
    │
    └─ RefactorAllAsync
           └─ AddFileBannerHelpers.CopyBannerAsync

AddFileBannerHelpers
    │
    └─ CopyBannerAsync
           ├─ GetBannerTriviaAsync
           └─ WithPrependedLeadingTrivia
```

### データフロー図

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

他ファイル ───▶ TryGetBannerAsync ───▶ ImmutableArray<SyntaxTrivia>
    │                 │
    │                 ├─ TryGetSyntaxRoot（既存Tree優先）
    │                 └─ ISyntaxFactsService.ParseToken
    │
    ▼
現在ファイル ───▶ WithPrependedLeadingTrivia ───▶ 更新済みDocument
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractAddFileBannerCodeRefactoringProvider.cs | `src/Features/Core/Portable/AddFileBanner/` | ソース | リファクタリングプロバイダー基底クラス |
| AbstractAddFileBannerNewDocumentFormattingProvider.cs | `src/Features/Core/Portable/AddFileBanner/` | ソース | 新規ドキュメントフォーマットプロバイダー |
| AddFileBannerHelpers.cs | `src/Features/Core/Portable/AddFileBanner/` | ソース | ヘルパーメソッド |
| CSharpAddFileBannerCodeRefactoringProvider.cs | `src/Features/CSharp/Portable/AddFileBanner/` | ソース | C#用プロバイダー |
| CSharpAddFileBannerNewDocumentFormattingProvider.cs | `src/Features/CSharp/Portable/AddFileBanner/` | ソース | C#用新規ドキュメントプロバイダー |
