+
Skip to content

Conversation

ptkagori
Copy link
Contributor

Summary

Added more lint rules for Qwik framework.

  • useQwikMethodUsage
  • useQwikValidLexicalScope

Handoff Notes:

  1. This is a WIP PR which follows up on feat(qwik): add few new lint rules (already merged)
  2. Any requested changes on this PR should be addressed accordingly and the branch should be kept in sync with latest changes from main.

PS: The branch builds successfully in local as of the first commit

Resource: https://qwik.dev/docs/getting-started/

Test Plan

  • Unit Tests: Added/Updated valid and invalid test cases for the above added rules

Docs

Added: biomejs/website#2727 to sync addition of Qwik domain with website
Added changeset documentation for each rule

Each rule includes insightful documentation with:

  • Clear purpose and Qwik-specific context
  • Invalid/valid code examples
  • Automatic fix capabilities where applicable
  • Integration with Biome's configuration schema

Copy link

changeset-bot bot commented Jul 30, 2025

🦋 Changeset detected

Latest commit: d2371e9

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-CLI Area: CLI A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Jul 30, 2025
Copy link

codspeed-hq bot commented Jul 30, 2025

CodSpeed Performance Report

Merging #7071 will not alter performance

Comparing ptkagori:feat/qwik-useMethodUsage (d2371e9) with main (29e4229)1

Summary

✅ 53 untouched
⏩ 85 skipped2

Footnotes

  1. No successful run was found on main (459a6ac) during the generation of this report, so 29e4229 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 85 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.

@ptkagori ptkagori force-pushed the feat/qwik-useMethodUsage branch from 8c0d727 to eef697d Compare August 18, 2025 17:25
Copy link
Contributor

coderabbitai bot commented Aug 18, 2025

Walkthrough

Adds two new Qwik lint rules—UseQwikMethodUsage and UseQwikValidLexicalScope—declared via declare_lint_rule! in crates/biome_js_analyze/src/lint/nursery. Adds corresponding options types and new modules in crates/biome_rule_options. Provides comprehensive valid and invalid test fixtures for both rules and changeset files. Rules detect improper Qwik hook usage and non‑serialisable lexical scopes, emit diagnostics with notes and links to Qwik docs, and introduce new public lint rule symbols and public options structs. No existing public signatures were removed.

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title follows the conventional commit style and accurately summarises the main change by indicating the addition of the two Qwik lint rules useQwikMethodUsage and useQwikValidLexicalScope, matching the files and tests introduced.
Description Check ✅ Passed The description is directly related to the changeset and outlines the addition of the two new Qwik lint rules, test coverage, and documentation updates, making it sufficiently on-topic and informative for reviewers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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: 4

🧹 Nitpick comments (12)
crates/biome_cli/src/logging.rs (1)

38-42: “Pretty” now uses compact formatting; semantics and docs diverge

Switching the Pretty branch to compact() makes Pretty and Compact identical and contradicts the enum doc (“A pretty log on multiple lines with nice colours”). If this change is intentional, please update the user-facing description (and consider deprecating/aliasing Pretty). If it’s not intentional, revert to pretty().

Proposed fix to restore Pretty semantics:

-                let format = format.compact();
+                let format = format.pretty();

and

-                let format = format.compact();
+                let format = format.pretty();

Optional: when writing to a file (Line 35), consider disabling ANSI (with_ansi(false)) to avoid escape sequences in log files.

Also applies to: 59-63

crates/biome_cli/tests/commands/ci.rs (1)

910-912: Switching to .jsx fixtures for skip-parse-errors looks good.

This keeps the test aligned with other CLI suites moving to JSX fixtures. No behavioural change; the test still exercises lint error vs parse error with the flag.

Optional: rename the variables to valid_jsx/invalid_jsx for instant readability.

-    let valid = Utf8Path::new("valid.jsx");
-    let invalid = Utf8Path::new("invalid.jsx");
+    let valid_jsx = Utf8Path::new("valid.jsx");
+    let invalid_jsx = Utf8Path::new("invalid.jsx");
@@
-    fs.insert(valid.into(), LINT_ERROR.as_bytes());
-    fs.insert(invalid.into(), PARSE_ERROR.as_bytes());
+    fs.insert(valid_jsx.into(), LINT_ERROR.as_bytes());
+    fs.insert(invalid_jsx.into(), PARSE_ERROR.as_bytes());
@@
-                valid.as_str(),
-                invalid.as_str(),
+                valid_jsx.as_str(),
+                invalid_jsx.as_str(),
.changeset/all-rivers-appear.md (2)

12-18: Make the invalid example explicitly Qwik-contextual.

To better illustrate why class methods are problematic in Qwik, wrap the class usage inside a component$ and an event handler. This makes the diagnostic rationale crystal clear.

-```js
-class Counter {
-  increment() {  // Class methods are invalid in Qwik components
-    this.count++;
-  }
-}
-```
+```js
+export const Counter = component$(() => {
+  class Logic {
+    increment() { // Class methods are invalid inside Qwik components
+      this.count++;
+    }
+  }
+  const logic = new Logic();
+  return <button onClick$={() => logic.increment()}>+</button>;
+});
+```

8-8: Nit: unify “anti-patterns” spelling with docs style.

LanguageTool suggests “antipatterns”; the Qwik ecosystem commonly uses “anti-patterns”. Pick one and keep it consistent across changesets and docs.

crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (2)

1-3: Tighten up the fixture (EOF newline and trailing space).

Minor formatting polish to keep snapshots tidy and avoid spurious diffs.

