Fix function tokens terminating at a nested closing parenthesis#190
Open
jhaygood86 wants to merge 1 commit into
Open
Fix function tokens terminating at a nested closing parenthesis#190jhaygood86 wants to merge 1 commit into
jhaygood86 wants to merge 1 commit into
Conversation
jhaygood86
marked this pull request as ready for review
July 22, 2026 21:14
jhaygood86
marked this pull request as draft
July 22, 2026 21:40
jhaygood86
marked this pull request as ready for review
July 22, 2026 21:43
Lexer.NewFunction consumed argument tokens until the first
RoundBracketClose, so a bare parenthesized group inside a function's
arguments ended the function early. "calc((1px + 2px) * 3)" tokenized as
a calc function containing only "(1px + 2px)", leaving "* 3)" behind as
stray top-level tokens and corrupting the rest of the value.
Track the parenthesis depth instead, so only the ')' matching the
function's own '(' terminates it. A nested function call's parens are
already consumed by its own recursive call before being added here as a
single token, so they never surface as bare bracket tokens at this level
and cannot skew the count.
jhaygood86
force-pushed
the
bugfix/lexer-nested-parentheses-in-functions
branch
from
July 23, 2026 22:22
d83fd3e to
7d88742
Compare
Contributor
Author
|
Rebased onto current Note on scope after the rebase: the actual lexer fix (tracking paren depth in
Happy to close this instead if you'd rather not take the extra tests — the behaviour is already covered on |
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.
Problem
Lexer.NewFunctionconsumes argument tokens until the firstRoundBracketClose:A bare parenthesized group inside a function's arguments therefore ends the function early.
calc((1px + 2px) * 3)tokenizes as acalcfunction containing only(1px + 2px), and* 3)is left behind as stray top-level tokens that corrupt the remainder of the value.Grouping parentheses are explicitly part of the
calc()grammar (CSS Values and Units 3 §10.1), and CSS Syntax 3 §5.4.9 "Consume a function" requires consuming until the matching), not the first one.Fix
Track the parenthesis depth and terminate only on the
)that matches the function's own(.A nested function call is already fully consumed by its own recursive
NewFunctioncall before it is added here as a singleFunctiontoken, so its parentheses never surface as bareRoundBracketOpen/RoundBracketClosetokens at this level and cannot skew the count.min(10px, (2px + 3px))nested insidecalc(...)is covered by a test for exactly that reason.Unbalanced input still terminates at EOF, unchanged.
Tests
Four tests in
Tokenization.cs, asserting both that the function token round-trips to the full source text viaToValue()and that no stray tokens follow it:calc((1px + 2px) * 3)— the base casecalc(((1px + 2px) * (3 - 1)) / 2)— multiple nesting levelscalc(min(10px, (2px + 3px)) * 2)— nested function alongside a bare groupcalc((1px + 2px— unbalanced input still stops at EOFThree of the four fail on
master. The full suite (1263 existing tests) stays green, and all seven target frameworks build with no new warnings.