-
-
Notifications
You must be signed in to change notification settings - Fork 475
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
719 additions
and
43 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use biome_deserialize::{ | ||
Deserializable, DeserializableType, DeserializableValue, DeserializationDiagnostic, | ||
}; | ||
use biome_deserialize_macros::{Deserializable, Merge}; | ||
use schemars::JsonSchema; | ||
use serde::{Deserialize, Serialize}; | ||
use std::str::FromStr; | ||
|
||
#[derive(Clone, Debug, Default, Deserialize, Deserializable, Eq, Merge, PartialEq, Serialize)] | ||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] | ||
#[serde(rename_all = "camelCase", deny_unknown_fields)] | ||
pub struct Plugins(pub Vec<PluginConfiguration>); | ||
|
||
impl FromStr for Plugins { | ||
type Err = String; | ||
|
||
fn from_str(_s: &str) -> Result<Self, Self::Err> { | ||
Ok(Self::default()) | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] | ||
#[cfg_attr(feature = "schema", derive(JsonSchema))] | ||
#[serde(rename_all = "camelCase", deny_unknown_fields, untagged)] | ||
pub enum PluginConfiguration { | ||
Path(String), | ||
// TODO: PathWithOptions(PluginPathWithOptions), | ||
} | ||
|
||
impl Deserializable for PluginConfiguration { | ||
fn deserialize( | ||
value: &impl DeserializableValue, | ||
rule_name: &str, | ||
diagnostics: &mut Vec<DeserializationDiagnostic>, | ||
) -> Option<Self> { | ||
if value.visitable_type()? == DeserializableType::Str { | ||
Deserializable::deserialize(value, rule_name, diagnostics).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. | ||
// Also, we don't have a way to configure Grit plugins yet. | ||
/*Deserializable::deserialize(value, rule_name, diagnostics) | ||
.map(|plugin| Self::PathWithOptions(plugin))*/ | ||
None | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[package] | ||
authors.workspace = true | ||
categories.workspace = true | ||
description = "Biome plugin loader" | ||
edition.workspace = true | ||
homepage.workspace = true | ||
keywords.workspace = true | ||
license.workspace = true | ||
name = "biome_plugin_loader" | ||
publish = false | ||
repository.workspace = true | ||
version = "0.0.1" | ||
|
||
[dependencies] | ||
biome_analyze = { workspace = true } | ||
biome_console = { workspace = true } | ||
biome_deserialize = { workspace = true } | ||
biome_deserialize_macros = { workspace = true } | ||
biome_diagnostics = { workspace = true } | ||
biome_fs = { workspace = true } | ||
biome_grit_patterns = { workspace = true } | ||
biome_json_parser = { workspace = true } | ||
biome_parser = { workspace = true } | ||
biome_rowan = { workspace = true } | ||
grit-util = { workspace = true } | ||
serde = { workspace = true } | ||
|
||
[dev-dependencies] | ||
insta = { workspace = true } | ||
|
||
[lints] | ||
workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use std::{ | ||
fmt::Debug, | ||
path::{Path, PathBuf}, | ||
rc::Rc, | ||
}; | ||
|
||
use biome_analyze::RuleDiagnostic; | ||
use biome_console::markup; | ||
use biome_diagnostics::category; | ||
use biome_fs::FileSystem; | ||
use biome_grit_patterns::{ | ||
compile_pattern, GritQuery, GritQueryResult, GritTargetFile, GritTargetLanguage, | ||
JsTargetLanguage, | ||
}; | ||
use biome_parser::AnyParse; | ||
use biome_rowan::TextRange; | ||
|
||
use crate::{AnalyzerPlugin, PluginDiagnostic}; | ||
|
||
/// Definition of an analyzer plugin. | ||
#[derive(Clone, Debug)] | ||
pub struct AnalyzerGritPlugin { | ||
grit_query: Rc<GritQuery>, | ||
} | ||
|
||
impl AnalyzerGritPlugin { | ||
pub fn load(fs: &dyn FileSystem, path: &Path) -> Result<Self, PluginDiagnostic> { | ||
let source = fs.read_file_from_path(path)?; | ||
let query = compile_pattern( | ||
&source, | ||
Some(path), | ||
// TODO: Target language should be determined dynamically. | ||
GritTargetLanguage::JsTargetLanguage(JsTargetLanguage), | ||
)?; | ||
|
||
Ok(Self { | ||
grit_query: Rc::new(query), | ||
}) | ||
} | ||
} | ||
|
||
impl AnalyzerPlugin for AnalyzerGritPlugin { | ||
fn evaluate(&self, root: AnyParse, path: PathBuf) -> Vec<RuleDiagnostic> { | ||
let name: &str = self.grit_query.name.as_deref().unwrap_or("anonymous"); | ||
|
||
let file = GritTargetFile { parse: root, path }; | ||
match self.grit_query.execute(file) { | ||
Ok((results, logs)) => results | ||
.into_iter() | ||
.filter_map(|result| match result { | ||
GritQueryResult::Match(match_) => Some(match_), | ||
GritQueryResult::Rewrite(_) | GritQueryResult::CreateFile(_) => None, | ||
}) | ||
.map(|match_| { | ||
RuleDiagnostic::new( | ||
category!("plugin"), | ||
match_ | ||
.ranges | ||
.into_iter() | ||
.next() | ||
.map(RangeExt::to_text_range), | ||
markup!(<Emphasis>{name}</Emphasis>" matched"), | ||
) | ||
}) | ||
.chain(logs.iter().map(|log| { | ||
RuleDiagnostic::new( | ||
category!("plugin"), | ||
log.range.map(RangeExt::to_text_range), | ||
markup!(<Emphasis>{name}</Emphasis>" logged: "<Info>{log.message}</Info>), | ||
) | ||
.verbose() | ||
})) | ||
.collect(), | ||
Err(error) => vec![RuleDiagnostic::new( | ||
category!("plugin"), | ||
None::<TextRange>, | ||
markup!(<Emphasis>{name}</Emphasis>" errored: "<Error>{error.to_string()}</Error>), | ||
)], | ||
} | ||
} | ||
} | ||
|
||
trait RangeExt { | ||
fn to_text_range(self) -> TextRange; | ||
} | ||
|
||
impl RangeExt for grit_util::Range { | ||
fn to_text_range(self) -> TextRange { | ||
TextRange::new(self.start_byte.into(), self.end_byte.into()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use biome_analyze::RuleDiagnostic; | ||
use biome_parser::AnyParse; | ||
use std::{fmt::Debug, path::PathBuf}; | ||
|
||
/// Definition of an analyzer plugin. | ||
pub trait AnalyzerPlugin: Debug { | ||
fn evaluate(&self, root: AnyParse, path: PathBuf) -> Vec<RuleDiagnostic>; | ||
} |
Oops, something went wrong.