# 機能設計書 75-コード解析

## 概要

本ドキュメントは、Nushellのコード解析機能の設計仕様を定義する。ast、view ir、view source、view spanコマンドは、Nushellコードの内部表現を解析・表示する機能を提供する。

### 本機能の処理概要

コード解析機能は、Nushellスクリプトやコマンドの内部表現（AST、IR、ソースコード）を可視化し、開発者がコードの動作を深く理解できるようにする機能群である。パーサーの出力、コンパイル済みIR、ソースコードの参照が可能。

**業務上の目的・背景**：Nushellのコードがどのようにパースされ、コンパイルされるかを理解することは、高度なスクリプト開発やデバッグに不可欠である。本機能により、構文解析結果やコンパイル済みコードを直接確認でき、パフォーマンス最適化やバグ解析に活用できる。

**機能の利用シーン**：
- パーサーがコードをどのように解釈しているか確認したい場合
- IR（Intermediate Representation）レベルでの動作を確認したい場合
- カスタムコマンドやモジュールのソースコードを表示したい場合
- エラー発生箇所のスパン情報を確認したい場合

**主要な処理内容**：
1. `ast`：パイプラインの抽象構文木（AST）を表示
2. `view ir`：コンパイル済みIRコードを表示
3. `view source`：コマンド、モジュール、エイリアスのソースコードを表示
4. `view span`：スパン情報に対応するソースコードを表示

**関連システム・外部連携**：
- nu-parserクレート：AST生成、flatten_block関数
- nu-protocolクレート：IrBlock、ブロック情報

**権限による制御**：特になし。全ユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 主画面 | コード解析コマンドの実行と結果表示 |

## 機能種別

コード解析・デバッグ機能

## 入力仕様

### 入力パラメータ

#### ast

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pipeline | String | Yes | ASTを表示するパイプライン | - |
| --json (-j) | switch | No | JSON形式でシリアライズ | - |
| --minify (-m) | switch | No | 出力を圧縮 | - |
| --flatten (-f) | switch | No | 読みやすいフラット表示 | - |

#### view ir

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| target | Any | Yes | コマンド名、クロージャ、ブロックID | - |
| --json (-j) | switch | No | JSON形式でダンプ | - |
| --decl-id (-d) | switch | No | 整数を宣言IDとして扱う | - |

#### view source

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| item | Any | Yes | 表示するコマンド名、モジュール名、クロージャ | - |

### 入力データソース

- パイプライン文字列（astコマンド）
- EngineState（view ir、view sourceコマンド）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast出力 | Record/Table/String | AST情報（block, error） |
| view ir出力 | String | フォーマット済みIRコード |
| view source出力 | String | ソースコード（メタデータ付き） |

### 出力先

標準出力（パイプライン出力）

## 処理フロー

### 処理シーケンス

```
1. ast コマンド
   └─ StateWorkingSetを作成
   └─ parse()でパイプラインを解析
   └─ flatten指定時: flatten_block()でトークン抽出
   └─ 通常: ブロックとエラーを出力

2. view ir コマンド
   └─ targetの種類を判定（クロージャ/文字列/整数）
   └─ ブロックIDを取得
   └─ IrBlockを取得
   └─ フォーマット済みIRを出力

3. view source コマンド
   └─ 引数の種類を判定（整数/文字列/クロージャ）
   └─ ブロック/モジュール/エイリアスを検索
   └─ スパンからソースコードを取得
   └─ メタデータ（ファイルパス）を付加して出力
```

### フローチャート

