+
Skip to content

Conversation

vladimir-ivanov
Copy link
Contributor

@vladimir-ivanov vladimir-ivanov commented Sep 7, 2025

Summary

moves class_member_references fn into a dedicated semantic class service

closes #7460

Copy link

changeset-bot bot commented Sep 7, 2025

⚠️ No Changeset found

Latest commit: 1ebfaaa

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

This PR includes no changesets

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

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

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

Copy link
Contributor

coderabbitai bot commented Sep 7, 2025

Walkthrough

Removes the standalone class_member_references module declaration from crates/biome_js_analyze/src/lib.rs. Adds pub mod semantic_class; to crates/biome_js_analyze/src/services/mod.rs and introduces crates/biome_js_analyze/src/services/semantic_class.rs, implementing SemanticClass services, model, visitors, and a SemanticClass<N> query wrapper. Updates the use_readonly_class_properties rule to use SemanticClass<JsClassDeclaration> and ctx.model.class_member_references(&members), refactors helpers to operate on JsClassMemberList, and tightens visibility of several helpers (making previous public functions private or module-local).

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Most changes are in scope for transforming class_member_references into a service, but the PR also tightens unrelated API visibility (notably making ThisScopeReferences::new and collect_function_this_references private) which is not described in the linked issue and could break external consumers. Either revert or justify the visibility reductions and split them into a separate PR, or document and update all impacted call sites and add tests showing the API contraction is safe before merging.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately describes the primary change — adding a class member references service to biome-js-analyze — and aligns with the code that moves class_member_references into a SemanticClass service.
Linked Issues Check ✅ Passed The changes add a SemanticClass service (SemanticClassServices and SemanticClassModel) exposing a class_member_references(&self, &JsClassMemberList) accessor and update callers to use ctx.model.class_member_references(&members), which implements the coding objectives in the linked issue [#7460].
Description Check ✅ Passed The PR description concisely states the core change (moving class_member_references into a dedicated semantic class service) and references the linked issue, which is directly related to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d87dad and 1ebfaaa.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/services/semantic_class.rs (21 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/services/semantic_class.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
🧠 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_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
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)
crates/biome_rowan/src/ast/mod.rs (1)
  • unwrap_cast (199-211)
⏰ 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). (24)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

@vladimir-ivanov vladimir-ivanov marked this pull request as draft September 7, 2025 18:23
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Sep 7, 2025
@vladimir-ivanov
Copy link
Contributor Author

need help on this one please, run method is not getting executed.

@dyc3
Copy link
Contributor

dyc3 commented Sep 7, 2025

Could you elaborate a little more on the problems you're having? At a glance it looks correct. What have you tried? What are you expecting?

I noticed that you implement your own SemanticClassVisitor where other services seem to use SyntaxVisitor::default, maybe that could be part of the problem?
struggled for a bit to understand the design of service bags. Now I get it. Wanted to have just one service and skip the service bags, but that could not work.
just the registry.rs (see my comment on it) was swallowing the error and confused me for a bit.

@vladimir-ivanov vladimir-ivanov force-pushed the feat/classMemberReferencesService branch from f2169f2 to 968bc3f Compare September 8, 2025 20:55
@vladimir-ivanov vladimir-ivanov changed the title Feat/class member references service feat(biome-js-analyze): class member references service Sep 8, 2025
Copy link

codspeed-hq bot commented Sep 8, 2025

CodSpeed Performance Report

Merging #7428 will degrade performances by 7.12%

Comparing vladimir-ivanov:feat/classMemberReferencesService (1ebfaaa) with main (002cded)1

Summary

❌ 1 regression
✅ 132 untouched

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
js_analyzer[parser_13571644119461115204.ts] 90.5 ms 97.5 ms -7.12%

Footnotes

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

@vladimir-ivanov vladimir-ivanov force-pushed the feat/classMemberReferencesService branch from 65b73ab to 7260163 Compare September 8, 2025 21:08
@vladimir-ivanov
Copy link
Contributor Author

