Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/test/ケース01-生成と実行時API.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ K9 の表記変種(import 別名・FQN・star import・typealias)と診断
| ID | 次元/値 | 観測と期待 | 実装 | 備考(関連V/診断) |
|---|---|---|---|---|
| API-12 | K3=全種別 × K6=自動生成 | 10 種別末端(data class/data object/object/final class/open/abstract/interface/fun interface/enum/value class)で 1 末端=1 kind・label=単純名・object 系=自身/他=companion(自動生成 companion 含む) | ZooTest#oneKindPerLeafAcrossAllShapes | V3・V10 |
| API-13 | K15=多段サブタイプ | 吸収: open 直下・多段・object サブタイプ・interface 第三者実装(default asEnumish の JVM lowering 込み)・テスト内無名 object 実装・テスト内 local class 実装・末端 interface への委譲実装(`: IfaceLeaf by impl`)は kind 新設せず entries 不変・asEnumish 継承 | ZooTest#subtypesAreAbsorbedIntoLeafKinds | V10・AK 非発火→ケース04・基底直接委譲は DIA-69 |
| API-13 | K15=多段サブタイプ × K5=探索境界(下方向) | 吸収: open 直下・多段・object サブタイプ・interface 第三者実装(default asEnumish の JVM lowering 込み)・テスト内無名 object 実装・テスト内 local class 実装・末端 interface への委譲実装(`: IfaceLeaf by impl`)・非 sealed 末端配下の sealed 部分階層(探索が末端で止まり中間・末端とも自 kind を持たない)は kind 新設せず entries 不変・asEnumish 継承 | ZooTest#subtypesAreAbsorbedIntoLeafKinds | V10・AK 非発火→ケース04・基底直接委譲は DIA-69 |
| API-14 | K3=非 final 末端 | 非 final 末端の enumizedClass=分類代表(実行時クラスと不一致可) | ZooTest#enumizedClassIsRepresentativeForOpenLeaves | V10 |
| API-15 | K3=interface 末端下限 | 実装者ゼロの interface 末端(Ghost・自動 companion)も entries 掲載 | ZooTest#implementorlessInterfaceLeafHasKind | V10 |
| API-16 | O4=値 when | 値 when の is 末端枝がサブタイプを被覆(sealed 地力) | ZooTest#valueWhenCoversSubtypesByLeafBranch | V10 |
Expand Down Expand Up @@ -64,14 +64,14 @@ K9 の表記変種(import 別名・FQN・star import・typealias)と診断
| API-27 | K1=sealed class × K9=コンストラクタ呼び出し形 | `:Task()` 形 supertype でも所属判定・companion 自動生成が成立 | SealedClassBaseTest#constructorCallSupertypeWorks | V3 |
| API-28 | K1=sealed class × K3=object | sealed class 基底の object / data object 末端=自身が kind・toString 生成差分(非 data=生成 / data=言語合成) | SealedClassBaseTest#objectLeavesOfClassBase | V11 |

## 7. 中間 sealed(mid・K5 × K9)
## 7. 中間 sealed と合流(mid・K5 × K9)