```mermaid
flowchart TD
    A[コード解析コマンド] --> B{コマンド種別?}

    B -->|ast| C[StateWorkingSet作成]
    C --> D[parse実行]
    D --> E{--flatten?}
    E -->|Yes| F[flatten_block]
    F --> G{--json?}
    G -->|Yes| H[JSON出力]
    G -->|No| I[Table出力]
    E -->|No| J[ブロック+エラー出力]

    B -->|view ir| K{target種別?}
    K -->|Closure| L[val.block_id取得]
    K -->|String| M[find_decl → block_id]
    K -->|Int| N[BlockId/DeclId変換]
    L --> O[IrBlock取得]
    M --> O
    N --> O
    O --> P{--json?}
    P -->|Yes| Q[JSON出力]
    P -->|No| R[フォーマット出力]

    B -->|view source| S{item種別?}
    S -->|Int| T[ブロックID検索]
    S -->|String| U[コマンド/モジュール検索]
    S -->|Closure| V[クロージャのブロック取得]
    T --> W[スパンからソース取得]
    U --> W
    V --> W
    W --> X[メタデータ付加]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-1 | flatten出力 | content, shape, spanの3カラムで出力 | ast --flatten指定時 |
| BR-75-2 | span_source埋め込み | JSON出力時にスパンにソースコードを埋め込む | ast --json指定時 |
| BR-75-3 | 内部コマンド拒否 | 内部コマンドはソースコードを持たない | view ir/view source実行時 |
| BR-75-4 | メタデータ付加 | view sourceはファイルパスをメタデータに含める | ソースコードがファイル由来の場合 |

### 計算ロジック

特になし

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

該当なし（本機能はデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | GenericError | 内部コマンドのIR/ソース表示を試みた | 「internal commands don't have Nushell source code」 |
| - | GenericError | 無効なブロックID | 「ensure the block ID is correct」 |
| - | GenericError | コンパイルエラーでIRがない | 「block is missing compiled representation」 |
| - | CantConvert | JSON変換失敗 | エラーメッセージを返却 |

### リトライ仕様

リトライは行わない。

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

該当なし

## パフォーマンス要件

特になし

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

- ソースコードの表示は、現在のセッションで読み込まれたコードに限定
- カスタムコマンドのソースコードが第三者に見られる可能性がある

## 備考

- view irの出力はdebug profileコマンドと合わせて使用すると効果的
- astコマンドの--flatten出力はシンタックスハイライターの実装に使用可能

---

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

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

### 推奨読解順序

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

AST、IR、Spanの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ast.rs | `crates/nu-command/src/debug/ast.rs` | flatten出力の構造（content, shape, span） |
| 1-2 | view_ir.rs | `crates/nu-command/src/debug/view_ir.rs` | IrBlockの表示形式 |

**読解のコツ**: flatten出力はパーサーの内部で使用される(Span, FlatShape)のペアを人間が読みやすい形式に変換している。

#### Step 2: 各コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ast.rs | `crates/nu-command/src/debug/ast.rs` | ASTコマンドの3種類の出力モード |
| 2-2 | view_ir.rs | `crates/nu-command/src/debug/view_ir.rs` | view irコマンド - ターゲット種別の判定 |
| 2-3 | view_source.rs | `crates/nu-command/src/debug/view_source.rs` | view sourceコマンド - ソース取得とメタデータ |

**主要処理フロー** (ast.rs):
- **156-158行目**: StateWorkingSetの作成とparse実行
- **161-217行目**: --flatten時のトークン抽出とJSON/Table出力
- **219-310行目**: 通常時のブロック+エラー出力

**主要処理フロー** (view_ir.rs):
- **62-124行目**: ターゲット種別の判定（クロージャ/文字列/整数）
- **136-145行目**: IrBlockの取得
- **147-173行目**: JSON/フォーマット出力の分岐

**主要処理フロー** (view_source.rs):
- **84-112行目**: 整数（ブロックID）の場合
- **114-286行目**: 文字列（コマンド/モジュール名）の場合
- **324-352行目**: make_output関数 - メタデータ付加

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

```
Ast::run (ast.rs)
    ├─ StateWorkingSet::new()
    ├─ parse()
    │
    ├─ --flatten時:
    │      └─ flatten_block()
    │             └─ JSON出力 または Table出力
    │
    └─ 通常時:
           └─ serde_json::to_string()
                  └─ embed_span_sources()

ViewIr::run (view_ir.rs)
    ├─ target種別判定
    │      ├─ Closure: val.block_id
    │      ├─ String: find_decl() → block_id()
    │      └─ Int: BlockId::new() / DeclId::new()
    │
    ├─ engine_state.try_get_block()
    │
    └─ ir_block.display() または JSON出力

ViewSource::run (view_source.rs)
    ├─ item種別判定
    │      ├─ Int: try_get_block()
    │      ├─ String: find_decl() / find_module()
    │      └─ Closure: get_block()
    │
    ├─ get_span_contents()
    │
    └─ make_output()
           └─ PipelineMetadata設定
```

### データフロー図

```
[ast]
String (パイプライン) ───▶ parse() ───▶ Block ───▶ Record/Table/String
                                            │
                                            ├─ flatten: トークン列
                                            └─ 通常: ブロック+エラー

[view ir]
コマンド名/クロージャ/ID ───▶ ブロック取得 ───▶ IrBlock ───▶ String

[view source]
コマンド名/モジュール名 ───▶ スパン取得 ───▶ ソースコード ───▶ String + Metadata
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ast.rs | `crates/nu-command/src/debug/ast.rs` | ソース | astコマンド |
| view_ir.rs | `crates/nu-command/src/debug/view_ir.rs` | ソース | view irコマンド |
| view_source.rs | `crates/nu-command/src/debug/view_source.rs` | ソース | view sourceコマンド |
| view_span.rs | `crates/nu-command/src/debug/view_span.rs` | ソース | view spanコマンド |
| view_blocks.rs | `crates/nu-command/src/debug/view_blocks.rs` | ソース | view blocksコマンド |
| view_files.rs | `crates/nu-command/src/debug/view_files.rs` | ソース | view filesコマンド |
| mod.rs | `crates/nu-command/src/debug/mod.rs` | ソース | debugモジュール定義 |
