Summary
Sub-case 3 of #755. In compiled mode, a class method declared with a non-symbol computed key — a string or number — is not callable. The interpreter handles it (it evaluates the key at runtime and installs a dynamically-named member); compiled mode emits no member for it, so the call throws TypeError: undefined is not a function.
class C { ["dyn"]() { return 42; } }
console.log((new C() as any).dyn()); // interp: 42 compiled: TypeError: undefined is not a function
const KEY = "dyn"; class C2 { [KEY]() { return 42; } }
console.log((new C2() as any).dyn()); // interp: 42 compiled: TypeError
let k = "dyn"; class C3 { [k]() { return 42; } }
console.log((new C3() as any).dyn()); // interp: 42 compiled: TypeError
The interpreter supports even the fully dynamic form (let k = "dyn"), so a compile-time constant-fold of literal/const keys would still diverge from the interpreter for the non-constant case.
Why it's hard
A .NET method's name is fixed at IL-emit time, so a method whose name is a runtime string can't be emitted as a normally-named method. Unlike the symbol-keyed case (#647, which has a dedicated symbol-method registry keyed by $TSSymbol), string keys live in the same namespace as ordinary named properties, so matching interpreter semantics requires:
- Emitting the body as a uniquely-named method (e.g.
$strmethod_N), and
- Registering it at class-definition time keyed by the runtime-evaluated string, and
- Having named property access (
obj.dyn, GetFieldsProperty) and computed access (obj["dyn"], GetIndex) consult that registry as a fallback.
Step 3 adds a lookup to the hot property-access path, so it needs to be gated/structured to avoid a perf regression for the common (no-string-keyed-methods) case.
Scope
Compiled-only; interpreter is correct. The regression test NonSymbolComputedMethodKey_FoldsToNamedMethod in SharpTS.Tests/SharedTests/ComputedSymbolMethodTests.cs stays InterpretedOnly until this lands. Split out from #755 (whose symbol-keyed sub-cases 1 & 2 are fixed).
Summary
Sub-case 3 of #755. In compiled mode, a class method declared with a non-symbol computed key — a string or number — is not callable. The interpreter handles it (it evaluates the key at runtime and installs a dynamically-named member); compiled mode emits no member for it, so the call throws
TypeError: undefined is not a function.The interpreter supports even the fully dynamic form (
let k = "dyn"), so a compile-time constant-fold of literal/constkeys would still diverge from the interpreter for the non-constant case.Why it's hard
A .NET method's name is fixed at IL-emit time, so a method whose name is a runtime string can't be emitted as a normally-named method. Unlike the symbol-keyed case (#647, which has a dedicated symbol-method registry keyed by
$TSSymbol), string keys live in the same namespace as ordinary named properties, so matching interpreter semantics requires:$strmethod_N), andobj.dyn,GetFieldsProperty) and computed access (obj["dyn"],GetIndex) consult that registry as a fallback.Step 3 adds a lookup to the hot property-access path, so it needs to be gated/structured to avoid a perf regression for the common (no-string-keyed-methods) case.
Scope
Compiled-only; interpreter is correct. The regression test
NonSymbolComputedMethodKey_FoldsToNamedMethodinSharpTS.Tests/SharedTests/ComputedSymbolMethodTests.csstaysInterpretedOnlyuntil this lands. Split out from #755 (whose symbol-keyed sub-cases 1 & 2 are fixed).