Skip to content

Commit

Permalink
fix(linter): correctly override linter presets
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Jan 19, 2024
1 parent 44ebe0c commit 7643adb
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 118 deletions.
29 changes: 0 additions & 29 deletions crates/biome_service/src/configuration/linter/rules.rs

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

70 changes: 24 additions & 46 deletions crates/biome_service/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
configuration::FilesConfiguration, Configuration, ConfigurationDiagnostic, Matcher, Rules,
WorkspaceError,
};
use biome_analyze::{AnalyzerRules, RuleFilter};
use biome_analyze::AnalyzerRules;
use biome_css_formatter::context::CssFormatOptions;
use biome_css_parser::CssParserOptions;
use biome_css_syntax::CssLanguage;
Expand All @@ -25,7 +25,7 @@ use biome_json_formatter::context::JsonFormatOptions;
use biome_json_parser::JsonParserOptions;
use biome_json_syntax::JsonLanguage;
use indexmap::IndexSet;
use std::ops::{BitOr, Sub};
use std::borrow::Cow;
use std::path::{Path, PathBuf};
use std::{
num::NonZeroU64,
Expand Down Expand Up @@ -175,13 +175,26 @@ impl WorkspaceSettings {
}
}

/// Returns rules
pub fn as_rules(&self, path: &Path) -> Option<Rules> {
/// Returns rules taking overrides into account.
pub fn as_rules(&self, path: &Path) -> Option<Cow<Rules>> {
let mut result = self.linter.rules.as_ref().map(Cow::Borrowed);
let overrides = &self.override_settings;
self.linter
.rules
.as_ref()
.map(|rules| overrides.override_as_rules(path, rules.clone()))
for pattern in overrides.patterns.iter() {
let excluded = pattern.exclude.matches_path(path);
if !excluded && !pattern.include.is_empty() && pattern.include.matches_path(path) {
let pattern_rules = pattern.linter.rules.as_ref();
if let Some(pattern_rules) = pattern_rules {
result = if let Some(mut result) = result.take() {
// Override rules
result.to_mut().merge_with(pattern_rules.clone());
Some(result)
} else {
Some(Cow::Borrowed(pattern_rules))
};
}
}
}
result
}
}

Expand Down Expand Up @@ -758,45 +771,10 @@ impl OverrideSettings {
})
}

/// Retrieves the enabled rules that match the given `path`
pub fn overrides_enabled_rules<'a>(
&'a self,
path: &Path,
rules: IndexSet<RuleFilter<'a>>,
) -> IndexSet<RuleFilter> {
self.patterns.iter().fold(rules, move |mut rules, pattern| {
let excluded = !pattern.exclude.is_empty() && pattern.exclude.matches_path(path);
if !excluded && !pattern.include.is_empty() && pattern.include.matches_path(path) {
if let Some(pattern_rules) = pattern.linter.rules.as_ref() {
let disabled_rules = pattern_rules.as_disabled_rules();
let enabled_rules = pattern_rules.as_enabled_rules();

rules = rules.bitor(&enabled_rules).sub(&disabled_rules);
}
}

rules
})
}

pub fn override_as_rules(&self, path: &Path, rules: Rules) -> Rules {
self.patterns.iter().fold(rules, |mut rules, pattern| {
let excluded = !pattern.exclude.is_empty() && pattern.exclude.matches_path(path);
if !excluded && !pattern.include.is_empty() && pattern.include.matches_path(path) {
let pattern_rules = pattern.linter.rules.as_ref();
if let Some(patter_rules) = pattern_rules {
rules.merge_with(patter_rules.clone())
}
}

rules
})
}

