Skip to content

Conversation

@Faizanq
Copy link

@Faizanq Faizanq commented Jan 6, 2026

Summary

Adds noExcessiveLinesPerFile rule to CSS and GraphQL by extracting shared logic into biome_analyze::utils::count_lines_in_file.

  • Shared helper for line counting across languages
  • CSS and GraphQL implementations
  • Refactored JS to use shared helper

Fixes #8673

Test plan

  • cargo test -p biome_css_analyze -- no_excessive_lines_per_file
  • cargo test -p biome_graphql_analyze -- no_excessive_lines_per_file
  • cargo test -p biome_js_analyze -- no_excessive_lines_per_file

- Add shared count_lines_in_file helper to biome_analyze::utils
- Refactor JS implementation to use shared helper
- Add CSS and GraphQL implementations
- Add test specs for both languages

Fixes biomejs#8673
@changeset-bot
Copy link

changeset-bot bot commented Jan 6, 2026

🦋 Changeset detected

Latest commit: d2a1903

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-Linter Area: linter L-JavaScript Language: JavaScript and super languages L-CSS Language: CSS labels Jan 6, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Walkthrough

Implements the noExcessiveLinesPerFile lint for CSS and GraphQL, adds a shared utility count_lines_in_file in biome_analyze to count lines in a syntax tree (optionally skipping blank lines), and refactors the JavaScript rule to use this utility. Adds test fixtures and options for CSS and GraphQL that assert diagnostics when files exceed configured max lines.

Possibly related PRs

  • PR #8639: Introduced the JavaScript implementation of noExcessiveLinesPerFile and the shared options that this change reuses and refactors.

Suggested labels

A-Parser, A-Diagnostic

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: adding noExcessiveLinesPerFile rule to CSS and GraphQL languages.
Description check ✅ Passed The description clearly relates to the changeset, detailing the extraction of shared line-counting logic and implementations for CSS and GraphQL.
Linked Issues check ✅ Passed The PR fulfils the primary objectives from issue #8673: implements noExcessiveLinesPerFile for CSS and GraphQL [#8673], extracts shared count_lines_in_file utility, and refactors JavaScript implementation.
Out of Scope Changes check ✅ Passed All changes align with issue #8673 objectives: new CSS and GraphQL rule implementations, shared utility function, and JavaScript refactoring are in scope.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30a5b73 and d2a1903.

📒 Files selected for processing (1)
  • .changeset/no-excessive-lines-cross-lang.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/no-excessive-lines-cross-lang.md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

🤖 Fix all issues with AI Agents
In @crates/biome_analyze/src/utils.rs:
- Around line 162-184: The count_lines_in_file function unnecessarily collects
tokens into a Vec inside flat_map and lacks doc clarity: replace the
.flat_map(|descendant| descendant.tokens().collect::<Vec<_>>()) with
.flat_map(|descendant| descendant.tokens()) to avoid allocation, and expand the
function doc comment for count_lines_in_file to state (1) when skip_blank_lines
is true a "line" is counted by presence of leading newlines on tokens (i.e.,
blank lines are ignored), (2) when skip_blank_lines is false a "line" equals
each newline piece in token.leading_trivia after trimming trailing trivia
(explain trimming removes trailing-only trivia that would miscount lines at
token boundaries), and (3) note the +1 offset is to account for the initial
first line before any newline is encountered.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 957cd8e and 30a5b73.

⛔ Files ignored due to path filters (6)
  • crates/biome_css_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.css.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (13)
  • .changeset/no-excessive-lines-cross-lang.md
  • crates/biome_analyze/src/utils.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.css
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_analyze/src/utils.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
🧠 Learnings (34)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `action` function and add `fix_kind` metadata to the rule macro if the rule provides code actions
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : When porting rules from other linters, use `sources` metadata with `RuleSource::Eslint().same()` for identical behavior or `.inspired()` for different behavior
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule

Applied to files:

  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic

Applied to files:

  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : New rules must be placed inside the `nursery` group before promotion to other groups

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule documentation must include an `## Examples` section followed by `### Invalid` and `### Valid` subsections, with Invalid appearing first

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table

