Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(analyzer): use enumflags2 #3230

Merged
merged 3 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion crates/biome_analyze/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ biome_deserialize = { workspace = true, optional = true }
biome_deserialize_macros = { workspace = true, optional = true }
biome_diagnostics = { workspace = true }
biome_rowan = { workspace = true }
bitflags = { workspace = true }
enumflags2 = { workspace = true }
rustc-hash = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"], optional = true }
Expand Down
106 changes: 87 additions & 19 deletions crates/biome_analyze/src/categories.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use enumflags2::{bitflags, BitFlags};
use std::borrow::Cow;

use bitflags::bitflags;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "serde",
Expand Down Expand Up @@ -172,13 +171,38 @@ pub enum SourceActionKind {
Other(Cow<'static, str>),
}

bitflags! {
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct RuleCategories: u8 {
const SYNTAX = 1 << RuleCategory::Syntax as u8;
const LINT = 1 << RuleCategory::Lint as u8;
const ACTION = 1 << RuleCategory::Action as u8;
const TRANSFORMATION = 1 << RuleCategory::Transformation as u8;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[bitflags]
#[repr(u8)]
pub(crate) enum Categories {
Syntax = 1 << RuleCategory::Syntax as u8,
Lint = 1 << RuleCategory::Lint as u8,
Action = 1 << RuleCategory::Action as u8,
Transformation = 1 << RuleCategory::Transformation as u8,
}

#[derive(Debug, Copy, Clone)]
/// The categories supported by the analyzer.
///
/// The default implementation of this type returns an instance with all the categories.
///
/// Use [RuleCategoriesBuilder] to generate the categories you want to query.
pub struct RuleCategories(BitFlags<Categories>);

impl RuleCategories {
pub fn empty() -> Self {
let empty: BitFlags<Categories> = BitFlags::empty();
Self(empty)
}

pub fn all() -> Self {
let empty: BitFlags<Categories> = BitFlags::all();
Self(empty)
}

/// Checks whether the current categories contain a specific [RuleCategories]
pub fn contains(&self, other: impl Into<RuleCategories>) -> bool {
self.0.contains(other.into().0)
}
}

Expand All @@ -190,17 +214,19 @@ impl Default for RuleCategories {

impl RuleCategories {
pub fn is_syntax(&self) -> bool {
*self == RuleCategories::SYNTAX
self.0.contains(Categories::Syntax)
}
}

impl From<RuleCategory> for RuleCategories {
fn from(input: RuleCategory) -> Self {
match input {
RuleCategory::Syntax => RuleCategories::SYNTAX,
RuleCategory::Lint => RuleCategories::LINT,
RuleCategory::Action => RuleCategories::ACTION,
RuleCategory::Transformation => RuleCategories::TRANSFORMATION,
RuleCategory::Syntax => RuleCategories(BitFlags::from_flag(Categories::Syntax)),
RuleCategory::Lint => RuleCategories(BitFlags::from_flag(Categories::Lint)),
RuleCategory::Action => RuleCategories(BitFlags::from_flag(Categories::Action)),
RuleCategory::Transformation => {
RuleCategories(BitFlags::from_flag(Categories::Transformation))
}
}
}
}
Expand All @@ -213,19 +239,19 @@ impl serde::Serialize for RuleCategories {
{
let mut flags = Vec::new();

if self.contains(Self::SYNTAX) {
if self.0.contains(Categories::Syntax) {
flags.push(RuleCategory::Syntax);
}

if self.contains(Self::LINT) {
if self.0.contains(Categories::Lint) {
flags.push(RuleCategory::Lint);
}

if self.contains(Self::ACTION) {
if self.0.contains(Categories::Action) {
flags.push(RuleCategory::Action);
}

if self.contains(Self::TRANSFORMATION) {
if self.0.contains(Categories::Transformation) {
flags.push(RuleCategory::Transformation);
}

Expand Down Expand Up @@ -258,7 +284,7 @@ impl<'de> serde::Deserialize<'de> for RuleCategories {
let mut result = RuleCategories::empty();

while let Some(item) = seq.next_element::<RuleCategory>()? {
result |= RuleCategories::from(item);
result.0 |= RuleCategories::from(item).0;
}

Ok(result)
Expand All @@ -279,3 +305,45 @@ impl schemars::JsonSchema for RuleCategories {
<Vec<RuleCategory>>::json_schema(gen)
}
}

#[derive(Debug, Default)]
/// A convenient type create a [RuleCategories] type
///
/// ```
/// use biome_analyze::{RuleCategoriesBuilder, RuleCategory};
/// let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint().build();
///
/// assert!(categories.contains(RuleCategory::Lint));
/// assert!(categories.contains(RuleCategory::Syntax));
/// assert!(!categories.contains(RuleCategory::Action));
/// assert!(!categories.contains(RuleCategory::Transformation));
/// ```
pub struct RuleCategoriesBuilder {
flags: BitFlags<Categories>,
}

impl RuleCategoriesBuilder {
pub fn with_syntax(mut self) -> Self {
self.flags.insert(Categories::Syntax);
self
}

pub fn with_lint(mut self) -> Self {
self.flags.insert(Categories::Lint);
self
}

pub fn with_action(mut self) -> Self {
self.flags.insert(Categories::Action);
self
}

pub fn with_transformation(mut self) -> Self {
self.flags.insert(Categories::Transformation);
self
}

pub fn build(self) -> RuleCategories {
RuleCategories(self.flags)
}
}
5 changes: 3 additions & 2 deletions crates/biome_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ mod visitor;
pub use biome_diagnostics::category_concat;

pub use crate::categories::{
ActionCategory, RefactorKind, RuleCategories, RuleCategory, SourceActionKind,
ActionCategory, RefactorKind, RuleCategories, RuleCategoriesBuilder, RuleCategory,
SourceActionKind,
};
pub use crate::diagnostics::AnalyzerDiagnostic;
pub use crate::diagnostics::SuppressionDiagnostic;
Expand Down Expand Up @@ -885,7 +886,7 @@ impl<'analysis> AnalysisFilter<'analysis> {

/// Return `true` if the category `C` matches this filter
pub fn match_category<C: GroupCategory>(&self) -> bool {
self.categories.contains(C::CATEGORY.into())
self.categories.contains(C::CATEGORY)
}

/// Return `true` if the group `G` matches this filter
Expand Down
4 changes: 2 additions & 2 deletions crates/biome_cli/src/execute/process_file/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use crate::execute::process_file::{
DiffKind, FileResult, FileStatus, Message, SharedTraversalOptions,
};
use crate::execute::TraversalMode;
use biome_analyze::RuleCategoriesBuilder;
use biome_diagnostics::{category, Diagnostic, DiagnosticExt, Error, Severity};
use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler};
use biome_service::workspace::RuleCategories;
use std::path::Path;
use std::sync::atomic::Ordering;
use tracing::debug;
Expand All @@ -27,7 +27,7 @@ pub(crate) fn format_with_guard<'ctx>(
let diagnostics_result = workspace_file
.guard()
.pull_diagnostics(
RuleCategories::SYNTAX,
RuleCategoriesBuilder::default().with_syntax().build(),
max_diagnostics.into(),
Vec::new(),
Vec::new(),
Expand Down
7 changes: 5 additions & 2 deletions crates/biome_cli/src/execute/process_file/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use crate::execute::diagnostics::ResultExt;
use crate::execute::process_file::workspace_file::WorkspaceFile;
use crate::execute::process_file::{FileResult, FileStatus, Message, SharedTraversalOptions};
use crate::TraversalMode;
use biome_analyze::RuleCategoriesBuilder;
use biome_diagnostics::{category, Error};
use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler};
use biome_service::workspace::RuleCategories;
use std::path::Path;
use std::sync::atomic::Ordering;

Expand Down Expand Up @@ -66,7 +66,10 @@ pub(crate) fn lint_with_guard<'ctx>(
let pull_diagnostics_result = workspace_file
.guard()
.pull_diagnostics(
RuleCategories::LINT | RuleCategories::SYNTAX,
RuleCategoriesBuilder::default()
.with_syntax()
.with_lint()
.build(),
max_diagnostics.into(),
only,
skip,
Expand Down
9 changes: 6 additions & 3 deletions crates/biome_cli/src/execute/std_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
use crate::execute::diagnostics::{ContentDiffAdvice, FormatDiffDiagnostic};
use crate::execute::Execution;
use crate::{CliDiagnostic, CliSession, TraversalMode};
use biome_analyze::RuleCategoriesBuilder;
use biome_console::{markup, ConsoleExt};
use biome_diagnostics::PrintDiagnostic;
use biome_diagnostics::{Diagnostic, DiagnosticExt, Error};
use biome_fs::BiomePath;
use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler};
use biome_service::workspace::{
ChangeFileParams, DropPatternParams, FeaturesBuilder, FixFileParams, FormatFileParams,
OpenFileParams, OrganizeImportsParams, PullDiagnosticsParams, RuleCategories,
SupportsFeatureParams,
OpenFileParams, OrganizeImportsParams, PullDiagnosticsParams, SupportsFeatureParams,
};
use biome_service::WorkspaceError;
use std::borrow::Cow;
Expand Down Expand Up @@ -163,7 +163,10 @@ pub(crate) fn run<'a>(
};
if !mode.is_check_apply_unsafe() {
let result = workspace.pull_diagnostics(PullDiagnosticsParams {
categories: RuleCategories::LINT | RuleCategories::SYNTAX,
categories: RuleCategoriesBuilder::default()
.with_lint()
.with_syntax()
.build(),
path: biome_path.clone(),
max_diagnostics: mode.max_diagnostics.into(),
only,
Expand Down
1 change: 0 additions & 1 deletion crates/biome_grit_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ biome_grit_factory = { workspace = true }
biome_grit_syntax = { workspace = true }
biome_parser = { workspace = true }
biome_rowan = { workspace = true }
bitflags = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions crates/biome_js_analyze/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl Error for RuleError {}
#[cfg(test)]
mod tests {
use biome_analyze::options::RuleOptions;
use biome_analyze::{AnalyzerOptions, Never, RuleCategories, RuleFilter, RuleKey};
use biome_analyze::{AnalyzerOptions, Never, RuleCategoriesBuilder, RuleFilter, RuleKey};
use biome_console::fmt::{Formatter, Termcolor};
use biome_console::{markup, Markup};
use biome_diagnostics::category;
Expand Down Expand Up @@ -451,7 +451,7 @@ mod tests {
);

let filter = AnalysisFilter {
categories: RuleCategories::SYNTAX,
categories: RuleCategoriesBuilder::default().with_syntax().build(),
..AnalysisFilter::default()
};

Expand Down
6 changes: 4 additions & 2 deletions crates/biome_js_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub(crate) type JsBatchMutation = BatchMutation<JsLanguage>;

#[cfg(test)]
mod tests {
use biome_analyze::{AnalyzerOptions, Never, RuleCategories, RuleFilter};
use biome_analyze::{AnalyzerOptions, Never, RuleCategoriesBuilder, RuleFilter};
use biome_js_parser::{parse, JsParserOptions};
use biome_js_syntax::JsFileSource;
use std::slice;
Expand All @@ -140,7 +140,9 @@ mod tests {
transform(
&parsed.tree(),
AnalysisFilter {
categories: RuleCategories::TRANSFORMATION,
categories: RuleCategoriesBuilder::default()
.with_transformation()
.build(),
enabled_rules: Some(slice::from_ref(&rule_filter)),
..AnalysisFilter::default()
},
Expand Down
10 changes: 5 additions & 5 deletions crates/biome_lsp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::extension_settings::ExtensionSettings;
use crate::extension_settings::CONFIGURATION_SECTION;
use crate::utils;
use anyhow::Result;
use biome_analyze::RuleCategories;
use biome_analyze::RuleCategoriesBuilder;
use biome_configuration::ConfigurationPathHint;
use biome_console::markup;
use biome_diagnostics::PrintDescription;
Expand Down Expand Up @@ -316,18 +316,18 @@ impl Session {
})?;

let diagnostics: Vec<Diagnostic> = {
let mut categories = RuleCategories::SYNTAX;
let mut categories = RuleCategoriesBuilder::default().with_syntax();
if self.configuration_status().is_loaded() {
if file_features.supports_lint() {
categories |= RuleCategories::LINT
categories = categories.with_lint();
}
if file_features.supports_organize_imports() {
categories |= RuleCategories::ACTION
categories = categories.with_action();
}
}
let result = self.workspace.pull_diagnostics(PullDiagnosticsParams {
path: biome_path.clone(),
categories,
categories: categories.build(),
max_diagnostics: u64::MAX,
only: Vec::new(),
skip: Vec::new(),
Expand Down
10 changes: 6 additions & 4 deletions crates/biome_service/src/file_handlers/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use crate::workspace::{
use crate::WorkspaceError;
use biome_analyze::options::PreferredQuote;
use biome_analyze::{
AnalysisFilter, AnalyzerConfiguration, AnalyzerOptions, ControlFlow, Never, RuleCategories,
AnalysisFilter, AnalyzerConfiguration, AnalyzerOptions, ControlFlow, Never,
RuleCategoriesBuilder, RuleCategory,
};
use biome_css_analyze::analyze;
use biome_css_formatter::context::CssFormatOptions;
Expand Down Expand Up @@ -386,7 +387,7 @@ fn lint(params: LintParams) -> LintResults {
// - it is a syntax-only analyzer pass, or
// - if a single rule is run.
let ignores_suppression_comment =
!filter.categories.contains(RuleCategories::LINT) || has_only_filter;
!filter.categories.contains(RuleCategory::Lint) || has_only_filter;

let mut diagnostic_count = diagnostics.len() as u32;
let mut errors = diagnostics
Expand Down Expand Up @@ -488,10 +489,11 @@ pub(crate) fn code_actions(params: CodeActionsParams) -> PullActionsResult {

let mut filter = AnalysisFilter::from_enabled_rules(filter.as_slice());

filter.categories = RuleCategories::SYNTAX | RuleCategories::LINT;
let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint();
if settings.organize_imports.enabled {
filter.categories |= RuleCategories::ACTION;
categories = categories.with_action();
}
filter.categories = categories.build();
filter.range = Some(range);

let analyzer_options = workspace.analyzer_options::<CssLanguage>(path, &language);
Expand Down
Loading
Loading