Skip to content

feat(parse/html): parse astro directives#9128

Merged
dyc3 merged 11 commits intomainfrom
dyc3/parse-astro-directives
Feb 19, 2026
Merged

feat(parse/html): parse astro directives#9128
dyc3 merged 11 commits intomainfrom
dyc3/parse-astro-directives

Conversation

@dyc3
Copy link
Copy Markdown
Contributor

@dyc3 dyc3 commented Feb 17, 2026

Summary

I tried to replicate how svelte directives are parsed, since it's basically the same syntax as that.

Generated by kimi k2.5 and gpt 5.2 codex.

fixes #9107

Test Plan

added parser and formatter tests

Docs

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 17, 2026

🦋 Changeset detected

Latest commit: bdd041f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-HTML Language: HTML and super languages labels Feb 17, 2026
@github-actions

This comment was marked as resolved.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Feb 17, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 152 skipped benchmarks1


Comparing dyc3/parse-astro-directives (bdd041f) with main (4a5ff40)

Open in CodSpeed

Footnotes

  1. 152 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@github-actions github-actions Bot added the A-CLI Area: CLI label Feb 17, 2026
@dyc3 dyc3 marked this pull request as ready for review February 17, 2026 15:24
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 17, 2026

No actionable comments were generated in the recent review. 🎉


Walkthrough

Adds comprehensive Astro directive support across the HTML pipeline: new lexer IdentifierContext and HtmlLexContext variants (InsideTagAstro), keyword tokens for Astro directives, parser logic to detect and build Astro directive nodes and directive values (client/set/class/is/server/define), grammar additions in the ungrammar (AnyAstroDirective and AstroDirectiveValue), formatter implementations for each directive and AnyAstroDirective, and tests exercising parsing/formatting (including SVG/colon-attribute cases). Also updates generated formatting glue (generated.rs) and test fixtures.

Possibly related PRs

Suggested reviewers

  • ematipico
  • arendjr
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and specifically describes the main change: adding Astro directive parsing support to the HTML parser.
Description check ✅ Passed The description explains the motivation, approach, and includes a disclosure of AI assistance, which is directly related to the changeset.
Linked Issues check ✅ Passed The PR implements parsing and formatting for Astro directives (client, set, class, is, server, define) and adds tests, directly addressing issue #9107's requirement to correctly parse Astro directives without extra spacing.
Out of Scope Changes check ✅ Passed All changes are focused on Astro directive parsing/formatting support, lexing context additions, and associated tests. SVG colon attribute test files are tangentially related to lexing improvements mentioned in PR comments.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dyc3/parse-astro-directives

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/biome_html_formatter/tests/specs/html/astro/directives.astro (1)

1-3: Good coverage for the initial implementation.

The test covers client:load, client:idle, class:list, and set:text directives nicely. Consider adding tests for the remaining directive types (server:defer, is:inline, define:vars) in a follow-up to ensure full coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_html_formatter/tests/specs/html/astro/directives.astro` around
lines 1 - 3, Add tests that cover the remaining Astro directive types by adding
example components using server:defer, is:inline, and define:vars directives to
the existing spec file; specifically, include a component invocation exercising
server:defer (e.g., a component with server:defer attribute), an inline
component using is:inline, and a define:vars usage that defines and references a
variable (so the formatter sees variable definition and interpolation). Ensure
these new examples follow the same style as existing entries (like BuyButton and
ShowHideButton) so the test harness picks them up and validates formatting for
server:defer, is:inline, and define:vars.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_html_parser/src/syntax/mod.rs`:
- Around line 130-145: inside_tag_context currently defaults to
HtmlLexContext::InsideTagAstro when Astro.is_supported(p), which splits normal
coloned attributes; change the logic in inside_tag_context to return
HtmlLexContext::InsideTag (the neutral tag context) by default and only return
HtmlLexContext::InsideTagAstro when Astro.is_supported(p) AND the parser is
actually at an Astro directive start (use the existing
is_at_astro_directive_start predicate or equivalent). Update the same pattern
wherever InsideTagAstro was used as a broad default (search for uses of
HtmlLexContext::InsideTagAstro guarded only by Astro.is_supported) so coloned
attributes like xlink:href remain intact while real Astro directives still get
re‑lexed into InsideTagAstro.

