Repository navigation
Conversation
The CSS parser counts lines from 0 (cssparser convention) while bun_ast::Location counts from 1 and treats line 0 as "no location". Parse errors were converted in ErrorLocation::to_location, but the warning paths (ParserOptions::warn, warn_fmt, warn_fmt_with_notes and the composes note) passed the 0-based line straight through, so every CSS warning pointed one line too early and a first-line warning printed as "file.css:0". Route all of them through ParserOptions::logger_location, which builds the logger Location (line + 1), and replace the logger's line/column passthrough helpers with one that takes a Location.
|
Warning Review limit reached
Next review available in: 1 minute Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
Comment |
|
Updated 3:06 PM PT - Aug 12th, 2026
❌ @robobun, your commit 03a330c has 3 failures in
🧪 To try this PR locally: bunx bun-pr 37911That installs a local version of the PR into your bun-37911 --bun |
|
Status: reproduced on bun 1.4.0 with |
There was a problem hiding this comment.
LGTM — focused off-by-one fix aligning CSS parser warnings with the existing error-path conversion.
What was reviewed:
- Verified
logger_location'sline + 1matchesErrorLocation::to_location(src/css/error.rs:190) anddependencies::Location::from_source_location(src/css/dependencies.rs:31), and thatSourceLocation.lineis documented 0-based (src/css/lib.rs:299). - Confirmed no remaining callers of the removed
add_warning_fmt_line_col*/to_logger_location; allwarn_fmt*call sites (declaration.rs) updated to the newSourceLocationsignature. - Checked that
warn→warn_fmt→warn_fmt_with_notesfunneling preserves the movedSAFETYcomment on the single remainingunsafederef. - Tests cover every warning emission path (invalid @rule, both composes variants + note, unsupported pseudo) via both
Bun.build()and the CLI, for module and non-module CSS.
Extended reasoning...
Overview
This PR fixes an off-by-one in CSS parser warning line numbers. The parser's internal SourceLocation uses 0-based lines (documented in src/css/lib.rs:299), while bun_ast::Location uses 1-based lines. The error path (ErrorLocation::to_location) already added 1; the warning path did not. The fix introduces ParserOptions::logger_location as the single conversion point, funnels warn/warn_fmt through warn_fmt_with_notes, and replaces the two ad-hoc Log::add_warning_fmt_line_col* helpers with one add_warning_fmt_with_location that takes a pre-built Location. Four files touched: src/ast/lib.rs, src/css/css_parser.rs, src/css/declaration.rs, and new tests in test/bundler/css/css-modules.test.ts.
Security risks
None. This is diagnostic metadata (line numbers in warning messages) with no effect on parsing, output, or control flow.
Level of scrutiny
Low-to-medium. The change is mechanical and mirrors two existing in-crate conversions (ErrorLocation::to_location, dependencies::Location::from_source_location) that already do line + 1. I grepped for stale callers of every removed/re-signatured function (add_warning_fmt_line_col, add_warning_fmt_line_col_with_notes, to_logger_location, warn_fmt, warn_fmt_with_notes) — all are either gone or updated. ParseError.location is SourceLocation, so warn()'s new delegation type-checks. The SAFETY comment on the unsafe { &mut *lg.as_ptr() } was preserved (moved from the deleted warn body to the remaining warn_fmt_with_notes). Columns are unchanged (already 1-based per the SourceLocation doc).
Other factors
The tests are thorough: one Bun.build() test exercises every warning-emission code path in a single fixture (invalid @rule via warn, nested-composes via warn_fmt, non-single-class-composes via warn_fmt_with_notes including the note's location, unsupported pseudo via warn), a second covers non-module .css, and a third asserts the CLI file:line:column format. The PR description documents fail-before output on 1.4.0 and lists the additional test files run on the debug build. The refactor also improves the API shape (callers can no longer hand the logger an unconverted 0-based line as a bare u32), which follows the review guideline of moving the guard into the shared helper.
|
Closing: #45787 supersedes this. It gives a CSS parser warning its file, its 1-based line, its column and its line text from the sheet's |
Problem
invalid @ rule encountered, unsupported pseudo-class/element, deprecated@nest, the two css-modulescomposeswarnings and the note attached to one of them) points one line too early. A warning on the first line of a file is reported as line 0, which the logger prints asat x.module.css:0(no column), whichBun.build()exposes asposition.line === 0, and which the dev server's error overlay payload cannot represent (see bake: serialize bundler messages with line 0 as having no location #37885 for the writer side of that).src/css/error.rsErrorLocation::to_locationadds 1 when it builds the logger location, because the parser'sSourceLocation/Locationlines are 0-based (src/css/lib.rs, "line is 0-based") whilebun_ast::Location.lineis 1-based withline <= 0meaning "no position" (src/ast/lib.rs).ParserOptions::warn/warn_fmt/warn_fmt_with_notes(src/css/css_parser.rs) passed the raw line intoLog::add_warning_fmt_line_col[_with_notes](src/ast/lib.rs), which stored it verbatim, andSourceLocation::to_logger_location(used for thecomposesnote insrc/css/declaration.rs) did the same.Fix
ParserOptions::logger_location(SourceLocation)is now the single place a parser location becomes abun_ast::Locationfor a warning; it adds 1 likeErrorLocation::to_locationdoes.warnandwarn_fmtfunnel intowarn_fmt_with_notes, which uses it, and thecomposesnote uses it too.warn_fmt/warn_fmt_with_notestake aSourceLocationinstead of a bareline, columnpair so a caller cannot hand the logger an unconverted line again.Log::add_warning_fmt_line_col/add_warning_fmt_line_col_with_notes(only the CSS parser used them) are replaced byadd_warning_fmt_with_location(Location, args, notes): the logger stores aLocationwhose field documentation defines the contract instead of a line number of unspecified base.ErrorLocation::to_location,dependencies::Location::from_source_location), and it matches lightningcss, which this parser is a port of:lightningcss@1.30.2transform()reports the two warnings from the repro above at{ line: 1, column: 13 }and{ line: 4, column: 7 }, exactly what bun prints with this change (itsWarning.loctype documentslineas 1-based). Columns were already 1-based and are unchanged.BuildMessage.linegetter (which subtracts 1) becomes correct as well, and a first-line CSS warning no longer produces a line 0 location for the dev server overlay serializer. The terminal output of a first-line warning changes fromat x.module.css:0toat x.module.css:1:13..cssfiles still carry no file name because the bundler only setsParserOptions.filenamefor css modules, and warnings still have noline_text, so they print without a code frame.test/bundler/css/css-modules.test.ts: oneBun.build()test covering all three emission paths plus the note in one.module.cssfile (every expected line is exactly one higher than what 1.4.0 reports), one for a non-module stylesheet, and one checking thebun buildstderr format. All three fail withUSE_SYSTEM_BUN=1and pass withbun bd test.test/bundler/esbuild/css.test.ts, the othertest/bundler/css/*.test.tsfiles,test/js/bun/css/css.test.ts,test/bake/dev/css.test.ts;cargo clippy -p bun_css -p bun_astis clean.Background
bun_ast::Logis the diagnostics sink shared by the bundler, the CLI andBun.build(); aMsgcarries aData { text, location }plus notes (moreData). ALocationis file / 1-based line / column / optionalline_text; the printer emitsfile:line:columnonly whenline > 0,BuildMessage.positionexposes it as is, and the dev server overlay serializes it per message.src/css, a port of lightningcss on top of a cssparser-style tokenizer) tracks positions asSourceLocation { line (0-based), column (1-based) }. Fatal problems come back asErr<ParserError>and the bundler converts them withErrorLocation::to_location(source); non-fatal ones are written into theLogduring parsing throughParserOptions.logger, which is the path this PR fixes.Fail-before output of the new tests on bun 1.4.0