Skip to content

fix(dart): three residual func_start/args defects from #2308/#2309 - #2311

Merged
squid-protocol merged 2 commits into
mainfrom
fix/dart-func-start-residual-gaps-2308-2309
Aug 27, 2026
Merged

fix(dart): three residual func_start/args defects from #2308/#2309#2311
squid-protocol merged 2 commits into
mainfrom
fix/dart-func-start-residual-gaps-2308-2309

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

Fixes three confirmed, source-evidenced dart engine defects found while re-investigating #2308 and #2309 (a tri-comparison-ledger-sweep re-check of dart's ledger shapes, which turned up that #2072 had been closed as "completed" while only 2 of its 6 documented items were actually fixed by #2129).

  1. func_start: implements/with could appear as an ordinary interior token in the return-type-prefix consumption loop when a match starts on an earlier mixin-name line of a multi-line class header, letting the following identifier become a phantom function name (AutofillClient in flutter/editable_text.dart). extends deliberately left out of the fix — already confirmed ambiguous with generic method type-parameter bounds (pushNamed<T extends Object?>(...)) in the prior investigation.
  2. _dart_scan_terminator (detector.py): a bare comparison operator inside a constructor's colon-initializer list (assert(order < double.infinity)) was mistaken for a generic angle-bracket open, permanently poisoning the depth counter and making the terminator scan run off the end of the file — OrdinalSortKey (flutter/semantics.dart) was silently dropped from output entirely, not just miscounted.
  3. args counting: a bodyless this./super.-forwarding constructor (_DeleteTextAction(this.state, ...);) read 0 args. Tried extending the shared args regex to accept a bare ; terminator directly; reverted after it broke test_dart_args_invalid and independently regressed zero-paren getters into borrowing an unrelated inner call statement's args. Fixed instead via args_count_override, counting the already-func_start-validated parameter list directly for this one shape without loosening the regex's own contract.

#2309's original hypothesis (func_start matching a generic-bounded class header itself under the constructor's name) turned out not to be the actual mechanism for the case investigated here — left open, since the class-header collision itself wasn't reproduced with real evidence in this pass.

Test plan

  • Standalone regex re-tests for all 3 fixes against real corpus snippets, plus a regression guard for the generic-bound extends case
  • pytest tests/extraction/languages/test_dart.py tests/extraction/languages/test_dart_strict.py (196 passed)
  • pytest tests/extraction/ — full suite, all languages (6234 passed, no regressions)
  • pytest tests/ --ignore=tests/extraction (broader suite, passed)
  • python tests/ruff_audit.py --ci / python tests/mypy_audit.py --ci — no new findings
  • python tests/tools/crucible_check.py — full precision + zero-dependency, full ~80-repo corpus: PASS
  • python tests/tools/tree_sitter_accuracy_audit.py --ci --lang dart — improved, no regression
  • python tests/tools/tri_comparison_chart.py --all --ci — no regression (dart has no committed baseline yet)
  • Golden masters re-blessed; diff traces entirely to dart's corrected structural signatures plus expected spatial-layout ripple in a handful of unrelated files (confirmed via full diff review, not just skimmed)

Fixes #2308. Partially addresses #2309 — the args undercount for the _DeleteTextAction-shaped bodyless constructors is fixed; the generic-bounded class-header args misattribution hypothesis in that issue is unresolved and left open.

🤖 Generated with Claude Code

…-bracket poisoning, bodyless-ctor args undercount