unsure if I need to raise a ticket and do a changeset. Assuming the changesets are for end users only, we don't need one? please confirm.

@vladimir-ivanov vladimir-ivanov marked this pull request as ready for review September 10, 2025 06:22
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: 3

Caution

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

⚠️ Outside diff range comments (2)
crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs (2)

138-179: Fix borrow pattern and remove O(n²) clones in run

  • Destructuring a reference with let ClassMemberReferences { writes, .. } = &... doesn’t work as written; take a reference to the set instead.
  • Current pipeline clones constructor_params and writes repeatedly; precompute name sets and filter once.

Apply this diff:

@@
-        let ClassMemberReferences { writes, .. } = ctx.class_member_references();
+        let writes = &ctx.class_member_references().writes;
@@
-        let constructor_params: Vec<_> =
-            collect_non_readonly_constructor_parameters(&members, private_only);
+        let constructor_params: Vec<_> =
+            collect_non_readonly_constructor_parameters(&members, private_only);
+
+        // Precompute names for faster membership checks
+        let write_names: std::collections::HashSet<_> =
+            writes.iter().map(|r| r.name.clone()).collect();
+        let ctor_names: std::collections::HashSet<_> = constructor_params
+            .iter()
+            .filter_map(|n| extract_property_or_param_range_and_text(n).map(|t| t.text))
+            .collect();
@@
-        constructor_params
-            .clone()
-            .into_iter()
-            .chain(
-                non_readonly_class_property_members.filter(|class_property_member| {
-                    !constructor_params.clone().into_iter().any(|node| {
-                        node.to_trimmed_text() == class_property_member.to_trimmed_text()
-                    })
-                }),
-            )
-            .filter_map(|prop_or_param| {
-                if writes
-                    .clone()
-                    .into_iter()
-                    .any(|ClassMemberReference { name, .. }| {
-                        if let Some(TextAndRange { text, .. }) =
-                            extract_property_or_param_range_and_text(&prop_or_param.clone())
-                        {
-                            return name.eq(&text);
-                        }
-
-                        false
-                    })
-                {
-                    None
-                } else {
-                    Some(prop_or_param.clone())
-                }
-            })
+        constructor_params
+            .into_iter()
+            .filter_map(|node| {
+                extract_property_or_param_range_and_text(&node)
+                    .map(|t| (!write_names.contains(&t.text)).then_some(node))
+                    .flatten()
+            })
+            .chain(
+                non_readonly_class_property_members.filter_map(|member| {
+                    extract_property_or_param_range_and_text(&member).map(|t| {
+                        (!ctor_names.contains(&t.text) && !write_names.contains(&t.text))
+                            .then_some(member)
+                    }).flatten()
+                }),
+            )
             .collect::<Vec<_>>()
             .into_boxed_slice()

268-268: User-facing text: “modifier”, not “decorator”

The fix adds a readonly modifier. Let’s avoid confusing users.

-            markup! { "Add "<Emphasis>"readonly"</Emphasis>" decorator." }.to_owned(),
+            markup! { "Add "<Emphasis>"readonly"</Emphasis>" modifier." }.to_owned(),
🧹 Nitpick comments (5)
crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs (2)

20-20: Minor import tidy-up for new HashSet usage

If you take the refactor above, pull HashSet into scope.

-use std::iter::once;
+use std::{collections::HashSet, iter::once};

328-330: Doc nit: duplicated word and clearer phrasing

Small clean-up; makes the comment easier to scan.

-/// Collects all all mutable (non-readonly) constructor parameters from a given class member list. If private_only is true, it only includes parameters with private visibility.
-/// It returns a Vec<PropOrParam> representing these parameters, which are candidates for being marked as readonly.
+/// Collects all mutable (non-`readonly`) constructor parameters from a given class member list.
+/// If `private_only` is true, only parameters with private visibility are included.
+/// Returns a `Vec<AnyPropertyMember>` of parameters that are candidates for `readonly`.
crates/biome_js_analyze/src/services/semantic_class.rs (3)