Applied to files:

  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • .changeset/no-excessive-lines-cross-lang.md
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_analyze/src/utils.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` format for test files containing multiple code snippets, where each snippet is a string in an array

Applied to files:

  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/specs/**/options.json : Create an `options.json` file (formatted as `biome.json`) in test specification folders to apply non-default formatting options to all test files in that folder

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Rule options must be defined in the `biome_rule_options` crate with a file named after the rule

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(deny_unknown_fields)]` to rule option structs to enforce strict configuration validation

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Biome linter rules must be designed to work across languages, requiring careful naming to indicate intended scope

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-11-21T01:10:53.059Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8171
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:125-137
Timestamp: 2025-11-21T01:10:53.059Z
Learning: In the Biome codebase, each lint rule has its own options type declaration (e.g., `type Options = RuleNameOptions`) as part of the codegen process, even if the options struct is empty or unused. This is standard practice and should not be flagged as an issue.

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-09-25T12:32:59.003Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2025-12-31T15:35:41.261Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:41.261Z
Learning: In crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs, the `issue_number` field in `declare_lint_rule!` macro is optional and the vast majority of nursery rules do not need it. Do not recommend adding `issue_number` unless there's a specific reason.

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
  • crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json
  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use helper functions like `map`, `filter`, and `and_then` to avoid excessive nested `if let` statements

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_analyze/src/utils.rs
📚 Learning: 2025-12-31T15:35:32.899Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:32.899Z
Learning: In Rust lint rules under the nursery category, the issue_number field in declare_lint_rule! is optional and should not be added unless there is a compelling reason. In code reviews, verify that no unnecessary issue_number is included in nursery lint declarations. Only add issue_number if there is an explicit, justified reason (e.g., tracked issue for external observers). This guidance broadly applies to all nursery lint rule files, not just the single file.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Avoid string allocations by using `&str` or `TokenText` instead of `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_analyze/src/utils.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_node_union!` macro to query multiple node types together to avoid redundant traversal passes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_analyze/src/utils.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `Markup!` macro for diagnostic messages and code action descriptions to ensure proper formatting

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use the `Semantic<T>` query type to access semantic information about bindings, references, and scope within a rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : When porting rules from other linters, use `sources` metadata with `RuleSource::Eslint().same()` for identical behavior or `.inspired()` for different behavior

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Check if a variable is global using the semantic model before reporting diagnostics for rules that ban global functions or variables

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `use` prefix when the rule's sole intention is to mandate a single concept

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_lint_rule!` macro with a `version` field set to `next` for new rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation

Applied to files:

  • crates/biome_analyze/src/utils.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `no` prefix when the rule's sole intention is to forbid a single concept

Applied to files:

  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `action` function and add `fix_kind` metadata to the rule macro if the rule provides code actions

Applied to files:

  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
  • crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement the `diagnostic` function to provide error messages explaining what the error is, why it is triggered, and what the user should do

Applied to files:

  • crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/**/*.rs : Apply `#[serde(rename_all = "camelCase")]` to rule option structs to match JSON configuration naming convention

Applied to files:

  • crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json
🧬 Code graph analysis (2)
crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (1)
crates/biome_analyze/src/utils.rs (1)
  • count_lines_in_file (163-184)
crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (3)
crates/biome_analyze/src/utils.rs (1)
  • count_lines_in_file (163-184)
crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (2)
  • run (70-85)
  • diagnostic (87-103)
crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (2)
  • run (127-142)
  • diagnostic (144-160)
🔇 Additional comments (15)
crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json (1)

1-15: LGTM!

Test configuration properly set up with maxLines: 2 to validate the rule against the 4-line invalid.css fixture.

crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json (1)

1-15: LGTM!

Test configuration properly set up with maxLines: 4 to validate that the valid.css fixture passes the rule.

crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.graphql (1)

1-4: LGTM!

Clean test fixture with four queries to validate the rule's line-counting behaviour.

.changeset/no-excessive-lines-cross-lang.md (1)

1-5: LGTM!

Changeset properly formatted with appropriate minor version bump and clear issue reference.

crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.css (1)

1-4: LGTM!

