Two items flagged in the dual-agent review of commit 883051f (feat(ts): lower [Import] methods to direct call sites + $T0 type-arg placeholder) but deferred to keep the original commit focused.
1. Drop _templateExternals field from ImportCollector
File: src/Metano.Compiler.TypeScript/Transformation/ImportCollector.cs
Currently the field is set/cleared via try/finally in Collect() and read by the TsTemplate walker case in CollectFromExpression. Bob marked this Major — implicit stateful coupling across an otherwise pure walker.
Two acceptable shapes:
- (a) Thread
List<IrExternalImport> templateExternals as an extra param through CollectReferencedTypeNames → CollectFromTopLevel → CollectFromStatements → CollectFromStatement → CollectFromExpression (~47 call sites — mechanical).
- (b) Introduce a
CollectionSink record bundling (names, valueNames, runtimeHelpers, crossPackageOrigins, templateExternals) and pass that one object. Pick (b) if also cleaning up the existing 4-param chain.
2. [Emit] template path bypasses argument normalization
File: src/Metano.Compiler/Extraction/IrExpressionExtractor.cs
Helpers: BuildEmitTemplateExpression + CollectPositionalReceiverAndArgs
Compiler-man flagged this Major. Currently the [Emit] template path does:
inv.ArgumentList.Arguments.Select(a => Extract(a.Expression))
— bypasses ExtractArgument/ApplyParamsSpread/NormalizeArguments. Consequences:
- Named args (
Foo(b: 2, a: 1)) land positionally — \$0=b, \$1=a — instead of parameter-declaration order.
params T[] becomes a positional array, not spread.
ref/out flow through as plain expressions.
- Skipped optional defaults aren't filled.
The [Import] facade path (BuildImportFacadeTemplateExpression) added in 883051f uses normalization correctly — port the same approach back to the [Emit] path.
Tests to add
- TUnit golden: named args at
[Emit] call site reorder to parameter declaration order.
- TUnit golden:
params T[] at [Emit] call site spreads.
- TUnit golden: explicit defaults filled when caller omits the arg.
- Diagnostic for
RefKind != None at [Emit] call site (TS has no out/ref).
Validation
dotnet run --project tests/Metano.Tests/
cd targets/js/sample-counter-v5 && bun run build
cd targets/js/sample-todo && bun run build && bun test
cd targets/js/sample-issue-tracker && bun run build && bun test
cd targets/js/sample-todo-service && bun run build && bun test
Workflow
Open a stacked PR per item if both can land independently. Use the compiler-man and bob agents in parallel for review before committing.
Refs: 883051f, #188, #189.
Two items flagged in the dual-agent review of commit 883051f (
feat(ts): lower [Import] methods to direct call sites + $T0 type-arg placeholder) but deferred to keep the original commit focused.1. Drop
_templateExternalsfield fromImportCollectorFile:
src/Metano.Compiler.TypeScript/Transformation/ImportCollector.csCurrently the field is set/cleared via try/finally in
Collect()and read by theTsTemplatewalker case inCollectFromExpression. Bob marked this Major — implicit stateful coupling across an otherwise pure walker.Two acceptable shapes:
List<IrExternalImport> templateExternalsas an extra param throughCollectReferencedTypeNames→CollectFromTopLevel→CollectFromStatements→CollectFromStatement→CollectFromExpression(~47 call sites — mechanical).CollectionSinkrecord bundling(names, valueNames, runtimeHelpers, crossPackageOrigins, templateExternals)and pass that one object. Pick (b) if also cleaning up the existing 4-param chain.2.
[Emit]template path bypasses argument normalizationFile:
src/Metano.Compiler/Extraction/IrExpressionExtractor.csHelpers:
BuildEmitTemplateExpression+CollectPositionalReceiverAndArgsCompiler-man flagged this Major. Currently the
[Emit]template path does:— bypasses
ExtractArgument/ApplyParamsSpread/NormalizeArguments. Consequences:Foo(b: 2, a: 1)) land positionally —\$0=b, \$1=a— instead of parameter-declaration order.params T[]becomes a positional array, not spread.ref/outflow through as plain expressions.The
[Import]facade path (BuildImportFacadeTemplateExpression) added in 883051f uses normalization correctly — port the same approach back to the[Emit]path.Tests to add
[Emit]call site reorder to parameter declaration order.params T[]at[Emit]call site spreads.RefKind != Noneat[Emit]call site (TS has noout/ref).Validation
Workflow
Open a stacked PR per item if both can land independently. Use the
compiler-manandbobagents in parallel for review before committing.Refs: 883051f, #188, #189.