# 機能設計書 40-DScanner設定取得 (served/getDscannerConfig)

## 概要

本ドキュメントは、指定ドキュメントに対する現在のD-Scanner設定（有効/無効なチェック項目）を返却するserved/getDscannerConfigリクエストの設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：D-Scannerは多数の静的解析チェック項目を持ち、プロジェクトごとにdscanner.iniファイルで設定をカスタマイズできる。本機能はクライアントに対して現在のD-Scanner設定を提供し、設定UIの構築やデバッグに利用できるようにする。

**機能の利用シーン**：クライアントがD-Scannerの設定を確認・表示したい場合に使用する。例えば、エディタの設定パネルでD-Scannerのチェック項目の有効/無効状態を一覧表示する場合など。

**主要な処理内容**：
1. パラメータからテキストドキュメントを特定する
2. DscannerComponentのインスタンスを取得する
3. ドキュメントに対応するdscanner.iniファイルのパスを解決する
4. DscannerComponent.getConfig でini設定を読み込む
5. 設定を DScannerIniSection/DScannerIniFeature 形式に変換して返却する

**関連システム・外部連携**：DscannerComponent（workspace-dサブパッケージ）がdscanner.iniの読み込みを担当する。dscanner.iniファイルはD-Scannerの静的解析設定ファイルである。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | DScanner設定取得（served/getDscannerConfig） | 主画面 | 指定ドキュメントに対する現在のD-Scanner設定を返却 |

## 機能種別

設定情報取得処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| params.textDocument | TextDocumentIdentifier | Yes | 対象ドキュメントの識別子（URI） | - |

### 入力データソース

LSPクライアントからの `served/getDscannerConfig` リクエスト。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | DScannerIniSection[] | D-Scanner設定セクションの配列（通常1要素） |
| DScannerIniSection.description | string | セクションの説明文 |
| DScannerIniSection.name | string | セクション名 |
| DScannerIniSection.features | DScannerIniFeature[] | チェック項目一覧 |
| DScannerIniFeature.description | string | チェック項目の説明文 |
| DScannerIniFeature.name | string | チェック項目名 |
| DScannerIniFeature.enabled | string | 状態（"enabled", "disabled", "skip-unittest"等） |

### 出力先

LSPクライアントへのレスポンスとして返却する。

## 処理フロー

### 処理シーケンス

```
1. DscannerComponentインスタンス取得
   └─ backend.getBestInstance!DscannerComponent で取得
   └─ 取得できない場合はnullを返却
2. dscanner.iniパス解決
   └─ params.textDocument.uri が指定されている場合:
     └─ getDscannerIniForDocument で対応するini取得
   └─ 指定されていない場合:
     └─ デフォルト "dscanner.ini" を使用
3. 設定読み込み
   └─ instance.get!DscannerComponent.getConfig(ini) で設定を取得
4. DScannerIniSection形式に変換
   └─ __traits(getAttributes, ...) でセクションの description と name を取得
   └─ config.tupleof を反復して、string型のフィールドを DScannerIniFeature に変換
   └─ __traits(getAttributes, ...) でフィールドの description を取得
   └─ __traits(identifier, ...) でフィールド名を取得
   └─ フィールド値を enabled に設定
5. 結果返却
   └─ [sec] を単一要素配列として返却
```

### フローチャート

