Skip to content

Commit d29dd19

Browse files
fix(lint): resolve false positive in noAssignInExpressions for Svelte {@const} blocks (#10079)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent de58f92 commit d29dd19

9 files changed

Lines changed: 69 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed false positive in `noAssignInExpressions` for Svelte `{@const}` blocks. Assignments in `{@const name = value}` are now correctly recognized as declarations rather than accidental assignments in expressions.

crates/biome_js_analyze/src/lint/suspicious/no_assign_in_expressions.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ impl Rule for NoAssignInExpressions {
7272
return None;
7373
}
7474

75+
// Skip assignments in Svelte const blocks ({@const name = value})
76+
// These are declaration statements, not accidental assignments in expressions
77+
if file_source.is_svelte_const_block() {
78+
return None;
79+
}
80+
7581
let assign = ctx.query();
7682
let mut ancestor = assign
7783
.syntax()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- should not generate diagnostics -->
2+
<script lang="ts">
3+
const numbers = [1, 2, 3, 4];
4+
</script>
5+
6+
{#each numbers as number, index (number)}
7+
{@const n = number + 1}
8+
<p>{n}</p>
9+
{/each}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
source: crates/biome_js_analyze/tests/spec_tests.rs
3+
assertion_line: 149
4+
expression: valid-svelte-const.svelte
5+
---
6+
# Input
7+
```svelte
8+
<!-- should not generate diagnostics -->
9+
<script lang="ts">
10+
const numbers = [1, 2, 3, 4];
11+
</script>
12+
13+
{#each numbers as number, index (number)}
14+
{@const n = number + 1}
15+
<p>{n}</p>
16+
{/each}
17+
18+
```

crates/biome_js_parser/tests/spec_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_
8989
is_source: false,
9090
is_function_signature: false,
9191
kind: biome_js_syntax::SvelteFileKind::Component,
92+
is_const_block: false,
9293
});
9394
}
9495

crates/biome_js_syntax/src/file_source.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ pub enum EmbeddingKind {
165165

166166
/// Whether this is the declaration of a function, usually declared in `#snippet`
167167
is_function_signature: bool,
168+
169+
/// Whether this is a `{@const name = value}` block.
170+
is_const_block: bool,
168171
},
169172
#[default]
170173
None,
@@ -222,6 +225,15 @@ impl EmbeddingKind {
222225
}
223226
)
224227
}
228+
pub const fn is_svelte_const_block(&self) -> bool {
229+
matches!(
230+
self,
231+
Self::Svelte {
232+
is_const_block: true,
233+
..
234+
}
235+
)
236+
}
225237
}
226238

227239
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
@@ -315,6 +327,7 @@ impl JsFileSource {
315327
is_source: true,
316328
is_function_signature: false,
317329
kind: SvelteFileKind::Component,
330+
is_const_block: false,
318331
})
319332
}
320333

@@ -421,6 +434,11 @@ impl JsFileSource {
421434
self.embedding_kind.is_vue_event_handler()
422435
}
423436

437+
/// Returns true if this is a Svelte `{@const}` block
438+
pub const fn is_svelte_const_block(&self) -> bool {
439+
self.embedding_kind.is_svelte_const_block()
440+
}
441+
424442
pub const fn as_embedding_kind(&self) -> &EmbeddingKind {
425443
&self.embedding_kind
426444
}
@@ -510,6 +528,7 @@ impl JsFileSource {
510528
is_source: true,
511529
is_function_signature: false,
512530
kind: SvelteFileKind::SourceModule,
531+
is_const_block: false,
513532
}));
514533
}
515534

crates/biome_service/src/file_handlers/html/parse_embedded_nodes.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ fn parse_matched_embed(
790790
is_source: true,
791791
is_function_signature: false,
792792
kind: SvelteFileKind::Component,
793+
is_const_block: false,
793794
});
794795
} else if ctx.host_file_source.is_vue() {
795796
js_source = js_source.with_embedding_kind(EmbeddingKind::Vue {
@@ -813,6 +814,10 @@ fn parse_matched_embed(
813814
is_source: false,
814815
is_function_signature,
815816
kind: SvelteFileKind::Component,
817+
is_const_block: matches!(
818+
block_kind,
819+
EmbedBlockKind::Svelte(SvelteBlockKind::Const)
820+
),
816821
});
817822
} else if ctx.host_file_source.is_vue() {
818823
js_source = js_source.with_embedding_kind(EmbeddingKind::Vue {
@@ -846,6 +851,7 @@ fn parse_matched_embed(
846851
is_source: false,
847852
is_function_signature: false,
848853
kind: SvelteFileKind::Component,
854+
is_const_block: false,
849855
});
850856
}
851857
}

crates/biome_service/src/file_handlers/svelte.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ impl SvelteFileHandler {
8282
is_source: true,
8383
is_function_signature: false,
8484
kind: SvelteFileKind::Component,
85+
is_const_block: false,
8586
}),
8687
)
8788
})

packages/@biomejs/backend-jsonrpc/src/workspace.ts

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)