feat(runtime): Phase 87 CoreBoxId/CoreMethodId 箱化完了

ハードコード文字列から型安全な enum への箱化により、
Box名・メソッド名管理を完全にコンパイル時検証可能に。

主な実装:
- CoreBoxId enum 定義(19個)
  - core_required: 6個(String, Integer, Bool, Array, Map, Console)
  - core_optional: 9個(Float, Null, File, Path, Regex, Math, Time, Json, Toml)
  - 特殊型: 4個(Function, Result, Method, Missing)
- CoreMethodId enum 定義(30個)
  - 各 Box のメソッドを型安全に管理
  - 引数数、戻り値型情報を統合
- is_reserved_type() を CoreBoxId ベースにリファクタリング
- infer_boxcall_return_type() を CoreMethodId ベースに改良(75行 → 25行、67%削減)

検証結果:
- テスト:  11/11 passed(新規追加)
- ビルド:  成功(0エラー)
- 型安全性:  タイポ不可能

効果:
- SSOT 確立(src/runtime/core_box_ids.rs に一元化)
- コンパイル時検証(実行時エラー → コンパイルエラー)
- 保守性向上(変更箇所の一元化)
- IDE 支援(enum 補完可能)

ドキュメント:
- core_boxes_design.md 作成(Phase 87 完全仕様)
- Phase 85 README 更新(Phase 87 セクション追加)

Phase 15.5「Everything is Plugin」アーキテクチャ基盤完成

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-02 22:22:32 +09:00
parent 268a56fdfe
commit 8cd9729375
5 changed files with 715 additions and 65 deletions

View File

