From 03cb402db0a485715fd206fd7a48459c74706a10 Mon Sep 17 00:00:00 2001 From: cs01 Date: Mon, 20 Apr 2026 04:17:16 -0700 Subject: [PATCH] refactor(codegen): widen variableallocatorcontext with typeof+resolveexpressiontyperich (phase-e step 5) --- src/codegen/infrastructure/variable-allocator.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/codegen/infrastructure/variable-allocator.ts b/src/codegen/infrastructure/variable-allocator.ts index e0e66bd8..b6e2efcd 100644 --- a/src/codegen/infrastructure/variable-allocator.ts +++ b/src/codegen/infrastructure/variable-allocator.ts @@ -199,6 +199,11 @@ export interface VariableAllocatorContext { setLastTypeAssertionSourceVar(name: string | null): void; setCurrentVarDeclKey(key: string | null): void; isStackEligibleKey(key: string): boolean; + // New methods pinned at END of interface: adding them mid-interface shifts + // native vtable slot positions for everything below — see CLAUDE.md rule #5 + // and memory/native-method-deletion-breaks-vtable.md. + resolveExpressionTypeRich(expr: Expression): ResolvedType | null; + typeOf(expr: Expression): ResolvedType | null; } export class VariableAllocator { @@ -737,6 +742,13 @@ export class VariableAllocator { const stmtDeclaredType: string = stmt.declaredType || ""; const strippedDeclType = stripNullable(stmtDeclaredType); + // NOTE: stays on flat resolveExpressionType. Switching to typeOf() + // returns a freshly-allocated enriched clone; passing that to the + // downstream consumer here produces wrong native GEP offsets (likely + // Phase C normalizer didn't canonicalize the enrichResolvedType + // literal). Calling typeOf() and DISCARDING works; USING the result + // breaks. Needs normalizer coverage on enrichResolvedType before + // this consumer can migrate. const resolved = this.ctx.resolveExpressionType(stmtValue); const nodeType = (stmtValue as ExprBase).type;