/// Scans the overrides and checks if there's an override that disable the formatter for `path`
pub fn formatter_disabled(&self, path: &Path) -> Option<bool> {
for pattern in &self.patterns {
if !pattern.exclude.is_empty() && pattern.exclude.matches_path(path) {
if pattern.exclude.matches_path(path) {
continue;
}
if !pattern.include.is_empty() && pattern.include.matches_path(path) {
Expand All @@ -812,7 +790,7 @@ impl OverrideSettings {
/// Scans the overrides and checks if there's an override that disable the linter for `path`
pub fn linter_disabled(&self, path: &Path) -> Option<bool> {
for pattern in &self.patterns {
if !pattern.exclude.is_empty() && pattern.exclude.matches_path(path) {
if pattern.exclude.matches_path(path) {
continue;
}
if !pattern.include.is_empty() && pattern.include.matches_path(path) {
Expand All @@ -828,7 +806,7 @@ impl OverrideSettings {
/// Scans the overrides and checks if there's an override that disable the organize imports for `path`
pub fn organize_imports_disabled(&self, path: &Path) -> Option<bool> {
for pattern in &self.patterns {
if !pattern.exclude.is_empty() && pattern.exclude.matches_path(path) {
if pattern.exclude.matches_path(path) {
continue;
}
if !pattern.include.is_empty() && pattern.include.matches_path(path) {
Expand Down
47 changes: 19 additions & 28 deletions crates/biome_service/src/workspace/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ use super::{
};
use crate::file_handlers::{Capabilities, FixAllParams, Language, LintParams};
use crate::project_handlers::{ProjectCapabilities, ProjectHandlers};
use crate::settings::OverrideSettings;
use crate::workspace::{
FileFeaturesResult, GetFileContentParams, IsPathIgnoredParams, OrganizeImportsParams,
OrganizeImportsResult, RageEntry, RageParams, RageResult, ServerInfo,
};
use crate::{
file_handlers::Features,
settings::{SettingsHandle, WorkspaceSettings},
Rules, Workspace, WorkspaceError,
Workspace, WorkspaceError,
};
use biome_analyze::{AnalysisFilter, RuleFilter};
use biome_diagnostics::{
Expand All @@ -26,6 +25,7 @@ use biome_fs::{RomePath, BIOME_JSON};
use biome_parser::AnyParse;
use biome_rowan::NodeCache;
use dashmap::{mapref::entry::Entry, DashMap};
use std::borrow::Borrow;
use std::ffi::OsStr;
use std::path::Path;
use std::{panic::RefUnwindSafe, sync::RwLock};
Expand Down Expand Up @@ -131,22 +131,6 @@ impl WorkspaceServer {
}
}

fn build_rule_filter_list<'a>(
&'a self,
rules: Option<&'a Rules>,
overrides: &'a OverrideSettings,
path: &'a Path,
) -> Vec<RuleFilter> {
let enabled_rules =
rules.map(|rules| overrides.overrides_enabled_rules(path, rules.as_enabled_rules()));

if let Some(enabled_rules) = enabled_rules {
enabled_rules.into_iter().collect::<Vec<RuleFilter>>()
} else {
vec![]
}
}

/// Get the parser result for a given file
///
/// Returns and error if no file exists in the workspace with this path or
Expand Down Expand Up @@ -438,10 +422,14 @@ impl Workspace for WorkspaceServer {
let (diagnostics, errors, skipped_diagnostics) = if let Some(lint) =
self.get_file_capabilities(&params.path).analyzer.lint
{
let rules = settings.linter().rules.as_ref();
let overrides = &settings.override_settings;
let mut rule_filter_list =
self.build_rule_filter_list(rules, overrides, params.path.as_path());
// Compite final rules (taking `overrides` into account)
let rules = settings.as_rules(params.path.as_path());
let mut rule_filter_list = rules
.as_ref()
.map(|rules| rules.as_enabled_rules())
.unwrap_or_default()
.into_iter()
.collect::<Vec<_>>();
if settings.organize_imports.enabled && !params.categories.is_syntax() {
rule_filter_list.push(RuleFilter::Rule("correctness", "organizeImports"));
}
Expand All @@ -454,7 +442,7 @@ impl Workspace for WorkspaceServer {
let results = lint(LintParams {
parse,
filter,
rules,
rules: rules.as_ref().map(|x| x.borrow()),
settings: self.settings(),
max_diagnostics: params.max_diagnostics,
path: &params.path,
Expand Down Expand Up @@ -571,15 +559,18 @@ impl Workspace for WorkspaceServer {
.ok_or_else(self.build_capability_error(&params.path))?;
let settings = self.settings.read().unwrap();
let parse = self.get_parse(params.path.clone(), Some(FeatureName::Lint))?;

// Compite final rules (taking `overrides` into account)
let rules = settings.as_rules(params.path.as_path());
let overrides = &settings.override_settings;
let rule_filter_list =
self.build_rule_filter_list(rules.as_ref(), overrides, params.path.as_path());
let rule_filter_list = rules
.as_ref()
.map(|rules| rules.as_enabled_rules())
.unwrap_or_default()
.into_iter()
.collect::<Vec<_>>();
let filter = AnalysisFilter::from_enabled_rules(Some(rule_filter_list.as_slice()));
fix_all(FixAllParams {
parse,
rules: rules.as_ref(),
rules: rules.as_ref().map(|x| x.borrow()),
fix_file_mode: params.fix_file_mode,
filter,
settings: self.settings(),
Expand Down
15 changes: 0 additions & 15 deletions xtask/codegen/src/generate_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> {
let mut line_groups = Vec::new();
let mut default_for_groups = Vec::new();
let mut group_as_default_rules = Vec::new();
let mut group_as_disabled_rules = Vec::new();
let mut group_match_code = Vec::new();
let mut group_get_severity = Vec::new();
let mut group_name_list = vec!["recommended", "all"];
Expand Down Expand Up @@ -112,12 +111,6 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> {
}
});

group_as_disabled_rules.push(quote! {
if let Some(group) = self.#property_group_name.as_ref() {
disabled_rules.extend(&group.get_disabled_rules());
}
});

group_get_severity.push(quote! {
#group => self
.#property_group_name
Expand Down Expand Up @@ -265,14 +258,6 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> {

enabled_rules.difference(&disabled_rules).copied().collect()
}

/// It returns only the disabled rules
pub fn as_disabled_rules(&self) -> IndexSet<RuleFilter> {
let mut disabled_rules = IndexSet::new();
#( #group_as_disabled_rules )*

disabled_rules
}
}

#( #struct_groups )*
Expand Down

0 comments on commit 7643adb

Please sign in to comment.