Skip to content

Commit

Permalink
Implement plugin loading
Browse files Browse the repository at this point in the history
  • Loading branch information
arendjr committed Feb 19, 2025
1 parent 2357028 commit f52f06b
Show file tree
Hide file tree
Showing 31 changed files with 601 additions and 323 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions crates/biome_analyze/src/analyzer_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use crate::RuleDiagnostic;
use biome_parser::AnyParse;
use camino::Utf8PathBuf;
use std::fmt::Debug;
use std::{fmt::Debug, sync::Arc};

/// Slice of analyzer plugins that can be cheaply cloned.
pub type AnalyzerPluginSlice<'a> = &'a [Arc<Box<dyn AnalyzerPlugin>>];

/// Vector of analyzer plugins that can be cheaply cloned.
pub type AnalyzerPluginVec = Vec<Arc<Box<dyn AnalyzerPlugin>>>;

/// Definition of an analyzer plugin.
pub trait AnalyzerPlugin: Debug {
pub trait AnalyzerPlugin: Debug + Send + Sync {
fn evaluate(&self, root: AnyParse, path: Utf8PathBuf) -> Vec<RuleDiagnostic>;

fn supports_css(&self) -> bool;
Expand Down
7 changes: 4 additions & 3 deletions crates/biome_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use biome_parser::AnyParse;
use std::collections::{BTreeMap, BinaryHeap};
use std::fmt::{Debug, Display, Formatter};
use std::ops;
use std::sync::Arc;

mod analyzer_plugin;
mod categories;
Expand All @@ -25,7 +26,7 @@ mod visitor;
// Re-exported for use in the `declare_group` macro
pub use biome_diagnostics::category_concat;

pub use crate::analyzer_plugin::AnalyzerPlugin;
pub use crate::analyzer_plugin::{AnalyzerPlugin, AnalyzerPluginSlice, AnalyzerPluginVec};
pub use crate::categories::{
ActionCategory, OtherActionCategory, RefactorKind, RuleCategories, RuleCategoriesBuilder,
RuleCategory, SourceActionKind, SUPPRESSION_INLINE_ACTION_CATEGORY,
Expand Down Expand Up @@ -72,7 +73,7 @@ pub struct Analyzer<'analyzer, L: Language, Matcher, Break, Diag> {
/// List of visitors being run by this instance of the analyzer for each phase
phases: BTreeMap<Phases, Vec<Box<dyn Visitor<Language = L> + 'analyzer>>>,
/// Plugins to be run after the phases for built-in rules.
plugins: Vec<Box<dyn AnalyzerPlugin>>,
plugins: AnalyzerPluginVec,
/// Holds the metadata for all the rules statically known to the analyzer
metadata: &'analyzer MetadataRegistry,
/// Executor for the query matches emitted by the visitors
Expand Down Expand Up @@ -128,7 +129,7 @@ where
}

/// Registers an [AnalyzerPlugin] to be executed after the regular phases.
pub fn add_plugin(&mut self, plugin: Box<dyn AnalyzerPlugin>) {
pub fn add_plugin(&mut self, plugin: Arc<Box<dyn AnalyzerPlugin>>) {
self.plugins.push(plugin);
}

Expand Down
5 changes: 4 additions & 1 deletion crates/biome_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,13 +801,16 @@ pub(crate) trait CommandRunner: Sized {
open_uninitialized: true,
})?;

workspace.update_settings(UpdateSettingsParams {
let result = workspace.update_settings(UpdateSettingsParams {
project_key,
workspace_directory: configuration_path.map(BiomePath::from),
configuration,
vcs_base_path: vcs_base_path.map(BiomePath::from),
gitignore_matches,
})?;
for diagnostic in result.diagnostics {
console.log(markup! {{PrintDiagnostic::simple(&diagnostic)}});
}

let execution = self.get_execution(cli_options, console, workspace, project_key)?;

Expand Down
11 changes: 9 additions & 2 deletions crates/biome_configuration/src/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ use std::str::FromStr;
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct Plugins(pub Vec<PluginConfiguration>);

impl Plugins {
pub fn iter(&self) -> impl Iterator<Item = &PluginConfiguration> {
self.0.iter()
}
}

impl FromStr for Plugins {
type Err = String;

Expand All @@ -36,8 +42,9 @@ impl Deserializable for PluginConfiguration {
Deserializable::deserialize(ctx, value, rule_name).map(Self::Path)
} else {
// TODO: Fix this to allow plugins to receive options.
// Difficulty is that we need a `Deserializable` implementation
// for `serde_json::Value`, since plugin options are untyped.
// We probably need to pass them as `AnyJsonValue` or
// `biome_json_value::JsonValue`, since plugin options are
// untyped.
// Also, we don't have a way to configure Grit plugins yet.
/*Deserializable::deserialize(value, rule_name, diagnostics)
.map(|plugin| Self::PathWithOptions(plugin))*/
Expand Down
18 changes: 9 additions & 9 deletions crates/biome_css_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod utils;
pub use crate::registry::visit_registry;
use crate::suppression_action::CssSuppressionAction;
use biome_analyze::{
to_analyzer_suppressions, AnalysisFilter, AnalyzerOptions, AnalyzerPlugin, AnalyzerSignal,
to_analyzer_suppressions, AnalysisFilter, AnalyzerOptions, AnalyzerPluginSlice, AnalyzerSignal,
AnalyzerSuppression, ControlFlow, LanguageRoot, MatchQueryParams, MetadataRegistry, RuleAction,
RuleRegistry,
};
Expand All @@ -36,7 +36,7 @@ pub fn analyze<'a, F, B>(
root: &LanguageRoot<CssLanguage>,
filter: AnalysisFilter,
options: &'a AnalyzerOptions,
plugins: Vec<Box<dyn AnalyzerPlugin>>,
plugins: AnalyzerPluginSlice<'a>,
emit_signal: F,
) -> (Option<B>, Vec<Error>)
where
Expand All @@ -57,7 +57,7 @@ pub fn analyze_with_inspect_matcher<'a, V, F, B>(
filter: AnalysisFilter,
inspect_matcher: V,
options: &'a AnalyzerOptions,
plugins: Vec<Box<dyn AnalyzerPlugin>>,
plugins: AnalyzerPluginSlice<'a>,
mut emit_signal: F,
) -> (Option<B>, Vec<Error>)
where
Expand Down Expand Up @@ -111,7 +111,7 @@ where

for plugin in plugins {
if plugin.supports_css() {
analyzer.add_plugin(plugin);
analyzer.add_plugin(plugin.clone());
}
}

Expand Down Expand Up @@ -189,7 +189,7 @@ mod tests {
..AnalysisFilter::default()
},
&options,
Vec::new(),
&[],
|signal| {
if let Some(diag) = signal.diagnostic() {
error_ranges.push(diag.location().span.unwrap());
Expand Down Expand Up @@ -234,7 +234,7 @@ mod tests {
};

let options = AnalyzerOptions::default();
analyze(&parsed.tree(), filter, &options, Vec::new(), |signal| {
analyze(&parsed.tree(), filter, &options, &[], |signal| {
if let Some(diag) = signal.diagnostic() {
let error = diag
.with_file_path("dummyFile")
Expand Down Expand Up @@ -274,7 +274,7 @@ a {
};

let options = AnalyzerOptions::default();
analyze(&parsed.tree(), filter, &options, Vec::new(), |signal| {
analyze(&parsed.tree(), filter, &options, &[], |signal| {
if let Some(diag) = signal.diagnostic() {
let error = diag
.with_file_path("dummyFile")
Expand Down Expand Up @@ -310,7 +310,7 @@ a {
};

let options = AnalyzerOptions::default();
analyze(&parsed.tree(), filter, &options, Vec::new(), |signal| {
analyze(&parsed.tree(), filter, &options, &[], |signal| {
if let Some(diag) = signal.diagnostic() {
let error = diag
.with_file_path("dummyFile")
Expand Down Expand Up @@ -343,7 +343,7 @@ a {
};

let options = AnalyzerOptions::default();
analyze(&parsed.tree(), filter, &options, Vec::new(), |signal| {
analyze(&parsed.tree(), filter, &options, &[], |signal| {
if let Some(diag) = signal.diagnostic() {
let code = diag.category().unwrap();
if code != category!("suppressions/unused") {
Expand Down
13 changes: 7 additions & 6 deletions crates/biome_css_analyze/tests/spec_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use biome_analyze::{
AnalysisFilter, AnalyzerAction, AnalyzerPlugin, ControlFlow, Never, RuleFilter,
AnalysisFilter, AnalyzerAction, AnalyzerPluginSlice, ControlFlow, Never, RuleFilter,
};
use biome_css_parser::{parse_css, CssParserOptions};
use biome_css_syntax::{CssFileSource, CssLanguage};
Expand All @@ -14,6 +14,7 @@ use biome_test_utils::{
};
use camino::Utf8Path;
use std::ops::Deref;
use std::sync::Arc;
use std::{fs::read_to_string, slice};

tests_macros::gen_tests! {"tests/specs/**/*.{css,json,jsonc}", crate::run_test, "module"}
Expand Down Expand Up @@ -72,7 +73,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
input_file,
CheckActionType::Lint,
parser_options,
Vec::new(),
&[],
);
}

Expand All @@ -90,7 +91,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
input_file,
CheckActionType::Lint,
parser_options,
Vec::new(),
&[],
)
};

Expand All @@ -116,7 +117,7 @@ pub(crate) fn analyze_and_snap(
input_file: &Utf8Path,
check_action_type: CheckActionType,
parser_options: CssParserOptions,
plugins: Vec<Box<dyn AnalyzerPlugin>>,
plugins: AnalyzerPluginSlice,
) -> usize {
let parsed = parse_css(input_code, parser_options);
let root = parsed.tree();
Expand Down Expand Up @@ -241,7 +242,7 @@ pub(crate) fn run_suppression_test(input: &'static str, _: &str, _: &str, _: &st
input_file,
CheckActionType::Suppression,
CssParserOptions::default(),
Vec::new(),
&[],
);

insta::with_settings!({
Expand Down Expand Up @@ -288,7 +289,7 @@ fn run_plugin_test(input: &'static str, _: &str, _: &str, _: &str) {
&input_path,
CheckActionType::Lint,
CssParserOptions::default(),
vec![Box::new(plugin)],
&[Arc::new(Box::new(plugin))],
);

insta::with_settings!({
Expand Down
Loading

0 comments on commit f52f06b

Please sign in to comment.