Thanks to visit codestin.com
Credit goes to github.com

Skip to content

refactor(codegen): generate lint/assist/syntax groups by proc macro#8901

Merged
dyc3 merged 1 commit intomainfrom
dyc3/codegen-refactor
Jan 29, 2026
Merged

refactor(codegen): generate lint/assist/syntax groups by proc macro#8901
dyc3 merged 1 commit intomainfrom
dyc3/codegen-refactor

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Jan 28, 2026

Summary

The goal of this refactor is to make it so that we can avoid merge conflicts when merging new rules.

Frequently, as new nursery rules get added, merging one rule causes all the other PRs for new rules to have merge conflicts.

There's 2 parts to this:

  • the proc macro, which literally inspects the filesystem to output the right contents.
  • the build scripts, which trigger rebuilds when rules are added or removed.

This was generated by sonnet 4.5.

Test Plan

CI should remain green. No changes to any snapshots.

Docs

@changeset-bot
Copy link

changeset-bot bot commented Jan 28, 2026

⚠️ No Changeset found

Latest commit: d2f0adf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@github-actions github-actions bot added A-Linter Area: linter A-Tooling Area: internal tools L-JavaScript Language: JavaScript and super languages L-CSS Language: CSS L-JSON Language: JSON and super languages L-HTML Language: HTML and super languages labels Jan 28, 2026
@dyc3 dyc3 force-pushed the dyc3/codegen-refactor branch 2 times, most recently from d65df35 to 544b125 Compare January 29, 2026 14:03
@github-actions
Copy link
Contributor

github-actions bot commented Jan 29, 2026

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 52865 52865 0
Passed 51647 51647 0
Failed 1176 1176 0
Panics 42 42 0
Coverage 97.70% 97.70% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 38 38 0
Passed 37 37 0
Failed 1 1 0
Panics 0 0 0
Coverage 97.37% 97.37% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6300 6300 0
Passed 2085 2085 0
Failed 4215 4215 0
Panics 0 0 0
Coverage 33.10% 33.10% 0.00%

ts/babel

Test result main count This PR count Difference
Total 628 628 0
Passed 562 562 0
Failed 66 66 0
Panics 0 0 0
Coverage 89.49% 89.49% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18856 18856 0
Passed 14055 14055 0
Failed 4800 4800 0
Panics 1 1 0
Coverage 74.54% 74.54% 0.00%

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 29, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 95 skipped benchmarks1


Comparing dyc3/codegen-refactor (d2f0adf) with main (f788cff)

Open in CodSpeed

Footnotes

  1. 95 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.

@dyc3 dyc3 marked this pull request as ready for review January 29, 2026 14:28
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2026

Walkthrough

Adds a new procedural‑macro crate biome_analyze_macros to the workspace and introduces declare_group_from_fs! to generate analyzer group modules from the filesystem. Multiple analyzer crates (CSS, GraphQL, HTML, JS, JSON, etc.) replace explicit pub mod + declare_*_group! wiring with declare_group_from_fs! invocations. New build scripts (build.rs) were added to several analyzers to emit Cargo rerun hints and touch group files (using filetime) so the proc‑macro re-runs when rule files change. Workspace Cargo.toml now references biome_analyze_macros, filetime and prettyplease.

Possibly related PRs

Suggested reviewers

  • ematipico
  • arendjr
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main refactoring: generating lint/assist/syntax groups via a procedural macro instead of manual code generation.
Description check ✅ Passed The description explains the motivation (reducing merge conflicts), the two-part approach (proc macro and build scripts), and confirms the implementation is working with green CI.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link
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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
crates/biome_graphql_analyze/src/lint/correctness.rs (1)

1-3: Duplicate "Generated file" comment.

Lines 1 and 3 both contain the same comment. This appears to be unintentional duplication from codegen.

crates/biome_css_analyze/src/lint/suspicious.rs (1)

1-3: Duplicate "Generated file" comment.

Same issue as in correctness.rs - lines 1 and 3 both contain identical comments.

crates/biome_css_analyze/src/assist/source.rs (1)

