diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9ec291c0ebad..a85a8b0c3078 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -21,6 +21,7 @@ concurrency: env: RUST_LOG: info RUST_BACKTRACE: 1 + RUSTUP_WINDOWS_PATH_ADD_BIN: 1 jobs: format: diff --git a/CHANGELOG.md b/CHANGELOG.md index 39650d70be0a..84aaaa942564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ### Analyzer +#### Enhancements + +- Assume Vue compiler macros are globals when processing `.vue` files. ([#2771](https://github.com/biomejs/biome/pull/2771)) Contributed by @dyc3 + ### CLI #### New features diff --git a/crates/biome_analyze/src/rule.rs b/crates/biome_analyze/src/rule.rs index 6bebb6b0bf06..424519ed9a0c 100644 --- a/crates/biome_analyze/src/rule.rs +++ b/crates/biome_analyze/src/rule.rs @@ -75,6 +75,17 @@ impl Display for FixKind { } } +impl TryFrom for Applicability { + type Error = &'static str; + fn try_from(value: FixKind) -> Result { + match value { + FixKind::None => Err("The fix kind is None"), + FixKind::Safe => Ok(Applicability::Always), + FixKind::Unsafe => Ok(Applicability::MaybeIncorrect), + } + } +} + #[derive(Debug, Clone, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] @@ -315,6 +326,12 @@ impl RuleMetadata { self.language = language; self } + + pub fn to_applicability(&self) -> Applicability { + self.fix_kind + .try_into() + .expect("Fix kind is not set in the rule metadata") + } } pub trait RuleMeta { @@ -820,7 +837,7 @@ impl RuleDiagnostic { /// Code Action object returned by a single analysis rule pub struct RuleAction { pub category: ActionCategory, - pub applicability: Applicability, + applicability: Applicability, pub message: MarkupBuf, pub mutation: BatchMutation, } @@ -839,6 +856,10 @@ impl RuleAction { mutation, } } + + pub fn applicability(&self) -> Applicability { + self.applicability + } } /// An action meant to suppress a lint rule diff --git a/crates/biome_analyze/src/signals.rs b/crates/biome_analyze/src/signals.rs index af3bf09c2396..76de3f6421b9 100644 --- a/crates/biome_analyze/src/signals.rs +++ b/crates/biome_analyze/src/signals.rs @@ -396,7 +396,7 @@ where if let Some(action) = R::action(&ctx, &self.state) { actions.push(AnalyzerAction { rule_name: Some((::NAME, R::METADATA.name)), - applicability: configured_applicability.unwrap_or(action.applicability), + applicability: configured_applicability.unwrap_or(action.applicability()), category: action.category, mutation: action.mutation, message: action.message, diff --git a/crates/biome_cli/tests/cases/handle_vue_files.rs b/crates/biome_cli/tests/cases/handle_vue_files.rs index 96d5cd90f342..a3d029bea037 100644 --- a/crates/biome_cli/tests/cases/handle_vue_files.rs +++ b/crates/biome_cli/tests/cases/handle_vue_files.rs @@ -119,6 +119,28 @@ a.c = undefined; "#; +const VUE_TS_FILE_SETUP_GLOBALS: &str = r#" +"#; + #[test] fn format_vue_implicit_js_files() { let mut fs = MemoryFileSystem::default(); @@ -846,3 +868,30 @@ fn check_stdin_apply_unsafe_successfully() { result, )); } + +#[test] +fn vue_compiler_macros_as_globals() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let vue_file_path = Path::new("file.vue"); + fs.insert(vue_file_path.into(), VUE_TS_FILE_SETUP_GLOBALS.as_bytes()); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from([("lint"), vue_file_path.as_os_str().to_str().unwrap()].as_slice()), + ); + + assert!(result.is_err(), "run_cli returned {result:?}"); + + assert_file_contents(&fs, vue_file_path, VUE_TS_FILE_SETUP_GLOBALS); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "vue_compiler_macros_as_globals", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/vue_compiler_macros_as_globals.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/vue_compiler_macros_as_globals.snap new file mode 100644 index 000000000000..208b55226cfe --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_vue_files/vue_compiler_macros_as_globals.snap @@ -0,0 +1,63 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: content +--- +## `file.vue` + +```vue + + +``` + +# Termination Message + +```block +lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Some errors were emitted while running checks. + + + +``` + +# Emitted Messages + +```block +file.vue:16:36 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected any. Specify a different type. + + 15 │ const slots = defineSlots<{ + > 16 │ default(props: { msg: string }): any + │ ^^^ + 17 │ }>() + 18 │ + + i any disables many type checking rules. Its use should be avoided. + + +``` + +```block +Checked 1 file in