Three confirmed, evidenced defects from #2308/#2309, found via a
tri-comparison-ledger-sweep re-investigation of dart after #2072 was closed
prematurely (only 2 of its 6 items were actually fixed by #2129):

- func_start: `implements`/`with` can appear as an ordinary interior token in
  the return-type-prefix consumption loop when a match starts on an earlier
  mixin-name line of a multi-line class header, letting the following
  identifier become a phantom function name (`AutofillClient` in
  flutter/editable_text.dart). Added to the shared keyword-exclusion list
  everywhere it appears; `extends` deliberately left out (ambiguous with
  generic method type-parameter bounds, already confirmed unsafe to exclude
  in the prior investigation).

- detector.py's `_dart_scan_terminator`: bare comparison operators inside a
  constructor's colon-initializer list (`assert(order < double.infinity)`)
  were mistaken for generic angle-bracket opens, permanently poisoning
  `depth_angle` and making the terminator scan run off the end of the file
  without ever finding the real `;`/`{` (`OrdinalSortKey` in
  flutter/semantics.dart, silently dropped from output entirely). Now only
  counts a `<` as a generic-open when directly attached to an identifier.

- args counting: a bodyless `this.`/`super.`-forwarding constructor
  (`_DeleteTextAction(this.state, ...);`) read 0 args because the separate
  `args` regex never accepted a bare `;` terminator. Tried extending the
  regex directly; reverted after it broke `test_dart_args_invalid` and
  independently regressed zero-paren getters (`Rect get bounds { ... }`)
  into borrowing an unrelated inner call statement's args. Fixed instead via
  `args_count_override`, counting the already-`func_start`-validated
  parameter list directly for this one shape.

Verified: dart extraction gauntlet + strict tests, full extraction suite
(all languages), ruff/mypy audits, crucible_check.py (full precision +
zero-dependency, full ~80-repo corpus), tree_sitter_accuracy_audit,
tri_comparison_chart --ci. Golden masters re-blessed; diff traces entirely
to dart's corrected structural signatures plus expected spatial-layout
ripple in a handful of unrelated files.

Fixes #2308, partially addresses #2309 (the class-header-vs-constructor
args misattribution for generic-bounded classes remains open, tracked in
that issue).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

@squid-protocol
squid-protocol merged commit 7358125 into main Aug 27, 2026
30 checks passed
@squid-protocol
squid-protocol deleted the fix/dart-func-start-residual-gaps-2308-2309 branch August 27, 2026 08:49
squid-protocol added a commit that referenced this pull request Aug 27, 2026
…#2309) (#2335)

`_count_top_level_args` unwraps a signature's outer `(...)` and counts
depth-0 commas in the remaining body. For a Dart parameter list whose
parameters live in a named group `({a, b, c})` or an optional-positional
group `([a, b])`, the group's own `{`/`[` was read as ordinary nesting --
so every comma inside sat at depth 1 and none counted. A Flutter widget
constructor like `EditableText({super.key, required this.controller, ...})`
measured **1** argument instead of 76; `_Editable`, `_UpdateTextSelectionAction`
and ~dozens more were similarly flattened. This is the args half of #2309
(the `func_start` existence half, and the bodyless `this.`/`super.`-forwarding
constructor case, were handled by #2071 / #2311).

Fix: in `_count_top_level_args`, for `primary_lang_id == "dart"`, when the
parameter-list body ends (ignoring trailing whitespace) in `}` or `]`,
locate that terminal group's matching opener at depth 0 and blank just those
two delimiter characters, so the group's members land at the top level and
their separating commas are counted. A `{...}` / `[...]` that is a
default-VALUE literal (`{int x = const [1, 2, 3]}`, `{Map m = const {'a': 1}}`)
is never flush against the body's end, so it stays nested and its internal
commas stay correctly ignored. Scoped to dart -- no other language's count
path is touched.

Result (name-matched `gather_language("dart")` args diff vs tree-sitter):
GitGalaxy under-counts by >=2 (excluding tree-sitter's own same-name
reconciliation inflation) drop from ~40 to 2, and those 2 are tree-sitter /
reconciler quirks, not GitGalaxy defects (`build` at editable_text.dart:6253
is genuinely 1 param; `copyWith` at theme_data.dart:140 is a bodyless
abstract method with 0). `EditableText` (1->76), `_Editable` (1->39),
`_UpdateTextSelectionAction` (4->6) now match tree-sitter exactly.

Regenerated:
- Both golden masters -- 328 diffs, all dart (arg counts + downstream
  structural-impact / spatial-coordinate ripple); 0 non-dart content change.
- `tree_sitter_accuracy_baseline_dart.json` -- `args_exact_match` 1519 -> 1633
  (+114); summary table in `language_standards.py` Dart row 99.4% -> 99.5%.
- `tree_sitter_accuracy_baseline_javascript.json` -- `files_scanned` 18 -> 17,
  a stale value left by #2331 (GATE D relegating `threejs/Nodes.js`); the
  tree-sitter-accuracy workflow doesn't trigger on statistical_auditor.py
  paths so it was never updated. Included here so this PR's own
  tree-sitter-accuracy-audit run (which `detector.py` does trigger) is green.

Verification: test_detector.py (+ new `_count_top_level_args` dart case) and
tests/extraction (6234) green; ruff/mypy/dead-key/ast-accuracy clean;
crucible_check both modes PASS; tree_sitter_accuracy_audit --all --ci and
tri_comparison_chart --all --ci both green.

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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 func_start: three residual false-positive/recall gaps left when #2072 was closed as complete

1 participant