653-657: Use the member token range for precision

Diagnostic ranges are sharper if we point at the property name, not the whole this.member expression.

-        reads.insert(ClassMemberReference {
-            name: member.to_trimmed_text(),
-            range: static_member.syntax().text_trimmed_range(),
-        });
+        let name_text = member.to_trimmed_text();
+        reads.insert(ClassMemberReference {
+            range: member.syntax().text_trimmed_range(),
+            name: name_text,
+        });

686-698: Consider covering more compound assignment operators

You handle many, but miss some common ones (e.g. -= and shifts/xor). Low effort to extend while we’re here.

             && matches!(
                 operator.kind(),
                 JsSyntaxKind::PIPE2EQ
                     | JsSyntaxKind::AMP2EQ
+                    | JsSyntaxKind::CARET_EQ
                     | JsSyntaxKind::SLASHEQ
                     | JsSyntaxKind::STAREQ
                     | JsSyntaxKind::PERCENTEQ
                     | JsSyntaxKind::PLUSEQ
+                    | JsSyntaxKind::MINUSEQ
+                    | JsSyntaxKind::LT2EQ
+                    | JsSyntaxKind::GT2EQ
+                    | JsSyntaxKind::GT3EQ
                     | JsSyntaxKind::QUESTION2EQ
             )

1-13: Small import hygiene

You can drop a couple of unused imports after the refactors (if any remain post-diff). Let rustfmt/clippy guide this.

📜 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 aa06833 and d42ff3b.

📒 Files selected for processing (4)
  • crates/biome_js_analyze/src/lib.rs (0 hunks)
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs (4 hunks)
  • crates/biome_js_analyze/src/services/mod.rs (1 hunks)
  • crates/biome_js_analyze/src/services/semantic_class.rs (6 hunks)
💤 Files with no reviewable changes (1)
  • crates/biome_js_analyze/src/lib.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/services/mod.rs
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
  • crates/biome_js_analyze/src/services/semantic_class.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/services/mod.rs
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
  • crates/biome_js_analyze/src/services/semantic_class.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/services/mod.rs
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
  • crates/biome_js_analyze/src/services/semantic_class.rs
🧠 Learnings (8)
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : If a rule provides a code action, declare fix_kind in declare_lint_rule!

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : When porting a lint rule, set sources in declare_lint_rule! (RuleSource::Eslint(...).same() or .inspired())

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : Set the language field in declare_lint_rule! to the most specific applicable language (js/jsx/ts/tsx)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : When returning a code action, pass category via ctx.action_category(ctx.category(), ctx.group()) and applicability via ctx.metadata().applicability()

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/**/*.rs : Place all new rules in the nursery group under biome_js_analyze/lib/src/lint/nursery

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : Use rule_category!() when creating RuleDiagnostic instead of dynamic string categories

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : In declare_lint_rule! metadata, set version: "next"

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : When deprecating a rule, add deprecated: "<reason>" to declare_lint_rule!

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)
crates/biome_rowan/src/ast/mod.rs (2)
  • cast_ref (142-151)
  • unwrap_cast (199-211)
⏰ 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). (18)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_css_formatter)
🔇 Additional comments (5)
crates/biome_js_analyze/src/services/mod.rs (1)

6-6: Publicly exposing semantic_class looks right

Module placement is consistent with the existing structure. No further action.

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

116-124: Double-check rule metadata (version and language scope)

  • Our guidance usually sets version: "next" when introducing/porting a rule.
  • Consider whether this should also run for tsx (classes appear there too). If yes, adjust language accordingly.

Would you confirm the repo’s current convention for new/changed rules and whether we should broaden from "ts" to also cover "tsx"?

crates/biome_js_analyze/src/services/semantic_class.rs (3)

35-48: Service initialisation through FromServices is solid

Nice: clear error if the service is missing, and cloning the references keeps things immutable for consumers.


50-54: Phase declaration is correct

Binding SemanticClassServices to Phases::Semantic aligns with how the service is consumed.