-export const Counter = () => {
-  const count = useSignal(0);
-}; 
+export const Counter = () => {
+  const count = useSignal(0);
+};

1-3: Align the invalid case with the rule’s documentation.

Docs emphasise avoiding class methods inside Qwik components; this fixture targets a different smell (using useSignal in a plain function). If the rule is meant to flag class-method usage patterns, consider adding an additional invalid case exercising that scenario to prevent drift between docs and tests.

Would you like me to draft an additional invalid.jsx that introduces a class method inside component$ and an onClick$ capturing it?

crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1)

4-14: Good invalid coverage; consider broadening cases.

This exercises unwrapped arrow functions well. If the rule is intended to also flag function declarations or function expressions, consider adding one such example to harden the fixture. Happy to sketch it if useful.

crates/biome_rule_options/src/use_qwik_method_usage.rs (1)

4-6: Align UseQwikMethodUsageOptions with house style

To mirror other rule options (and improve config robustness), add serde attributes and standardise the struct shape. Verified that UseQwikMethodUsageOptions is exported in crates/biome_rule_options/src/lib.rs and used in biome_js_analyze.

File: crates/biome_rule_options/src/use_qwik_method_usage.rs

 #[derive(Default, Clone, Debug, Deserialize, Deserializable, Eq, PartialEq, Serialize)]
 #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
- pub struct UseQwikMethodUsageOptions;
+ #[serde(rename_all = "camelCase", deny_unknown_fields, default)]
+ pub struct UseQwikMethodUsageOptions {}
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (1)

2-9: Minor clarity nit: explicitly import Qwik APIs in the fixture.

Not required for the rule to run, but it makes the example self-explanatory and future-proof if the parser tightens.

-// should not generate diagnostics 
+// should not generate diagnostics
+import { component$, useSignal } from '@builder.io/qwik';
 
 export const Counter = component$(() => {
   const count = useSignal(0);
 });
 
 export const useCounter = () => {
   const count = useSignal(0);
   return count;
 };
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1)

128-170: Support “const useX = function() {…}” to avoid false positives.

JsFunctionExpression only reads a function's own id(). It misses the common pattern const useX = function() {} (anonymous function expression bound via a variable declarator), which will report as invalid today.

Apply this diff to add a variable-declarator fallback for function expressions, mirroring the arrow branch:

-            AnyJsFunction::JsFunctionExpression(expr) => expr
-                .id()
-                .and_then(|binding| binding.as_js_identifier_binding().cloned())
-                .and_then(|ident| ident.name_token().ok())
-                .map(|token| token.token_text_trimmed()),
+            AnyJsFunction::JsFunctionExpression(expr) => {
+                expr.id()
+                    .and_then(|binding| binding.as_js_identifier_binding().cloned())
+                    .and_then(|ident| ident.name_token().ok())
+                    .map(|token| token.token_text_trimmed())
+                    .or_else(|| {
+                        expr.syntax()
+                            .ancestors()
+                            .find(|a| JsVariableDeclarator::can_cast(a.kind()))
+                            .and_then(JsVariableDeclarator::cast)
+                            .and_then(|decl| decl.id().ok())
+                            .and_then(|binding_pattern| {
+                                binding_pattern
+                                    .as_any_js_binding()
+                                    .and_then(|binding| binding.as_js_identifier_binding().cloned())
+                            })
+                            .and_then(|ident| ident.name_token().ok())
+                            .map(|token| token.token_text_trimmed())
+                    })
+            }
crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (2)

18-30: Tiny docs nit: code fence language.

The “Invalid” example uses a typed parameter (msg: string) but the fence is js. Consider ts for accuracy.


71-84: Docs link should point to lexical scope, not use-methods.

The diagnostic’s “Learn more” link currently targets the use-methods page. For this rule, the lexical scope page is more precise.

Apply this diff to fix the URL:

-            "Wrap the expression with "<Emphasis>"$(...)"</Emphasis>" to make it serializable. "
-            "Learn more: " <Hyperlink href="https://qwik.dev/docs/components/state/#use-methods">"Qwik documentation"</Hyperlink>"."
+            "Wrap the expression with "<Emphasis>"$(...)"</Emphasis>" to make it serializable. "
+            "Learn more: " <Hyperlink href="https://qwik.dev/docs/advanced/optimizer/#lexical-scope">"Qwik documentation"</Hyperlink>"."
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 62fdbc8 and eef697d.

