Skip to content

Commit 4b19b2c

Browse files
committed
changesets and better testing suite
1 parent cde517c commit 4b19b2c

File tree

11 files changed

+113
-65
lines changed

11 files changed

+113
-65
lines changed

.changeset/odd-flies-nail.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"@biomejs/biome": minor
3+
---
4+
5+
Improved the CSS parser for CSS modules. When Biome encounters a `*.module.css` file, enables the CSS modules feature.
6+
7+
If your codebase has only `*.module.css` files, you can disable the parser feature as follows:
8+
9+
```diff
10+
{
11+
"css": {
12+
"parser": {
13+
- "cssModules": true
14+
}
15+
}
16+
}
17+
```

.changeset/plenty-hornets-hide.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@biomejs/biome": minor
3+
---
4+
5+
Added support for parsing `:global` and `:local` inside `.astro`, `.svelte` and `.vue` files, in `<style>` portion of the file.
6+
7+
Added support for parsing `:slotted` and `:deep` inside `.vue` files, in `<style>` portion of the file.
8+
9+
This capability is only available when `experimentalFullHtmlSupportedEnabled` is set to `true`.

crates/biome_css_analyze/src/lint/correctness/no_unknown_pseudo_class.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ impl Rule for NoUnknownPseudoClass {
177177
}
178178
};
179179

