Skip to content

fix(dart): index extension type members in both extraction arms (#1784) - #1791

Open
inth3shadows wants to merge 2 commits into
colbymchenry:mainfrom
inth3shadows:fix/1784-dart-extension-type
Open

fix(dart): index extension type members in both extraction arms (#1784)#1791
inth3shadows wants to merge 2 commits into
colbymchenry:mainfrom
inth3shadows:fix/1784-dart-extension-type

Conversation

@inth3shadows

Copy link
Copy Markdown

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 behind isInsideClassLikeNode() so a TS interface member could not mint a phantom free function. That is right for TS, but a Dart 3 extension type body 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,

extension type Meters(double value) {
  double get km => value / 1000;
  void show() { print(km); }
}

extracts function:show and nothing else — no Meters, no km. So extension type was 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_declaration to Dart's extraClassNodeTypes fixes both halves at once and gives the members the right owner — method:Meters::km instead of a loose top-level km. 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:km while wasm emitted nothing, which is why kernel-dart-parity is red on main today — all four cases, torture.dart and TortureCtors.dart including their CRLF variants. codegraph-kernel/src/dart.rs listed the class-like node types in two places (enclosing_type_name and 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:11 is exactly this construct. The suite simply never runs without a staged .node, since every kernel-*-parity suite describe.skipIfs itself. From source, npm test reports 188 skipped; after scripts/build-kernel.sh, 10, and those four turn red.

Verification

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 three remaining failures — object-literal-methods and two in ui-steps-api — reproduce on a clean upstream/main worktree and are unrelated to this change.

The new test pins both directions: the extension type and its members are indexed, and extension / mixin / class bodies are unaffected.

Note for whoever merges: this changes the kind and qualified name of extension-type members (function:kmmethod: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.

…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.
@bompus

bompus commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Verified on Linux (WSL2, Node v26.8.2, from-source kernel build) at 133f9fa: dart-extension-type.test.ts (2 new tests) green, and the full kernel-dart-parity.test.ts file green 18/18 — including the 4 torture.dart / TortureCtors.dart cases that are red on current main per #1784 (kernel emitting function:km with no wasm counterpart). Both arms now agree on method:Meters::km.

This was reported from our side in #1784, so noting for the record: the fix matches the diagnosed cause (language check on the method_signature gate) and the parity suite we pointed at now passes with it.

@bompus

bompus commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

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 133f9fa30082fc7bc2fec147c395461ca93ce593, with a native kernel built from that checkout.

Both test runs exited 0, with no native crash or dead-worker output. The extension-type assertions retain class:Meters, method:Meters::km, and method:Meters::show; the parity suite agrees on nodes, edges, and unresolved references.

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.

@inth3shadows

Copy link
Copy Markdown
Author

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 CODEGRAPH_KERNEL_EXPECT=1 so the parity cases actually ran rather than skipped, is worth more than anything I can assert about my own branch.

Re-checked just now: the head is still 133f9fa, MERGEABLE, and 0 behind main @ 3ed73bc. Nothing has moved under it since your run, so your evidence still describes what is on the branch.

Nothing outstanding from my side — happy to rebase or re-run anything if it sits long enough to drift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dart: extension type members stopped being indexed in #1780 — the method_signature gate has no language check

2 participants