# 機能設計書 49-MSBuildタスク（Fsi）

## 概要

本ドキュメントは、F#ビルドシステムにおけるMSBuild用F# Interactive（fsi.exe）タスクの機能設計を記述する。

### 本機能の処理概要

Fsiタスクは、MSBuildからF# Interactive（fsi.exe）を呼び出すためのタスク実装である。F#スクリプトの実行やインタラクティブなコード評価をMSBuildワークフロー内で実行可能にする。

**業務上の目的・背景**：ビルドプロセスの一部としてF#スクリプトを実行する必要がある場合や、コード生成やテストスクリプトをビルド時に実行する場合に使用される。FsiタスクはMSBuildとF# Interactiveを接続するブリッジとして機能する。

**機能の利用シーン**：
- ビルド時のスクリプト実行
- コード生成スクリプトの実行
- プリビルド/ポストビルドスクリプト
- テストスクリプトの実行

**主要な処理内容**：
1. MSBuildプロパティからインタラクティブオプションの受け取り
2. コマンドラインの生成
3. fsi.exeの実行またはホストオブジェクト経由の実行
4. 実行結果のMSBuildへの報告

**関連システム・外部連携**：MSBuild、fsi.exe、Visual Studioホストオブジェクト

**権限による制御**：特になし

## 関連画面

本機能はビルドシステム機能のため、直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

ビルドタスク / スクリプト実行

## 入力仕様

### 入力パラメータ

主要なプロパティ:

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Sources | ITaskItem[] | Yes | 実行するソースファイル | - |
| References | ITaskItem[] | No | 参照アセンブリ一覧 | - |
| LoadSources | ITaskItem[] | No | --loadで読み込むスクリプト | - |
| UseSources | ITaskItem[] | No | --useで実行するスクリプト | - |
| CodePage | string | No | ソースファイルのコードページ | - |
| DefineConstants | ITaskItem[] | No | 条件付きコンパイルシンボル | - |
| DisabledWarnings | string | No | 無効化する警告 | - |
| LangVersion | string | No | 言語バージョン | - |
| NoFramework | bool | No | フレームワーク参照を除外 | - |
| Optimize | bool | No | 最適化有効化 | - |
| OtherFlags | string | No | その他のフラグ | - |
| FsiExec | bool | No | --execフラグの追加 | - |

### 入力データソース

MSBuildプロジェクトファイルからのプロパティ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 終了コード（0: 成功、非0: 失敗） |
| CommandLineArgs | ITaskItem[] | 生成されたコマンドライン引数 |
| TextOutput | string | キャプチャされた出力テキスト |

### 出力先

コンソール出力、キャプチャされたテキスト

## 処理フロー

### 処理シーケンス

```
1. MSBuildからタスク呼び出し
   └─ Execute()メソッドが呼ばれる
2. コマンドライン生成
   └─ GenerateResponseFileCommands()でオプションを生成
3. スクリプト実行
   └─ ExecuteTool()またはHostObject経由で実行
4. 出力のキャプチャ
   └─ CaptureTextOutputがtrueの場合
5. 結果の返却
   └─ 終了コードをMSBuildに返す
```

### フローチャート