1-3: Duplicate "Generated file" comment.

Consistent with other generated files - the duplicate should be addressed in the codegen template.

xtask/codegen/src/generate_analyzer.rs (1)

141-156: Double preamble causing duplicate "Generated file" comments.

xtask_glue::reformat (line 141) and reformat (line 156) both add the "Generated file" preamble, resulting in the duplicate comments visible in all generated group files. Consider using reformat_without_preamble for one of these calls.

🔧 Proposed fix
-    let tokens = xtask_glue::reformat(quote! {
+    let tokens = xtask_glue::reformat_without_preamble(quote! {
         //! Group description generated by proc macro at compile time.

Alternatively, remove the explicit //! doc comment from the quote and let the single reformat call add the standard preamble.

crates/biome_js_analyze/src/lint/correctness.rs (1)

1-3: Duplicate header comment.

Lines 1 and 3 both contain the same "Generated file, do not edit by hand" comment. One of these should be removed.

🧹 Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
crates/biome_graphql_analyze/src/lint/suspicious.rs (1)

1-3: Duplicate header comment.

Same issue as in other files — lines 1 and 3 both contain the "Generated file" comment.

🧹 Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
🤖 Fix all issues with AI agents
In `@crates/biome_json_analyze/Cargo.toml`:
- Line 22: Add the internal crate to the workspace dependencies and switch the
local path usage to the workspace alias: add biome_analyze_macros = { version =
"<appropriate-version-or-omit-if-managed>", workspace = true } to the root
Cargo.toml [workspace.dependencies] and then change the dependency in the
crate's Cargo.toml (the line with biome_analyze_macros) to biome_analyze_macros
= { workspace = true } so the crate uses the workspace-managed dependency
instead of a path.
🧹 Nitpick comments (7)
crates/biome_html_analyze/build.rs (1)

50-50: Consider using &Path instead of &PathBuf for the parameter type.

Using &Path is more idiomatic as it accepts both &Path and &PathBuf via deref coercion. This is a minor nit and consistent with what's done in other build.rs files in this PR, so feel free to address across all of them together or leave as-is.

♻️ Suggested change
-fn touch_file(path: &PathBuf) -> io::Result<()> {
+fn touch_file(path: &Path) -> io::Result<()> {

You'd also need to add use std::path::Path; to the imports.

crates/biome_js_analyze/Cargo.toml (1)

24-24: Path dependency for biome_analyze_macros.

Same pattern as other crates - uses path instead of workspace. If workspace dependencies are updated, this should follow suit.

crates/biome_graphql_analyze/Cargo.toml (1)

16-16: Consider adding biome_analyze_macros to workspace dependencies for consistency.

biome_analyze_macros currently uses a path dependency whilst other internal crates use workspace = true. All other analyse crates (biome_js_analyze, biome_css_analyze, etc.) follow the same pattern, but if biome_analyze_macros is added to root workspace dependencies, this reference should be updated to { workspace = true } to align with the coding guideline: "Use workspace dependencies with workspace = true for internal crates in Cargo.toml".

crates/biome_json_analyze/build.rs (1)

52-61: Consider using &Path instead of &PathBuf.

The function only reads the path; accepting &Path is more flexible and idiomatic, as it works with both PathBuf and Path references.

♻️ Proposed fix
-fn touch_file(path: &PathBuf) -> io::Result<()> {
+fn touch_file(path: &Path) -> io::Result<()> {

You'll also need to add Path to the import:

-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
crates/biome_js_analyze/build.rs (2)

62-71: Consider using &Path instead of &PathBuf.

Same suggestion as for the JSON analyzer — &Path is more idiomatic when only reading the path.

♻️ Proposed fix
-fn touch_file(path: &PathBuf) -> io::Result<()> {
+fn touch_file(path: &Path) -> io::Result<()> {

Add Path to the import:

-use std::path::PathBuf;
+use std::path::{Path, PathBuf};

1-71: Consider extracting shared build script logic.

The watch_group and touch_file functions are duplicated across multiple crates' build scripts (css, graphql, html, js, json). While build scripts are isolated per crate, you might consider extracting this logic to a shared utility crate (e.g., biome_build_utils) to reduce maintenance burden if the pattern needs to change in future.

This is purely optional and can be deferred.

crates/biome_analyze_macros/src/group_macro.rs (1)

78-108: Defensively ignore non‑.rs files and guard duplicate rule names.
A stray README/fixture would be treated as a rule today, and duplicate generated names would silently overwrite earlier entries. Filtering and explicit duplicate checks make failures clearer.

Proposed tweak
         let entry = entry?.path();
         if !entry.is_file() {
             continue;
         }
+        if entry.extension().and_then(|e| e.to_str()) != Some("rs") {
+            continue;
+        }

         let file_name = entry
             .file_stem()
             .context("path has no file name")?
             .to_str()
             .context("could not convert file name to string")?;

         let rule_type = Case::Pascal.convert(file_name);

         let key = rule_type.clone();
         let module_name = format_ident!("{}", file_name);
         let rule_type = format_ident!("{}", rule_type);

-        rules.insert(
-            key,
+        if rules.insert(
+            key.clone(),
             (
                 quote! {
                     pub mod `#module_name`;
                 },
                 quote! {
                     self::`#module_name`::`#rule_type`
                 },
             ),
-        );
+        ).is_some() {
+            bail!("Duplicate rule name generated: {}", key);
+        }

@dyc3 dyc3 force-pushed the dyc3/codegen-refactor branch from 544b125 to f53e0d3 Compare January 29, 2026 15:17
Copy link
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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
xtask/codegen/src/generate_analyzer.rs (1)

139-157: Avoid double preamble by formatting only once.

xtask_glue::reformat already prepends the generated header, so the second reformat duplicates it (see the double “Generated file” lines in the output). One pass is enough.

🧹 Suggested tweak
-    let tokens = xtask_glue::reformat(quote! {
+    let tokens = reformat(quote! {
         //! Group description generated by proc macro at compile time.
         //!
         //! To add a new rule, create a `.rs` file in the group subdirectory
         //! and run `cargo check`. The build system will automatically discover
         //! and register your rule.

         use biome_analyze_macros::declare_group_from_fs;

         declare_group_from_fs! {
             category: `#category`,
             group: `#group`
         }
     })?;

-    let tokens = reformat(tokens)?;
     fs2::write(base_path.join(category).join(format!("{group}.rs")), tokens)?;
crates/biome_graphql_analyze/src/lint/suspicious.rs (1)

1-4: Duplicate module-level doc comment.

Lines 1 and 3 contain identical //! Generated file... comments. This appears to be a codegen artifact — consider deduplicating in the generation logic.

🤖 Fix all issues with AI agents
In `@crates/biome_analyze_macros/src/group_macro.rs`:
- Around line 78-109: Filter directory entries to only Rust source files and
skip mod.rs to avoid invalid modules: when iterating results from
fs2::read_dir(&group_dir) in the loop that builds module_name and rule_type,
first check that entry.path().is_file(), that
entry.path().extension().and_then(|e| e.to_str()) == Some("rs"), and that the
file_stem (the value later used as module_name/file_name) is not "mod"; if any
of these checks fail, continue the loop. Keep using the same symbols
(fs2::read_dir, entry.path(), file_stem(), module_name, rule_type, rules.insert)
so the guard sits before creating format_ident! and inserting into rules.
🧹 Nitpick comments (1)
crates/biome_json_analyze/build.rs (1)

8-12: Prefer &Path in touch_file to avoid unnecessary type coupling.

Keeps the helper flexible without changing behaviour.

♻️ Suggested tweak
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
...
-fn touch_file(path: &PathBuf) -> io::Result<()> {
+fn touch_file(path: &Path) -> io::Result<()> {

Also applies to: 53-54

@dyc3 dyc3 force-pushed the dyc3/codegen-refactor branch from f53e0d3 to 6ab3bf4 Compare January 29, 2026 15:59
Copy link
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
crates/biome_js_analyze/src/assist/source.rs (1)

1-4: Duplicate header comment.

Lines 1 and 3 both contain the same "Generated file, do not edit by hand" comment. This appears to be a generation artefact that should be deduplicated.

🧹 Suggested fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
crates/biome_css_analyze/src/assist/source.rs (1)

1-4: Duplicate header comment.

Same issue as in biome_js_analyze/src/assist/source.rs — lines 1 and 3 contain identical "Generated file" comments.

🧹 Suggested fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
crates/biome_js_analyze/src/lint/security.rs (1)

1-3: Duplicate generated file comment.

Lines 1 and 3 contain the same //! Generated file... comment. This appears to be a codegen artefact that occurs across all modified files. Consider updating xtask/codegen to emit this comment only once.

crates/biome_css_analyze/src/lint/a11y.rs (1)

1-3: Duplicate header comment.

Lines 1 and 3 both contain the same generated file notice. Looks like the codegen is stuttering a bit.

Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
🧹 Nitpick comments (2)
crates/biome_css_analyze/build.rs (1)

57-57: Nit: prefer &Path over &PathBuf in function signatures.

Clippy's ptr_arg lint recommends using &Path for better API flexibility—callers can pass &PathBuf, &Path, or &str without conversion.

♻️ Suggested change
-fn touch_file(path: &PathBuf) -> io::Result<()> {
+fn touch_file(path: &Path) -> io::Result<()> {

And add use std::path::Path; to the imports.

crates/biome_js_analyze/src/lint/style/use_block_statements.rs (1)

77-116: Macros are safely local and the enum is only used within this file. The macros have zero external callers, so moving them to function scope poses no risk. The UseBlockStatementsOperationType enum could be made private if you'd prefer to keep the public API surface tighter—all eight usages are contained within this module.

@dyc3 dyc3 requested review from a team January 29, 2026 16:08
Comment on lines 15 to 20
Copy link
Member

Choose a reason for hiding this comment

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

I believe we can codegen these (checking the code), so that when we add a new group, we don't need to manually update the build file. It would be unfortunate if a contributor adds a new lint rule to a new group, and we miss that part. If we can't codegen, maybe we can read the folders under assist and lint.

What do you think? I hope you see the issue. Maybe you'll have better solution

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that makes sense.

@dyc3 dyc3 force-pushed the dyc3/codegen-refactor branch from 6ab3bf4 to 5450c18 Compare January 29, 2026 17:16
Copy link
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/biome_json_analyze/src/assist/source.rs (1)

1-3: Duplicate "generated file" comment.

Lines 1 and 3 both contain the same comment. Likely a codegen hiccup worth tidying up.

🔧 Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`

 #![doc = r" Group description generated by proc macro at compile time."]
crates/biome_js_analyze/src/lint/performance.rs (1)

1-3: Duplicate header comment.

Lines 1 and 3 contain identical //! Generated file... comments. This appears to be a codegen oversight.

🤖 Fix all issues with AI agents
In `@crates/biome_html_analyze/build.rs`:
- Around line 21-36: In watch_group, do not ignore fs::read_dir errors: when
read_dir(&group_dir) returns Err, check the error kind and propagate or return
the error if it's not NotFound so filesystem problems surface during build;
update the block that currently does `if let Ok(entries) =
fs::read_dir(&group_dir) { ... }` to match on the Result for
fs::read_dir(&group_dir) and return Err(e) (or propagate with the ? operator)
when e.kind() != io::ErrorKind::NotFound, while keeping the existing handling of
Ok(entries) and still calling touch_file(&group_file) at the end.

In `@xtask/codegen/src/generate_analyzer.rs`:
- Around line 20-36: The code creates _category_comment as a borrowed temporary
and then references an undefined identifier inside the quote; change to create
an owned String (e.g., let category_comment: String = match *category { "lint"
=> "Lint groups".into(), "assist" => "Assist groups".into(), "syntax" => "Syntax
groups".into(), other => { let mut title = other.to_string(); if let Some(ch) =
title.get_mut(0..1) { ch.make_ascii_uppercase(); } format!("{} groups", title) }
}; then splice that owned variable into the quote! invocation used to push into
watch_calls (watch_calls.push(quote! { // `#category_comment` });) so the
identifier exists and no temporary borrow occurs.

Comment on lines +21 to +36
fn watch_group(category: &str, group: &str) -> io::Result<()> {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let base_path = PathBuf::from(&manifest_dir).join("src");
let group_dir = base_path.join(category).join(group);
let group_file = base_path.join(category).join(format!("{}.rs", group));
println!("cargo:rerun-if-changed={}", group_dir.display());
if let Ok(entries) = fs::read_dir(&group_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "rs") {
println!("cargo:rerun-if-changed={}", path.display());
}
}
}
touch_file(&group_file)?;
Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Don’t silently ignore read_dir failures.
If read_dir fails for reasons other than “not found”, the build continues without rerun hints, which can hide filesystem problems.

🔧 Suggested tweak
-    if let Ok(entries) = fs::read_dir(&group_dir) {
-        for entry in entries.flatten() {
-            let path = entry.path();
-            if path.extension().is_some_and(|ext| ext == "rs") {
-                println!("cargo:rerun-if-changed={}", path.display());
-            }
-        }
-    }
+    match fs::read_dir(&group_dir) {
+        Ok(entries) => {
+            for entry in entries.flatten() {
+                let path = entry.path();
+                if path.extension().is_some_and(|ext| ext == "rs") {
+                    println!("cargo:rerun-if-changed={}", path.display());
+                }
+            }
+        }
+        Err(err) if err.kind() == io::ErrorKind::NotFound => {}
+        Err(err) => return Err(err),
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn watch_group(category: &str, group: &str) -> io::Result<()> {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let base_path = PathBuf::from(&manifest_dir).join("src");
let group_dir = base_path.join(category).join(group);
let group_file = base_path.join(category).join(format!("{}.rs", group));
println!("cargo:rerun-if-changed={}", group_dir.display());
if let Ok(entries) = fs::read_dir(&group_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "rs") {
println!("cargo:rerun-if-changed={}", path.display());
}
}
}
touch_file(&group_file)?;
Ok(())
fn watch_group(category: &str, group: &str) -> io::Result<()> {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let base_path = PathBuf::from(&manifest_dir).join("src");
let group_dir = base_path.join(category).join(group);
let group_file = base_path.join(category).join(format!("{}.rs", group));
println!("cargo:rerun-if-changed={}", group_dir.display());
match fs::read_dir(&group_dir) {
Ok(entries) => {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "rs") {
println!("cargo:rerun-if-changed={}", path.display());
}
}
}
Err(err) if err.kind() == io::ErrorKind::NotFound => {}
Err(err) => return Err(err),
}
touch_file(&group_file)?;
Ok(())
}
🤖 Prompt for AI Agents
In `@crates/biome_html_analyze/build.rs` around lines 21 - 36, In watch_group, do
not ignore fs::read_dir errors: when read_dir(&group_dir) returns Err, check the
error kind and propagate or return the error if it's not NotFound so filesystem
problems surface during build; update the block that currently does `if let
Ok(entries) = fs::read_dir(&group_dir) { ... }` to match on the Result for
fs::read_dir(&group_dir) and return Err(e) (or propagate with the ? operator)
when e.kind() != io::ErrorKind::NotFound, while keeping the existing handling of
Ok(entries) and still calling touch_file(&group_file) at the end.

Copy link
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.

Looks good. The one thing I would like to address before merging, if possible, is the removal of xtask from the biome crates. The rest is mostly nitpicks

@dyc3 dyc3 force-pushed the dyc3/codegen-refactor branch from 5450c18 to d2f0adf Compare January 29, 2026 22:28
Copy link
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (11)
crates/biome_js_analyze/src/syntax/correctness.rs (1)

1-9: Clarify generation source in the header docs.

The new proc‑macro docs say the file is generated at compile time, but the header still (twice) points at xtask/codegen, which is now misleading. Consider collapsing to a single, accurate header.

💡 Suggested tidy-up
-//! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
+//! Generated file, do not edit by hand. Contents are produced at compile time by `declare_group_from_fs!`.
crates/biome_js_analyze/src/assist/source.rs (1)

1-3: Duplicate header comment.

The "Generated file, do not edit by hand" comment appears twice (lines 1 and 3). This looks like a codegen bug.

crates/biome_graphql_analyze/src/lint/suspicious.rs (1)

1-3: Duplicate header comment (codegen-wide issue).

Same as other generated files — the header appears twice. The codegen template likely has this bug.

crates/biome_css_analyze/src/assist/source.rs (1)

1-4: Duplicate "Generated file" comment.

Lines 1 and 3 both contain the same //! Generated file, do not edit by hand, see xtask/codegen comment. Looks like the codegen duplicated this accidentally.

🧹 Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`

 #![doc = r" Group description generated by proc macro at compile time."]
crates/biome_css_analyze/src/lint/suspicious.rs (1)

1-4: Duplicate "Generated file" comment.

Same issue as other files — lines 1 and 3 are duplicates.

crates/biome_js_analyze/src/lint/performance.rs (1)

1-4: Duplicate "Generated file" comment.

Lines 1 and 3 — same duplication issue present across all these generated files.

crates/biome_js_analyze/src/lint/style.rs (1)

1-4: Duplicate "Generated file" comment.

Consistent with the other files — duplicate on lines 1 and 3.

crates/biome_css_analyze/src/lint/correctness.rs (1)

1-4: Duplicate "Generated file" comment.

Same duplication on lines 1 and 3.

crates/biome_js_analyze/src/lint/a11y.rs (1)

1-4: Duplicate "Generated file" comment.

Lines 1 and 3 duplicated.

crates/biome_js_analyze/src/lint/complexity.rs (1)

1-4: Fix duplicate "Generated file" comment in the codegen template.

The comment appears on both lines 1 and 3 of all generated group files across the codebase — this needs fixing at the source rather than in individual files.

crates/biome_js_analyze/src/lint/correctness.rs (1)

1-3: Duplicate header comment.

Lines 1 and 3 are identical. Looks like one slipped through during generation—one of these should be removed.

🧹 Proposed fix
 //! Generated file, do not edit by hand, see `xtask/codegen`
-
-//! Generated file, do not edit by hand, see `xtask/codegen`
🧹 Nitpick comments (3)
crates/biome_analyze_macros/src/lib.rs (1)

5-25: Prefer a runnable doctest for the macro example.
The current ignore block won’t be validated; consider adding a small rust/no_run doctest (with an assertion) and keep the full macro usage in a separate ignored block if needed. As per coding guidelines: Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests.

xtask/codegen/src/generate_analyzer.rs (1)

114-149: Consider extracting the repeated category-checking pattern.

The same pattern (check if directory exists → generate category → insert if non-empty) is repeated across all generate_*_analyzer functions. A helper function could reduce duplication.

♻️ Suggested helper approach
fn try_add_category(
    category: &'static str,
    base_path: &Path,
    analyzers: &mut BTreeMap<&'static str, TokenStream>,
    categories_and_groups: &mut BTreeMap<&'static str, Vec<String>>,
) -> Result<()> {
    let path = base_path.join(category);
    if path.exists() {
        let groups = generate_category(category, analyzers, base_path)?;
        if !groups.is_empty() {
            categories_and_groups.insert(category, groups);
        }
    }
    Ok(())
}
crates/biome_json_analyze/src/assist/source.rs (1)

1-4: Minor: Duplicate generated-file comment.

Lines 1 and 3 both contain //! Generated file, do not edit by hand, see xtask/codegen. This appears to be a codegen artifact worth tidying up.

@dyc3 dyc3 merged commit 3d52eed into main Jan 29, 2026
30 checks passed
@dyc3 dyc3 deleted the dyc3/codegen-refactor branch January 29, 2026 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter A-Tooling Area: internal tools L-CSS Language: CSS L-HTML Language: HTML and super languages L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments