Skip to content

fix(grit): make $filename metavariable accessible in GritQL plugins#8755

Merged
dyc3 merged 9 commits intobiomejs:mainfrom
arturalkaim:fix/filename-metavariable-binding
Jan 13, 2026
Merged

fix(grit): make $filename metavariable accessible in GritQL plugins#8755
dyc3 merged 9 commits intobiomejs:mainfrom
arturalkaim:fix/filename-metavariable-binding

Conversation

@arturalkaim
Copy link
Contributor

@arturalkaim arturalkaim commented Jan 12, 2026

This PR was written primarily by Claude Code.

Summary

This PR fixes GitHub issue #6670 where the metavariable was not accessible when using clauses in GritQL patterns.

For example, this pattern was not working:

`console.log()` where {
     <: r".*\.ts$"
}

Root Cause

Global variables (, , etc.) and local pattern variables were both stored in scope 0. When the auto-wrap bubble pattern entered scope 0, it would reset ALL variable values to None, including the `` that was set by FilePattern.

Solution

Separate the scopes:

  • Scope 0: Global variables only (, , , )
  • Scope 1: Local pattern variables (user-defined variables like , )

Now when the auto-wrap bubble enters scope 1, it resets local pattern variables (giving each match a fresh state) while preserving global variables in scope 0.

Additionally, wrap_pattern_in_file now uses Pattern::Variable(Variable::file_name()) to ensure `` is properly bound when FilePattern matches.

Test plan

  • Added test case filenameMatch.grit that verifies `` matches .ts files
  • Added test case filenameNoMatch.grit that verifies `` doesn't match .tsx for `.ts` files
  • Added unit test in quick_test.rs for the `` binding
  • All existing tests pass (33 spec tests)

Fixes #6670

Docs

N/A - This is a bug fix for an existing feature, no documentation changes required.

This fixes GitHub issue biomejs#6670 where the $filename metavariable was not
accessible when using where clauses in GritQL patterns.

The root cause was that global variables ($filename, $program, etc.) and
local pattern variables were both stored in scope 0. When the auto-wrap
bubble pattern entered scope 0, it would reset ALL variable values to None,
including the $filename that was set by FilePattern.

The fix separates these scopes:
- Scope 0: Global variables only ($new_files, $program, $filename, $absolute_filename)
- Scope 1: Local pattern variables (user-defined variables like $args, $message)

Now when the auto-wrap bubble enters scope 1, it resets local pattern variables
(giving each match a fresh state) while preserving global variables in scope 0.

Also adds Pattern::Variable(Variable::file_name()) to wrap_pattern_in_file
to ensure $filename is properly bound when FilePattern matches.

Fixes biomejs#6670

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Jan 12, 2026

🦋 Changeset detected

Latest commit: 0d02f10

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 the L-Grit Language: GritQL label Jan 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 12, 2026

Walkthrough

Ensures a two‑scope variable model: scope 0 for global metavariables and scope 1 for local pattern variables. NodeCompilationContext::new now guarantees a global scope exists, sets scope_index to the computed index, and appends a local scope. Auto-wrap uses context.scope_index for bubble PatternDefinition and binds FilePattern filenames with Pattern::Variable(Variable::file_name()). Removes an obsolete diagnostic comment. Adds tests and spec files validating filename matching and updates a few test expectations and a changelog entry for the $filename metavariable.

Suggested labels

A-Tooling

Suggested reviewers

  • arendjr
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main fix: making the $filename metavariable accessible in GritQL plugins, directly matching the core objective of the changeset.
Description check ✅ Passed The description is thorough and directly related to the changeset, explaining the root cause, solution, scope separation strategy, and testing approach. AI assistance is properly disclosed.
Linked Issues check ✅ Passed The PR fully addresses all objectives from issue #6670: scope separation is implemented (scope 0 for globals, scope 1 for locals), wrap_pattern_in_file uses Pattern::Variable(Variable::file_name()), and comprehensive tests validate both matching and non-matching filename cases.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the issue: scope restructuring in compilation_context, bubble pattern scope updates in auto_wrap, filename binding changes, test additions, and scope expectation updates. No extraneous modifications detected.

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


📜 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 a879f34 and 0d02f10.

📒 Files selected for processing (1)
  • .changeset/fix-filename-metavariable.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/fix-filename-metavariable.md
⏰ 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). (9)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Check Dependencies
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API

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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
crates/biome_grit_patterns/tests/quick_test.rs (1)