```mermaid
flowchart TD
    A[MSBuildからの呼び出し] --> B[Execute]
    B --> C[GenerateCommandLineCommands]
    C --> D[GenerateResponseFileCommands]
    D --> E{SkipCompilerExecution?}
    E -->|Yes| F[コマンドライン引数を出力のみ]
    E -->|No| G{HostObjectあり?}
    G -->|Yes| H[HostObject.Compile呼び出し]
    G -->|No| I[fsi.exe実行]
    I --> J{CaptureTextOutput?}
    J -->|Yes| K[出力をキャプチャ]
    J -->|No| L[完了]
    F --> L
    H --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 警告76をエラー化 | HashReference関連警告を常にエラーに | 常時 |
| BR-02 | ホストオブジェクト優先 | Visual Studio内ではHostObjectを使用 | HostObject存在時 |
| BR-03 | 出力バッファリング | BufferLimitで出力をバッファ制限 | CaptureTextOutput時 |

### 計算ロジック

コマンドラインオプションの対応:
| プロパティ | コマンドラインオプション |
|-----------|------------------------|
| CodePage | --codepage: |
| LangVersion | --langversion: |
| NoFramework=true | --noframework |
| DefineConstants | --define: |
| Optimize=true | --optimize+ |
| Tailcalls=false | --tailcalls- |
| References | -r: |
| DisabledWarnings | --nowarn: |
| WarningLevel | --warn: |
| LoadSources | --load: |
| UseSources | --use: |
| FsiExec=true | --exec |

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidOperationException | 実行時エラー | ToolPathが未設定 | F# Interactiveをインストール |
| TargetInvocationException | 実行時エラー | ビルドキャンセル | 再実行 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- YieldDuringToolExecution=trueで並列ビルドを最適化
- BufferLimitで出力バッファサイズを制限可能

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

- スクリプトの実行には注意が必要
- 信頼できないスクリプトを実行しないこと

## 備考

FsiタスクはFscタスクと同様にToolTaskを継承しているが、コンパイルではなくスクリプト実行を目的としている。

---

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

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

### 推奨読解順序

#### Step 1: クラス構造を理解する

Fsiタスククラスの全体構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **20-22行目**: Fsiクラス定義とToolTask継承 |
| 1-2 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **24-64行目**: プライベートフィールド定義 |

**読解のコツ**: Fscと同様の構造だが、スクリプト実行特有のオプション（LoadSources, UseSources, FsiExec）がある。

#### Step 2: プロパティを理解する

公開プロパティがMSBuildプロパティと対応する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **188-190行目**: CodePageプロパティ |
| 2-2 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **264-267行目**: Sourcesプロパティ |
| 2-3 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **256-258行目**: LoadSourcesプロパティ |

**主要プロパティ一覧**:
- **206-208行目**: FsiExec
- **224-226行目**: Optimize
- **245-248行目**: References
- **282-285行目**: UseSources

#### Step 3: コマンドライン生成を理解する

generateCommandLineBuilder関数によるコマンドライン構築を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **69-157行目**: generateCommandLineBuilder関数 |
| 3-2 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **72-74行目**: codepageの処理 |
| 3-3 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **109-113行目**: warningsAsErrorsの処理 |

**主要処理フロー**:
- **70行目**: FSharpCommandLineBuilderを作成
- **72行目**: --codepage:オプション追加
- **82-85行目**: Optimizeで--optimize+/-を追加
- **109-113行目**: 警告76をエラーに追加

#### Step 4: 出力キャプチャを理解する

テキスト出力のキャプチャ機能を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **159-162行目**: bufferLimitとtextOutput |
| 4-2 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **164-172行目**: LogEventsFromTextOutputオーバーライド |
| 4-3 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **180-185行目**: TextOutputプロパティ |

#### Step 5: 実行処理を理解する

ExecuteToolなどの実行処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **339-398行目**: ExecuteToolメソッド |
| 5-2 | Fsi.fs | `src/FSharp.Build/Fsi.fs` | **400-412行目**: GenerateResponseFileCommands |

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

```
MSBuild (Fsiタスク呼び出し)
    │
    ├─ Fsi.Execute() (ToolTaskから継承)
    │      │
    │      ├─ GenerateCommandLineCommands()
    │      │      └─ dotnetFsiCompilerPathの設定
    │      │
    │      ├─ GenerateResponseFileCommands()
    │      │      └─ generateCommandLineBuilder()
    │      │             ├─ AppendSwitchIfNotNull("--codepage:", ...)
    │      │             ├─ AppendSwitch("--optimize+/-")
    │      │             ├─ AppendSwitchIfNotNull("--load:", ...)
    │      │             ├─ AppendSwitchIfNotNull("--use:", ...)
    │      │             └─ AppendSwitch("--exec")
    │      │
    │      └─ ExecuteTool()
    │             │
    │             ├─ provideCommandLineArgs → CommandLineArgs出力
    │             │
    │             ├─ skipCompilerExecution → 0返却
    │             │
    │             └─ HostObject確認
    │                    │
    │                    ├─ あり → HostObject.Compile()
    │                    │
    │                    └─ なし → base.ExecuteTool()
    │                              └─ fsi.exe プロセス実行
    │
    └─ 終了コード返却
```

### データフロー図

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

スクリプトファイル ───▶  MSBuild             ───▶  Fsiタスクプロパティ
  .fsx                   (プロパティ評価)            Sources, LoadSources等
    │
    ▼
プロパティ      ───▶  generateCommandLine  ───▶  コマンドライン
  値一覧               Builder                    --load:... --use:...
    │
    ▼
fsi.exe/        ───▶  ExecuteTool         ───▶  実行結果
HostObject            (スクリプト実行)            TextOutput, 終了コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Fsi.fs | `src/FSharp.Build/Fsi.fs` | ソース | Fsiタスク実装 |
| Fsc.fs | `src/FSharp.Build/Fsc.fs` | ソース | Fscタスク実装（類似構造） |
| FSharpCommandLineBuilder.fs | `src/FSharp.Build/FSharpCommandLineBuilder.fs` | ソース | コマンドラインビルダー |