@ -0,0 +1,241 @@
# Core Boxes 設計ドキュメントPhase 87 完了版)
Phase 87 で実装された CoreBoxId/CoreMethodId の完全仕様。
**目的**: Box名・メソッド名のハードコードを型安全な enum に箱化することで、以下を実現:
- ✅ コンパイル時検証(タイポ撲滅)
- ✅ IDE 支援(補完・リファクタリング)
- ✅ SSOTSingle Source of Truth確立
- ✅ 保守性向上
**実装状況**: ✅ Phase 87 完了2025-12-02
---
## 1. CoreBoxId — コア Box の識別子(実装完了)
### 1.1 役割
- Nyash 言語仕様的に「コア」とみなす Box の ID を定義する。
- 文字列名 `"StringBox"` / `"ArrayBox"` をここに集約し、他のモジュールは enum 経由で参照する。
- 例:
- 予約型チェックBoxFactory
- core_required 判定PluginHost / FactoryPolicy
- 将来の Method Registry との連携など。
### 1.2 想定 API
```rust
pub enum CoreBoxId {
String,
Integer,
Bool,
Float,
Null,
Array,
Map,
Result,
Method,
Console,
File,
// 将来: Path, Json, Time, Regex, etc.
}
impl CoreBoxId {
/// "StringBox" / "ArrayBox" などの内部名
pub fn name(&self) -> &'static str;
/// 将来のための iterator予約型チェックなどで利用
pub fn iter() -> impl Iterator<Item = CoreBoxId>;
}
```
### 1.3 補足
- Ring0Context からはこの enum を直接は参照しない(あくまで ring1-core の責務)。
- `is_reserved_type(name: &str)` のような関数は、この enum を使って実装する想定:
```rust
fn is_reserved_type(name: &str) -> bool {
CoreBoxId::iter().any(|id| id.name() == name)
}
```
---
## 2. CoreMethodId — コアメソッドの識別子
### 2.1 役割
- 「どの Box のどのメソッドか」を安全に表現する ID。
- メソッド名(`"length"` / `"push"` など)や arity を 1 箇所に集約し、呼ぶ側は enum だけを見る。
- 代表例:
- `StringBox.length/0`
- `ArrayBox.push/1`
- `MapBox.get/1`
- `ConsoleBox.println/1`
### 2.2 想定 API
```rust
pub enum CoreMethodId {
// StringBox
StringLength,
StringSubstring,
StringLastIndexOf,
StringEscJson,
// ArrayBox
ArraySize,
ArrayGet,
ArraySet,
ArrayPush,
// MapBox
MapSize,
MapHas,
MapGet,
MapSet,
// ConsoleBox
ConsolePrint,
ConsolePrintln,
ConsoleLog,
// FileBox
FileOpen,
FileRead,
FileClose,
}
impl CoreMethodId {
/// このメソッドが属する BoxCoreBoxId
pub fn box_id(&self) -> CoreBoxId;
/// 実際のメソッド名("length" など)
pub fn name(&self) -> &'static str;
/// 引数個数(将来可変長も考慮)
pub fn arity(&self) -> usize;
}
```
### 2.3 用途の例
- Method Registry / BoxFactory でのメソッド解決:
```rust
fn resolve_core_method(box_name: &str, method_name: &str, arity: usize) -> Option<CoreMethodId> {
CoreMethodId::iter().find(|id| {
id.box_id().name() == box_name && id.name() == method_name && id.arity() == arity
})
}
```
- 型推論や BoxCall lowering で、「この CoreMethodId なら戻り値型は Integer」という判定に使う。
---
## 3. BoxFactory / PluginHost との関係
### 3.1 BoxFactory 側
- 予約型チェックや FactoryPolicy の判定を、CoreBoxId ベースに書き換える想定:
```rust
fn is_core_required(name: &str) -> bool {
matches!(
CoreBoxId::from_name(name),
Some(CoreBoxId::String | CoreBoxId::Integer | CoreBoxId::Bool
| CoreBoxId::Float | CoreBoxId::Null
| CoreBoxId::Array | CoreBoxId::Map | CoreBoxId::Result | CoreBoxId::Method)
)
}
```
### 3.2 PluginHost 側
- `PluginHost.core: CoreServices` の設計と合わせて、CoreBoxId に基づいた必須サービスセットを定義する:
```rust
pub struct CoreServices {
pub string: Arc<dyn StringService>,
pub array: Arc<dyn ArrayService>,
pub map: Arc<dyn MapService>,
pub console: Arc<dyn ConsoleService>,
// ...
}
```
- 初期化時に CoreServices の全フィールドが埋まっているかチェックし、足りなければ起動時に fail-fast する方針にする。
---
## 4. Ring0Context との分離
- Ring0Context はあくまで「OS API」の箱であり、CoreBoxId/CoreMethodId を知らない。
- CoreBoxes は Ring1-core 層として、Ring0Context の上に構築される:
```rust
// Ring0: OS API
pub struct Ring0Context { pub io: Box<dyn IoApi>, /* ... */ }
// Ring1-core: Box 実装StringBox/ArrayBox/MapBox/FileBox/ConsoleBox
// CoreBoxId/CoreMethodId で識別される
```
これにより、ring0 側の変更IO 実装差し替えなど)が CoreBoxes の識別や FactoryPolicy に影響しないようにできる。
---
## 5. Phase 87 実装完了
### 5.1 実装内容
**CoreBoxId enum 定義** (`src/runtime/core_box_ids.rs`)
- 19個の CoreBox: core_required (6個), core_optional (9個), 特殊型 (4個)
- API: `name()`, `from_name()`, `is_core_required()`, `category()`, `iter()`
**CoreMethodId enum 定義** (`src/runtime/core_box_ids.rs`)
- 30個のメソッド: StringBox (8), IntegerBox (3), BoolBox (3), ArrayBox (4), MapBox (4), ConsoleBox (3), FileBox (3), ResultBox (2)
- API: `box_id()`, `name()`, `arity()`, `return_type_name()`, `from_box_and_method()`, `iter()`
**is_reserved_type() リファクタリング** (`src/box_factory/mod.rs`)
- ハードコード matches! → CoreBoxId による型安全判定
- 環境変数 NYASH_USE_PLUGIN_BUILTINS / NYASH_PLUGIN_OVERRIDE_TYPES 対応維持
**infer_boxcall_return_type() リファクタリング** (`src/mir/builder/utils.rs`)
- 75行のハードコード → 25行の CoreMethodId ベース実装(**67%削減**
- 型推論が SSOT 化され、保守性が大幅向上
**テスト 11件追加** (`src/runtime/core_box_ids.rs`)
- CoreBoxId: from_name, name, iter, is_core_required, category (5件)
- CoreMethodId: box_id, name, arity, return_type_name, from_box_and_method, iter (6件)
### 5.2 実装効果
| 項目 | Before | After | 効果 |
|------|--------|-------|------|
| infer_boxcall_return_type() | 75行 | 25行 | **67%削減** |
| is_reserved_type() | 12行 | 9行 | 25%削減 |
| 型安全性 | 文字列ハードコード | enum | タイポ不可能 |
| SSOT | 分散 | 1ファイル | 保守性向上 |
| IDE支援 | なし | 補完可能 | 開発体験向上 |
### 5.3 Phase 85 との関係
Phase 85 の調査結果を完全反映:
- **core_required (6個)**: StringBox, IntegerBox, BoolBox, ArrayBox, MapBox, ConsoleBox
- **core_optional (9個)**: FloatBox, NullBox, FileBox, PathBox, RegexBox, MathBox, TimeBox, JsonBox, TomlBox
- **特殊型 (4個)**: FunctionBox, ResultBox, MethodBox, MissingBox
### 5.4 今後の拡張
新しいメソッド追加は `src/runtime/core_box_ids.rs` の編集のみで完結:
1. CoreMethodId enum にバリアント追加
2. box_id(), name(), arity(), return_type_name() に対応追加
3. iter() にバリアント追加
4. テスト追加
すべて1ファイルで完結するため、Phase 84-4-B のような分散ハードコード問題は完全解消。