ADFA-5414 + ADFA-5416: cleanup and guard-order fixes in the tree-sitter query path - #1778
Open
davidschachterADFA wants to merge 2 commits into
Open
Conversation
doSafeExecQueryCursor had two ways out and only one of them cleaned up.
The check after action(match) called onClosedOrEdited() and recycled the
match before breaking; the loop condition itself could also become false,
and that path exited straight out - the caller's compensating action never
ran and the match it was holding never went back to the pool.
That matters because onClosedOrEdited is how a caller discards a partial
result. updateCodeBlocks passes { blocks.clear() }, so an exit through the
loop condition committed a half-built list and the editor drew a truncated
set of fold and indent guides instead of none. TsScopedVariables passes
{ captures.clear() } and would commit a torn scope tree.
The loop is now driven by `match != null` - normal exhaustion, which must
not trigger onClosedOrEdited - with the condition re-checked at the top as
well as after the action. Both failure exits run onClosedOrEdited() and
recycle; the whileTrue exit recycles without it, since the caller stopping
on purpose is not an error.
Pre-existing, but ADFA-5401 widened it by adding query.canAccess() to
matchCondition, so a freed query now reaches this exit as well as an
edited node.
Also corrects the debug diagnostic beside it, which printed
node.hasErrors() under a "node.hasChanges" label - matchCondition tests
hasChanges, so the log pointed at the wrong thing exactly when someone
would be reading it.
Not addressed here: the early `return result` path still skips the
node.recycle() below the loop. That is a separate leak and a separate
decision about whether a returned result may reference the node.
Verified on device (Pixel 6 Pro, Android 17): syntax highlighting renders
and updates normally - this loop is what feeds it - with no
"AnalyzeWorker crashed", no "Cannot access native object" and no SIGSEGV.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Crj29d6Q2DGjioWPxtuSR
updateCodeBlocks() guarded on
blocksQuery.patternCount == 0 || !blocksQuery.canAccess() || ...
but TSQuery.getPatternCount() calls checkAccess() internally, so on a
closed query the first operand throws IllegalStateException before the
guard beside it can return. The exception left updateStyles() and was
swallowed by processNextMessage()'s catch as "AnalyzeWorker crashed",
dropping the whole style update rather than skipping just the code-blocks
step the guard existed to skip.
Swapped, matching TsBracketPairs, which already had the operands this way
round.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Crj29d6Q2DGjioWPxtuSR
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
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.
ADFA-5414 + ADFA-5416: cleanup and guard-order fixes in the tree-sitter query path
Two independent fixes found while reviewing #1776. Both are small; they share a branch because they are in the same two files and the same review context.
ADFA-5414 — clean up on both exits from the query cursor loop (
68ed840)doSafeExecQueryCursorhad two ways out and only one cleaned up. The check afteraction(match)calledonClosedOrEdited()and recycled the match; the loop condition could also become false, and that path exited straight out — the caller's compensating action never ran, and the match it was holding never went back to the pool.That matters because
onClosedOrEditedis how a caller discards a partial result:onClosedOrEditedupdateCodeBlocks{ blocks.clear() }TsScopedVariables.init{ captures.clear() }The loop is now driven by
match != null— normal exhaustion, which must not triggeronClosedOrEdited— with the condition re-checked at the top as well as after the action. Both failure exits runonClosedOrEdited()and recycle; thewhileTrueexit recycles without it, since a caller stopping on purpose is not an error.Pre-existing, but #1776 widened it: adding
query.canAccess()tomatchConditionmeans a freed query now reaches this exit too, not just an edited node.Also corrects the diagnostic beside it, which printed
node.hasErrors()under anode.hasChangeslabel —matchConditiontestshasChanges, so the log pointed at the wrong thing precisely when someone would be reading it.Not addressed: the early
return resultpath still skips thenode.recycle()below the loop. Separate leak, and a separate decision about whether a returned result may reference the node.ADFA-5416 — check
canAccess()before readingpatternCount(aa973a8)updateCodeBlocks()guarded onblocksQuery.patternCount == 0 || !blocksQuery.canAccess() || …, butgetPatternCount()callscheckAccess()internally — so on a closed query the first operand throws before the guard beside it can return. The exception leftupdateStyles()and was swallowed as "AnalyzeWorker crashed", dropping the whole style update rather than skipping just the code-blocks step. Swapped, matchingTsBracketPairs, which already had the operands this way round.Testing
AnalyzeWorker crashed, noCannot access native object, no SIGSEGV.:editor-api:,:editor-treesitter:and:editor:compile;spotlessApplyclean.editor-apihas no test source set for this helper, and the behaviour is a teardown race. The argument is the control flow, which is small enough to read.🤖 Generated with Claude Code
https://claude.ai/code/session_011Crj29d6Q2DGjioWPxtuSR