⛔ Files ignored due to path filters (10)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (19)
  • .changeset/all-rivers-appear.md (1 hunks)
  • .changeset/long-garlics-flow.md (1 hunks)
  • .changeset/tame-dolls-serve.md (0 hunks)
  • .changeset/yummy-kids-judge.md (0 hunks)
  • crates/biome_cli/src/logging.rs (2 hunks)
  • crates/biome_cli/tests/commands/check.rs (1 hunks)
  • crates/biome_cli/tests/commands/ci.rs (1 hunks)
  • crates/biome_cli/tests/commands/format.rs (2 hunks)
  • crates/biome_cli/tests/commands/lint.rs (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs (1 hunks)
  • crates/biome_service/src/file_handlers/javascript.rs (0 hunks)
💤 Files with no reviewable changes (3)
  • .changeset/tame-dolls-serve.md
  • crates/biome_service/src/file_handlers/javascript.rs
  • .changeset/yummy-kids-judge.md
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{rs,toml}

📄 CodeRabbit Inference Engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs
  • crates/biome_cli/src/logging.rs
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
crates/biome_*/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs
  • crates/biome_cli/src/logging.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/tests/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
.changeset/*.md

📄 CodeRabbit Inference Engine (CONTRIBUTING.md)

.changeset/*.md: Create changesets with just new-changeset; store them in .changeset/ with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.

Files:

  • .changeset/long-garlics-flow.md
  • .changeset/all-rivers-appear.md
🧠 Learnings (22)
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in biome_lsp’s server.tests.rs

Applied to files:

  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_cli/tests/commands/lint.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_cli/tests/commands/lint.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/{invalid*,valid*}.{js,jsx,ts,tsx,css,graphql,jsonc} : Place snapshot test cases under `tests/specs/<group>/<ruleName>/` using files prefixed with `invalid` and `valid`

Applied to files:

  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
  • crates/biome_cli/tests/commands/lint.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_tests.rs : Create tests/spec_tests.rs in the biome_html_formatter crate that generates tests via tests_macros::gen_tests! for all HTML files at tests/specs/html/**/*.html

Applied to files:

  • crates/biome_cli/tests/commands/ci.rs
  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/*.jsonc : `.jsonc` snapshot files must contain an array of code strings; they are interpreted in script mode (no ESM syntax)

Applied to files:

  • crates/biome_cli/tests/commands/check.rs
  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/language.rs : Create tests/language.rs defining HtmlTestFormatLanguage and implement TestFormatLanguage for it

Applied to files:

  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the FormatNode trait and implement it for your Node

Applied to files:

  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use the generic Format trait and FormatNode for AST nodes when implementing the formatter

Applied to files:

  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Build an intermediate IR via the provided helper APIs when formatting

Applied to files:

  • crates/biome_cli/tests/commands/format.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_rule_options/src/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`

Applied to files:

  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active

Applied to files:

  • crates/biome_cli/tests/commands/lint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule provides a code action, add `fix_kind` in `declare_lint_rule!` and use `ctx.action_category(ctx.category(), ctx.group())` and `ctx.metadata().applicability()` when constructing actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule is deprecated, set the `deprecated:` field in `declare_lint_rule!` with a reason and alternative

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Choose an appropriate `severity` in `declare_lint_rule!` (default is info); use `Severity::Error` for hard errors, `Warning` for potential issues, `Information` for style

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When banning globals (e.g., `console.log`), consult the semantic model to avoid false positives on locally shadowed identifiers

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use the local `rule_category!()` macro in diagnostics for the rule’s category, not string-parsed categories

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-08-17T08:56:30.822Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧬 Code Graph Analysis (7)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (1)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (3)
  • Counter (1-3)
  • Counter (1-3)
  • count (2-2)
crates/biome_cli/tests/commands/format.rs (1)
crates/biome_fs/src/path.rs (1)
  • new (53-61)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (5)
  • HelloWorld (3-21)
  • HelloWorld (3-21)
  • print (4-6)
  • handleClick (8-10)
  • processData (12-14)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (5)
  • HelloWorld (4-22)
  • HelloWorld (4-22)
  • print (5-7)
  • handleClick (9-11)
  • processData (13-15)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (4)
  • Counter (2-4)
  • Counter (2-4)
  • count (3-3)
  • count (7-7)
crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (4)
crates/biome_service/src/workspace.rs (1)
  • markup (1117-1119)
crates/biome_analyze/src/rule.rs (4)
  • sources (553-556)
  • same (233-238)
  • recommended (538-541)
  • domains (568-571)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
  • run (52-65)
  • diagnostic (67-87)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
crates/biome_analyze/src/rule.rs (4)
  • sources (553-556)
  • same (233-238)
  • recommended (538-541)
  • domains (568-571)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
🪛 LanguageTool
.changeset/all-rivers-appear.md

[misspelling] ~8-~8: This word is normally spelled as one.
Context: ...serializability and prevent common Qwik anti-patterns. Invalid: ```js class Counter { ...

(EN_COMPOUNDS_ANTI_PATTERNS)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: End-to-end tests
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: autofix
  • GitHub Check: Check JS Files
🔇 Additional comments (11)
crates/biome_cli/tests/commands/format.rs (2)

3518-3521: JSX fixtures: good move

Switching the valid/invalid fixtures to .jsx aligns with the broader JSX-centric tests in this PR. No issues spotted.


3556-3556: Consistent extension switch

Using invalid.jsx here keeps consistency with the earlier test in this file and across the suite.

crates/biome_cli/tests/commands/check.rs (1)

3045-3046: JSX fixture names look good

The .jsx switch for valid/invalid paths is consistent with related test updates. Behaviour expectations remain the same.

crates/biome_cli/tests/commands/lint.rs (1)

3999-4000: LGTM on the JSX migration

The change to valid.jsx/invalid.jsx matches the pattern used elsewhere in the PR. No test logic changes required.

crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1)

4-22: Solid valid fixture for lexical scope.

Closures are correctly wrapped with $ inside component$, and the task runs without tripping the rule. Looks good to me.

crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs (1)

4-7: LGTM; matches rule-options conventions.

Derives and serde attributes are in place and consistent with the crate’s pattern. Nicely done.

crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (4)

35-43: Rule declaration looks solid (domain-gated, sourced, JSX-targeted).

Good use of version: "next", domains: &[RuleDomain::Qwik], and wiring to the ESLint analogue via sources. Severity and recommended defaults also look sensible for a framework rule.


52-65: Signal logic is clean and idiomatic.

Nice use of Option<bool> helpers and short-circuiting to produce a range only for invalid contexts. No nits here.


101-126: Confirm allowed wrappers (are we intentionally excluding non-use wrappers?).

Currently we only allow contexts wrapped by component$ or other use* calls. If Qwik allows use* inside other Qwik wrappers (e.g. routeLoader$/routeAction$/server$), we may need to widen this check.

Would you like me to extend this to accept a small allowlist of additional Qwik wrappers if confirmed?


67-87: Diagnostic reads well and uses rule_category! correctly.

Copy and links are clear; good use of markup and rule_category!(). No change requested.

crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (1)

32-40: Rule registration looks good (version, domain, JSX).

Domain-gated and sourced to the ESLint rule; severity and recommended make sense for framework correctness.

@ptkagori ptkagori force-pushed the feat/qwik-useMethodUsage branch from eef697d to 15a6ed2 Compare August 18, 2025 19:12
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

♻️ Duplicate comments (2)
.changeset/long-garlics-flow.md (2)

12-20: Invalid/valid examples are reversed; fix the “Invalid” snippet.

The current “Invalid” shows state defined inside the component, which is actually correct for Qwik. Swap to an example where state is defined outside the component’s lexical scope.

Apply this diff:

-```js
-const Component = component$(() => {
-  const state = useStore({ count: 0 }); // Defined in wrong scope
-
-  return <button onClick$={() => state.count++}>
-    Invalid: {state.count}
-  </button>;
-});
-```
+```js
+// Invalid: state defined outside the component's lexical scope.
+let state = useStore({ count: 0 });
+const Component = component$(() => {
+  return <button onClick$={() => state.count++}>
+    Invalid: {state.count}
+  </button>;
+});
+```

24-33: Fix the “Valid” snippet; current version reinitialises state in the handler and references an out-of-scope identifier.

Show state initialised within component scope and captured by the event.

Apply this diff:

-```js
-const Component = component$(() => {
-  return <button onClick$={() => {
-    const state = useStore({ count: 0 }); // Correct lexical scope
-    state.count++;
-  }}>
-    Valid: {state.count}
-  </button>;
-});
-```
+```js
+// Valid: state initialised within the component's lexical scope and captured by the event.
+const Component = component$(() => {
+  const state = useStore({ count: 0 });
+  return <button onClick$={() => state.count++}>
+    Valid: {state.count}
+  </button>;
+});
+```
🧹 Nitpick comments (1)
.changeset/all-rivers-appear.md (1)

4-4: Confirm changeset coverage for the second rule.

If useQwikValidLexicalScope ships in the same release, either add a separate changeset or mention both rules here. Otherwise, all good.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between eef697d and 15a6ed2.

⛔ Files ignored due to path filters (10)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (11)
  • .changeset/all-rivers-appear.md (1 hunks)
  • .changeset/long-garlics-flow.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • crates/biome_rule_options/src/use_qwik_valid_lexical_scope.rs
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md

📄 CodeRabbit Inference Engine (CONTRIBUTING.md)

.changeset/*.md: Create changesets with just new-changeset; store them in .changeset/ with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.

Files:

  • .changeset/long-garlics-flow.md
  • .changeset/all-rivers-appear.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule provides a code action, add `fix_kind` in `declare_lint_rule!` and use `ctx.action_category(ctx.category(), ctx.group())` and `ctx.metadata().applicability()` when constructing actions
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Choose an appropriate `severity` in `declare_lint_rule!` (default is info); use `Severity::Error` for hard errors, `Warning` for potential issues, `Information` for style
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule is deprecated, set the `deprecated:` field in `declare_lint_rule!` with a reason and alternative
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.822Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When banning globals (e.g., `console.log`), consult the semantic model to avoid false positives on locally shadowed identifiers
🪛 LanguageTool
.changeset/all-rivers-appear.md

[misspelling] ~8-~8: This word is normally spelled as one.
Context: ...serializability and prevent common Qwik anti-patterns. Invalid: ```js class Counter { ...

(EN_COMPOUNDS_ANTI_PATTERNS)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
  • GitHub Check: Bench (biome_package)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Documentation
  • GitHub Check: End-to-end tests
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (3)
.changeset/long-garlics-flow.md (1)

6-9: Good summary and tone for the changeset.

Clear, user-facing, past/present tense looks right, and you’ve linked the rule doc. Nicely done.

.changeset/all-rivers-appear.md (2)

1-3: Frontmatter looks good.

Package key and change type are set correctly for a patch release.


6-6: Double-check Biome docs URL for useQwikMethodUsage

I couldn’t find a published page at https://biomejs.dev/linter/rules/use-qwik-method-usage — it’s not listed among Biome’s Qwik rules, so this link will 404. Please ensure the docs page is live and the slug matches before merging.

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.

There's a rule that isn't working at all

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

🧹 Nitpick comments (3)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (3)

71-87: Polish the diagnostic copy

Tiny grammar tweak and a slightly clearer headline.

Apply:

-            markup! {
-                "Qwik hook detected outside of allowed scope"
-            },
+            markup! {
+                "Qwik hook detected outside of an allowed scope."
+            },

90-99: Avoid false positives by resolving the callee via the semantic model

Right now we match any useXxx identifier. In Qwik apps, user‑defined use* helpers are common and will be incorrectly flagged outside components/hooks. Resolve the identifier to an import from @builder.io/qwik (and consider re‑exports) to narrow matches.

Apply (sketch):

-fn is_qwik_hook(call: &JsCallExpression) -> Option<bool> {
+fn is_qwik_hook(call: &JsCallExpression, model: &biome_js_semantic::SemanticModel) -> Option<bool> {
     let binding = call
         .callee()
         .ok()?
         .as_js_reference_identifier()?
         .value_token()
         .ok()?;
-    let name = binding.text();
-    Some(name.starts_with("use") && name.chars().nth(3).is_some_and(|c| c.is_uppercase()))
+    let name = binding.text();
+    let is_use_like = name.starts_with("use") && name.chars().nth(3).is_some_and(|c| c.is_uppercase());
+    if !is_use_like {
+        return Some(false);
+    }
+    let ident = call.callee().ok()?.as_js_reference_identifier()?;
+    let sym = model.binding(&ident)?;
+    let imported = sym.as_import_binding()?;
+    let source = imported.import().ok()?.source().ok()?.inner_string_text().ok()?;
+    Some(source.text() == "@builder.io/qwik")
 }

And in run:

-        let is_hook = is_qwik_hook(call)?;
+        let is_hook = is_qwik_hook(call, ctx.model())?;

128-170: Tidy up name checks and avoid repeated .text()

Minor readability micro‑optimisation and a small doc nudge.

Apply:

-    function_name.map(|name| {
-        name.text() == "component$"
-            || (name.text().starts_with("use")
-                && name.text().chars().nth(3).is_some_and(|c| c.is_uppercase()))
-    })
+    function_name.map(|token_text| {
+        let n = token_text.text();
+        n == "component$" || (n.starts_with("use") && n.chars().nth(3).is_some_and(|c| c.is_uppercase()))
+    })

Also consider a brief doc comment on what “named function” means here (declaration name or variable declarator for arrow/functions).

📜 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 15a6ed2 and 0995277.

⛔ Files ignored due to path filters (4)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (6)
  • .changeset/all-rivers-appear.md (1 hunks)
  • .changeset/long-garlics-flow.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1 hunks)
  • crates/biome_rule_options/src/use_qwik_method_usage.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
  • .changeset/all-rivers-appear.md
  • .changeset/long-garlics-flow.md
  • crates/biome_rule_options/src/use_qwik_method_usage.rs
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Quick test: edit `tests/quick_test.rs`, remove or comment `#[ignore]`, set `SOURCE`, and adjust `RuleFilter`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Set the `language` field in `declare_lint_rule!` to the primary language (`js`, `jsx`, `ts`, or `tsx`) the rule targets
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/*.jsonc : Snapshot test `.jsonc` files must contain an array of code snippets (strings); these run in script mode (no ESM syntax)

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
crates/biome_analyze/src/rule.rs (1)
  • same (233-238)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
🔇 Additional comments (7)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (6)

36-37: Rule metadata looks solid

Good: version set to "next", mapped to ESLint Qwik source, recommended with Severity::Error, and scoped to the Qwik domain.

Also applies to: 39-43


52-65: Early‑return flow is clean

Short‑circuiting non‑hooks and returning the call range only for invalid contexts keeps the hot path lean.


101-111: Skip the current node when walking ancestors

This makes intent explicit and avoids surprises if traversal order changes.

Apply:

-    let outer_call = call
-        .syntax()
-        .ancestors()
-        .find_map(AnyJsFunction::cast)
-        .and_then(|function| {
-            function
-                .syntax()
-                .ancestors()
-                .find_map(JsCallExpression::cast)
-        });
+    let outer_call = call
+        .syntax()
+        .ancestors()
+        .find_map(AnyJsFunction::cast)
+        .and_then(|function| {
+            function
+                .syntax()
+                .ancestors()
+                .skip(1)
+                .find_map(JsCallExpression::cast)
+        });

113-125: Use trimmed token text for robustness

Aligns with prior guidance and avoids edge cases.

Apply:

-            .map(|token| {
-                let name = token.text();
+            .map(|token| {
+                let name = token.text_trimmed();
                 name == "component$"
                     || (name.starts_with("use")
                         && name.chars().nth(3).is_some_and(|c| c.is_uppercase()))
             })

17-34: Docs: good examples and expect_diagnostic

Examples are crisp and in the right format.


38-38: Keep language: "jsx" — follow repo convention

Other Qwik rules in crates/biome_js_analyze/src/lint/nursery use "jsx" (e.g. use_qwik_valid_lexical_scope.rs, use_qwik_classlist.rs, no_qwik_use_visible_task.rs). Change to "tsx" only if the rule must target .tsx/TypeScript-specific syntax.

crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1)

1-3: This “invalid” fixture won’t trigger the rule

No Qwik API usage or JSX/event closures are present, so useQwikValidLexicalScope won’t emit a diagnostic. Either move this to a “valid” case or make it an actual invalid example.

Apply one of these:

  • Option A: Convert to a real invalid lexical-scope case (missing $ wrapper for an event handler capturing local state):
-// should emit diagnostics
-// minimal example and concise-body arrow function without braces
-
-const f = () => "bar";
+import { component$, useSignal } from '@builder.io/qwik';
+
+// should emit diagnostics
+export const C = component$(() => {
+  const count = useSignal(0);
+  // Not wrapped in $, should be flagged by valid-lexical-scope
+  const onClick = () => count.value++;
+  return <button onClick$={onClick}>+</button>;
+});
  • Option B: If the intent was to test hook-usage (arrow without braces), move it under useQwikMethodUsage/invalid.jsx and add the Qwik import + call that should be flagged.

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

🧹 Nitpick comments (3)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (3)

66-86: Nit: end the primary diagnostic message with a full stop.

Consistent punctuation improves output polish.

-                "Qwik hook detected outside of an allowed scope"
+                "Qwik hook detected outside of an allowed scope."

52-64: Simplify option flow: make is_qwik_hook return bool.

Avoids Option<bool> + ? noise; default to false when the callee isn’t a bare identifier.

-        let is_hook = is_qwik_hook(call)?;
-        if !is_hook {
+        if !is_qwik_hook(call) {
             return None;
         }
-fn is_qwik_hook(call: &JsCallExpression) -> Option<bool> {
+fn is_qwik_hook(call: &JsCallExpression) -> bool {
     let binding = call
         .callee()
-        .ok()?
-        .as_js_reference_identifier()?
+        .ok()
+        .and_then(|c| c.as_js_reference_identifier())
         .and_then(|ident| ident.value_token().ok());
-    let name = binding.text();
-    Some(is_qwik_hook_name(name))
+    binding
+        .map(|tok| is_qwik_hook_name(tok.text()))
+        .unwrap_or(false)
 }

Also applies to: 89-98


100-123: Broaden ancestor scan: handle nested wrappers above component$.

Currently we only inspect the first call above the enclosing function. If users wrap component$ (e.g. withSomething(component$(() => {}))), this may false‑negative. Scan all ancestor call expressions above the function and accept if any matches.

-fn is_inside_component_or_hook(call: &JsCallExpression) -> bool {
-    let outer_call = call
-        .syntax()
-        .ancestors()
-        .skip(1)
-        .find_map(AnyJsFunction::cast)
-        .and_then(|function| {
-            function
-                .syntax()
-                .ancestors()
-                .skip(1)
-                .find_map(JsCallExpression::cast)
-        });
-
-    outer_call
-        .and_then(|call_expr| {
-            call_expr
-                .callee()
-                .ok()
-                .and_then(|callee| callee.as_js_reference_identifier())
-                .and_then(|ident| ident.value_token().ok())
-        })
-        .is_some_and(|token| is_component_or_hook_name(token.text()))
-}
+fn is_inside_component_or_hook(call: &JsCallExpression) -> bool {
+    let Some(enclosing_fn) = call
+        .syntax()
+        .ancestors()
+        .skip(1)
+        .find_map(AnyJsFunction::cast)
+    else {
+        return false;
+    };
+
+    enclosing_fn
+        .syntax()
+        .ancestors()
+        .skip(1)
+        .filter_map(JsCallExpression::cast)
+        .any(|call_expr| {
+            call_expr
+                .callee()
+                .ok()
+                .and_then(|callee| callee.as_js_reference_identifier())
+                .and_then(|ident| ident.value_token().ok())
+                .map_or(false, |token| is_component_or_hook_name(token.text()))
+        })
+}
📜 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 8d911a3 and 30aa716.

📒 Files selected for processing (2)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Set the `language` field in `declare_lint_rule!` to the primary language (`js`, `jsx`, `ts`, or `tsx`) the rule targets
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Quick test: edit `tests/quick_test.rs`, remove or comment `#[ignore]`, set `SOURCE`, and adjust `RuleFilter`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (3)
crates/biome_analyze/src/rule.rs (4)
  • sources (569-572)
  • same (241-246)
  • recommended (554-557)
  • domains (584-587)
crates/biome_js_analyze/src/lint/nursery/use_qwik_valid_lexical_scope.rs (2)
  • run (51-68)
  • diagnostic (70-92)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
🔇 Additional comments (4)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (4)

35-43: Rule metadata looks solid (version, language, domains, severity).

Good use of version: "next", language: "jsx", Qwik domain gating, and marking it recommended.

If Qwik users primarily write TSX, confirm that setting language: "jsx" is the right choice for rule discovery/UX. If Biome treats language as “primary” only, we’re fine; otherwise consider "tsx".


8-34: Docs/readme snippet quality is good.

Examples use proper markers (js, expect_diagnostic). Nice touch linking Qwik docs.


125-136: Hook name check is fine; keep ASCII expectations in mind.

The use[A-Z] heuristic matches Qwik hooks. If you later accept non‑ASCII uppercase, you’re covered via is_uppercase().


138-185: Variant present — no change required.
JsFunctionExportDefaultDeclaration exists and is used in the repo (e.g. crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs:177; crates/biome_js_syntax/src/union_ext.rs).

@ptkagori ptkagori requested review from dyc3 and unvalley September 22, 2025 22:15
@ptkagori ptkagori requested a review from ematipico September 23, 2025 15:38
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. I would add more failing tests

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

🧹 Nitpick comments (7)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (7)

1-1: Name the rule explicitly in the header comment

Make the intent crystal clear for future readers and snapshots.

-// should emit diagnostics
+// should emit diagnostics for useQwikValidLexicalScope

4-6: This snippet won’t trigger the rule

A bare concise arrow doesn’t involve $. Either move it to the valid fixture or wrap it to exercise the concise-body shape inside $.

-const f = () => "bar";
+const conciseHandler = $(() => "bar");

54-62: Comment/code mismatch

The comment reads as if we’re testing a non-$ event handler; the code tests $ usage inside that handler. Clarify the comment to match the scenario.

-// 8. $ usage in event handler not using $
+// 8. $ usage inside a non-$ event handler (invalid lexical scope)

65-75: Add a direct in-block case (optional)

Currently you nest a function inside the if. Consider also a direct $ in the conditional to broaden coverage.

   if (true) {
-    const regularFunction = () => {
-      const handler = $(() => {
-        console.log("invalid conditional");
-      });
-    };
+    const regularFunction = () => {
+      const handler = $(() => {
+        console.log("invalid conditional");
+      });
+    };
+    const directConditional = $(() => {
+      console.log("invalid conditional - direct");
+    });
   }

77-87: Add a direct in-loop case (optional)

Mirror the above in loops to catch block-level $ usage too.

   for (let i = 0; i < 5; i++) {
-    const regularFunction = () => {
-      const handler = $(() => {
-        console.log("invalid loop");
-      });
-    };
+    const regularFunction = () => {
+      const handler = $(() => {
+        console.log("invalid loop");
+      });
+    };
+    const directLoop = $(() => {
+      console.log("invalid loop - direct");
+    });
   }

89-101: Add a direct in-try case (optional)

Same idea for try blocks.

   try {
-    const regularFunction = () => {
-      const handler = $(() => {
-        console.log("invalid try-catch");
-      });
-    };
+    const regularFunction = () => {
+      const handler = $(() => {
+        console.log("invalid try-catch");
+      });
+    };
+    const directTry = $(() => {
+      console.log("invalid try-catch - direct");
+    });
   } catch (e) {

1-166: Add a “shadowed $” case in the valid suite

To avoid false positives when $ is locally shadowed (semantic model check), add this to valid.jsx. Based on learnings.

// crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx
import { component$ } from "@builder.io/qwik";

// 99. locally shadowed $ should not be treated as Qwik $
export const ShadowedDollar = component$(() => {
  const $ = (fn) => fn; // local shadow
  const handler = $(() => console.log("shadowed, not Qwik"));
  return <div />;
});
📜 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 a0e002b and 1fad973.

⛔ Files ignored due to path filters (4)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (3)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Set the `language` field in `declare_lint_rule!` to the primary language (`js`, `jsx`, `ts`, or `tsx`) the rule targets
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx
🧬 Code graph analysis (2)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (2)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (9)
  • myObject (28-34)
  • handleClick (57-59)
  • ConditionalComponent (83-88)
  • ConditionalComponent (83-88)
  • LoopComponent (91-96)
  • LoopComponent (91-96)
  • i (92-92)
  • TryCatchComponent (99-106)
  • TryCatchComponent (99-106)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1)
  • handleClick (9-11)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (2)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (4)
  • Counter (2-4)
  • Counter (2-4)
  • count (3-3)
  • count (7-7)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (9)
  • myObject (36-42)
  • handleClick (56-60)
  • ConditionalComponent (65-74)
  • ConditionalComponent (65-74)
  • LoopComponent (77-86)
  • LoopComponent (77-86)
  • i (78-78)
  • TryCatchComponent (89-100)
  • TryCatchComponent (89-100)
🔇 Additional comments (3)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1)

3-149: Thorough invalid coverage 👍

Appreciate the wide sweep of bad patterns; this should keep the rule honest.

crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (2)

2-2: Good catch importing $

Import now includes $, so the rule can actually fire. Thanks for addressing the earlier feedback.


132-136: Multiple $ in one scope: single diagnostic confirmed
Snapshot shows one × Non-serializable expression for the three $ calls, matching the intended dedupe behaviour.

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

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1)

19-40: Docs: examples and link are helpful

Invalid/valid snippets and the link to Qwik docs look solid. Minor nit: consider adding a note that named use* functions (custom hooks) are considered valid contexts.

📜 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 1fad973 and 6485115.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Set the `language` field in `declare_lint_rule!` to the primary language (`js`, `jsx`, `ts`, or `tsx`) the rule targets
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Quick test: edit `tests/quick_test.rs`, remove or comment `#[ignore]`, set `SOURCE`, and adjust `RuleFilter`
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
PR: biomejs/biome#7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
crates/biome_analyze/src/rule.rs (4)
  • sources (569-572)
  • same (241-246)
  • recommended (554-557)
  • domains (584-587)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
🔇 Additional comments (5)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (5)

41-49: Rule metadata looks good

Version, name, language, sources, recommended, severity, and domains are consistent with our conventions for nursery rules targeting Qwik.

Based on learnings


58-71: Signal flow is clean and conservative

Early return on non-hooks and “unknown” cases via ? keeps false positives low. Nice.


107-130: Ancestor search pattern is sound

Using ancestors().skip(1) to find the enclosing function and then its wrapping call mirrors our established pattern for JSX/Qwik wrappers like component$(() => ...).

Based on learnings


96-105: Good: avoids false positives by consulting the semantic model

Checking the binding and origin module before treating a call as a Qwik hook is the right call. This guards against local use* functions.

Based on learnings


132-139: Hook name predicate is fine, but consider edge cases

The uppercase-4th-char heuristic matches Qwik conventions (useSignal, useTask$, etc.). If you later need to support $-suffixed names starting with use but with non-letter 4th chars, we can relax this, but no action needed now.

@ptkagori ptkagori force-pushed the feat/qwik-useMethodUsage branch from 6485115 to 3a2fa0e Compare September 26, 2025 15:32
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

📜 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 3a2fa0e and b679b43.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (2)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Set the `language` field in `declare_lint_rule!` to the primary language (`js`, `jsx`, `ts`, or `tsx`) the rule targets
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Quick test: edit `tests/quick_test.rs`, remove or comment `#[ignore]`, set `SOURCE`, and adjust `RuleFilter`
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
PR: biomejs/biome#7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧬 Code graph analysis (2)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
crates/biome_analyze/src/rule.rs (4)
  • sources (569-572)
  • same (241-246)
  • recommended (554-557)
  • domains (584-587)
crates/biome_js_syntax/src/expr_ext.rs (1)
  • callee (32-37)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (3)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (4)
  • Counter (2-4)
  • Counter (2-4)
  • count (3-3)
  • count (7-7)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (9)
  • myObject (36-42)
  • handleClick (56-60)
  • ConditionalComponent (65-74)
  • ConditionalComponent (65-74)
  • LoopComponent (77-86)
  • LoopComponent (77-86)
  • i (78-78)
  • TryCatchComponent (89-100)
  • TryCatchComponent (89-100)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1)
  • handleClick (9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
  • GitHub Check: autofix
🔇 Additional comments (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1)

182-189: Normalise the import source before matching

source.text() still includes the surrounding quotes, so nothing imported via "@builder.io/qwik" or "qwik" ever matches QWIK_IMPORT_NAMES, and the rule slips every real hook. Strip the quotes (or use the literal’s inner text) before comparing.

-        .is_some_and(|source| QWIK_IMPORT_NAMES.contains(&source.text()))
+        .is_some_and(|source| {
+            let raw = source.text();
+            let normalised = raw.trim_matches(['"', '\'']);
+            QWIK_IMPORT_NAMES.iter().any(|candidate| *candidate == normalised)
+        })

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

📜 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 b679b43 and 5a88770.

⛔ Files ignored due to path filters (2)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Quick test: edit `tests/quick_test.rs`, remove or comment `#[ignore]`, set `SOURCE`, and adjust `RuleFilter`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/{lint,assist}/**/*.rs : When banning globals (e.g., `noConsoleLog`), check the semantic model to avoid false positives from locally shadowed bindings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)
🧬 Code graph analysis (1)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/invalid.jsx (3)
crates/biome_js_analyze/tests/specs/nursery/useQwikMethodUsage/valid.jsx (5)
  • Counter (5-8)
  • Counter (5-8)
  • count (6-6)
  • count (11-11)
  • count (17-17)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/invalid.jsx (9)
  • myObject (36-42)
  • handleClick (56-60)
  • ConditionalComponent (65-74)
  • ConditionalComponent (65-74)
  • LoopComponent (77-86)
  • LoopComponent (77-86)
  • i (78-78)
  • TryCatchComponent (89-100)
  • TryCatchComponent (89-100)