```mermaid
flowchart TD
    A["served/getDscannerConfig リクエスト受信"] --> B{DscannerComponent利用可能?}
    B -->|No| C[null を返却]
    B -->|Yes| D[dscanner.iniパス解決]
    D --> E["DscannerComponent.getConfig(ini)"]
    E --> F[DScannerIniSection形式に変換]
    F --> G["[DScannerIniSection] を返却"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-40-01 | DScanner必須 | DscannerComponentが利用不可の場合はnullを返却 | 常時 |
| BR-40-02 | iniパス解決 | テキストドキュメントが指定されている場合はそのドキュメントに対応するdscanner.iniを使用 | URI指定時 |
| BR-40-03 | デフォルトini | URIが空の場合はデフォルト "dscanner.ini" を使用 | URI未指定時 |
| BR-40-04 | string型フィルタ | config構造体のstring型フィールドのみをfeatureとして出力 | 常時 |

### 計算ロジック

特になし。設定ファイルの読み込みとD言語のコンパイル時リフレクション（__traits）による型情報取得のみ。

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

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

本機能にデータベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | コンポーネント未初期化 | DscannerComponentが利用不可 | nullを返却 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要（読み取り専用処理）。

## パフォーマンス要件

dscanner.iniファイルの読み込みのみであり、即座に応答可能。

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

特になし。ローカル設定ファイルの読み取りのみ。

## 備考

- D言語の `__traits(getAttributes, ...)` を使用してコンパイル時にStructural Analysis Configの属性情報（description, name）を取得している。これはD-Scannerの設定構造体のメタデータ。
- DScannerIniSection/DScannerIniFeature型はserved.lsp.protoextモジュールで定義されている。
- getDscannerIniForDocument関数はNo.35「DScanner静的解析」でも使用される共通関数。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | DScannerIniSection構造体（258行目）、DScannerIniFeature構造体（269行目）を確認 |
| 1-2 | protoext.d | `source/served/lsp/protoext.d` | SimpleTextDocumentIdentifierParams構造体（92行目）を確認 |

**読解のコツ**: DScannerIniFeatureのenabledフィールドはstring型で、"enabled", "disabled", "skip-unittest"等の値を取る。bool型ではないことに注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.d | `source/served/extension.d` | `getDscannerConfig` 関数（1189-1224行目）がserved/getDscannerConfigリクエストハンドラ |

**主要処理フロー**:
1. **1189行目**: `@protocolMethod("served/getDscannerConfig")` でLSPメソッド登録
2. **1190行目**: パラメータ型は `SimpleTextDocumentIdentifierParams`
3. **1194-1195行目**: `backend.getBestInstance!DscannerComponent` でインスタンス取得
4. **1197-1198行目**: インスタンスがなければnull返却
5. **1200-1202行目**: dscanner.iniパス解決（URI指定ありの場合getDscannerIniForDocument使用）
6. **1204行目**: `instance.get!DscannerComponent.getConfig(ini)` で設定読み込み
7. **1207-1208行目**: `__traits(getAttributes, ...)` でセクションのdescription/name取得
8. **1211-1219行目**: `config.tupleof` 反復でstring型フィールドをDScannerIniFeatureに変換
9. **1223行目**: `[sec]` を単一要素配列で返却

#### Step 3: 共通関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dscanner.d | `source/served/linters/dscanner.d` | `getDscannerIniForDocument`（121-133行目）- インスタンスcwd/dscanner.iniの存在チェック |

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

```
getDscannerConfig (extension.d:1189)
    |
    +-- backend.getBestInstance!DscannerComponent
    |
    +-- getDscannerIniForDocument (dscanner.d:121)
    |       └─ buildPath(instance.cwd, "dscanner.ini") 存在チェック
    |
    +-- DscannerComponent.getConfig(ini)
    |       └─ dscanner.ini読み込み・パース
    |
    +-- __traits(getAttributes, ...) (メタデータ取得)
    |
    +-- config.tupleof (フィールド反復)
            └─ DScannerIniFeature[] 構築
```

### データフロー図

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

SimpleTextDocumentIdentifierParams ──▶ getDscannerConfig()       ──▶ DScannerIniSection[]
  .textDocument.uri                     |                                .description
                                        +-- dscanner.ini解決             .name
                                        +-- getConfig(ini)               .features[]
                                        +-- __traits メタデータ取得          .description
                                        +-- tupleof フィールド反復           .name
                                                                          .enabled
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.d | `source/served/extension.d` | ソース | getDscannerConfig関数（リクエストハンドラ） |
| protoext.d | `source/served/lsp/protoext.d` | ソース | DScannerIniSection/DScannerIniFeature/SimpleTextDocumentIdentifierParams型定義 |
| dscanner.d (linters) | `source/served/linters/dscanner.d` | ソース | getDscannerIniForDocument共通関数 |
| dscanner.d (workspace-d) | `workspace-d/source/workspaced/com/dscanner.d` | ソース | DscannerComponent.getConfig実装 |
| types.d | `source/served/types.d` | ソース | 共通型定義 |