833-1157: Tests are thorough and readable

Good spread across patterns; these will catch regressions in the collectors.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)

190-196: Don’t record arbitrary static members in property initialisers; require this

We currently count any a.b in a class field initialiser as a read. Gate it on this.

-                    } else if let Some(static_member_expression) =
-                        expression.as_js_static_member_expression()
-                    {
-                        return collect_class_property_reads_from_static_member(
-                            static_member_expression,
-                        );
-                    }
+                    } else if let Some(static_member_expression) =
+                        expression.as_js_static_member_expression()
+                    {
+                        if let Ok(obj) = static_member_expression.object()
+                            && obj.as_js_this_expression().is_some()
+                        {
+                            return collect_class_property_reads_from_static_member(
+                                static_member_expression,
+                            );
+                        }
+                    }

And double-guard inside the helper:

 fn collect_class_property_reads_from_static_member(
     static_member: &JsStaticMemberExpression,
 ) -> Option<ClassMemberReferences> {
     let mut reads = HashSet::new();
     let writes = HashSet::new();
 
+    // Only consider `this.prop` / `this.#prop`
+    if let Ok(object) = static_member.object() {
+        if object.as_js_this_expression().is_none() {
+            return None;
+        }
+    }
+
     if let Ok(member) = static_member.member() {
         let name = member.to_trimmed_text();
         reads.insert(ClassMemberReference {
             name,
             range: static_member.syntax().text_trimmed_range(),
         });
     }
 
     Some(ClassMemberReferences { reads, writes })
 }

Also applies to: 794-809

♻️ Duplicate comments (4)
crates/biome_js_analyze/src/services/semantic_class.rs (4)

299-299: Nix the commented debug println

It’s noise in the visitor.

-                // println!("leave node in ThisScopeVisitor {:?}", node);

71-79: Emit the Syntax-phase match so rules’ run() actually executes

You’re collecting refs but never emitting a Syntax-phase match. Call ctx.match_query when entering a class. This fixes the “run not executed” issue.

-    fn visit(&mut self, event: &WalkEvent<JsSyntaxNode>, _ctx: VisitorContext<JsLanguage>) {
+    fn visit(&mut self, event: &WalkEvent<JsSyntaxNode>, ctx: VisitorContext<JsLanguage>) {
         if let WalkEvent::Enter(node) = event
             && let Some(js_class_declaration) = JsClassDeclaration::cast_ref(node)
         {
+            // Emit the Syntax-phase query match for this class
+            ctx.match_query(node.clone());
             let class_member_list = js_class_declaration.members();
             let refs = class_member_references(&class_member_list);
             self.references.reads.extend(refs.reads);
             self.references.writes.extend(refs.writes);
         }
     }
#!/bin/bash
# Expect: match_query is called inside ClassMemberReferencesVisitor; no SemanticClassVisitor present.
rg -nP -C2 'impl\s+Visitor\s+for\s+ClassMemberReferencesVisitor|match_query\(' crates/biome_js_analyze/src/services/semantic_class.rs
rg -nP -C1 'SemanticClassVisitor' crates/biome_js_analyze/src/services/semantic_class.rs || true

99-114: Delete the redundant Semantic-phase visitor and its registration

With Syntax-phase matching in place, this visitor just confuses things and risks double work.

-struct SemanticClassVisitor;
-
-impl Visitor for SemanticClassVisitor {
-    type Language = JsLanguage;
-
-    fn visit(&mut self, event: &WalkEvent<JsSyntaxNode>, mut ctx: VisitorContext<JsLanguage>) {
-        match event {
-            WalkEvent::Enter(node) => {
-                if JsClassDeclaration::can_cast(node.kind()) {
-                    ctx.match_query(node.clone());
-                }
-            }
-            WalkEvent::Leave(_) => {}
-        };
-    }
-}
@@
     fn build_visitor(analyzer: &mut impl AddVisitor<JsLanguage>, root: &AnyJsRoot) {
         analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor::new(root));
-        analyzer.add_visitor(Phases::Semantic, || SemanticClassVisitor);
     }

