Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed May 16, 2024
2 parents 2e8ad62 + 32e422d commit 57ad88c
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 17 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ concurrency:
env:
RUST_LOG: info
RUST_BACKTRACE: 1
RUSTUP_WINDOWS_PATH_ADD_BIN: 1

jobs:
format:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 22 additions & 1 deletion crates/biome_analyze/src/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ impl Display for FixKind {
}
}

impl TryFrom<FixKind> for Applicability {
type Error = &'static str;
fn try_from(value: FixKind) -> Result<Self, Self::Error> {
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"))]
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -820,7 +837,7 @@ impl RuleDiagnostic {
/// Code Action object returned by a single analysis rule
pub struct RuleAction<L: Language> {
pub category: ActionCategory,
pub applicability: Applicability,
applicability: Applicability,
pub message: MarkupBuf,
pub mutation: BatchMutation<L>,
}
Expand All @@ -839,6 +856,10 @@ impl<L: Language> RuleAction<L> {
mutation,
}
}

pub fn applicability(&self) -> Applicability {
self.applicability
}
}

/// An action meant to suppress a lint rule
Expand Down
2 changes: 1 addition & 1 deletion crates/biome_analyze/src/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ where
if let Some(action) = R::action(&ctx, &self.state) {
actions.push(AnalyzerAction {
rule_name: Some((<R::Group as RuleGroup>::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,
Expand Down
49 changes: 49 additions & 0 deletions crates/biome_cli/tests/cases/handle_vue_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,28 @@ a.c = undefined;
</script>
<template></template>"#;

const VUE_TS_FILE_SETUP_GLOBALS: &str = r#"<script setup lang="ts">
// These are magic vue macros, and should be treated as globals.
defineProps(['foo'])
defineEmits(['change', 'delete'])
defineModel()
const a = 1
defineExpose({
a,
})
defineOptions({
inheritAttrs: false,
})
const slots = defineSlots<{
default(props: { msg: string }): any
}>()
</script>
<template></template>"#;

#[test]
fn format_vue_implicit_js_files() {
let mut fs = MemoryFileSystem::default();
Expand Down Expand Up @@ -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,
));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: content
---
## `file.vue`

```vue
<script setup lang="ts">
// These are magic vue macros, and should be treated as globals.
defineProps(['foo'])
defineEmits(['change', 'delete'])
defineModel()
const a = 1
defineExpose({
a,
})
defineOptions({
inheritAttrs: false,
})
const slots = defineSlots<{
default(props: { msg: string }): any
}>()
</script>
<template></template>
```

# 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 <TIME>. No fixes needed.
Found 1 error.
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use biome_analyze::{
context::RuleContext, declare_rule, ActionCategory, Ast, FixKind, Rule, SourceActionKind,
};
use biome_console::markup;
use biome_diagnostics::Applicability;
use biome_js_factory::make;
use biome_js_syntax::{
AnyJsImportClause, AnyJsModuleItem, AnyJsNamedImportSpecifier, JsImport, JsLanguage, JsModule,
Expand Down Expand Up @@ -262,7 +261,7 @@ impl Rule for OrganizeImports {

Some(JsRuleAction::new(
ActionCategory::Source(SourceActionKind::OrganizeImports),
Applicability::MaybeIncorrect,
ctx.metadata().to_applicability(),
markup! { "Organize Imports (Biome)" },
mutation,
))
Expand Down
17 changes: 9 additions & 8 deletions crates/biome_migrate/src/analyzers/nursery_rules.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{declare_migration, MigrationAction};
use biome_analyze::context::RuleContext;
use biome_analyze::{ActionCategory, Ast, Rule, RuleDiagnostic};
use biome_analyze::{ActionCategory, Ast, FixKind, Rule, RuleDiagnostic};
use biome_console::markup;
use biome_diagnostics::{category, Applicability};
use biome_diagnostics::category;
use biome_json_factory::make::{
json_member, json_member_list, json_member_name, json_object_value, json_string_literal, token,
};
Expand All @@ -16,6 +16,7 @@ declare_migration! {
pub(crate) NurseryRules {
version: "1.7.0",
name: "nurseryRules",
fix_kind: FixKind::Unsafe,
}
}

Expand Down Expand Up @@ -299,15 +300,15 @@ impl Rule for NurseryRules {
mutation.replace_node(rules, json_member_list(new_members, separators));
};

Some(MigrationAction {
mutation,
message: markup! {
Some(MigrationAction::new(
ActionCategory::QuickFix,
ctx.metadata().to_applicability(),
markup! {
"Move the rule to the new stable group."
}
.to_owned(),
category: ActionCategory::QuickFix,
applicability: Applicability::MaybeIncorrect,
})
mutation,
))
}
}

Expand Down
26 changes: 21 additions & 5 deletions crates/biome_service/src/file_handlers/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use biome_parser::AnyParse;
use biome_rowan::{AstNode, BatchMutationExt, Direction, NodeCache};
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::ffi::OsStr;
use std::fmt::Debug;
use std::path::PathBuf;
use tracing::{debug, debug_span, error, info, trace, trace_span};
Expand Down Expand Up @@ -873,13 +874,28 @@ fn compute_analyzer_options(
JsxRuntime::ReactClassic => biome_analyze::options::JsxRuntime::ReactClassic,
};

let mut globals: Vec<_> = settings
.override_settings
.override_js_globals(&path, &settings.languages.javascript.globals)
.into_iter()
.collect();
if file_path.extension().and_then(OsStr::to_str) == Some("vue") {
globals.extend(
[
"defineEmits",
"defineProps",
"defineExpose",
"defineModel",
"defineOptions",
"defineSlots",
]
.map(ToOwned::to_owned),
);
}

let configuration = AnalyzerConfiguration {
rules: to_analyzer_rules(settings, file_path.as_path()),
globals: settings
.override_settings
.override_js_globals(&path, &settings.languages.javascript.globals)
.into_iter()
.collect(),
globals,
preferred_quote,
jsx_runtime: Some(jsx_runtime),
};
Expand Down

0 comments on commit 57ad88c

Please sign in to comment.