crates/biome_js_analyze/tests/specs/nursery/useQwikValidLexicalScope/valid.jsx (1)
  • handleClick (9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check JS Files
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_css_parser)

@ptkagori ptkagori requested a review from ematipico September 29, 2025 13:34
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. Just a minor nit to address

@ptkagori ptkagori force-pushed the feat/qwik-useMethodUsage branch from 468ff45 to d2371e9 Compare October 3, 2025 13:27
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

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1)

143-146: Remove unnecessary string allocation.

text_trimmed() already returns a type that derefs to &str, so .contains() works directly without .to_string().

Based on learnings

Apply this diff:

-                if text.to_string().contains("component$") {
+                if text.contains("component$") {
🧹 Nitpick comments (2)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)

159-165: Consider adding rustdoc comments.

Brief inline docs on is_qwik_hook_name and is_component_or_hook_name would clarify the Qwik-specific pattern (hook names must start with "use" followed by an uppercase char, and valid contexts include component$ or other hooks).

As per coding guidelines


167-206: Consider adding rustdoc comments.

A brief comment explaining that this helper checks whether the call is within a function whose name follows the Qwik hook pattern (e.g., useCounter) would help future maintainers.

As per coding guidelines

📜 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 f71227d and d2371e9.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Before committing, format Rust and TOML files (e.g., via just f/just format)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and options via inline rustdoc in Rust source

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : Place all new JavaScript lint rules in the nursery group under biome_js_analyze/lib/src/lint/nursery/<rule_name>.rs
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/**/src/**/lint/**/*.rs : In declare_lint_rule! blocks, set version: "next" for all rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/**/src/**/lint/**/*.rs : If a rule returns a code action, add fix_kind in declare_lint_rule! and ensure action uses ctx.action_category(ctx.category(), ctx.group()) and ctx.metadata().applicability()
📚 Learning: 2025-10-02T12:57:33.209Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : Place all new JavaScript lint rules in the nursery group under biome_js_analyze/lib/src/lint/nursery/<rule_name>.rs

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-10-02T12:57:33.209Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/**/src/**/lint/**/*.rs : When deprecating a rule, add deprecated: "<reason>" in declare_lint_rule! with an explanatory message

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-10-02T12:57:33.209Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.209Z
Learning: Applies to crates/biome_analyze/crates/**/src/**/lint/**/*.rs : Avoid unnecessary string allocations; compare against &str or TokenText instead of calling to_string()

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
📚 Learning: 2025-09-12T08:06:16.650Z
Learnt from: ematipico
PR: biomejs/biome#7410
File: crates/biome_js_analyze/src/lint/nursery/no_jsx_props_bind.rs:103-149
Timestamp: 2025-09-12T08:06:16.650Z
Learning: In Biome AST traversal, `ancestors().skip(1)` is a reasonable pattern to skip the current node and prevent false positives when searching for ancestor nodes of the same kind.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_qwik_method_usage.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (4)
  • RuleDomain (904-912)
  • Severity (9224-9224)
  • UseQwikMethodUsageOptions (8243-8243)
  • TextRange (9243-9243)
crates/biome_js_syntax/src/import_ext.rs (1)
  • source_text (30-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: autofix
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Check JS Files

@ematipico
Copy link
Member

@dyc3 can you review?

@ematipico ematipico merged commit a8e7301 into biomejs:main Oct 3, 2025
19 checks passed
@github-actions github-actions bot mentioned this pull request Oct 3, 2025
ematipico added a commit that referenced this pull request Oct 3, 2025
Co-authored-by: ematipico <602478+ematipico@users.noreply.github.com>
Co-authored-by: dyc3 <1808807+dyc3@users.noreply.github.com>
Co-authored-by: unvalley <38400669+unvalley@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载