Also applies to: 126-129


19-28: Track references per class (don’t mix all classes together)

The service currently aggregates reads/writes for the whole root. That breaks when multiple classes exist. Store refs keyed by class range (or node key) and expose a query by range, aligning with earlier feedback.

-#[derive(Clone)]
-pub struct SemanticClassServices {
-    class_member_references: ClassMemberReferences,
-}
+#[derive(Clone)]
+pub struct SemanticClassServices {
+    class_member_references: std::collections::BTreeMap<TextRange, ClassMemberReferences>,
+}
@@
-impl SemanticClassServices {
-    pub fn class_member_references(&self) -> &ClassMemberReferences {
-        &self.class_member_references
-    }
-}
+impl SemanticClassServices {
+    pub fn class_member_references(&self, range: TextRange) -> Option<&ClassMemberReferences> {
+        self.class_member_references.get(&range)
+    }
+}
@@
-#[derive(Debug, Clone)]
-pub struct SemanticClassModel {
-    pub references: ClassMemberReferences,
-}
+#[derive(Debug, Clone)]
+pub struct SemanticClassModel {
+    pub references_by_class: std::collections::BTreeMap<TextRange, ClassMemberReferences>,
+}
@@
         let service: &SemanticClassModel = services.get_service().ok_or_else(|| {
             ServicesDiagnostic::new(rule_key.rule_name(), &["SemanticClassModel"])
         })?;
         Ok(Self {
-            class_member_references: service.references.clone(),
+            class_member_references: service.references_by_class.clone(),
         })
     }
 }
@@
-pub struct ClassMemberReferencesVisitor {
-    references: ClassMemberReferences,
-}
+pub struct ClassMemberReferencesVisitor {
+    by_class: std::collections::BTreeMap<TextRange, ClassMemberReferences>,
+}
@@
 impl ClassMemberReferencesVisitor {
     pub(crate) fn new(_root: &AnyJsRoot) -> Self {
         Self {
-            references: ClassMemberReferences::default(),
+            by_class: Default::default(),
         }
     }
 }
@@
-        {
-            let class_member_list = js_class_declaration.members();
-            let refs = class_member_references(&class_member_list);
-            self.references.reads.extend(refs.reads);
-            self.references.writes.extend(refs.writes);
+        {
+            let class_member_list = js_class_declaration.members();
+            let refs = class_member_references(&class_member_list);
+            let class_range = js_class_declaration.syntax().text_trimmed_range();
+            let entry = self.by_class.entry(class_range).or_default();
+            entry.reads.extend(refs.reads);
+            entry.writes.extend(refs.writes);
         }
@@
-        ctx.services.insert_service(SemanticClassModel {
-            references: self.references,
-        });
+        ctx.services.insert_service(SemanticClassModel {
+            references_by_class: self.by_class,
+        });

If you prefer NodeKey over TextRange for stability, happy to sketch that too.

Also applies to: 30-48, 56-66, 82-86

🧹 Nitpick comments (5)
crates/biome_js_analyze/src/services/semantic_class.rs (5)

647-656: Prefer the member’s range over the whole expression

This makes diagnostics crisper (highlights foo, not this.foo).

-        reads.insert(ClassMemberReference {
-            name: member.to_trimmed_text(),
-            range: static_member.syntax().text_trimmed_range(),
-        });
+        reads.insert(ClassMemberReference {
+            name: member.to_trimmed_text(),
+            range: member.syntax().text_trimmed_range(),
+        });

682-701: Cover all compound assignments (or centralise the check)

The operator list misses some tokens (e.g. -= and shifts). Either expand it fully or add a helper like “is_compound_assignment”.

Would you like me to propose a complete token set based on JsSyntaxKind?


2-7: Remove unused union and import

AnyPropertyMember isn’t used. Trim it and the TsPropertyParameter import.

-    JsVariableDeclarator, TextRange, TsPropertyParameter,
+    JsVariableDeclarator, TextRange,
@@
-declare_node_union! {
-    pub AnyPropertyMember = JsPropertyClassMember | TsPropertyParameter
-}
+// (removed unused AnyPropertyMember)

Also applies to: 152-155


56-66: Minor: Visitor can be Default

Root isn’t used; consider impl Default + analyzer.add_visitor(..., ClassMemberReferencesVisitor::default).

Happy to wire it if you prefer.


10-13: Naming: singular ‘Service’ reads better

Most codebases use FooService (singular). Consider SemanticClassService for consistency with SemanticModel.

If you want, I’ll prep a follow-up PR-wide rename.

📜 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 d42ff3b and 0fb0dc1.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/services/semantic_class.rs (5 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/services/semantic_class.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
🧠 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_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
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)
crates/biome_rowan/src/ast/mod.rs (2)
  • cast_ref (142-151)
  • unwrap_cast (199-211)
⏰ 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). (24)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Documentation
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: autofix

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
crates/biome_js_analyze/src/services/semantic_class.rs (2)