Clean test fixture with four CSS rules to validate the line-counting behaviour.

crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.options.json (1)

1-15: Configuration looks correct.

The test options file is properly structured with an appropriate maxLines limit for the valid test case.

crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.graphql (1)

1-3: Test fixture is appropriate.

The 3-line fixture correctly tests the valid case against the maxLines: 4 configuration.

crates/biome_graphql_analyze/tests/specs/nursery/noExcessiveLinesPerFile/invalid.options.json (1)

1-15: Configuration looks correct.

The maxLines: 2 setting is appropriate for testing the invalid case where diagnostics should be triggered.

crates/biome_css_analyze/tests/specs/nursery/noExcessiveLinesPerFile/valid.css (1)

1-3: Test fixture is appropriate.

The CSS fixture follows the same simple pattern as the GraphQL test, which is good for consistency.

crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (2)

3-3: Clean refactor to use shared utility.

The import of count_lines_in_file enables code reuse across language implementations.


131-135: Correctly delegates line counting to the shared utility.

The function call properly passes the EOF token predicate and the skip_blank_lines option, maintaining the original behaviour whilst eliminating code duplication.

crates/biome_graphql_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (2)

64-103: LGTM!

The rule implementation correctly uses the shared count_lines_in_file utility, properly detects EOF tokens, and provides a clear diagnostic message with the line count and limit.


10-13: Consolidate the first paragraph into a single line.

The first paragraph must be written as a single line to ensure proper rendering in the rules overview table.

Based on learnings, this applies to all rule documentation in biome_analyze/**/*_analyze/**/src/lint/**/*.rs.

🔎 Proposed fix
-    /// Restrict the number of lines in a file.
-    ///
-    /// Large files tend to do many things and can make it hard to follow what's going on.
-    /// This rule can help enforce a limit on the number of lines in a file.
+    /// Restrict the number of lines in a file to improve maintainability and readability by preventing excessively large files.
+    ///
+    /// Large files tend to do many things and can make it hard to follow what's going on. This rule can help enforce a limit on the number of lines in a file.
⛔ Skipped due to learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:41.261Z
Learning: In crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs, the `issue_number` field in `declare_lint_rule!` macro is optional and the vast majority of nursery rules do not need it. Do not recommend adding `issue_number` unless there's a specific reason.
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule documentation must include an `## Examples` section followed by `### Invalid` and `### Valid` subsections, with Invalid appearing first
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `no` prefix when the rule's sole intention is to forbid a single concept
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : New rules must be placed inside the `nursery` group before promotion to other groups
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Use `declare_lint_rule!` macro with a `version` field set to `next` for new rules
crates/biome_css_analyze/src/lint/nursery/no_excessive_lines_per_file.rs (2)

64-103: LGTM!

The CSS rule implementation mirrors the GraphQL variant correctly, using the shared utility and providing clear diagnostics.


10-13: Consolidate the first paragraph into a single line.

Same issue as the GraphQL rule: the first paragraph must be written as a single line to ensure proper rendering in the rules overview table.

Based on learnings, this applies to all rule documentation in biome_analyze/**/*_analyze/**/src/lint/**/*.rs.

🔎 Proposed fix
-    /// Restrict the number of lines in a file.
-    ///
-    /// Large files tend to do many things and can make it hard to follow what's going on.
-    /// This rule can help enforce a limit on the number of lines in a file.
+    /// Restrict the number of lines in a file to improve maintainability and readability by preventing excessively large files.
+    ///
+    /// Large files tend to do many things and can make it hard to follow what's going on. This rule can help enforce a limit on the number of lines in a file.
⛔ Skipped due to learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : The first paragraph of rule documentation must be written in a single line to ensure proper rendering in the rules overview table
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Invalid code snippets in rule documentation must emit exactly one diagnostic
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:41.261Z
Learning: In crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs, the `issue_number` field in `declare_lint_rule!` macro is optional and the vast majority of nursery rules do not need it. Do not recommend adding `issue_number` unless there's a specific reason.
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule documentation must include an `## Examples` section followed by `### Invalid` and `### Valid` subsections, with Invalid appearing first
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `no` prefix when the rule's sole intention is to forbid a single concept
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Code blocks in rule documentation must specify a language identifier and be tagged with `expect_diagnostic` for invalid examples or remain untagged for valid examples
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : New rules must be placed inside the `nursery` group before promotion to other groups
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Rule names should use the `use` prefix when the rule's sole intention is to mandate a single concept
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Deprecated rules must include a `deprecated` field in the `declare_lint_rule!` macro with an explanation of what rule to use instead

