Skip to content

Compiled: non-symbol (string/number) computed class method keys are unsupported #791

@nickna

Description

@nickna

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:

  1. Emitting the body as a uniquely-named method (e.g. $strmethod_N), and
  2. Registering it at class-definition time keyed by the runtime-evaluated string, and
  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions