#[cfg(not(target_arch = "wasm32"))]
use super::corsa_session::CorsaTypeAwareSession;
use crate::{
diagnostic::{HelpLevel, LintDiagnostic},
preset::{builtin_script_rule_names, LintPreset},
rule::RuleRegistry,
};
#[cfg(not(target_arch = "wasm32"))]
use std::sync::Mutex;
use vize_carton::{i18n::Locale, FxHashSet, String};
#[derive(Debug, Clone)]
pub struct LintResult {
pub filename: String,
pub diagnostics: Vec<LintDiagnostic>,
pub error_count: usize,
pub warning_count: usize,
}
impl LintResult {
#[inline]
pub fn has_errors(&self) -> bool {
self.error_count > 0
}
#[inline]
pub fn has_diagnostics(&self) -> bool {
!self.diagnostics.is_empty()
}
}
pub struct Linter {
pub(crate) preset: Option<LintPreset>,
pub(crate) registry: RuleRegistry,
pub(crate) initial_capacity: usize,
pub(crate) locale: Locale,
pub(crate) enabled_rules: Option<FxHashSet<String>>,
pub(crate) help_level: HelpLevel,
pub(crate) script_rules: &'static [&'static str],
#[cfg(not(target_arch = "wasm32"))]
pub(crate) native_corsa: Mutex<Option<CorsaTypeAwareSession>>,
}
impl Linter {
pub(crate) const DEFAULT_INITIAL_CAPACITY: usize = 64 * 1024;
#[inline]
pub fn new() -> Self {
let preset = LintPreset::default();
Self {
preset: Some(preset),
registry: RuleRegistry::with_preset(preset),
initial_capacity: Self::DEFAULT_INITIAL_CAPACITY,
locale: Locale::default(),
enabled_rules: None,
help_level: HelpLevel::default(),
script_rules: builtin_script_rule_names(preset),
#[cfg(not(target_arch = "wasm32"))]
native_corsa: Mutex::new(None),
}
}
#[inline]
pub fn with_preset(preset: LintPreset) -> Self {
Self {
preset: Some(preset),
registry: RuleRegistry::with_preset(preset),
initial_capacity: Self::DEFAULT_INITIAL_CAPACITY,
locale: Locale::default(),
enabled_rules: None,
help_level: HelpLevel::default(),
script_rules: builtin_script_rule_names(preset),
#[cfg(not(target_arch = "wasm32"))]
native_corsa: Mutex::new(None),
}
}
#[inline]
pub fn with_registry(registry: RuleRegistry) -> Self {
Self {
preset: None,
registry,
initial_capacity: Self::DEFAULT_INITIAL_CAPACITY,
locale: Locale::default(),
enabled_rules: None,
help_level: HelpLevel::default(),
script_rules: &[],
#[cfg(not(target_arch = "wasm32"))]
native_corsa: Mutex::new(None),
}
}
#[inline]
pub fn with_capacity(mut self, capacity: usize) -> Self {
self.initial_capacity = capacity;
self
}
#[inline]
pub fn with_locale(mut self, locale: Locale) -> Self {
self.locale = locale;
self
}
#[inline]
pub fn with_enabled_rules(mut self, rules: Option<Vec<String>>) -> Self {
if rules.is_some() && matches!(self.preset, Some(LintPreset::Incremental)) {
self.registry = RuleRegistry::with_preset(LintPreset::Opinionated);
self.script_rules = builtin_script_rule_names(LintPreset::Opinionated);
}
self.enabled_rules = rules.map(|r| r.into_iter().collect());
self
}
#[inline]
pub fn with_help_level(mut self, level: HelpLevel) -> Self {
self.help_level = level;
self
}
#[inline]
pub fn locale(&self) -> Locale {
self.locale
}
#[inline]
pub fn is_rule_enabled(&self, rule_name: &str) -> bool {
match &self.enabled_rules {
Some(set) => set.contains(rule_name),
None => true,
}
}
#[inline]
pub fn registry(&self) -> &RuleRegistry {
&self.registry
}
#[inline]
pub fn rules(&self) -> &[Box<dyn crate::rule::Rule>] {
self.registry.rules()
}
}
impl Default for Linter {
fn default() -> Self {
Self::new()
}
}