fix(queryLanguage): allow parenthesized regex alternation in filter values#946
Conversation
…alues Queries like `file:(test|spec)` or `-file:(test|spec)` previously failed with "No parse at N" because the word tokenizer unconditionally deferred to parenToken whenever a token started with balanced parentheses, even in value contexts (right after a prefix keyword colon like `file:`, `repo:`, `sym:`, etc.). The fix detects value context by looking backward for a preceding ':' and, when found, uses depth-tracking to consume the entire '(...)' as a word instead of deferring. This correctly handles nested parens, stops at an outer ParenExpr closing paren, and leaves all existing parse behaviour unchanged for non-value contexts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... 📒 Files selected for processing (2)
✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. WalkthroughAdds support for parenthesized regex alternation in search filter values (e.g., Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: Brendan Kellam <brendan-kellam@users.noreply.github.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/queryLanguage/src/tokens.ts (1)
337-352: Consider handling escaped parentheses for consistency.The depth-tracking loop doesn't skip escaped parentheses (e.g.,
\(or\)), whilehasBalancedParensAt()at lines 124-127 does handle escapes. This inconsistency could cause unexpected behavior for patterns containing escaped parens likefile:(test\)|spec).If escaped parens in filter values are not a supported use case, this is fine. Otherwise, consider adding escape handling:
♻️ Proposed fix to handle escaped parens
let depth = 0; while (input.next !== EOF) { const ch = input.next; if (isWhitespace(ch)) break; + // Handle escaped characters - skip the next character after a backslash + if (ch === 92 /* backslash */) { + input.advance(); + if (input.next !== EOF) input.advance(); + continue; + } if (ch === OPEN_PAREN) { depth++; } else if (ch === CLOSE_PAREN) { if (depth === 0) break; // outer ParenExpr closing — don't consume depth--; } input.advance(); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/queryLanguage/src/tokens.ts` around lines 337 - 352, The depth-tracking loop inside the inValueParenContext branch doesn't account for escaped parens, causing mismatched depth when encountering \(' or \)'; update the loop (the code using input.next, input.advance, OPEN_PAREN and CLOSE_PAREN) to detect and skip escaped characters (e.g., when a backslash precedes a paren) so escaped '(' or ')' do not change depth or terminate the loop, and ensure this behavior mirrors hasBalancedParensAt's escape handling for consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/queryLanguage/src/tokens.ts`:
- Around line 337-352: The depth-tracking loop inside the inValueParenContext
branch doesn't account for escaped parens, causing mismatched depth when
encountering \(' or \)'; update the loop (the code using input.next,
input.advance, OPEN_PAREN and CLOSE_PAREN) to detect and skip escaped characters
(e.g., when a backslash precedes a paren) so escaped '(' or ')' do not change
depth or terminate the loop, and ensure this behavior mirrors
hasBalancedParensAt's escape handling for consistency.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
CHANGELOG.mdpackages/queryLanguage/src/tokens.tspackages/queryLanguage/test/negation.txtpackages/queryLanguage/test/prefixes.txt
…orkflow Replaces the two separate workflows with a single `test.yml` that runs `yarn test` at the repo root, which executes all workspace tests topologically via `yarn workspaces foreach`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
file:(test|spec),-file:(test|spec),repo:(org1|org2), andsym:(Foo|Bar)previously failed with a parse error because the word tokenizer unconditionally deferred toparenTokenwhenever a token started with balanced parentheses, even in filter value contexts:) and using depth-tracking to consume the entire(...)as a word rather than deferringfile:,repo:,sym:,content:, negated alternation, and combined queriesTest plan
file:(test|spec)parses asPrefixExpr(FileExpr)✓-file:(test|spec)parses asNegateExpr(PrefixExpr(FileExpr))✓chat lang:TypeScript -file:(test|spec)parses successfully ✓(foo bar)still works asParenExpr✓-(file:test or file:spec)still works asNegateExpr(ParenExpr(...))✓🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Chores