Skip to content

fix(dart): index a Dart 3 extension type as the type it is (#1784) - #1865

Open
Dshuishui wants to merge 1 commit into
colbymchenry:mainfrom
Dshuishui:fix/dart-extension-type
Open

Dshuishui wants to merge 1 commit into
colbymchenry:mainfrom
Dshuishui:fix/dart-extension-type

Conversation

@Dshuishui

@Dshuishui Dshuishui commented Sep 14, 2026

Copy link
Copy Markdown

Fixes #1784 — implements the report's option 2. Rebased onto 58c07e8.

The change

Four places, in two of which the report already pointed:

// src/extraction/languages/dart.ts
extraClassNodeTypes: ['mixin_declaration', 'extension_declaration'],   // named in the report
// and dartEnclosingTypeName, which walks up the parents for the enclosing type's name
// codegraph-kernel/src/dart.rs — two matches! arms
"class_definition" | "mixin_declaration" | "extension_declaration" | "enum_declaration"

extension_declaration, the older extension, is in all four;
extension_type_declaration is in none. classTypes and enumTypes are left
alone — extraClassNodeTypes is where extension and mixin already sit, and
that is enough.

What main does today

On 58c07e8, both extraction paths agree, and both are wrong. The report's
repro yields two top-level functions and no type for them to belong to:

function:km   function:report        (no MetersT node)

That is the report's option 1 already in the tree. #1862 narrowed the
isInsideClassLikeNode gate to TS/JS/ArkTS — the same shape the report
proposed — and it does what the report said it would: km is back. It landed as
part of a regression audit rather than against #1784, so the issue reads as
though nothing has moved, which is worth knowing before checking the repro: what
you see now is a top-level function, not the missing member the report describes.

What option 1 leaves is the mis-kinding the report also calls out — a top-level
function rather than a member of its type.

kernel-dart-parity is green there — 18/18 — because the two arms agree. The
suite proves the paths match each other; it cannot prove either is right, so
this defect sits behind a green gate with nothing pinning it.

Result

With this PR, on the report's repro verbatim, both paths:

class:MetersT · method:MetersT::km

which is the shape the report calls strictly better — a member of its type
rather than a top-level function. With a fixture that has a second member, that
member's span recovers too: it runs to its closing brace instead of stopping at
the signature line. An ordinary class is unchanged, and so are extension and
mixin — those two are already covered by the parity suite's Dart torture
fixtures, which stay green.

The two sides have to move together: with only dart.ts changed the walker
reads the type correctly while the kernel keeps minting top-level functions, and
the paths disagree. The numbers for that are under Tests.

Tests

Adds __tests__/dart-extension-type.test.ts — the extension-type fixture the
report notes is missing. It pins the node kind, the qualified name, the span of
the member that follows, and an ordinary class as a control.

Each half of the change is pinned by a different gate, which is worth stating
exactly. Reverting the dart.ts hunks fails this suite's first case on the wasm
path (1 of 3). Reverting the .rs hunks leaves this suite green — with a kernel
staged it is the kernel that answers — and instead takes kernel-dart-parity
from 18/18 to 4 failures. Both measured on this branch.

Full suite on this branch: 4 failures. 58c07e8, built and run on its own:
the same 4, git-hooks.test.ts, which depend on this machine's global
core.hooksPath. Nothing here is new. kernel-dart-parity stays 18/18, now
agreeing on the right answer.

So this is the report's option 2, on top of option 1 rather than instead of it —
the two are complementary, and #1862 got the first half there ahead of this. What
remains is the difference the report calls strictly better: method:MetersT::km
rather than function:km.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Dshuishui
Dshuishui force-pushed the fix/dart-extension-type branch 2 times, most recently from b7a15f4 to 778e372 Compare September 14, 2026 11:08
Dshuishui added a commit to fmagent-project/codegraph that referenced this pull request Sep 14, 2026
`class Repo { loadAll = function* () {…} }` is a method written as a field.
Two helpers decide that — one classifies the field, one finds the body to walk
— and each lists the node types a field's value may have.

Upstream's generator fix (colbymchenry#1743) is wider than the fork's everywhere except
here: it did not reach those two helpers. The merge took upstream's copy of
`languages/typescript.ts` and `languages/javascript.ts` wholesale, so the
lists lost `generator_function` on the walker side while the kernel kept it —
and the kernel runs by default. The same source then read as a method on one
extraction path and a property on the other:

  node:missing-in-kernel:property  Repo::loadAll
  node:extra-in-kernel:method      Repo::loadAll
  (with its contains edge and its body's call moving with it)

Which one a project got depended on whether a kernel binary was staged.
`kernel-tsjs-parity` did not catch it: no fixture holds a generator-valued
field.

Restoring the six hunks on the walker side settles it, and settles it the way
the kernel already reads — a generator field is a method, which is what it is.
The fixture now reports 2/2 byte-parity, and a sweep of this repo's own 274
TypeScript sources reports none.

FORK.md's patch list was two short of the tree: this one, and the Dart
extension type carried since aa8d4ae. Both are listed now, the Dart one marked
temporary against upstream PR colbymchenry#1865. CHANGELOG gets an entry and loses a
duplicated `### Fixes` heading left by two separate commits.

`repro-1373/` goes: three scratch files for upstream issue colbymchenry#1373, left at the
repository root by an earlier sync, referenced from nowhere, shipped in every
release and indexed into every graph built here.
@bompus

bompus commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Option 2 matches the diagnosis in #1784: extension_type_declaration on extraClassNodeTypes and the enclosing-type walk, plus the two kernel matches! arms so the native path does not keep minting km as a top-level function. The new fixture pins method:MetersT::km, the following member's span, and an ordinary class as control.

Option 1 (language-narrow the method_signature gate) is still a separate guard, as you said. I have not run the suite on this branch.

Dshuishui added a commit to fmagent-project/codegraph that referenced this pull request Sep 15, 2026
…iant

The patch here reached the same result by a different lever than the one sent
upstream as colbymchenry#1865: it listed `extension_type_declaration` on `classTypes`, where
the pull request lists it on `extraClassNodeTypes` and in the enclosing-type
walk. Both make an extension type's members methods under it — on this fixture
the two produce the same nodes, spans and kinds — but they are different edits,
and FORK.md called them the same change.

That costs something precisely when the patch is supposed to be free: colbymchenry#1865
merges, the base moves past it, and whoever drops this patch finds the lines it
names are not the lines that arrived. So take the pull request's version
verbatim. `dart.ts` and `dart.rs` now match its diff line for line, and the
kernel arms were already identical.

The issue's author has read colbymchenry#1865 and confirmed it answers his diagnosis; no
maintainer review yet.

Dart cover passes 21 of 21 — this fork's three cases plus upstream's
kernel-dart-parity — and the suite's 18 failures are the same set as before,
which is upstream's own set minus the Dart ones.
@bompus

bompus commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Independently verified on Linux (REDACTED_SECRETS, from-source kernel build). Two findings, one for the fix and one for the branch:

1. The fix is correct and complete. On current main (58c07e8) both paths emit function:km with no MetersT node at all — the parity suite is green there only because both arms agree on the wrong answer, so the bug is real and unpinned. With this PR applied: kernel-dart-parity 18/18, the new dart-extension-type 3/3 (it pins the right shape, class:MetersT · method:MetersT::km, plus the second-member span and the ordinary-class control).

2. The branch needs a rebase, and it is a clean one. As pushed (based at 3ed73bc) the branch fails 12 unrelated tests on a current tree — mcp-callers-truncation, object-literal-methods, react-native-bridge, nextjs, ui-steps-* — purely from staleness (all fixed on main by #1849/#1862 after this branched). I cherry-picked 778e372 onto 58c07e8: zero conflicts (none of its 3 files were touched since), rebuilt the kernel, and re-ran everything — all green, including those 12. So: rebase and this is merge-ready from where I sit.

…nry#1784)

`extension_type_declaration` appears in none of the three places Dart's other
type-like declarations do. `extension_declaration` — the older `extension` — is
in all three, and the two names are near neighbours.

That is why colbymchenry#1780's `isInsideClassLikeNode()` gate dropped these members and no
others: the gate asks whether a class-like node is on the stack, and an
`extension type` never put one there, while `extension`, `mixin` and `class`
all did. The gate surfaced the omission rather than causing it. Before it, the
members were still reached — but as top-level `function:km` rather than
`method:MetersT::km`, indexed and attributed to nothing.

The kernel omits the same node type, so it walks the members through its own
fallback and mints them as top-level functions with no `MetersT` to belong to.
`kernel-dart-parity.test.ts` fails four cases on `main` because of it; fixing
only the wasm side would leave those red.

Listing it alongside the others is the whole fix — `extraClassNodeTypes` and
`dartEnclosingTypeName` on the wasm side, the two `matches!` arms on the
kernel's. Both paths now give:

    class:MetersT · method:MetersT::km · method:MetersT::report

with `report`'s span running to its closing brace rather than stopping at the
signature line, and an ordinary class untouched.
@Dshuishui
Dshuishui force-pushed the fix/dart-extension-type branch from 778e372 to 8d8c1ec Compare September 15, 2026 15:49
@Dshuishui

Copy link
Copy Markdown
Author

Rebased onto 58c07e8 — and confirmed your reading here first, since it changes what the body should say.

On current main both paths emit function:km / function:report with no MetersT, and kernel-dart-parity is 18/18 there. So the gate proves the arms agree, not that either is right, and this defect was sitting behind a green one. The body now says that instead of the stale "four parity failures" framing, which was true only against the older base.

The half you flagged as separate is measured too: reverting just the .rs hunks leaves the new suite green — with a kernel staged the kernel is what answers — and takes kernel-dart-parity from 18/18 to 4 failures. Reverting just the dart.ts hunks fails the new suite's first case on the wasm path. That is why both are in one commit.

Full suite here: 4 failures, the same git-hooks ones 58c07e8 has on its own.

@Dshuishui

Dshuishui commented Sep 16, 2026

Copy link
Copy Markdown
Author

Option 1 is already in the tree — #1862 narrowed the isInsideClassLikeNode gate to TS/JS/ArkTS, the same shape the report proposed. The body reflects that now.

Worth flagging because it changes what the repro looks like: on 58c07e8 you get a top-level function:km rather than the missing member #1784 describes. Since #1862 landed as a regression audit rather than against that issue, the issue reads as though nothing has moved — easy to check the repro and conclude it is fixed.

What is left is the half the report called strictly better — method:MetersT::km instead of function:km — which is what this PR does. The two are complementary rather than alternatives.

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