617-632: Use the member token range for reads (consistency with writes)
Reads currently record the entire this.foo span. Writes use the member token’s range. Align reads to the member’s range for consistency and better diagnostics.

     if let Some(static_member) = JsStaticMemberExpression::cast_ref(node)
         && let Ok(object) = static_member.object()
         && is_this_reference(&object, scoped_this_references)
         && let Ok(member) = static_member.member()
     {
         reads.insert(ClassMemberReference {
             name: member.to_trimmed_text(),
-            range: static_member.syntax().text_trimmed_range(),
+            range: member.syntax().text_trimmed_range(),
         });
     }

651-676: Detect all compound assignments, not a hand-picked subset
Limiting to a small set of operators misses cases like -= or **=. Simpler and safer: treat any assignment operator other than = as compound.

-        if let Ok(operator) = assignment.operator_token()
-            && let Some(operand) = left.as_any_js_assignment()
-            && matches!(
-                operator.kind(),
-                JsSyntaxKind::PIPE2EQ
-                    | JsSyntaxKind::AMP2EQ
-                    | JsSyntaxKind::SLASHEQ
-                    | JsSyntaxKind::STAREQ
-                    | JsSyntaxKind::PERCENTEQ
-                    | JsSyntaxKind::PLUSEQ
-                    | JsSyntaxKind::QUESTION2EQ
-            )
+        if let Ok(operator) = assignment.operator_token()
+            && operator.kind() != JsSyntaxKind::EQ
+            && let Some(operand) = left.as_any_js_assignment()
             && let Some(name) = ThisPatternResolver::extract_this_member_reference(
                 operand.as_js_static_member_assignment(),
                 scoped_this_references,
             )
         {
             reads.insert(name.clone());
         }

Add tests for -= / **= / <<= to avoid regressions.

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)

19-37: Naming: align with existing service/model conventions
Current split reads as “Services” (plural) holding a “Model”. Consider ClassMemberReferencesService (service) + ClassMemberReferencesModel (model), or adopt reviewer’s suggestion to mirror SemanticModel.

🧹 Nitpick comments (5)
crates/biome_js_analyze/src/services/semantic_class.rs (5)

577-599: Only record the bound property name (avoid key: alias text)
declarator.to_trimmed_text() will include aliases (foo: local). Extract the property key instead so the recorded read is the class field name.

-    for declarator in binding.properties() {
-        if let Some(declarator) = declarator.ok()
-            && is_this_reference(&expression, scoped_this_references)
-        {
-            reads.insert(ClassMemberReference {
-                name: declarator.to_trimmed_text(),
-                range: declarator.syntax().text_trimmed_range(),
-            });
-        }
-    }
+    for prop in binding.properties() {
+        if let Some(prop) = prop.ok()
+            && is_this_reference(&expression, scoped_this_references)
+            && let Some(p) = prop.as_js_object_binding_pattern_property()
+            && let Ok(key) = p.key()
+        {
+            reads.insert(ClassMemberReference {
+                name: key.to_trimmed_text(),
+                range: key.syntax().text_trimmed_range(),
+            });
+        }
+    }

