Expose index and siblings on walk context#20108
Conversation
These are just references to other information we already have. But it does mean that we can avoid things such as: ``` let idx = ctx.parent.nodes.indexOf(node) ```
Confidence Score: 5/5Safe to merge. The new fields are additive and backward-compatible, and all existing call sites that use them produce the same results as the patterns they replace. The changes are additive — new fields on an internal interface, with the walk engine setting them correctly in both enter and exit phases. Every updated call site is a straightforward mechanical substitution of an existing pattern. The test suite asserts ctx.index === ctx.siblings.indexOf(node) at every visited node, providing direct coverage of the invariant. No behavioral changes, no new edge cases introduced. No files require special attention. Reviews (2): Last reviewed commit: "use `ctx.index` and `ctx.siblings`" | Re-trigger Greptile |
07ee498 to
3082806
Compare
|
Caution Review failedPull request was closed or merged during review Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis PR adds index and siblings to VisitContext, initializes and maintains them during walk enter/exit, and forwards them through cssContext. Tests were updated to assert ctx.index. Consumers were refactored: candidate printing, canonicalize-candidates, and the migrate-theme-to-var codemod now use ctx.index/ctx.siblings for sibling-aware neighbor detection, whitespace trimming, operator handling, and conditional parenthesization. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/tailwindcss/src/canonicalize-candidates.ts`:
- Around line 983-1010: The loop that inspects the previous sibling in
canonicalize-candidates incorrectly initializes idx to ctx.index (causing it to
examine the current node) — change the initialization in the function/block that
declares let idx = ctx.index to start from the previous sibling (let idx =
ctx.index - 1) so the while loop checks ctx.siblings[idx] (and the subsequent
checks on previous.kind, previous.value, and potential wrapping of replacement)
operate on the actual previous node as intended.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e84b7102-ea21-4464-8265-13fe1f682ab4
📒 Files selected for processing (5)
packages/@tailwindcss-upgrade/src/codemods/template/migrate-theme-to-var.tspackages/tailwindcss/src/candidate.tspackages/tailwindcss/src/canonicalize-candidates.tspackages/tailwindcss/src/walk.test.tspackages/tailwindcss/src/walk.ts
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/tailwindcss/src/canonicalize-candidates.ts (1)
983-1010:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winOff-by-one: loop should start at
ctx.index - 1, notctx.index.Starting at
ctx.indexmeans the first iteration checks the currenttheme(...)node itself rather than the previous sibling. Compare withmigrate-theme-to-var.tswhich correctly starts atctx.index - 1.🐛 Proposed fix
- let idx = ctx.index + let idx = ctx.index - 1 while (idx !== -1) { let previous = ctx.siblings[idx]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/tailwindcss/src/canonicalize-candidates.ts` around lines 983 - 1010, The loop's start index is off-by-one: initialize idx to ctx.index - 1 (not ctx.index) so the loop examines the previous sibling rather than the current node; update the initialization of idx in the block that uses ctx.siblings and ctx.index, leaving the rest of the while loop logic (separator check, operator regex test, wrapping replacement) unchanged so that parentheses are applied based on the actual previous sibling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@packages/tailwindcss/src/canonicalize-candidates.ts`:
- Around line 983-1010: The loop's start index is off-by-one: initialize idx to
ctx.index - 1 (not ctx.index) so the loop examines the previous sibling rather
than the current node; update the initialization of idx in the block that uses
ctx.siblings and ctx.index, leaving the rest of the while loop logic (separator
check, operator regex test, wrapping replacement) unchanged so that parentheses
are applied based on the actual previous sibling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 664cb7a5-6728-4c1e-b4e2-5d9a045e65bd
📒 Files selected for processing (5)
packages/@tailwindcss-upgrade/src/codemods/template/migrate-theme-to-var.tspackages/tailwindcss/src/ast.tspackages/tailwindcss/src/candidate.tspackages/tailwindcss/src/canonicalize-candidates.tspackages/tailwindcss/src/walk.ts
2e12393 to
a9a939a
Compare
a9a939a to
68fefb0
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/tailwindcss/src/candidate.ts (1)
1102-1125:⚠️ Potential issue | 🟠 Major | ⚡ Quick winOff-by-one in sibling lookups after
ctx.indexmigration (Line 1102).
idxis already shifted (ctx.index - 1), but subsequent reads useidx - 1/idx - 2, so the immediate previous sibling is skipped. This can mis-detect whether--*functions should be parenthesized.🐛 Proposed fix
- let idx = ctx.index - 1 + let idx = ctx.index - 1 // When it's the first argument, then we don't have to wrap it in `(…)` @@ if (idx <= 0) return @@ - let previous = ctx.siblings[idx - 1] + let previous = ctx.siblings[idx] if (previous?.kind === 'separator' && previous.value === ',') return @@ - let previousPrevious = ctx.siblings[idx - 2] + let previousPrevious = ctx.siblings[idx - 1] if (previousPrevious && !symbols.has(previousPrevious.value)) return🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/tailwindcss/src/candidate.ts` around lines 1102 - 1125, The idx computation is off-by-one: change "let idx = ctx.index - 1" to "let idx = ctx.index" so that the subsequent sibling lookups (previous = ctx.siblings[idx - 1] and previousPrevious = ctx.siblings[idx - 2]) refer to the correct neighbors; keep or adjust the early-return check accordingly so it still guards first-argument cases (i.e., ensure the boundary check uses the updated idx).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/tailwindcss/src/candidate.ts`:
- Around line 1102-1125: The idx computation is off-by-one: change "let idx =
ctx.index - 1" to "let idx = ctx.index" so that the subsequent sibling lookups
(previous = ctx.siblings[idx - 1] and previousPrevious = ctx.siblings[idx - 2])
refer to the correct neighbors; keep or adjust the early-return check
accordingly so it still guards first-argument cases (i.e., ensure the boundary
check uses the updated idx).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: d7df8dd0-3aa4-4a62-be32-aa0e9f29e7c5
📒 Files selected for processing (3)
packages/@tailwindcss-upgrade/src/codemods/template/migrate-theme-to-var.tspackages/tailwindcss/src/candidate.tspackages/tailwindcss/src/canonicalize-candidates.ts
This PR is a small improvement of the current
walkimplementation where we will expose theindexand thesiblingson the current context.During a walk, we walk over objects that contain a
nodes: []field. Thectx.parentthat already exists is a reference to the parent node, butctx.siblingsis a reference to thectx.parent.nodes.The
ctx.indexis the index of the current node we are walking in thesiblingsarray. This way we can prevent the awkwardctx.parent?.nodes.indexOf(node)which is a bit silly because we already know the nodes we're walking and its index...The
ctx.parentcan benull, but thectx.siblingswill never benull, this can be seen in a situation like this:In the above example, the
astis a separately variable, but if this was inlined, we would run into some issues:So, this PR doesn't change much, the additional information we track is already known information that is now exposed to the caller of the
walkfunction.In this PR we did update some usages and got rid of some awkward
ctx.parent?.nodes ?? []andctx.parent.nodes.indexOf(…)usages.Test plan