fix(dart): index extension type members in both extraction arms (#1784) - #1791
fix(dart): index extension type members in both extraction arms (#1784)#1791inth3shadows wants to merge 2 commits into
Conversation
…ymchenry#1784) Dart spells an ordinary implemented method `method_signature` — the same node type TypeScript uses for a bodiless interface member. colbymchenry#1780 gated that node type behind isInsideClassLikeNode() to stop a TS interface member minting a phantom free function. Correct for TS, but a Dart 3 `extension type` body was not class-like, so every member in one failed the gate and was dropped. The declaration itself was missing too, not only its members: on main, extension type Meters(double value) { double get km => value / 1000; void show() { print(km); } } extracts `function:show` alone — no `Meters`, no `km`. So `extension type` was never a class-like node in the first place; colbymchenry#1780 only made the omission visible by making the members depend on it. Adding `extension_type_declaration` to Dart's extraClassNodeTypes fixes both halves at once, and gives the members the right owner: `method:Meters::km` rather than a loose top-level `km`. MIRRORED INTO THE KERNEL. Dart is default-routed to the native kernel, so a change made only in the TypeScript arm would not run in a published bundle — and here the two arms had already diverged: the kernel still emitted `function:km` while wasm emitted nothing, which is why kernel-dart-parity is RED on main today. dart.rs listed the class-like node types in two places (enclosing_type_name and the extract dispatch); both now include it. That parity suite is the regression pin this already had — it just never runs without a staged .node, since every kernel-*-parity suite describe.skipIf's itself. From source `npm test` reports 188 skipped; after build-kernel.sh, 10. Verified (Linux, Node 22.23.2, kernel built and staged): kernel-dart-parity 18/18 (4 of these fail on main) dart-extension-type 2/2 (new; both fail without the change) tsc --noEmit clean npm test 252 files, 4373 passed, 3 failed The 3 remaining failures — object-literal-methods and two in ui-steps-api — reproduce on a clean upstream/main worktree and are unrelated. Thanks to the reporter for the diagnosis; this is their suggested option 2, now measured, plus the kernel half.
# Conflicts: # CHANGELOG.md
|
Verified on Linux (WSL2, Node v26.8.2, from-source kernel build) at This was reported from our side in #1784, so noting for the record: the fix matches the diagnosed cause (language check on the |
|
Follow-up to my earlier validation comment: that run used Node 26, outside this project's supported runtime range. I have now repeated the checks on Node 24.21.0, Linux x86_64 / Ubuntu WSL2, at the same exact PR head
Both test runs exited 0, with no native crash or dead-worker output. The extension-type assertions retain This supplies supported-runtime evidence for the earlier conclusion. I did not rerun the full suite, real-repository sweeps, Windows validation, or the merge-base in this follow-up. |
|
Thank you for redoing this on a supported runtime — and for catching that the first pass was on Node 26 in the first place. Independent confirmation at the exact head, with the native kernel present and Re-checked just now: the head is still Nothing outstanding from my side — happy to rebase or re-run anything if it sits long enough to drift. |
Fixes #1784.
Dart spells an ordinary implemented method
method_signature— the same node type TypeScript uses for a bodiless interface member. #1780 gated that node type behindisInsideClassLikeNode()so a TS interface member could not mint a phantom free function. That is right for TS, but a Dart 3extension typebody is not class-like, so every member inside one failed the gate and was dropped.The declaration was missing too, not just its members
The issue reports the members disappearing. Reproducing it turned up more: on
main,extracts
function:showand nothing else — noMeters, nokm. Soextension typewas never a class-like node to begin with; #1780 only made the omission visible by making the members depend on it.That is why this takes the reporter's option 2 rather than option 1. Adding
extension_type_declarationto Dart'sextraClassNodeTypesfixes both halves at once and gives the members the right owner —method:Meters::kminstead of a loose top-levelkm. Option 1 would have restored the members while leaving the extension type itself invisible and its members mis-kinded.Mirrored into the kernel — the two arms had already diverged
Dart is default-routed to the native kernel, so a change made only in the TypeScript arm never runs in a published bundle. And the arms were already disagreeing here: the kernel still emitted
function:kmwhile wasm emitted nothing, which is whykernel-dart-parityis red onmaintoday — all four cases,torture.dartandTortureCtors.dartincluding their CRLF variants.codegraph-kernel/src/dart.rslisted the class-like node types in two places (enclosing_type_nameand the extract dispatch); both now include it.Worth noting for the "why didn't CI catch it" question in the issue: the fixture and the parity suite already exist in this repo —
__tests__/fixtures/kernel-parity/TortureCtors.dart:11is exactly this construct. The suite simply never runs without a staged.node, since everykernel-*-paritysuitedescribe.skipIfs itself. From source,npm testreports 188 skipped; afterscripts/build-kernel.sh, 10, and those four turn red.Verification
Linux, Node 22.23.2, kernel built and staged:
The three remaining failures —
object-literal-methodsand two inui-steps-api— reproduce on a cleanupstream/mainworktree and are unrelated to this change.The new test pins both directions: the extension type and its members are indexed, and
extension/mixin/classbodies are unaffected.Note for whoever merges: this changes the kind and qualified name of extension-type members (
function:km→method:Meters::km), so those nodes get new ids and a re-index is needed to see them — the CHANGELOG entry says so.Thanks to @bompus for the diagnosis; this is their option 2, measured, plus the kernel half.