# 機能設計書 30-TypeInfo

## 概要

本ドキュメントは、Symfony TypeInfoコンポーネントの機能設計を記述する。このコンポーネントはPHPの型情報を表現・解析するための型システムを提供し、リフレクションやPHPDocから型情報を抽出・表現する。

### 本機能の処理概要

**業務上の目的・背景**：PHPの型システムは複雑であり、プリミティブ型、クラス型、ユニオン型、交差型、ジェネリック型、null許容型など多様な型表現が存在する。TypeInfoコンポーネントは、これらの型情報を統一的なオブジェクトモデルで表現し、型の判定・比較・変換を安全に行えるようにする。PropertyInfo、Serializer、JsonStreamer等の多くのコンポーネントの基盤として機能する。

**機能の利用シーン**：PropertyInfoでのプロパティ型情報の表現、Serializerでの型に基づくデシリアライゼーション、JsonStreamerでのコード生成時の型解析、Validatorでの型ベースの制約判定、FrameworkBundleでの型情報キャッシュ。

**主要な処理内容**：
1. Typeクラス階層による型の表現（BuiltinType, ObjectType, CollectionType, UnionType, IntersectionType, NullableType, GenericType等）
2. TypeIdentifier列挙型によるPHPネイティブ型の識別（array, bool, int, float, string, object, null等）
3. TypeResolverによるリフレクション（パラメータ、プロパティ、戻り値）からの型解析
4. StringTypeResolverによるPHPDoc文字列からの型解析
5. TypeFactoryTraitによる静的ファクトリメソッド群（Type::int(), Type::string(), Type::object(), Type::list(), Type::nullable()等）
6. TypeContextFactoryによるジェネリクス解決のためのクラス型コンテキスト管理
7. Type::isSatisfiedBy()による型の仕様充足判定（WrappingType、CompositeTypeの再帰的評価）
8. Type::accepts()による値の型受け入れ判定

**関連システム・外部連携**：PropertyInfo（型情報の表現先）、Serializer（デシリアライゼーション型判定）、JsonStreamer（コード生成時の型解析）、Validator（型ベース制約）と連携する。

**権限による制御**：直接的な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （直接的な画面関連なし） | - | バックエンド型情報処理 |

## 機能種別

基盤ライブラリ / 型情報表現・解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| subject | ReflectionParameter/ReflectionProperty/ReflectionFunctionAbstract/string | Yes | 型解析対象 | 有効なリフレクションオブジェクトまたはクラス名 |
| typeString | string | Yes（StringTypeResolver） | PHPDoc型文字列 | 有効なPHP型文字列 |

### 入力データソース

PHPリフレクション情報、PHPDocコメント、文字列型表現

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Type | Type | 解析された型情報オブジェクト |
| isSatisfiedBy | bool | 型仕様充足判定結果 |
| isIdentifiedBy | bool | 型識別子による判定結果 |
| isNullable | bool | null許容性判定結果 |
| accepts | bool | 値の型受け入れ判定結果 |

### 出力先

PHP値（Typeオブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 型解析（TypeResolver::resolve）
   └─ リフレクションオブジェクトから型情報を抽出
   └─ ReflectionNamedType, ReflectionUnionType, ReflectionIntersectionTypeを処理
2. 文字列型解析（StringTypeResolver::resolve）
   └─ PHPStan PhpDocParserを使用してPHPDoc文字列を解析
3. 型オブジェクト構築
   └─ TypeFactoryTraitの静的メソッドで型オブジェクトを構築
4. 型判定
   └─ isSatisfiedBy()でWrappingType/CompositeTypeを再帰的に評価