180+
dbg!(&file_source.is_css_modules());
180181
if is_valid_class || file_source.is_css_modules() && is_css_module_pseudo_class(lower_name)
181182
{
182183
None

crates/biome_css_analyze/src/lint/style/no_value_at_rule.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use biome_analyze::{Ast, Rule, RuleDiagnostic, context::RuleContext, declare_lint_rule};
22
use biome_console::markup;
3-
use biome_css_syntax::CssAtRule;
3+
use biome_css_syntax::{CssAtRule, CssFileSource};
44
use biome_diagnostics::Severity;
55
use biome_rowan::AstNode;
66
use biome_rule_options::no_value_at_rule::NoValueAtRuleOptions;
77

88
declare_lint_rule! {
9-
/// Disallow use of `@value` rule in css modules.
9+
/// Disallow use of `@value` rule in CSS modules.
1010
///
1111
/// Use of CSS variables is recommended instead of `@value` rule.
1212
///
@@ -47,8 +47,9 @@ impl Rule for NoValueAtRule {
4747

4848
fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
4949
let node = ctx.query();
50+
let file_source = ctx.source_type::<CssFileSource>();
5051

51-
if node.rule().ok()?.as_css_value_at_rule().is_some() {
52+
if node.rule().ok()?.as_css_value_at_rule().is_some() && file_source.is_css_modules() {
5253
return Some(node.clone());
5354
}
5455

crates/biome_css_analyze/tests/spec_tests.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use biome_analyze::{
22
AnalysisFilter, AnalyzerAction, AnalyzerPluginSlice, ControlFlow, Never, RuleFilter,
33
};
44
use biome_css_analyze::CssAnalyzerServices;
5-
use biome_css_parser::{CssModulesKind, CssParserOptions, parse_css};
5+
use biome_css_parser::{CssParserOptions, parse_css};
66
use biome_css_semantic::semantic_model;
77
use biome_css_syntax::{CssFileSource, CssLanguage};
88
use biome_diagnostics::advice::CodeSuggestionAdvice;
@@ -11,7 +11,7 @@ use biome_plugin_loader::AnalyzerGritPlugin;
1111
use biome_rowan::AstNode;
1212
use biome_test_utils::{
1313
CheckActionType, assert_diagnostics_expectation_comment, assert_errors_are_absent,
14-
code_fix_to_string, create_analyzer_options, diagnostic_to_string,
14+
code_fix_to_string, create_analyzer_options, create_parser_options, diagnostic_to_string,
1515
has_bogus_nodes_or_empty_slots, parse_test_path, register_leak_checker, scripts_from_json,
1616
write_analyzer_snapshot,
1717
};
@@ -53,15 +53,8 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
5353

5454
let mut snapshot = String::new();
5555
let extension = input_file.extension().unwrap_or_default();
56-
57-
let parser_options = if file_name.ends_with(".module.css") {
58-
CssParserOptions {
59-
css_modules: CssModulesKind::Classic,
60-
..CssParserOptions::default()
61-
}
62-
} else {
63-
CssParserOptions::default()
64-
};
56+
let mut diagnostics = vec![];
57+
let parser_options = create_parser_options::<CssLanguage>(&input_file, &mut diagnostics);
6558

6659
let input_code = read_to_string(input_file)
6760
.unwrap_or_else(|err| panic!("failed to read {input_file:?}: {err:?}"));
@@ -76,14 +69,17 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
7669
file_name,
7770
input_file,
7871
CheckActionType::Lint,
79-
parser_options,
72+
parser_options.unwrap_or_default(),
8073
&[],
8174
);
8275
}
8376
} else {
84-
let Ok(source_type) = input_file.try_into() else {
77+
let Ok(source_type): Result<CssFileSource, _> = input_file.try_into() else {
8578
return;
8679
};
80+
81+
let parser_options = parser_options.unwrap_or(CssParserOptions::from(&source_type));
82+
8783
analyze_and_snap(
8884
&mut snapshot,
8985
&input_code,

crates/biome_css_analyze/tests/specs/correctness/noUnknownPseudoClass/validGlobal.css renamed to crates/biome_css_analyze/tests/specs/correctness/noUnknownPseudoClass/validGlobal.module.css

File renamed without changes.

crates/biome_css_analyze/tests/specs/correctness/noUnknownPseudoClass/validGlobal.css.snap renamed to crates/biome_css_analyze/tests/specs/correctness/noUnknownPseudoClass/validGlobal.module.css.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/biome_css_analyze/tests/spec_tests.rs
3-
expression: validGlobal.css
3+
expression: validGlobal.module.css
44
---
55
# Input
66
```css

crates/biome_css_analyze/tests/specs/correctness/noUnknownPseudoClass/validGlobal.options.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

crates/biome_css_syntax/src/file_source.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ impl CssFileSource {
103103
self
104104
}
105105

106+
pub fn with_tailwind_directives(mut self) -> Self {
107+
self.variant = CssVariant::TailwindCss;
108+
self
109+
}
110+
106111
pub fn is_css_modules(&self) -> bool {
107112
self.variant == CssVariant::CssModules
108113
}
@@ -123,16 +128,26 @@ impl CssFileSource {
123128
}
124129

125130
/// Try to return the CSS file source corresponding to this file name from well-known files
126-
pub fn try_from_well_known(_: &Utf8Path) -> Result<Self, FileSourceError> {
127-
// TODO: to be implemented
128-
Err(FileSourceError::UnknownFileName)
131+
pub fn try_from_well_known(path: &Utf8Path) -> Result<Self, FileSourceError> {
132+
// Be careful with definition files, because `Path::extension()` only
133+
// returns the extension after the _last_ dot:
134+
let file_name = path.file_name().ok_or(FileSourceError::MissingFileName)?;
135+
if file_name.ends_with(".module.css") {
136+
return Self::try_from_extension("module.css");
137+
}
138+
139+
match path.extension() {
140+
Some(extension) => Self::try_from_extension(extension),
141+
None => Err(FileSourceError::MissingFileExtension),
142+
}
129143
}
130144

131145
/// Try to return the CSS file source corresponding to this file extension
132146
pub fn try_from_extension(extension: &str) -> Result<Self, FileSourceError> {
133147
// We assume the file extension is normalized to lowercase
134148
match extension {
135149
"css" => Ok(Self::css()),
150+
"module.css" => Ok(Self::new_css_modules()),
136151
_ => Err(FileSourceError::UnknownExtension),
137152
}
138153
}

crates/biome_service/src/file_handlers/css.rs

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ impl ServiceLanguage for CssLanguage {
156156
path: &BiomePath,
157157
file_source: &DocumentFileSource,
158158
) -> Self::ParserOptions {
159+
dbg!("css resolve_parse_options");
159160
let mut options = CssParserOptions {
160161
allow_wrong_line_comments: language
161162
.allow_wrong_line_comments
@@ -181,11 +182,13 @@ impl ServiceLanguage for CssLanguage {
181182
})
182183
.unwrap_or_default(),
183184
grit_metavariables: false,
184-
tailwind_directives: language.tailwind_directives_enabled(),
185+
tailwind_directives: language.tailwind_directives.unwrap_or_default().into(),
185186
};
186187

187188
overrides.apply_override_css_parser_options(path, &mut options);
188189

190+
dbg!(&options);
191+
189192
options
190193
}
191194

@@ -412,43 +415,7 @@ fn parse(
412415
settings: &SettingsWithEditor,
413416
cache: &mut NodeCache,
414417
) -> ParseResult {
415-
let mut options = CssParserOptions {
416-
allow_wrong_line_comments: settings
417-
.as_ref()
418-
.languages
419-
.css
420-
.parser
421-
.allow_wrong_line_comments
422-
.unwrap_or_default()
423-
.into(),
424-
css_modules: settings
425-
.as_ref()
426-
.languages
427-
.css
428-
.parser
429-
.css_modules_enabled
430-
.map_or(CssModulesKind::None, |bool| {
431-
if bool.value() {
432-
CssModulesKind::Classic
433-
} else {
434-
CssModulesKind::None
435-
}
436-
}),
437-
grit_metavariables: false,
438-
tailwind_directives: settings
439-
.as_ref()
440-
.languages
441-
.css
442-
.parser
443-
.tailwind_directives
444-
.unwrap_or_default()
445-
.into(),
446-
};
447-
448-
settings
449-
.as_ref()
450-
.override_settings
451-
.apply_override_css_parser_options(biome_path, &mut options);
418+
let options = settings.parse_options::<CssLanguage>(biome_path, &file_source);
452419

453420
let source_type = file_source.to_css_file_source().unwrap_or_default();
454421
let parse = biome_css_parser::parse_css_with_cache(text, source_type, cache, options);

0 commit comments

Comments
 (0)