In `@crates/biome_html_parser/src/token_source.rs`:
- Around line 33-35: The doc comment for InsideTagAstro is missing the Astro
directive "define:"; update the comment on the InsideTagAstro enum variant to
include "define:" in the listed directives (e.g., "client:, set:, class:, is:,
server:, define:") so the documentation accurately reflects supported Astro
directives.

---

Nitpick comments:
In `@crates/biome_html_formatter/tests/specs/html/astro/directives.astro`:
- Around line 1-3: Add tests that cover the remaining Astro directive types by
adding example components using server:defer, is:inline, and define:vars
directives to the existing spec file; specifically, include a component
invocation exercising server:defer (e.g., a component with server:defer
attribute), an inline component using is:inline, and a define:vars usage that
defines and references a variable (so the formatter sees variable definition and
interpolation). Ensure these new examples follow the same style as existing
entries (like BuyButton and ShowHideButton) so the test harness picks them up
and validates formatting for server:defer, is:inline, and define:vars.

Comment thread crates/biome_html_parser/src/syntax/mod.rs
Comment thread crates/biome_html_parser/src/token_source.rs
Comment thread crates/biome_html_parser/src/syntax/mod.rs
Comment thread crates/biome_html_parser/src/syntax/mod.rs Outdated
}
_ if is_at_svelte_directive_start(p) => {
Svelte.parse_exclusive_syntax(p, parse_svelte_directive, |p, m| {
_ if !Astro.is_supported(p) && is_at_svelte_directive_start(p) => Svelte
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, I would like to avoid checking different features like this here. Theoretically, they should never clash, so the check feels like a bug or poor architecture.

Comment thread crates/biome_html_parser/src/syntax/mod.rs Outdated
Comment thread crates/biome_html_parser/src/syntax/mod.rs Outdated
Comment thread crates/biome_html_parser/src/syntax/mod.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/biome_html_parser/src/syntax/mod.rs (1)

8-11: Imports for Astro helpers are clean.
Quick reminder to run just f and just l before merging.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_html_parser/src/syntax/mod.rs` around lines 8 - 11, Run the code
formatter and linter before merging: execute `just f` to format the crate and
`just l` to run linting/CI checks; verify the imports in the
crate::syntax::astro block (is_at_astro_directive_keyword,
is_at_astro_directive_start, parse_astro_directive, parse_astro_fence,
parse_astro_spread_or_expression) remain unchanged and commit any automatic
fixes produced by those commands.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/biome_html_parser/src/syntax/mod.rs`:
- Around line 137-145: The current branch chooses HtmlLexContext::InsideTagAstro
as the default which causes coloned attributes like xlink:href to be split;
change the fallback in the selection logic so the default is
HtmlLexContext::InsideTag (not InsideTagAstro) and only switch to
HtmlLexContext::InsideTagAstro when Astro.is_supported(p) AND an actual Astro
directive pattern is detected (e.g., an attribute name matching known Astro
directive prefixes such as "client:" or "set:" or an identifier followed
immediately by ':'). Update the code paths that call HtmlLexContext selection
(the block using Vue.is_supported(p), Astro.is_supported(p), and the default
branch) to perform this gating check so coloned SVG/XML attributes remain
tokenized under InsideTag until a real Astro directive is observed.

---

Nitpick comments:
In `@crates/biome_html_parser/src/syntax/mod.rs`:
- Around line 8-11: Run the code formatter and linter before merging: execute
`just f` to format the crate and `just l` to run linting/CI checks; verify the
imports in the crate::syntax::astro block (is_at_astro_directive_keyword,
is_at_astro_directive_start, parse_astro_directive, parse_astro_fence,
parse_astro_spread_or_expression) remain unchanged and commit any automatic
fixes produced by those commands.

Copy link
Copy Markdown
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great fix 🚀

@dyc3
Copy link
Copy Markdown
Contributor Author

dyc3 commented Feb 19, 2026

I think this and the svelte directive lexing/parsing has to be rewritten. The implementations should look pretty similar, but they are done completely differently, and reconciling it is more work than I originally thought.

However, I do want to get this fix released sooner rather than later. I'll try to at least reconcile the xlink:href issue the bot pointed out.

@dyc3 dyc3 merged commit 8ca3f7f into main Feb 19, 2026
18 checks passed
@dyc3 dyc3 deleted the dyc3/parse-astro-directives branch February 19, 2026 18:45
@github-actions github-actions Bot mentioned this pull request Feb 19, 2026
dyc3 added a commit that referenced this pull request Feb 20, 2026
…eywords and directives helpers (#9148)

<!--
  IMPORTANT!!
  If you generated this PR with the help of any AI assistance, please disclose it in the PR.
  https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#ai-assistance-notice
-->

<!--
	Thanks for submitting a Pull Request! We appreciate you spending the time to work on these changes.
	Please provide enough information so that others can review your PR.
	Once created, your PR will be automatically labeled according to changed files.
	Learn more about contributing: https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md
-->

## Summary

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve?-->
I noticed this when working on #9128. No changeset because no change in behavior, except maybe performance.

<!-- Link any relevant issues if necessary or include a transcript of any Discord discussion. -->

<!-- If you create a user-facing change, please write a changeset: https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#writing-a-changeset (your changeset is often a good starting point for this summary as well) -->

## Test Plan

<!-- What demonstrates that your implementation is correct? -->
CI should remain green

## Docs

<!-- If you're submitting a new rule or action (or an option for them), the documentation is part of the code. Make sure rules and actions have example usages, and that all options are documented. -->

<!-- For other features, please submit a documentation PR to the `next` branch of our website: https://github.com/biomejs/website/. Link the PR here once it's ready. -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Formatter Area: formatter A-Parser Area: parser A-Tooling Area: internal tools L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📝 Astro client directives include extra space after colon

2 participants