```

### フローチャート

```mermaid
flowchart TD
    A[TypeResolver::resolve] --> B{入力型}
    B -->|ReflectionParameter| C[ReflectionParameterTypeResolver]
    B -->|ReflectionProperty| D[ReflectionPropertyTypeResolver]
    B -->|ReflectionFunction| E[ReflectionReturnTypeResolver]
    B -->|string FQCN| F[ObjectType構築]
    C --> G{ReflectionType種別}
    D --> G
    E --> G
    G -->|ReflectionNamedType| H[BuiltinType/ObjectType]
    G -->|ReflectionUnionType| I[UnionType]
    G -->|ReflectionIntersectionType| J[IntersectionType]
    H --> K[NullableType判定]
    I --> K
    J --> K
    K --> L[Type返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-01 | 型階層モデル | Typeは抽象基底クラスであり、BuiltinType、ObjectType、CollectionType等の具象クラスが型の種類を表す | 全型操作 |
| BR-30-02 | isSatisfiedBy再帰評価 | WrappingTypeは内部型、CompositeTypeは構成型を再帰的に評価する | isSatisfiedBy()呼び出し時 |
| BR-30-03 | TypeIdentifier列挙 | 15種のPHPネイティブ型識別子（array, bool, callable, false, float, int, iterable, mixed, null, object, resource, string, true, never, void） | 型識別時 |
| BR-30-04 | スタンドアロン型 | mixed, never, voidはスタンドアロン型であり、他の型と組み合わせ不可 | isStandalone()判定時 |
| BR-30-05 | スカラー型 | string, float, int, bool, false, trueはスカラー型 | isScalar()判定時 |
| BR-30-06 | traverse | Type::traverse()で型ツリーを走査（CompositeType→子型、WrappingType→内部型） | 型ツリー解析時 |

### 計算ロジック

特になし。

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

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

直接的なデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | UnsupportedException | サポートされていないリフレクションタイプ | 対応するTypeResolverを登録 |
| - | LogicException | StringTypeResolverでPHPStan PhpDocParserが未インストール | composer require phpstan/phpdoc-parser |

### リトライ仕様

リトライは不要。

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

直接的なトランザクション管理は行わない。

## パフォーマンス要件

TypeオブジェクトはValueObjectとして不変であり、同一型に対して同一のオブジェクトインスタンスを返すことでメモリ効率を向上させている。TypeContextFactoryによるジェネリクスコンテキストはクラス単位でキャッシュ可能。

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

特別なセキュリティ上の考慮事項はない。

## 備考

TypeInfoコンポーネントはSymfony 7.1で導入された型情報表現の基盤であり、従来のPropertyInfo\Type（Symfony 6.x以前）を置き換える。PHPの型システムの進化（PHP 8.0+のユニオン型、PHP 8.1+の交差型、PHP 8.2+のDNF型）に完全対応している。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TypeIdentifier.php | `src/Symfony/Component/TypeInfo/TypeIdentifier.php` | 15種のPHPネイティブ型識別子の列挙型 |
| 1-2 | Type.php | `src/Symfony/Component/TypeInfo/Type.php` | 型の抽象基底クラス |
| 1-3 | WrappingTypeInterface.php | `src/Symfony/Component/TypeInfo/Type/WrappingTypeInterface.php` | ラッピング型（NullableType等）のインターフェース |
| 1-4 | CompositeTypeInterface.php | `src/Symfony/Component/TypeInfo/Type/CompositeTypeInterface.php` | 複合型（UnionType等）のインターフェース |

**読解のコツ**: 型ツリーは3つのカテゴリに分かれる。(1)基本型（BuiltinType, ObjectType）、(2)ラッピング型（NullableType, CollectionType, GenericType）、(3)複合型（UnionType, IntersectionType）。isSatisfiedByの再帰評価ではWrapping -> Composite -> selfの順で評価される。

#### Step 2: TypeIdentifierを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TypeIdentifier.php | `src/Symfony/Component/TypeInfo/TypeIdentifier.php` | 型識別子列挙型 |

**主要処理フロー**:
- **22-36行目**: 15種のケース定義（ARRAY, BOOL, CALLABLE, FALSE, FLOAT, INT, ITERABLE, MIXED, NULL, OBJECT, RESOURCE, STRING, TRUE, NEVER, VOID）
- **41-44行目**: values()でケース名のリスト取得
- **46-49行目**: isStandalone()でMIXED/NEVER/VOIDの判定
- **51-54行目**: isScalar()でSTRING/FLOAT/INT/BOOL/FALSE/TRUEの判定
- **56-59行目**: isBool()でBOOL/FALSE/TRUEの判定

#### Step 3: Type基底クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Type.php | `src/Symfony/Component/TypeInfo/Type.php` | 型の抽象基底クラス |

**主要処理フロー**:
- **24行目**: TypeFactoryTraitをuse（静的ファクトリメソッド提供）
- **30-41行目**: isSatisfiedBy()でWrappingType -> CompositeType -> callable($this) の順で評価
- **46-59行目**: isIdentifiedBy()でTypeIdentifierまたは文字列による型識別判定
- **61-64行目**: isNullable()（デフォルトfalse、NullableType等でオーバーライド）
- **69-84行目**: accepts()で値の型受け入れ判定（WrappingType/CompositeType対応）
- **91-107行目**: traverse()で型ツリーを走査（CompositeType→子型、WrappingType→内部型をyield）

#### Step 4: TypeResolverを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/TypeResolver.php` | 型リゾルバーの統合エントリーポイント |
| 4-2 | ReflectionTypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/ReflectionTypeResolver.php` | リフレクション型リゾルバー |
| 4-3 | StringTypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php` | 文字列型リゾルバー |

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

```
TypeResolver::resolve()
    |
    +-- [ReflectionParameter] ReflectionParameterTypeResolver
    |       +-- ReflectionTypeResolver::resolve()
    |
    +-- [ReflectionProperty] ReflectionPropertyTypeResolver
    |       +-- PhpDocAwareReflectionTypeResolver::resolve()
    |       +-- ReflectionTypeResolver::resolve()
    |
    +-- [ReflectionFunction] ReflectionReturnTypeResolver
    |       +-- ReflectionTypeResolver::resolve()
    |
    +-- [string] ObjectType構築

Type::isSatisfiedBy()
    |
    +-- [WrappingType] wrappedTypeIsSatisfiedBy()
    |       +-- NullableType -> 内部型
    |       +-- CollectionType -> 内部型
    |
    +-- [CompositeType] composedTypesAreSatisfiedBy()
    |       +-- UnionType -> いずれかの子型
    |       +-- IntersectionType -> 全ての子型
    |
    +-- specification($this)
```

### データフロー図

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

ReflectionParameter ---------> TypeResolver::resolve() ------> Type
ReflectionProperty ----------> (個別リゾルバー選択)
ReflectionFunction ---------->
string (FQCN) -------------->

Type + callable -------------> Type::isSatisfiedBy() --------> bool
                                   |
                              WrappingType/CompositeType
                              再帰評価

Type + value ----------------> Type::accepts() --------------> bool
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Type.php | `src/Symfony/Component/TypeInfo/Type.php` | ソース | 型の抽象基底クラス |
| TypeIdentifier.php | `src/Symfony/Component/TypeInfo/TypeIdentifier.php` | ソース | 型識別子列挙型 |
| TypeFactoryTrait.php | `src/Symfony/Component/TypeInfo/TypeFactoryTrait.php` | ソース | 静的ファクトリメソッド |
| BuiltinType.php | `src/Symfony/Component/TypeInfo/Type/BuiltinType.php` | ソース | ビルトイン型 |
| ObjectType.php | `src/Symfony/Component/TypeInfo/Type/ObjectType.php` | ソース | オブジェクト型 |
| CollectionType.php | `src/Symfony/Component/TypeInfo/Type/CollectionType.php` | ソース | コレクション型 |
| UnionType.php | `src/Symfony/Component/TypeInfo/Type/UnionType.php` | ソース | ユニオン型 |
| IntersectionType.php | `src/Symfony/Component/TypeInfo/Type/IntersectionType.php` | ソース | 交差型 |
| NullableType.php | `src/Symfony/Component/TypeInfo/Type/NullableType.php` | ソース | Null許容型 |
| GenericType.php | `src/Symfony/Component/TypeInfo/Type/GenericType.php` | ソース | ジェネリック型 |
| WrappingTypeInterface.php | `src/Symfony/Component/TypeInfo/Type/WrappingTypeInterface.php` | ソース | ラッピング型インターフェース |
| CompositeTypeInterface.php | `src/Symfony/Component/TypeInfo/Type/CompositeTypeInterface.php` | ソース | 複合型インターフェース |
| TypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/TypeResolver.php` | ソース | 型リゾルバー統合 |
| ReflectionTypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/ReflectionTypeResolver.php` | ソース | リフレクション型リゾルバー |
| StringTypeResolver.php | `src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php` | ソース | 文字列型リゾルバー |
| TypeContextFactory.php | `src/Symfony/Component/TypeInfo/TypeContext/TypeContextFactory.php` | ソース | 型コンテキストファクトリ |