319-344: Alias discovery misses nested block declarations
collect_local_this_references only scans top-level statements, so const self = this; inside a block is ignored. Consider descending into blocks to catch aliases with block scope.


274-274: Remove debug noise
Stray commented println! left behind.

-                // println!("leave node in ThisScopeVisitor {:?}", node);

127-129: Dead union?
AnyPropertyMember isn’t used. If truly unused, drop it and the TsPropertyParameter import.


807-1131: Add a few missing tests
Please add tests for:

  • Compound ops -=, **=, <<= to validate the generalised check.
  • Object binding with aliasing (const { foo: local } = this) to ensure only foo is recorded.

Happy to draft the cases if useful.

📜 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 0fb0dc1 and 744fa2b.

📒 Files selected for processing (2)
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs (4 hunks)
  • crates/biome_js_analyze/src/services/semantic_class.rs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.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/services/semantic_class.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
🧠 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_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
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)
crates/biome_rowan/src/ast/mod.rs (1)
  • unwrap_cast (199-211)
⏰ 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). (24)
  • GitHub Check: Test Node.js API
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix
🔇 Additional comments (2)
crates/biome_js_analyze/src/services/semantic_class.rs (2)

65-80: Syntax-phase matching fixed — good call

Emitting ctx.match_query on JsClassDeclaration in the Syntax phase and inserting the stateless model in finish looks correct. This should unblock rules’ run.


739-761: Behavioural sanity check across entry points
Constructor, method/property initialisers, and on-demand model all converge on visit_references_in_body/class_member_references. Looks cohesive; tests cover these paths.

Also applies to: 517-533, 138-194

Comment on lines 101 to 104
fn build_visitor(analyzer: &mut impl AddVisitor<JsLanguage>, _root: &AnyJsRoot) {
analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor {});
analyzer.add_visitor(Phases::Semantic, || ClassMemberReferencesVisitor {});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Register the visitor only once (Syntax phase)
Registering the same visitor for both Syntax and Semantic phases is redundant and can double-run finish(). Keep only the Syntax-phase registration.

     fn build_visitor(analyzer: &mut impl AddVisitor<JsLanguage>, _root: &AnyJsRoot) {
-        analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor {});
-        analyzer.add_visitor(Phases::Semantic, || ClassMemberReferencesVisitor {});
+        analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor {});
     }
📝 Committable suggestion

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

Suggested change
fn build_visitor(analyzer: &mut impl AddVisitor<JsLanguage>, _root: &AnyJsRoot) {
analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor {});
analyzer.add_visitor(Phases::Semantic, || ClassMemberReferencesVisitor {});
}
fn build_visitor(analyzer: &mut impl AddVisitor<JsLanguage>, _root: &AnyJsRoot) {
analyzer.add_visitor(Phases::Syntax, || ClassMemberReferencesVisitor {});
}
🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/services/semantic_class.rs around lines 101 to
104, the ClassMemberReferencesVisitor is being registered for both
Phases::Syntax and Phases::Semantic which is redundant and can cause its
finish() to run twice; remove the Phases::Semantic registration and keep only
the Phases::Syntax registration so the visitor is added once during the syntax
phase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we need both, if Semantic phase is not registered, it does not seem to make any matches.
Guessing the other option will be to split ClassMemberReferenceVisitor into two, - one for Syntax to register the service only and another for Semantic to register the node query
@ematipico please confirm ?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@vladimir-ivanov vladimir-ivanov Sep 15, 2025

Choose a reason for hiding this comment

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

I tried both, maybe I am missing something, but bot is wrong. removing Semantic only - fails, removing Syntax only also fails.
splitting into two visitors works - only thing that I can make work.
need to read the internals and do more debugging to understand why it is not working.
Leave it with me. thanks

Copy link
Member

