Skip to content

fix(dart): why the tri-comparison args shape was so large — 3 residual causes (#2309) - #2342

Merged
squid-protocol merged 1 commit into
mainfrom
fix-dart-tricomparison-args-residual
Aug 27, 2026
Merged

fix(dart): why the tri-comparison args shape was so large — 3 residual causes (#2309)#2342
squid-protocol merged 1 commit into
mainfrom
fix-dart-tricomparison-args-residual

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Explores and largely closes why dart is different in the tri-comparison — the
dart/function/args/agree[none]_vs[gitgalaxy,tree_sitter] shape (106 occurrences after #2335,
was 205; dart is the only language with an args shape this large).

Every one of the 106 was gg=N, ts=0 or gg=1, ts=0 — one tool reporting a real count, the other 0. None were a genuine arg-count disagreement. Three distinct causes:

1. tree-sitter ground truth wrong for const/factory constructors

_get_param_count in tree_sitter_accuracy_audit.py (reused by the tri-comparison gatherer): constant_constructor_signature (const PointerEvent({...})) and factory_constructor_signature (factory ThemeData({...})) don't expose a field-tagged parameters child — unlike plain constructor_signature — so they hit return 0. Every const/factory constructor in the dart corpus measured 0. Added both node types to the direct-formal_parameter_list branch. ~30 mismatches.

2. GitGalaxy over-counts a paren-less getter

Offset get pan;_count_top_level_args("Offset get pan") has no ( to unwrap → returns 1 (whole string as one segment). The bodyless-; branch now returns 0 when not has_parens. ~15 mismatches.

3. GitGalaxy under-counts operator overloads

bool operator ==(Object other) — the args regex needs NAME(...) but == sits between the name and the (, so .search() → None → count falls to 0. Added dart to the "regex failed → structural counter" fallback that c/cpp already use (#2012), guarded on a literal ( so paren-less getter bodies still read 0. ~12 mismatches.

Result

before #2309 after #2335 this PR
args mismatch shape 205 106 6
dart args accuracy ~87% 93.9% 99.65%
args_exact_match (tree-sitter baseline) 1519 1633 1733

The 6 survivors are all one unrelated shape — a multi-line @Deprecated('...' '...',) annotation that dart's func_start wrongly consumes as a return-type prefix, so the annotation's own parens get counted. Filed as #2341.

Regenerated

Verification

  • test_dart.py (+ new getter/operator slicer case) + tests/extraction (6235) — green
  • ruff / mypy / dead-key / ast-accuracy — clean
  • crucible_check.py — PASS both modes
  • tree_sitter_accuracy_audit --all --ci + tri_comparison_chart --all --ci — both green

🤖 Generated with Claude Code

…al causes (#2309)

Explored `dart/function/args/agree[none]_vs[gitgalaxy,tree_sitter]` (106
occurrences after #2335's named-parameter-group fix, was 205). Every one was
`gg=N ts=0` or `gg=1 ts=0` -- i.e. one tool reporting a real count and the
other 0. Three distinct causes, none of them a "real" arg-count disagreement:

1. **tree-sitter ground truth wrong for const/factory constructors**
   (`tree_sitter_accuracy_audit.py::_get_param_count`, reused by the
   tri-comparison gatherer). `constant_constructor_signature`
   (`const PointerEvent({...})`) and `factory_constructor_signature`
   (`factory ThemeData({...})`) don't expose a field-tagged "parameters"
   child -- unlike the plain `constructor_signature` -- so they fell through
   to `return 0`. Every `const`/`factory` constructor in the dart corpus (the
   dominant Flutter widget-constructor form) measured 0. Added both node types
   to the direct-`formal_parameter_list`-child branch that already handles
   `function_signature`/`setter_signature`. ~30 large mismatches.

2. **GitGalaxy over-counts a paren-less getter** (`detector.py`). A bodyless
   `Offset get pan;` reached `_count_top_level_args("Offset get pan")`, which
   has no `(` to unwrap and returns 1 (whole string as one segment). The
   bodyless-`;` branch now returns 0 when `not has_parens`. ~15 mismatches.

3. **GitGalaxy under-counts operator overloads** (`detector.py`). The `args`
   regex needs `NAME(...)`; `bool operator ==(Object other)` has `==` between
   the name token and the `(`, so `.search()` returns None and the count
   falls to 0. Added dart to the same "regex failed -> structural counter"
   fallback c/cpp already use (#2012), guarded on a literal `(` in the
   signature text so a paren-less getter body still reads 0. ~12 mismatches.

Result: the args shape drops 106 -> 6, dart args accuracy 93.9% -> 99.65%,
GitGalaxy and tree-sitter now agree on 1733/1739 comparable functions.

The 6 survivors are all one unrelated shape -- a multi-line
`@Deprecated('...' '...',)` annotation that dart's `func_start` wrongly
consumes as a return-type prefix, so the annotation's own parens get counted
instead of the real parameter list. Filed separately.

Regenerated: both golden masters (26 diffs, all dart -- arg counts +
downstream ripple, 0 non-dart content change); `tree_sitter_accuracy_baseline_
dart.json` (`args_exact_match` 1633 -> 1733). No summary-table or javascript-
baseline change needed (a post-#2335 companion already refreshed the latter).

Verification: test_dart.py (+ new getter/operator slicer case) + tests/
extraction (6235) green; ruff/mypy/dead-key/ast-accuracy clean; crucible_check
both modes PASS; tree_sitter_accuracy_audit --all --ci + tri_comparison_chart
--all --ci both green.

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 1676865 into main Aug 27, 2026
30 checks passed
@squid-protocol
squid-protocol deleted the fix-dart-tricomparison-args-residual branch August 27, 2026 20:06
squid-protocol added a commit that referenced this pull request Aug 27, 2026
#2341) (#2347)

dart's `func_start` match spans any leading `@annotation(...)` prefix and the
return-type prefix, so `start_idx` (the block start / args-span start) can
land on an annotation. When that annotation's argument list is multi-line and
carries a top-level comma -- `@Deprecated('Use x. ' 'Deprecated after v3.3.',)`
is the corpus shape -- its own `(...)` is the first paren the args counter
finds, and the declaration's real parameter list is never measured
(`ToolbarOptions` const ctor read 0 args, several deprecated getters read 1).

Fix: for dart, every args-span computation anchors at `match.start(match.
lastindex)` -- the name capture -- instead of `start_idx`. Same
`match.lastindex` name-anchor the typescript/javascript branch of
`_slice_by_braces` already uses. `start_idx` still bounds the block itself
(line numbers, body slice); only the parameter-count slice moves.

This closes out the `dart/function/args/agree[none]_vs[gitgalaxy,tree_sitter]`
shape entirely: **0 remaining args mismatches** across the 7-file Flutter
corpus (was 205 before #2309, 106 after #2335, 6 after #2342), dart args
accuracy 99.65% -> **100.0%** (`args_exact_match` 1733 -> 1739 / 1739).

Regenerated: both golden masters (16 diffs, all dart -- arg counts + downstream
ripple, 0 non-dart content change); `tree_sitter_accuracy_baseline_dart.json`.
No summary-table or javascript-baseline change.

Verification: test_dart.py (+ new annotation-prefix slicer case) + tests/
extraction (6236) green; ruff/mypy/dead-key/ast-accuracy clean; crucible_check
both modes PASS; tree_sitter_accuracy_audit --all --ci 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.

1 participant