| ID | 次元/値 | 観測と期待 | 実装 | 備考(関連V/診断) |
|---|---|---|---|---|
| API-29 | K5=1 段 × K9=中間経由再帰追跡 | 中間 sealed class / sealed interface 経由の raw 追跡再帰で末端 companion 自動生成 | MidTrackingTest#leavesViaIntermediatesGetAutoCompanions | V3 |
| API-30 | K5=中間非生成 | 中間には何も生成されず entries 非掲載(末端まで平坦化)・中間の明示 companion へも Enumish 非注入(kind 非成立)・中間型変数の asEnumish は末端 kind へ実体解決 | MidTrackingTest#intermediatesHaveNoKind | 多段の展開順→ケース03 |
| API-30 | K5=中間非生成 × K2=非注釈 sealed 祖先 | 中間には何も生成されず entries 非掲載(末端まで平坦化)・中間の明示 companion へも Enumish 非注入(kind 非成立)・中間型変数の asEnumish は末端 kind へ実体解決・非注釈 sealed 祖先の側(祖先直下の非所属メンバー)にも生成なし=探索の範囲は基底から下だけ | MidTrackingTest#intermediatesHaveNoKind | 多段の展開順→ケース03 |
| API-51 | K9=スコープ順の競合解決 | raw 追跡の優先関係を競合 3 形で固定: star import 基底 vs 同一 pkg 同名非基底=同一 pkg 勝ち(entries 非所属)・同一 pkg 同名 vs 明示 import 基底=import 勝ち(所属)・明示 import vs 外側ネスト同名=ネスト勝ち(非所属) | RawTrackingTest#scopePriorityDecidesMembership | V3。表記単独形の成立→ケース04 DIA-31/32 |
| API-57 | K5=多重経路(兄弟中間の同時実装) | 複数経路で到達する末端は初出位置に 1 回だけ entries 掲載・kind は 1 つ(どちらの中間型からも同じ kind へ解決・生成 Enumish の継承者一覧も重複せず kind-when は else 不要 | MultiPathTest#multiPathLeafIsListedOnceAtFirstOccurrence / MultiPathTest#multiPathLeafHasSingleKind | 基底は一意のため診断は非発火。展開順の規則→ケース03 §1 |
| API-57 | K5=合流(合流点の種別 × 経路の非対称性 × 入れ子) | 複数経路で到達するメンバーは初出位置に 1 回だけ entries 掲載(合流点が中間 sealed なら配下のサブツリーごと 1 回)・kind は 1 つでどの経路の静的型からも同じ kind へ解決・生成 Enumish の継承者一覧も重複せず kind-when は else 不要。合流点(非 sealed 末端 / 中間 sealed / companion 末端)× 経路(対称 / 基底直下併存 / sealed class 中間との混成)× 入れ子を 1 スナップショットで固定 | MultiPathTest#multiPathLeafIsListedOnceAtFirstOccurrence / MultiPathTest#multiPathLeafHasSingleKind | 基底は一意のため診断は非発火。展開順の規則→ケース03 §1 |

## 8. 型パラメータ(generic・K11)

Expand Down
3 changes: 2 additions & 1 deletion docs/test/ケース03-順序.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ FQN UTF-16 序数と DFS 入れ子展開に関する順序観測は本資料へ
- 順序 = コンパイラの sealed 継承者リスト走査順(setSealedClassInheritors セッター側で ClassId FQN 文字列の UTF-16 序数昇順に正規化・大小区別・ロケール非依存)。
- プラグインは FIR / IR とも並べ替えに一切介入しない(設計00 §6.2・設計02 §3)。
- 中間 sealed はその位置で継承者リストを深さ優先に入れ子展開し、entries には末端のみが載る。
- 複数経路で到達する末端(兄弟中間の同時実装)は初出位置に 1 回だけ載る(設計00 §6.2・設計02 §2。観測はケース01 API-57)。
- 複数経路で到達するメンバーは初出位置に 1 回だけ載る。合流点が中間 sealed の場合は配下のサブツリーごと 1 回であり、2 度目の到達では再展開しない。
初出位置は各段の継承者リストを深さ優先に辿った到達順が決めるため、基底直下と中間経由が競合する構成では基底の継承者リストで先に来た側の位置になる(設計00 §6.2・設計02 §2。観測はケース01 API-57)。
- 整列キーは末端の ClassId のみ(kind が companion でも companion 名は整列に関与しない)。

## 2. 期待列の導出
Expand Down
7 changes: 4 additions & 3 deletions docs/test/テスト戦略.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ Kotlin 言語仕様がこのプラグインに対して張る空間を次の次
| # | 次元 | 値 |
|---|---|---|
| K1 | 基底の宣言種別 | sealed interface / sealed class ‖ 負値: enum・annotation・object・data object・class(final/open/abstract/data/value)・interface・fun interface・sealed fun interface(言語拒否)・非クラス対象(言語 WRONG_TARGET) |
| K2 | 基底の修飾 | expect / actual(共にエラー)・inner(sealed 不能=NOT_SEALED 合流)・型パラメータ付き・ネスト配置・可視性 |
| K2 | 基底の修飾 | expect / actual(共にエラー)・inner(sealed 不能=NOT_SEALED 合流)・型パラメータ付き・ネスト配置・可視性・非注釈 sealed 祖先を持つ(上方向の探索境界) |
| K3 | 末端の宣言種別 | object / data object / class / data class / value class / enum class / open class / abstract class / interface / fun interface / 階層外クラスの companion(既定名・名前付き) |
| K4 | 末端の修飾 | inner(エラー)・型パラメータ付き・可視性・expect/actual(言語委譲) |
| K5 | 中間 sealed | 無 / 1 段 / 多段 / 兄弟複数 / 多重経路(兄弟中間の同時実装) / 継承者ゼロ / 可視性 / 配置(ネスト・トップレベル) |
| K5 | 中間 sealed | 無 / 1 段 / 多段 / 兄弟複数 / 継承者ゼロ / 可視性 / 配置(ネスト・トップレベル) ‖ 合流(多重経路)= 合流点の種別(非 sealed 末端・中間 sealed・companion 末端)× 経路の非対称性(対称・基底直下併存・sealed class 中間との混成)× 入れ子 ‖ 探索境界 = 非 sealed 末端配下の sealed 部分階層(下方向。吸収へ合流) |
| K6 | companion 状態 | 無し(自動生成) / 明示既定名 / 明示名前付き / 可視性 4 値 / ユーザーメンバー共存 / companion 自身が末端(外側=末端: エラー・外側=基底/中間: 成立・外側=階層外: 許容) / 非 companion のネスト宣言 `Companion` との衝突(実挙動固定) |
| K7 | 配置 | 基底ネスト / 同一ファイルトップレベル / 別ファイルトップレベル / 無関係クラス内ネスト / private 外側クラス内 / 非 sealed クラス内の基底 / 多段ネスト / local(関数内。実装は FIR・チェッカー・IR の全入口で一貫除外=無診断・無生成の素通りを固定する) / 別パッケージ(sealed の言語制約エラーへ委譲) |
| K8 | 可視性 | (基底/中間/末端/companion) × (public/internal/protected/private) → 実効可視性・asEnumish 3 段規則・IR-only アクセサ壁 3 形・基底より広い末端(E-2) |
Expand Down Expand Up @@ -58,7 +58,8 @@ Kotlin 言語仕様がこのプラグインに対して張る空間を次の次
- C2(分岐網羅): 実装に条件分岐が存在する次元の組は全分岐を踏む。
分岐の典拠は実装である: kind 解決(object=自身/他=companion)・asEnumish 返り値型 3 段規則・
IR-only アクセサの壁 3 形(壁なし/ネスト壁/トップレベル壁)・toString 生成の 3 非生成条件・
companion 自動生成の候補判定(raw supertype 追跡のスコープ順 5 表記)・順序(DFS 入れ子展開×FQN 正規化)。
companion 自動生成の候補判定(raw supertype 追跡のスコープ順 5 表記)・順序(DFS 入れ子展開×FQN 正規化)・
末端列挙の 4 分岐(初出 / 重複 × 非 sealed=掲載する / 中間 sealed=サブツリーを展開する)。
- C3(合成許容): 実装上相互作用しない次元値は同一フィクスチャに合成してよい。
根拠は生成が末端毎に独立(P1)・診断が宣言単位の条件検査であること。
合成時の制約: 同一階層内の label 一意・意図しないサブタイプ関係を作らない・
Expand Down
4 changes: 2 additions & 2 deletions docs/test/フィクスチャ構成.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ src/test には test compilation 配線検証用の小さな @Enumize 階層(T
| パッケージ | 階層 | 合成する次元値 | 主担当資料 |
|---|---|---|---|
| si | SI = sealed interface + data class Foo + data object Bar | 標準形(消費側・Java・binary-swap の共通参照) | API |
| zoo | Zoo = sealed interface + 全種別末端 12(data class/data object/object/final class/open/abstract/enum/value class=自動 companion・interface IfaceLeaf と fun interface FunLeaf=明示 public companion・fun interface FunAuto=自動 companion・実装者ゼロ interface Ghost=自動 companion)+ 吸収サブタイプ(open 直下・多段・object・interface 実装・SAM ラムダ・テスト内無名 object・テスト内 local class 実装・IfaceLeaf への委譲実装) | K3 全値 × K6 明示/自動 × kind 解決 2 分岐 × V10 吸収 × O1 | API/ORD |
| zoo | Zoo = sealed interface + 全種別末端 12(data class/data object/object/final class/open/abstract/enum/value class=自動 companion・interface IfaceLeaf と fun interface FunLeaf=明示 public companion・fun interface FunAuto=自動 companion・実装者ゼロ interface Ghost=自動 companion)+ 吸収サブタイプ(open 直下・多段・object・interface 実装・SAM ラムダ・テスト内無名 object・テスト内 local class 実装・IfaceLeaf への委譲実装・IfaceLeaf 配下の sealed 部分階層 Brood/Chick=下方向の探索境界) | K3 全値 × K6 明示/自動 × kind 解決 2 分岐 × V10 吸収 × O1 | API/ORD |
| enumleaf | Command = sealed interface + enum Builtin(自動 companion) + enum Verb(明示 companion・定数 toString override) + data object HELP(定数名対照) + data class Custom | K3=enum 深掘り(V4): 1 kind・name/label 分離・定数 toString 独立・明示 companion 流用・enum 複数 | API/ORD |
| plain | Plain = sealed interface + class Simple(明示既定名 companion) + class Stocked(companion にユーザーメンバー) + object Marker(非 data) + class Made(public 名前つき companion Factory) | K6: 明示既定名/ユーザーメンバー共存/名前つき public(規則 1・label 不変) | API |
| companionleaf | Token = sealed interface + Host.Companion(既定名 companion 末端) + WithNamed.Named(名前つき companion 末端) + data object HostA + Holder2.Zzz(名前つき・順序プローブ)。基底/中間 companion 末端の成立形は sealedbase / mid が担う | K3=companion 末端(外側=階層外)・label=宣言名・'.'(46) 序数境界 | API/ORD |
| sealedbase | Task = sealed class + data class Run(`:Task()`・自動 companion) + data object Done + object Plain + protected class Inner(基底ネスト・明示 companion・基底 companion に factory と asEnumish 型付き観測メンバー=規則 1 の基底スコープ内観測) + 基底自身の companion(`companion object : Task()`)=基底 companion 末端の成立形(label="Companion") | K1=sealed class・K9 コンストラクタ呼び出し形・protected 末端・K6 基底 companion 末端 | API/VIS |
| generic | `Generic<T>` = sealed class + data class `Box<T>` + class `Empty<T>` + 非 generic 末端 class Fixed(`:Generic<Unit>()`) ‖ Holder = 非 generic sealed interface + generic 末端 data class `Cell<out T>`(変位注釈) | K11: 型パラメータ(両方/基底のみ/末端のみ/変位)・star projection・kind の型引数非依存 | API |
| mid | RootVia = sealed interface + 中間 sealed class MidClass(companion object : RootVia=中間 companion 末端の成立形) + 中間 sealed interface MidIface(明示 companion=非実装・Enumish 非注入・kind 非成立の観測) + 各経由の companion 無し末端 ‖ MultiPath = 兄弟中間 MpLeft / MpRight + 両方を実装する末端 MpBoth(自動 companion) + 各単独経路末端 MpOnlyLeft / MpOnlyRight(RootVia の entries スナップショットを汚さないよう独立階層とする) | K5×K9×K6: 中間経由の raw 追跡再帰(V3)・中間へ非生成・中間 companion の非注入/末端成立の両形・多重経路の初出 1 回掲載 | API |
| mid | RootVia = sealed interface + 非注釈 sealed 祖先 ViaAncestor とその直下の非所属 ViaOutside(上方向の探索境界) + 中間 sealed class MidClass(companion object : RootVia=中間 companion 末端の成立形) + 中間 sealed interface MidIface(明示 companion=非実装・Enumish 非注入・kind 非成立の観測) + 各経由の companion 無し末端 ‖ MultiPath = 合流の合成階層: 兄弟中間 MpLeft / MpRight + sealed class 中間 MpClassMid + 合流点の中間 sealed MpShared / 合流するメンバー = MpBoth(非 sealed 末端・対称) / MpHost.Companion(companion 末端) / MpDirect(基底直下併存) / MpMixed(class 中間との混成) / MpNested(合流の入れ子) + MpShared 配下の MpDeep + 各単独経路末端 MpOnlyLeft / MpOnlyRight(RootVia の entries スナップショットを汚さないよう独立階層とする) | K5×K9×K6: 中間経由の raw 追跡再帰(V3)・中間へ非生成・中間 companion の非注入/末端成立の両形・探索境界(上方向)・合流の初出 1 回掲載(合流点の種別 × 経路の非対称性 × 入れ子) | API |
| scope | 真基底 scope.target.Holder.Base(@Enumize・object Holder 内ネスト)+囮トップレベル scope.target.Base(非 sealed interface)+別 pkg 実基底 scope.other.Base(@Enumize)。競合 3 形(末端は全て scope.target 配置): (1) 明示 import Holder.Base vs 同一 pkg 囮=import 勝ち→所属 (2) scope.other.* star import vs 同一 pkg 囮=同一 pkg 勝ち→非所属・コンパイル成功 (3) 明示 import vs ホストの内側ネスト同名=ネスト勝ち→非所属 | K9: raw 追跡スコープ順の優先関係を entries 所属/非所属+コンパイル成立で固定 | API |
| order.flat | FlatRoot = sealed interface + 文字境界末端(AB1/Ab2/aB3/ab4・A1/AA/A_/Az)+ 配置末端(基底ネスト Aaa・無関係クラス Box.Bbb・トップレベル Mmm/Zzz/aLower)+ 接頭辞対(Foo=class 自動 companion / FooBar=data object)+ セパレータ対(ネスト Sep.Q / トップレベル Sep0) | K7×O3: FQN UTF-16 序数の全境界を 1 スナップショット固定 | ORD |
| order.mid | MidRoot = sealed interface + MidNest{NestA,NestB}(トップレベル中間×ネスト末端=FQN 順一致) + MidTop{Early,Late}(トップレベル中間×トップレベル末端=break) + MidMulti.Deep{Bottom,Wide}(多段) + MidRoot.MidIn{Outpost}(基底ネスト中間×トップレベル末端) + 直接末端 Aaa/Zzz(in-place 展開の前後) + Probe=class 末端(自動 companion)+その内側ネスト data object 末端 Bb(単純名が Companion より序数で小=entries 順と inheritors 順の分岐プローブ) | K5×O3: DFS 入れ子展開・break・多段・中間配置 2 形・inheritors 分岐を 1 スナップショット固定 | ORD |
Expand Down
5 changes: 4 additions & 1 deletion docs/コンパイラプラグイン設計00.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,11 @@ entries = [Bbb, Aaa]
末端が中間 sealed の内側にネストしている通常の構成では、ネストした末端の FQN が中間の FQN を接頭辞に持つため結果的に
FQN 序数順と一致する

- **同じ末端へ複数経路で到達する構成**(兄弟の中間 sealed を同時に実装する末端)では、
- **複数経路で到達するメンバー**(兄弟の中間 sealed を同時に実装する末端・基底直下と中間経由を併せ持つ末端など)は
**初出位置に 1 回だけ載る**。
合流点が中間 sealed である場合は配下のサブツリーごと 1 回であり、2 度目の到達では展開しない。
初出位置は各段の継承者リストを深さ優先に辿った到達順が決めるため、
基底直下と中間経由が競合する構成では基底の継承者リストで先に来た側の位置になる。
重複の除去は並べ替えではなく、entries が kind の集合であることの帰結である
- 生成 Enumish の inheritors 属性(§5.2)も同様に、収集した順のまま登録する。
属性へ格納される時点でセッター側の正規化(§6.1)が働くため、プラグイン側で整える必要はない
Expand Down
Loading