Commit Graph

69 Commits

Author SHA1 Message Date
leaysgur aef8b4acce fix(formatter_css): handle less-test-suites failures (#26513)
Follow up on #26469 for CSS.

Updated `oxc-css-parser` to `v0.0.15`.

---

- Keep parens for `calc((a + b))` by adding `CalcParenthesized` AST
  - Do not follow JS formatter approach (remove all, then add back), only works for CSS, not for SCSS/Less
- Fix Less operand spacing: `2em*1em` -> `2em * 1em`
- Rework `@import` prelude fill
- Leave glued `and(` and `when(` as-is
  - `@media screen and (max-width:1280px) { }` and `@media screen and(max-width:1280px) { }` is different
  - We do not alter behavior
- Format `LessMixinDefinition` and `LessConditionalQualifiedRule`
  - We still have a room to go better than Prettier here, but keep for now
2026-09-10 03:31:42 +00:00
leaysgur 3d00a7635b fix(formatter_css): keep comment inside important and simple-vars colon (#26370)
Follow up on #26337

Also, normalize `important` token with/without comments.
2026-09-07 01:33:14 +00:00
leaysgur 68e12abe2c feat(formatter_css): follow the oxc-css-parser's acceptance line (#26337)
Fixes #26290, #26291.
Also, many changes to follow refined parser acceptance line.

---

CI will fail until parser version bumped, needs oxc-project/oxc-css-parser/pull/166
2026-09-07 01:33:14 +00:00
leaysgur 0f4af5d7df test(formatter_tests): assert fingerprint survives formatting (#26322)
Historically, only JS formatter has had the `detect_code_removal` feature, which uses CI to check for missing nodes or comments.

While this would be useful in other languages (especially CSS), but setting up the mechanism is difficult. For now, just start with something simple that just guarantees the number of comments.

That said, even with a mechanism in place, it can't detect anything unless the cases are fully covered by fixtures, so this only tells us that the current state is problem-free.
2026-09-04 07:14:53 +00:00
leaysgur 172ddb67dc fix(formatter_css): keep a same-line line comment on its line (#26321)
Consistent output with other language formatters.
2026-09-04 07:14:53 +00:00
leaysgur cafaf32de1 fix(formatter_css): never drop comments inside an at-rule prelude (#26320)
Fix missing comment bug.
2026-09-04 07:14:52 +00:00
leaysgur 534a0fe838 fix(formatter_css): keep a line comment on its comma's line (#26319)
e.g.

```scss
$my-map: (
  "foo": 1, // Comment
  "bar": 2, // Comment
);
```

should not be formatted:

```scss
$my-map: (
  "foo": 1,
  // Comment
  "bar": 2, // Comment
);
```
2026-09-04 07:14:52 +00:00
leaysgur 99cfd7556e fix(formatter_css): hide raw comment printing API, use strcut instead (#26316)
#26313 for CSS formatter. This also fixes some bugs.
2026-09-04 07:14:52 +00:00
leaysgur 2028896ab9 fix(formatter_css): preserve comments around SCSS/Less variable values (#26276)
```less
// input
@a: /* c */ 1;

// before
@a: 1;

// after
@a: /* c */ 1;
```

Comment should be preserved.

```scss
// input
$x: // c
  1;

// before
$x:
  // c1;

// after
$x: // c
  1;
```

Content should be preserved.
2026-09-03 08:17:36 +00:00
leaysgur 6752abc1a2 fix(formatter_css): keep leading comments before (#26272)
Apply comment printing policy.
2026-09-03 08:17:36 +00:00
leaysgur b3c287a47d fix(formatter_css): fix SCSS bracket list printing (#26270)
`$basic: [1, 2];` and `$basic: (1, 2);` should be formatted in the same way.
2026-09-03 08:17:35 +00:00
leaysgur bac770adaa fix(formatter_css): preserve comment in SCSS paren comma list (#26269)
Keep comment position for consistency.
2026-09-03 08:17:35 +00:00
leaysgur c7b57efc38 fix(formatter_css): print SCSS map consisntent with and without comment (#26268)
```scss
$no-comment: (
  a: 1,
);
$with-block: (
  /* c */ a: 1,
);
```

These should be formatted in the same way.
2026-09-03 08:17:34 +00:00
leaysgur 063e2b6249 fix(formatter_css): preserve trailing comma in single-item scss lists (#26245)
Keep these as-is.

```scss
foo: ("a",);

$x: "a",;
```

Even if they consist of a single element, these are still lists, and if the commas are removed, their type changes.

And also fixed inconsistent comment printing.
2026-09-03 08:17:33 +00:00
leaysgur 1fb37b6e47 feat(formatter/css): format declaration-shaped raw-prelude rules (postcss nested config blocks) (#26194)
Fixes #26158

---

> Otherwise, [restore a mark](https://drafts.csswg.org/css-syntax-3/#token-stream-restore-a-mark) from input, then [consume a qualified rule](https://drafts.csswg.org/css-syntax-3/#consume-a-qualified-rule) from input, with nested set to true, and [<semicolon-token>](https://drafts.csswg.org/css-syntax-3/#typedef-semicolon-token) as the stop token.
> https://drafts.csswg.org/css-syntax-3/#consume-block-contents

When fallback happens: format block, keep prelude verbatim.
2026-08-31 04:42:06 +00:00
leaysgur 57e8e22483 fix(formatter_css): space a folded sign after a call in Less operations (#26134)
Follow up on #26132.

By that change, Less is also possible to format binary operation like SCSS.
2026-08-27 07:49:30 +00:00
leaysgur 181953b92d docs(oxfmt,formatter_core,formatter,formatter_yaml,formatter_css,formatter_graphql): extract DIVERGENCES.md out from AGENTS.md (#26121)
- Extract "known divergences" section from `AGENTS.md` to explicit `DIVERGENCES.md` with code example
- Update all anchors
- Add missing pinned fixtures
2026-08-27 05:33:58 +00:00
leaysgur 5c0a5ff7bf fix(formatter_css): fill own-line block comments inside space-separated values (#25578)
Fixed idempotency issue.

Block comment is a normal fill item in values.
2026-08-13 07:45:25 +00:00
leaysgur 53debfa10e fix(formatter_css): keep trailing comma and indent after comment-preceded last map value (#25577)
Fixed idempotency issue.

```scss
$with-comment_n_comma: (
  a: (
    x: 1,
  ),
  /* This comment should not affect trailing comma, indent depth */
  b: (
    x: 2,
  ),
);
```
2026-08-13 07:45:25 +00:00
leaysgur 40d38a0813 fix(formatter_css): keep multi value function args intact after leading comment (#25518)
Fixes #25480
2026-08-12 05:36:15 +00:00
leaysgur b37b9f05b6 refactor(formatter_core): rename DispatchXxx (#25436)
Pure renaming.

- `DispatchOutcome` -> `DispatchResponse` (counter part of `DispatchRequest`)
- `DispatchResult` -> `DispatchPayload` (lives in `DispatchResponse`)
2026-08-09 15:07:42 +00:00
leaysgur 4ae3abbd22 refactor(formatter_core): share frontmatter writer in core (#25433)
FM support will be needed by Markdown formatting too.
2026-08-09 15:07:41 +00:00
leaysgur 8213e72f37 refactor(formatter,oxfmt): flatten embedded dispatch contract (#25391)
Due to historical reasons, the IR was passed as `[Doc, (Doc, ...Doc)]` only when processing `gql-in-js`, whilst for other cases such as `css-in-js` and `html-in-js`, it was always `[Doc]`.

Now, every result is single `Doc`.
2026-08-09 14:32:11 +00:00
leaysgur 465b723d04 refactor(formatter,oxfmt): unify host services as SessionServices on FormatSession (#25388)
- dispatcher
- string_embedder
- tailwind_sorter

Group these 3 together as `SessionServices`, make them available to `FormatSession`, and pass them around.
2026-08-09 14:32:10 +00:00
leaysgur 2eaede9b0b fix(formatter_core): unify leading-BOM handlings (#25340)
Follow up on #25333.
2026-08-09 14:32:09 +00:00
leaysgur fd02a8956e feat(oxfmt): dispatch yaml-in-css(frontmatter) to oxc_formatter_yaml (#25336)
Using the `Dispatcher` set up so far, detect the YAML front matter and process it using `oxc_formatter_yaml`.
2026-08-09 14:15:05 +00:00
leaysgur 567089f3c5 refactor(oxfmt): route JSDoc fence through the dispatcher (#25334)
Markdown code fences can also be written in JSDoc, and other languages can be formatted as inline code within them.
2026-08-09 13:54:12 +00:00
leaysgur 52b146f025 refactor(formatter_core): share split_bom helper (#25333)
In order to standardise the handling of front matter, it was also necessary to standardise the handling of the BOM, which may appear before the FM.
2026-08-09 13:06:35 +00:00
leaysgur b3ad060cfd refactor(formatter): migrate embedded entries to FormatSession (#25332)
Apply `FormatSession` everywhere introduced in #25329.
2026-08-09 13:06:35 +00:00
leaysgur 8e779c946b refactor(formatter_core): finalize documents once at print time (#25328)
Call `propagate_expand()` inside `Formatted`, here is the only place to finalize IRs.
2026-08-09 12:33:39 +00:00
leaysgur b91d5a8afe perf(formatter_css,formatter_graphql,formatter_yaml,formatter_json): Pre alloc IR buffers (#25234)
As like `oxc_formatter`(js).
2026-08-03 06:26:00 +00:00
leaysgur 9329862e3d refactor(formatter_core): share comment cursor via SpanCursor (#25228)
Standardising the logic for adjusting comment positions using `Span`.
2026-08-03 02:49:00 +00:00
leaysgur 68146bd3b9 fix(formatter_css): preserve glued plugin words in grid values (#25225)
Fixes #25223
2026-08-03 02:00:00 +00:00
leaysgur acfbf46767 refactor(formatter_core): add CoreFormatOptions and FormatOptions::apply_core (#25138)
These common, core format options:

- LineEnding
- LineWidth
- IndentWidth
- IndentStyle

should be defined in core, and to be shared.
2026-07-31 08:11:23 +00:00
leaysgur 7041ea70f1 refactor(formatter_css,formatter_graphql,formatter_yaml): move Gap utils to core (#25137)
CSS, GraphQL, YAML formatters had the same logic to inspect source blank lines.
2026-07-31 08:11:22 +00:00
leaysgur f56009a676 fix(oxfmt): correct prose about comment width in fits measurement (#25054)
Audited every formatter crate against the trailing-comment width discipline.

- same-line trailing line comments ride `line_suffix` and are excluded from the fits measurement
- while trailing block comments print inline and count

Corrected the prose that misstated it.
2026-07-29 02:57:17 +00:00
leaysgur 69450f4012 refactor(formatter_css): use cow_to_ascii_lowercase in normalize_an_plus_b (#24974) 2026-07-27 09:14:31 +00:00
leaysgur 761a882a49 fix(formatter_css): keep leading + in An+B to enable idempotency check (#24973)
Keep `:nth-child(+3n + 1)` as-is, NOT `:nth(+ 3n + 1)` which is not allowed.
2026-07-27 09:07:31 +00:00
leaysgur ae1a39b71c fix(formatter_css): align wrapped selector-arg indent (#24971)
Fixes #24843

---

Tracing back to the root cause, this is also related to what had diverged because of Prettier's inconsistent behavior.
Since I cannot determine for sure how it should be output in more complex cases (like that issue) at this point, decided to revert to being Prettier-compatible.
2026-07-27 06:47:19 +00:00
leaysgur fb34196ec7 fix(formatter_css): keep non-ASCII strings with quotes (#24870)
Fixes #24841
2026-07-24 02:13:21 +00:00
leaysgur 31783e997c fix(formatter_css): print nested SCSS map with consistent indent (#24789)
Fixes #24773
2026-07-22 01:58:53 +00:00
leaysgur fd7cf5b500 fix(formatter_css): update oxc-css-parser to 0.0.9 (#24745)
Fixes #24726
2026-07-21 04:52:30 +00:00
leaysgur 33e32d8e51 fix(formatter_css): use line_suffix for EOL line comment (#24580)
The same motivation as #24579
2026-07-16 01:37:31 +00:00
leaysgur 95262b9d94 fix(formatter_css): keep more value comments before comma (#24487)
Follow up on #24484.

Apply the same rule for all call sites.
2026-07-14 06:28:50 +00:00
leaysgur cd53d98460 fix(formatter_css): keep value comments before comma (#24484)
Fixes #24469

This keeps comments before/after `,` stay the same position.
2026-07-14 06:28:49 +00:00
leaysgur 3a7fe74366 feat(formatter_css): update oxc-css-parser to 0.0.7 (#24434)
- Shadow parts: `::part()`
- Scroll driven animations: `<timeline-range-name>`
2026-07-13 02:16:18 +00:00
leaysgur 0173cd37a3 feat(formatter_css): format Less :extend and merge props (#24358)
Follows:

- https://github.com/prettier/prettier/pull/19550
- https://github.com/prettier/prettier/pull/19517
2026-07-13 00:13:32 +00:00
leaysgur fcc28dfc9c fix(formatter_css): Keep glued-braket-value tight (#24352)
Fixes #24334
2026-07-13 00:08:30 +00:00
leaysgur eeabc4a55f fix(formatter_css): bail on EOF-recovered parse errors (#24282)
Also updated the code to reflect the changes in `oxc-css-parser` 0.0.6.
2026-07-08 02:17:08 +00:00
leaysgur 9af383371b fix(formatter_css): make scss formatter consistent (#24207)
Fix `@use`, `@forward` and its comment printing.
2026-07-06 06:01:17 +00:00