35-36: Consider using dbg!() for debugging output.

Per coding guidelines, prefer dbg!() over println! for debugging output in Rust tests. This applies to lines 35-36 and 73-74.

♻️ Suggested change
-    println!("Logs explicit: {:?}", logs);
-    println!("Effects explicit: {effects:#?}");
+    dbg!(&logs);
+    dbg!(&effects);
📜 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 f244526 and 5f97e8f.

⛔ Files ignored due to path filters (2)
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.snap is excluded by !**/*.snap and included by **
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (8)
  • crates/biome_grit_patterns/src/grit_query.rs
  • crates/biome_grit_patterns/src/pattern_compiler/auto_wrap.rs
  • crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs
  • crates/biome_grit_patterns/tests/quick_test.rs
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/biome_grit_patterns/tests/quick_test.rs
  • crates/biome_grit_patterns/src/pattern_compiler/auto_wrap.rs
  • crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs
  • crates/biome_grit_patterns/src/grit_query.rs
🧠 Learnings (17)
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/quick_test.rs
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` format for test files containing multiple code snippets, where each snippet is a string in an array

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Test snapshot output files must be placed in `tests/specs/` folder with subfolders matching the rule group and rule name

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/spec_tests.rs : Use the `tests_macros::gen_tests!` macro in `spec_tests.rs` to generate test functions for each specification file matching the pattern `tests/specs/<language>/**/*.<ext>`

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts
  • crates/biome_grit_patterns/tests/quick_test.rs
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Implement watcher tests for workspace methods in watcher.tests.rs and end-to-end tests in LSP tests

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Create test infrastructure with `tests/specs` folder structure and `spec_test.rs`, `spec_tests.rs`, and `language.rs` files in test directories

Applied to files:

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

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit
  • crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts
  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • crates/biome_grit_patterns/src/grit_query.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/local_inference.rs : Implement local inference in dedicated modules to derive type definitions from expressions without context of surrounding scopes

Applied to files:

  • crates/biome_grit_patterns/src/grit_query.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/*_analyze/**/src/lint/**/*.rs : Implement custom `Queryable` and `Visitor` types for rules that require deep inspection of child nodes to avoid inefficient traversals

Applied to files:

  • crates/biome_grit_patterns/src/grit_query.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

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

Applied to files:

  • crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit
🧬 Code graph analysis (3)
crates/biome_grit_patterns/tests/quick_test.rs (4)
crates/biome_grit_parser/src/lib.rs (1)
  • parse_grit (18-21)
crates/biome_grit_patterns/src/grit_query.rs (4)
  • from_node (112-206)
  • new (315-320)
  • new (349-354)
  • new (367-375)
crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs (2)
  • new (27-40)
  • new (71-79)
crates/biome_js_syntax/src/file_source.rs (1)
  • ts (185-192)
crates/biome_grit_patterns/src/pattern_compiler/auto_wrap.rs (1)
crates/biome_formatter_test/src/spec.rs (1)
  • file_name (100-102)
crates/biome_grit_patterns/src/grit_query.rs (1)
crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs (3)
  • new (27-40)
  • new (71-79)
  • new_with_scope (81-97)
🔇 Additional comments (10)
crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.grit (1)

1-3: LGTM!

Solid negative test case. The regex .*\.tsx$ will correctly filter out .ts files, validating that $filename constraints work as expected with the new scoping fix.

crates/biome_grit_patterns/src/pattern_compiler/auto_wrap.rs (2)

410-416: Nice fix for the scope separation.

Using context.scope_index (scope 1) for the bubble ensures local pattern variables are reset without clobbering globals like $filename in scope 0. The comment explains the rationale clearly.


419-426: Core fix for $filename binding.

Switching from Pattern::Top to Pattern::Variable(Variable::file_name()) ensures the filename is actually bound when FilePattern matches, making it accessible in where clauses. This directly addresses issue #6670.

crates/biome_grit_patterns/tests/specs/ts/filenameNoMatch.ts (1)

1-2: LGTM!

Clear test fixture. The .ts extension won't match the .tsx$ regex in filenameNoMatch.grit, confirming the negative case works.

crates/biome_grit_patterns/tests/specs/ts/filenameMatch.grit (1)

1-3: LGTM!

Good positive test case for validating $filename binding works.

Minor note: the regex .*\.ts$ will also match .mts, .cts, and .tsx files (since they end with "ts"). For a stricter match, you could use .*\.ts$ with a negative lookahead or .*[^x]\.ts$, but for this test's purpose it's fine as-is.

crates/biome_grit_patterns/tests/specs/ts/filenameMatch.ts (1)

1-2: LGTM!

Clean test fixture. Both console.log calls should match when filenameMatch.grit runs against this .ts file, validating the fix works end-to-end.

crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs (1)

71-97: LGTM!

Clean refactor introducing new_with_scope while maintaining backward compatibility via delegation from new. The existing documentation for scope_index and vars_array adequately explains the scoping model.

crates/biome_grit_patterns/tests/quick_test.rs (1)

44-78: Good coverage of the core fix.

This test directly validates the originally failing pattern from issue #6670. The structure is clear and the assertion confirms the fix works.

crates/biome_grit_patterns/src/grit_query.rs (2)

138-156: Well-documented scope separation.

The inline comments clearly explain the two-scope model and rationale. This is the crux of the fix—separating globals (scope 0) from locals (scope 1) so the auto-wrap bubble doesn't clobber $filename.


166-173: Correct scope initialisation.

Using scope 1 for local pattern variables ensures definitions and patterns are compiled in the right context, preserving global variables in scope 0.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

Please use our PR template

autofix-ci bot and others added 2 commits January 12, 2026 17:43
- Change println! to dbg! in quick_test.rs for debugging output
- Simplify changeset to be user-focused without jargon
- Add issue link to changeset
@arturalkaim arturalkaim requested a review from dyc3 January 12, 2026 18:35
@arturalkaim
Copy link
Contributor Author

@dyc3 thanks for the review, pushed a few changes now.

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 (1)
crates/biome_grit_patterns/tests/quick_test.rs (1)

67-67: Prefer dbg!() for consistency.

Lines 35-36 and 76-77 use dbg!(), but this line uses println!. As per coding guidelines, prefer dbg!() for debugging output in Rust tests.

♻️ Suggested fix
-    println!("Compiled pattern: {:?}", query.pattern);
+    dbg!(&query.pattern);
📜 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 e512e9c and aef2601.

📒 Files selected for processing (2)
  • .changeset/fix-filename-metavariable.md
  • crates/biome_grit_patterns/tests/quick_test.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/biome_grit_patterns/tests/quick_test.rs
🧠 Learnings (5)
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/spec_tests.rs : Use the `tests_macros::gen_tests!` macro in `spec_tests.rs` to generate test functions for each specification file matching the pattern `tests/specs/<language>/**/*.<ext>`

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
📚 Learning: 2026-01-02T14:58:16.536Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-02T14:58:16.536Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/* : Create test files with `invalid` and `valid` prefixes to represent code that should and should not trigger the rule

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Implement watcher tests for workspace methods in watcher.tests.rs and end-to-end tests in LSP tests

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language

Applied to files:

  • crates/biome_grit_patterns/tests/quick_test.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: In changesets, start with a link to the issue when fixing a bug (e.g., 'Fixed [#4444](link): ...')

Applied to files:

  • .changeset/fix-filename-metavariable.md
🧬 Code graph analysis (1)
crates/biome_grit_patterns/tests/quick_test.rs (3)
crates/biome_grit_parser/src/lib.rs (1)
  • parse_grit (18-21)
crates/biome_grit_patterns/src/grit_query.rs (4)
  • from_node (111-205)
  • new (314-319)
  • new (348-353)
  • new (366-374)
crates/biome_js_syntax/src/file_source.rs (1)
  • ts (185-192)
🔇 Additional comments (3)
.changeset/fix-filename-metavariable.md (1)

1-7: LGTM!

Changeset is well-formatted, starts with the issue link as expected, and the description is clear for users. Based on learnings, this follows the convention for bug fix changesets.

crates/biome_grit_patterns/tests/quick_test.rs (2)

8-43: LGTM!

Test is well-structured and uses dbg!() for debugging output as per coding guidelines. Good coverage for the explicit file pattern case.


69-84: LGTM!

Test logic correctly validates that $filename is bound in auto-wrapped where clauses. Good regression test for issue #6670.

@dyc3 dyc3 requested a review from arendjr January 12, 2026 20:11
@dyc3
Copy link
Contributor

dyc3 commented Jan 12, 2026

cc @arendjr or @morgante, if yall want to weigh in

Comment on lines 153 to 172
// Scope 1: Local pattern variables (initially empty)
Vec::new(),
];
let mut global_vars: BTreeMap<String, usize> = GLOBAL_VARS
.iter()
.map(|(global_var, index)| ((*global_var).to_string(), *index))
.collect();
let mut diagnostics = Vec::new();

// We're not in a local scope yet, so this map is kinda useless.
// It's just there because all node compilers expect one.
// Local variables map - used for pattern variables in scope 1
let mut vars = BTreeMap::new();

let mut node_context = NodeCompilationContext::new(
let mut node_context = NodeCompilationContext::new_with_scope(
&context,
&mut vars,
&mut vars_array,
&mut global_vars,
&mut diagnostics,
1, // Use scope 1 for local pattern variables
);
Copy link
Member

Choose a reason for hiding this comment

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

These changes seem unrelated to the issue. What do you @arturalkaim ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not really, this is the core of the fix

Previously, both global variables ($filename, $program, etc.) and local pattern variables were in scope 0. When the auto-wrap bubble pattern entered scope 0 via enter_scope(0), it reset ALL variable values to None - including $filename that FilePattern had just set.

Now when the bubble enters scope 1, it resets local pattern variables (giving each match a fresh state) while preserving global variables in scope 0.

Without this scope separation, the $filename fix in auto_wrap.rs alone doesn't work - the value still gets reset when the bubble enters the scope.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah using scope 1 here seems correct and matches the original GritQL implementation.

Copy link
Contributor

@morgante morgante left a comment

Choose a reason for hiding this comment

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

Let's fix the new() method to prevent creating incorrect contexts in the first place - the scope index of a new context should always default to the end of the vars array.

Comment on lines 153 to 172
// Scope 1: Local pattern variables (initially empty)
Vec::new(),
];
let mut global_vars: BTreeMap<String, usize> = GLOBAL_VARS
.iter()
.map(|(global_var, index)| ((*global_var).to_string(), *index))
.collect();
let mut diagnostics = Vec::new();

// We're not in a local scope yet, so this map is kinda useless.
// It's just there because all node compilers expect one.
// Local variables map - used for pattern variables in scope 1
let mut vars = BTreeMap::new();

let mut node_context = NodeCompilationContext::new(
let mut node_context = NodeCompilationContext::new_with_scope(
&context,
&mut vars,
&mut vars_array,
&mut global_vars,
&mut diagnostics,
1, // Use scope 1 for local pattern variables
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah using scope 1 here seems correct and matches the original GritQL implementation.

)
}

pub(crate) fn new_with_scope(
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't need this actually, just use the length of vars_array when choosing the scope index.

See the equivalent logic here: https://github.com/biomejs/gritql/blob/main/crates/core/src/pattern_compiler/mod.rs#L8-L15

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, then this one is not needed.

arturalkaim and others added 2 commits January 13, 2026 10:32
Address review feedback from @morgante:
- Remove new_with_scope() method
- Use vars_array.len() as scope index in new(), matching original GritQL
- See: https://github.com/biomejs/gritql/blob/main/crates/core/src/pattern_compiler/mod.rs#L8-L15

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs:
- Around line 78-84: NodeCompilationContext::new currently assumes callers
pre-populate vars_array with a global scope, but test_pattern_from_node in
snippet_compiler.rs passes an empty vars_array which makes scope_index 0 and
breaks global/local separation; fix by making NodeCompilationContext::new ensure
vars_array has a global scope (if vars_array.is_empty() push Vec::new()), set
scope_index accordingly, and add a short rustdoc on NodeCompilationContext::new
noting that it will create a global scope when none is provided so callers need
not pre-populate.
📜 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 ad261bb and 34b870b.

📒 Files selected for processing (2)
  • crates/biome_grit_patterns/src/grit_query.rs
  • crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_grit_patterns/src/grit_query.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs
🧠 Learnings (1)
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/local_inference.rs : Implement local inference in dedicated modules to derive type definitions from expressions without context of surrounding scopes

Applied to files:

  • crates/biome_grit_patterns/src/pattern_compiler/compilation_context.rs

@dyc3 dyc3 merged commit 3a15c29 into biomejs:main Jan 13, 2026
13 checks passed
@github-actions github-actions bot mentioned this pull request Jan 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L-Grit Language: GritQL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 $filename metavariable not set in GritQL plugins

4 participants