Comment on lines +162 to +184
/// Counts lines in a syntax tree, used by `noExcessiveLinesPerFile`.
pub fn count_lines_in_file<L: Language>(
node: &SyntaxNode<L>,
is_eof_token: impl Fn(&SyntaxToken<L>) -> bool,
skip_blank_lines: bool,
) -> usize {
node.descendants()
.flat_map(|descendant| descendant.tokens().collect::<Vec<_>>())
.filter(|token| !is_eof_token(token))
.fold(0, |acc, token| {
if skip_blank_lines {
return acc + token.has_leading_newline() as usize;
}

acc + token
.trim_trailing_trivia()
.leading_trivia()
.pieces()
.filter(|piece| piece.is_newline())
.count()
})
+ 1 // Add 1 for the first line
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Optimise token traversal and clarify line-counting semantics.

Two points:

  1. Line 169: Collecting to Vec within flat_map is unnecessary—flat_map already flattens iterators. Replace .flat_map(|descendant| descendant.tokens().collect::<Vec<_>>()) with .flat_map(|descendant| descendant.tokens()).

  2. Documentation gap: The current comment doesn't explain when each mode applies or what "line" means in each case. Add a doc comment clarifying:

    • What constitutes a "line" when skip_blank_lines is true vs false
    • Why trailing trivia is trimmed in the false case
    • The rationale for the + 1 offset
🔎 Proposed fix
+/// Counts lines in a syntax tree, used by `noExcessiveLinesPerFile`.
+///
+/// When `skip_blank_lines` is `true`, counts only tokens that introduce a new line
+/// (have a leading newline in their trivia).
+///
+/// When `skip_blank_lines` is `false`, counts all newline trivia pieces in each token's
+/// leading trivia after trimming trailing trivia from the previous token.
+///
+/// Tokens matching `is_eof_token` are excluded from the count.
+///
+/// Returns the total line count, including line 1.
-/// Counts lines in a syntax tree, used by `noExcessiveLinesPerFile`.
 pub fn count_lines_in_file<L: Language>(
     node: &SyntaxNode<L>,
     is_eof_token: impl Fn(&SyntaxToken<L>) -> bool,
     skip_blank_lines: bool,
 ) -> usize {
     node.descendants()
-        .flat_map(|descendant| descendant.tokens().collect::<Vec<_>>())
+        .flat_map(|descendant| descendant.tokens())
         .filter(|token| !is_eof_token(token))
         .fold(0, |acc, token| {
             if skip_blank_lines {
                 return acc + token.has_leading_newline() as usize;
             }

             acc + token
                 .trim_trailing_trivia()
                 .leading_trivia()
                 .pieces()
                 .filter(|piece| piece.is_newline())
                 .count()
         })
         + 1 // Add 1 for the first line
 }
🤖 Prompt for AI Agents
In @crates/biome_analyze/src/utils.rs around lines 162-184, The
count_lines_in_file function unnecessarily collects tokens into a Vec inside
flat_map and lacks doc clarity: replace the .flat_map(|descendant|
descendant.tokens().collect::<Vec<_>>()) with .flat_map(|descendant|
descendant.tokens()) to avoid allocation, and expand the function doc comment
for count_lines_in_file to state (1) when skip_blank_lines is true a "line" is
counted by presence of leading newlines on tokens (i.e., blank lines are
ignored), (2) when skip_blank_lines is false a "line" equals each newline piece
in token.leading_trivia after trimming trailing trivia (explain trimming removes
trailing-only trivia that would miscount lines at token boundaries), and (3)
note the +1 offset is to account for the initial first line before any newline
is encountered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-CSS Language: CSS L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📎 Implement noExcessiveLinesPerFile

2 participants