refactor: 「1 から実装したら妥当か」の観点で全体を見直す - #56
Merged
Merged
Conversation
- IR 側の空白 @EnumishLabel が FIR と食い違っていた。FIR の EnumizeHierarchyResolver.explicitLabelOf は空白を無指定へ倒すが、IR 側は そのまま label にしていた。ENUMIZE_INVALID_LABEL で止まるため到達しないが、 両者は同一規則で label を決めることが前提である - 生成 Enumish の companion を作る経路が 2 つあり、フォールバック側は ownerGenerator の刻印もキャッシュ登録も持たない別インスタンスを返しうる。 enumishCompanionOf へ一本化して常に刻印・共有する - kindOf の mapNotNull が companion を持たない末端を黙って落とし、entries が 静かに不完全になる経路だった。プラグインの中核保証に関わるため失敗させる Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
supertypeClosure はチェッカーがモジュール内の全クラスに対して呼ぶ(AMBIGUOUS_KIND の検査が無条件に走る)にもかかわらず、毎回 supertype グラフをフル走査していた。 階層メンバーの再帰展開と併せて FirCache へ載せ、既存の basesCache / labelIndexCache / labelCaseCache と同じ機構に揃える。いずれもプロデューサが自身のキャッシュを再入しない。 併せて、同じ探索を二重実装していた tracker の findEnumizeBase と findEnumizeBaseAmong を統合する。visited を再帰全体で共有するため、 基底の無い部分木の再訪も無くなる。 内部からしか引かれない照会(hierarchyMembersOf / leavesOf / kindClassIdOf / directlyImplements / explicitLabelOf)は private へ落とす。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- isOurGenerated / isOurGeneratedDeclaration は IR 側の IrDeclaration.isGeneratedByEnumize と同じ判定であり、名前だけが割れていた。 シンボル / 宣言のオーバーロードとして isGeneratedByEnumize へ揃え、 origin の照合そのものは 1 か所へ寄せる - ourPropertyGetter は backing field を除去する副作用を持つのに取得を名乗って いたため prepareGeneratedGetter とし、対になる ourFunction も generatedFunction とする - kind アクセサ生成が同一の kind を target / kind の 2 名で呼んでいたのを揃える Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
入口の check は CheckerContext / DiagnosticReporter をコンテキストパラメータで 受けているのに、そこから呼ぶ 15 個の検査は resolver と併せて 3 つを引数で手渡し、 reportOn も毎回 context を実引数に取っていた。検査を階層照会コンポーネントの 拡張関数にしたうえで文脈をコンテキストパラメータで受け、reportOn の コンテキストパラメータ版を使う。 宣言から callable 名を取り出す処理がチェッカーと resolver に二重にあったため、 resolver 側の callableNameOf へ寄せて共用する。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- EnumizeGenerationRole の GeneratedEnumishCompanion.enumish / KindCompanion.base / LeafObject.base は一度も読まれない。保持値を持たない 役割は object とし、シグネチャの構築に要る相手クラスだけを残す - EnumizeMembership.isIntermediate は !isLeaf の別名で、参照も 1 か所だった - EnumizeSupertypeGenerationExtension.couldBeHierarchyMember は tracker.isHierarchyCandidate の別名でしかなく、同一ファイル内に同じ判定の 名前が 2 つある状態だった - maven-plugin の unsupportedKotlinWarning は呼び出しが 1 か所のみで、 同じ文言を組む gradle-plugin 側は元から呼び出し位置に置いている Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 設計02 §6 の決定性規則が参照不能 kind のアクセサを列挙しておらず、 「生成する名前はいずれも固定文字列」がトップレベルアクセサ ($enumizeKindAccessor$<相対名>)に当てはまらない状態だった - 設計01 が存在しない診断 ID を名指ししていたため、記述から外す - エッジケースへの対応方針 §2.1 の見出しが、未実装の将来拡張を現行方針として 読ませていた - runtime-api のビルドスクリプトに、同ファイルで既に適用済みの Dokka を 「別途判断」とする陳腐化したコメントが残っていた - Enumish の toString 非宣言の理由、settings と生成拡張の「従来」表現を、 現状の事実だけを述べる形へ縮める Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
コンテキストパラメータ化の際に null 判定を省いた結果、左辺が Name? となって Set.contains ではなく Iterable.contains の拡張へ解決されるようになっていた。 判定結果は変わらないが、集合検索が線形走査へ落ちるうえ null の扱いが暗黙になる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
コード・ドキュメント全体を「1 から実装したと見た時に妥当か」の観点で見直し、表現修正・バグ取り・効率化を行った。
意味合いごとに 7 コミットへ分割してある。
バグ・整合性(
e279374)いずれも通常構成では表出しない潜在的な不整合であり、実測で症状を観測したものではない。
@EnumishLabelの扱いが FIR と IR で割れていた。FIR のexplicitLabelOfは空白を無指定へ倒すが、IR 側はそのまま label にしていた。
ENUMIZE_INVALID_LABELで止まるため通常は IR へ届かないが、この診断を
@Suppressで潰すと「labelが""になり、FIR 側の衝突検査は変換後の単純名で行われる」という食い違いが実害になる。両者は同一規則で label を決めることが前提である
ownerGeneratorの刻印もキャッシュ登録も持たない別インスタンスを返しうる。
enumishCompanionOfへ一本化したkindOfのmapNotNullが companion を持たない末端を黙って落とし、entriesが静かに不完全になる経路だった。プラグインの中核保証に関わるため失敗させる
効率(
a7415c0)supertypeClosureはチェッカーがモジュール内の全クラスに対して呼ぶ(ENUMIZE_AMBIGUOUS_KINDの検査が無条件に走る)にもかかわらず、毎回 supertype グラフをフル走査していた。
階層メンバーの再帰展開と併せて
FirCacheへ載せ、既存のbasesCache/labelIndexCache/labelCaseCacheと同じ機構に揃えた。いずれもプロデューサが自身のキャッシュを再入しない。
併せて、同じ探索を二重実装していた tracker の
findEnumizeBase/findEnumizeBaseAmongを統合した。構造・命名(
35e7437/db246de/22b8467/787d74f)EnumizeRegularClassCheckerresolver/context/reporterを引数で手渡ししていた。検査を階層照会コンポーネントの拡張関数にし、文脈はコンテキストパラメータで受けるEnumizeGenerationRoleGeneratedEnumishCompanion.enumish/KindCompanion.base/LeafObject.baseは一度も読まれない保持値EnumizeMembershipisIntermediateは!isLeafの別名(参照 1 か所)EnumizeIrContextourPropertyGetterは backing field を除去する副作用を持つのに取得を名乗っていた →prepareGeneratedGetterisOurGenerated/isOurGeneratedDeclarationを IR 側と同名のisGeneratedByEnumizeへ。内部専用の 5 メンバーを private 化couldBeHierarchyMember、呼び出し 1 か所のunsupportedKotlinWarningを除去ドキュメント(
62ad4fd)トップレベルアクセサ(
$enumizeKindAccessor$<相対名>)に当てはまらない状態だった検証
build: green・Kotlin 警告 0・Dokka 警告 0--rerunで強制再実行)w:2 件は producer-jvm のフィクスチャが意図的に発火させるENUMIZE_EXTENSION_SHADOWED(API-39/40 の観測対象)Gradle 10 非互換の deprecation 警告と、プレリリース版で解消する系は対象外とした。
未着手(判断待ち)
docs/修正方針案.md(#1〜#16・#18・#19 が欠番、生存は #17 のみ)とdocs/test/保留.md(15 行中 12 行が欠番)は、分量の大半が「過去にこう判断した」の記録になっている。1 から書くなら前者は「既知の制限 1 件」、
後者は「未検証領域 3 件」の短い節で足りるが、欠番運用は両資料が明文化した方針のため手を付けていない。
🤖 Generated with Claude Code