fix(typescript): recognize arrow/method-shorthand defs not at line start - #2285
Merged
Conversation
func_start's object-literal-property and method-shorthand branches
were anchored to `^[ \t]*` (true line start only), so a real function
value that wasn't the first thing on its line was invisible -- a
comma-preceded sibling property (`return { result, abort: () =>
aborted = true };`) or a method shorthand nested inside a one-line
call/return argument (`foo(bar, { report(n: number) { } });`).
Widened the anchor on both branches to
`(?:^[ \t]*|(?<=[,{])[ \t\n]*)` -- true line start, OR immediately
after a comma or opening brace. Bounded (fixed-width lookbehind, no
new unbounded quantifiers), confirmed via a pathological-input timing
probe.
That widening has a real side effect worth calling out: two
pre-existing gates in detector.py's _slice_by_braces (#1631/#1632,
guarding against a phantom parameter-type annotation and a ternary
false-positive) assumed `match.start() - 1`/`match.start() - 2` was
always the newline immediately preceding true line-start -- an
assumption this widened anchor breaks, since a match can now start
right after a `,`/`{` mid-line. A first draft of this fix (caught and
reverted during verification, not shipped) regressed 6 real functions
elsewhere in the corpus this way. Fixed by having both gates
independently resolve the true start of the line containing the
CAPTURED NAME (`match.start(match.lastindex)`, falling back to
`match.start()` when lastindex is None) rather than trusting the
match's own start position.
Verified via the full 23-file typescript corpus diff against
tree-sitter: all 3 originally-targeted examples fixed (abort, report,
dispose), zero new regressions (the 6 introduced by the first draft
are all gone), missing-function count 131 -> 127 (a `firstParallel`
overload-collapse case newly surfaced by this widening is the same
pre-existing #2278-class bug, not a new one -- resolves once combined
with #2278's fix on main).
Fixes #2277.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
Structural drift fully attributable to the fix: abort/report/dispose (and the confirmed downstream ripple into topological coordinates, structural-magnitude aggregates, and Function Analysis top-N reordering for the affected files/directory groups) now correctly extracted. Independently re-verified against tree_sitter_accuracy_ audit.py's own tree-sitter walker before blessing, given #2278's own verification pass on this same day caught a real discrepancy between that tool and the corpus-diff approach used elsewhere in this sweep -- both tools agree here: extra_functions unchanged at the 12-baseline for both typescript and javascript, found_functions genuinely improved (2773 -> 2777), zero regressions. tree_sitter_accuracy_audit --all --ci: all 31 languages OK. audit_check --ci: all clear. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
squid-protocol
enabled auto-merge (squash)
August 26, 2026 20:07
Resolves conflict with #2276 (now on main): both PRs touch the same func_start branch (modifier-prefixed method shorthand) -- combined #2276's catch/return/throw conditional exclusion with #2277's widened line-start anchor into one regex, since both changes are independent and compose cleanly. Golden masters taken from origin/main wholesale and will be regenerated fresh against the merged code before pushing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2277.
func_start's object-literal-property and method-shorthand branches were anchored to^[ \t]*(true line start only), so a real function value that wasn't the first thing on its line was invisible -- a comma-preceded sibling property (return { result, abort: () => aborted = true };) or a method shorthand nested inside a one-line call/return argument (foo(bar, { report(n: number) { } });).Fix
Widened the anchor on both branches to
(?:^[ \t]*|(?<=[,{])[ \t\n]*)-- true line start, OR immediately after a comma or opening brace. Bounded (fixed-width lookbehind, no new unbounded quantifiers).Real side effect, caught during this PR's own verification (not shipped): two pre-existing gates in
detector.py's_slice_by_braces(#1631/#1632) assumedmatch.start() - 1/- 2was always the newline immediately preceding true line-start -- an assumption this widened anchor breaks, since a match can now start right after a,/{mid-line. A first draft regressed 6 real functions elsewhere in the corpus this way (caught by a full corpus diff, not by narrow unit tests). Fixed by having both gates independently resolve the true start of the line containing the captured name (match.start(match.lastindex)) rather than trusting the match's own start position.Verification
firstParallel) is the same pre-existing [TypeScript] Same-name overload signatures collapse to one — detector.py drops 6 of 7 bodylesspipeableoverloads #2278-class overload-collapse bug newly surfaced by the widened anchor, not a new bug class; resolves once combined with [TypeScript] Same-name overload signatures collapse to one — detector.py drops 6 of 7 bodylesspipeableoverloads #2278's fix on main.pyteston typescript/javascript/detector suites: 463 passed. Cross-language spot-check (java/csharp/python/rust): 262 passed.tests/ruff_audit.py --ci/tests/mypy_audit.py --ci: no new findings beyond baseline.Implemented by a dispatched Gemini/agy subagent per this repo's
tree-sitter-accuracy-sweep-style workflow, across two rounds (round 1's regression was root-caused in the main session and the precise fix specified for round 2's implementation); independently re-verified before this push.Test plan
test_typescript.py/test_typescript_strict.py/test_javascript.py/test_javascript_strict.py/test_detector.py