Choose a reason for hiding this comment

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

All right, sounds good. Maybe reply to the bot and tell it why it's incorrect, so next time won't bother

@vladimir-ivanov
Copy link
Contributor Author

@ematipico planning to use this service if/when merged for my next pr, all the reads / writes are valuable for consistency in no_unused_private_properties for instance

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.

Great refactor! Thank you. Happy to merge once everything is green. Also, keep an eye on performance, I recall there was a small regression

@vladimir-ivanov
Copy link
Contributor Author

Great refactor! Thank you. Happy to merge once everything is green. Also, keep an eye on performance, I recall there was a small regression

what exactly is the code on regression that I am looking at please - is it now actually running the rules themselves? will look tonight at it. thanks

@ematipico
Copy link
Member

#7428 (comment)

@vladimir-ivanov
Copy link
Contributor Author

#7428 (comment)

crates/biome_js_analyze/benches/js_analyzer.rs thanks, it says it there actually :-)

@vladimir-ivanov vladimir-ivanov force-pushed the feat/classMemberReferencesService branch from a6da844 to 4d87dad Compare September 15, 2025 16:37
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

♻️ Duplicate comments (3)
crates/biome_js_analyze/src/services/semantic_class.rs (3)

274-274: Remove the debug print statement.

-                // println!("leave node in ThisScopeVisitor {:?}", node);

33-37: Model doesn't store any class data.

The SemanticClassModel is empty and can't provide class member references for specific classes. Rules need to query references by class range/identity.

Store class references in the model:

 #[derive(Debug, Clone)]
-pub struct SemanticClassModel {}
+pub struct SemanticClassModel {
+    class_references: FxHashMap<TextRange, ClassMemberReferences>,
+}

 impl SemanticClassModel {
-    pub fn class_member_references(&self, members: &JsClassMemberList) -> ClassMemberReferences {
-        class_member_references(members)
+    pub fn class_member_references(&self, class_range: TextRange) -> Option<&ClassMemberReferences> {
+        self.class_references.get(&class_range)
     }
 }

77-79: The service should be created once per root, not once per class.

The current approach inserts a new SemanticClassModel {} for every class encountered. This will overwrite previous instances, and rules won't be able to access data from other classes in the same file.

Move the service creation to happen once per file:

     fn finish(self: Box<Self>, ctx: VisitorFinishContext<JsLanguage>) {
-        ctx.services.insert_service(SemanticClassModel {});
+        // Service should be created once per root with collected data
+        // Consider storing class references in the visitor and creating
+        // the model here with all collected data
     }
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)

83-83: Naming: Consider SemanticClassClassSemanticQuery.

Given the existing feedback about naming and the pattern of other services, a more descriptive name might help distinguish this from general class handling.

📜 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 744fa2b and 4d87dad.

📒 Files selected for processing (4)
  • crates/biome_js_analyze/src/lib.rs (0 hunks)
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.rs (4 hunks)
  • crates/biome_js_analyze/src/services/mod.rs (1 hunks)
  • crates/biome_js_analyze/src/services/semantic_class.rs (21 hunks)
💤 Files with no reviewable changes (1)
  • crates/biome_js_analyze/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_js_analyze/src/services/mod.rs
  • crates/biome_js_analyze/src/lint/style/use_readonly_class_properties.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/services/semantic_class.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/services/semantic_class.rs
🧠 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_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
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/services/semantic_class.rs (1)
crates/biome_rowan/src/ast/mod.rs (1)
  • unwrap_cast (199-211)
⏰ 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). (24)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)

@vladimir-ivanov
Copy link
Contributor Author

merging, there is nothing different from before, apart of the introduction of a service, looks like the perf degradation is purely because of that. @ematipico please let me know if I missed anything, but I can not see it.
Service is just a proxy to class_member_references and there is nothing extra stored on the service (SemanticClass) itself as it stands to make the perf worse. Just a simple wrapper (transparently calls it) to class_member_references

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transform class_member_references into a service

3 participants

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