mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
refactor(css/lints): Simplify error reporting API (#3781)
This commit is contained in:
parent
bfc31c4bd1
commit
b8211da1c9
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::rules::{
|
||||
at_rule_no_unknown::AtRuleNoUnknownConfig, color_hex_length::ColorHexLengthConfig,
|
||||
no_invalid_position_at_import_rule::NoInvalidPositionAtImportRuleConfig,
|
||||
unit_no_unknown::UnitNoUnknownConfig,
|
||||
selector_max_class::SelectorMaxClassConfig, unit_no_unknown::UnitNoUnknownConfig,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
@ -64,10 +64,6 @@ impl<T: Debug + Clone + Serialize + Default> RuleConfig<T> {
|
||||
pub(crate) fn get_rule_config(&self) -> &T {
|
||||
&self.1
|
||||
}
|
||||
|
||||
pub(crate) fn is_enabled(&self) -> bool {
|
||||
!matches!(self.get_rule_reaction(), LintRuleReaction::Off)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
@ -93,7 +89,7 @@ pub struct RulesConfig {
|
||||
pub no_invalid_position_at_import_rule: RuleConfig<NoInvalidPositionAtImportRuleConfig>,
|
||||
|
||||
#[serde(default, alias = "selectorMaxClass")]
|
||||
pub selector_max_class: RuleConfig<Option<usize>>,
|
||||
pub selector_max_class: RuleConfig<SelectorMaxClassConfig>,
|
||||
|
||||
#[serde(default, alias = "colorHexLength")]
|
||||
pub color_hex_length: RuleConfig<ColorHexLengthConfig>,
|
||||
|
@ -3,10 +3,16 @@ use std::{fmt::Debug, sync::Arc};
|
||||
use auto_impl::auto_impl;
|
||||
use parking_lot::Mutex;
|
||||
use rayon::prelude::*;
|
||||
use swc_common::errors::{Diagnostic, DiagnosticBuilder, Emitter, Handler, HANDLER};
|
||||
use serde::Serialize;
|
||||
use swc_common::{
|
||||
errors::{Diagnostic, DiagnosticBuilder, Emitter, Handler, HANDLER},
|
||||
Spanned,
|
||||
};
|
||||
use swc_css_ast::Stylesheet;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use super::config::{LintRuleReaction, RuleConfig};
|
||||
|
||||
/// A lint rule.
|
||||
///
|
||||
/// # Implementation notes
|
||||
@ -83,3 +89,50 @@ where
|
||||
stylesheet.visit_with(&mut self.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct LintRuleContext<C>
|
||||
where
|
||||
C: Debug + Clone + Serialize + Default,
|
||||
{
|
||||
reaction: LintRuleReaction,
|
||||
config: C,
|
||||
}
|
||||
|
||||
impl<C> LintRuleContext<C>
|
||||
where
|
||||
C: Debug + Clone + Serialize + Default,
|
||||
{
|
||||
pub(crate) fn report<N, S>(&self, ast_node: N, message: S)
|
||||
where
|
||||
N: Spanned,
|
||||
S: AsRef<str>,
|
||||
{
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler
|
||||
.struct_span_err(ast_node.span(), message.as_ref())
|
||||
.emit(),
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(ast_node.span(), message.as_ref())
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn config(&self) -> &C {
|
||||
&self.config
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> From<&RuleConfig<C>> for LintRuleContext<C>
|
||||
where
|
||||
C: Debug + Clone + Serialize + Default,
|
||||
{
|
||||
fn from(config: &RuleConfig<C>) -> Self {
|
||||
Self {
|
||||
reaction: config.get_rule_reaction(),
|
||||
config: config.get_rule_config().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{errors::HANDLER, Spanned};
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@ -14,20 +10,14 @@ pub struct AtRuleNoUnknownConfig {
|
||||
ignore_at_rules: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
pub fn at_rule_no_unknown(config: &RuleConfig<AtRuleNoUnknownConfig>) -> Box<dyn LintRule> {
|
||||
visitor_rule(AtRuleNoUnknown {
|
||||
reaction: config.get_rule_reaction(),
|
||||
ignored: config
|
||||
.get_rule_config()
|
||||
.ignore_at_rules
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
pub fn at_rule_no_unknown(ctx: LintRuleContext<AtRuleNoUnknownConfig>) -> Box<dyn LintRule> {
|
||||
let ignored = ctx.config().ignore_at_rules.clone().unwrap_or_default();
|
||||
visitor_rule(AtRuleNoUnknown { ctx, ignored })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct AtRuleNoUnknown {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<AtRuleNoUnknownConfig>,
|
||||
ignored: Vec<String>,
|
||||
}
|
||||
|
||||
@ -40,16 +30,7 @@ impl Visit for AtRuleNoUnknown {
|
||||
|
||||
if self.ignored.iter().all(|item| name != item) {
|
||||
let message = format!("Unexpected unknown at-rule \"@{}\".", name);
|
||||
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler
|
||||
.struct_span_err(unknown_at_rule.name.span(), &message)
|
||||
.emit(),
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(unknown_at_rule.name.span(), &message)
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(&unknown_at_rule.name, message);
|
||||
}
|
||||
|
||||
unknown_at_rule.visit_children_with(self);
|
||||
|
@ -1,37 +1,23 @@
|
||||
use swc_common::errors::HANDLER;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn block_no_empty(config: &RuleConfig<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(BlockNoEmpty {
|
||||
reaction: config.get_rule_reaction(),
|
||||
})
|
||||
pub fn block_no_empty(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(BlockNoEmpty { ctx })
|
||||
}
|
||||
|
||||
const MESSAGE: &str = "Unexpected empty block.";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct BlockNoEmpty {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<()>,
|
||||
}
|
||||
|
||||
impl Visit for BlockNoEmpty {
|
||||
fn visit_simple_block(&mut self, simple_block: &SimpleBlock) {
|
||||
if simple_block.value.is_empty() {
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(simple_block.span, MESSAGE).emit()
|
||||
}
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(simple_block.span, MESSAGE).emit()
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(simple_block, MESSAGE);
|
||||
}
|
||||
|
||||
simple_block.visit_children_with(self);
|
||||
|
@ -1,12 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::errors::HANDLER;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub type ColorHexLengthConfig = Option<HexForm>;
|
||||
|
||||
@ -23,16 +19,14 @@ impl Default for HexForm {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn color_hex_length(config: &RuleConfig<ColorHexLengthConfig>) -> Box<dyn LintRule> {
|
||||
visitor_rule(ColorHexLength {
|
||||
reaction: config.get_rule_reaction(),
|
||||
form: config.get_rule_config().clone().unwrap_or_default(),
|
||||
})
|
||||
pub fn color_hex_length(ctx: LintRuleContext<ColorHexLengthConfig>) -> Box<dyn LintRule> {
|
||||
let form = ctx.config().clone().unwrap_or_default();
|
||||
visitor_rule(ColorHexLength { ctx, form })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct ColorHexLength {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<ColorHexLengthConfig>,
|
||||
form: HexForm,
|
||||
}
|
||||
|
||||
@ -51,29 +45,13 @@ impl Visit for ColorHexLength {
|
||||
HexForm::Long => {
|
||||
if let Some(lengthened) = lengthen(&hex_color.value) {
|
||||
let message = self.build_message(&hex_color.value, &lengthened);
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(hex_color.span, &message).emit()
|
||||
}
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(hex_color.span, &message).emit()
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(hex_color, message);
|
||||
}
|
||||
}
|
||||
HexForm::Short => {
|
||||
if let Some(shortened) = shorten(&hex_color.value) {
|
||||
let message = self.build_message(&hex_color.value, &shortened);
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(hex_color.span, &message).emit()
|
||||
}
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(hex_color.span, &message).emit()
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(hex_color, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,20 @@
|
||||
use swc_common::errors::HANDLER;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn color_no_invalid_hex(config: &RuleConfig<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(ColorNoInvalidHex {
|
||||
reaction: config.get_rule_reaction(),
|
||||
})
|
||||
pub fn color_no_invalid_hex(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(ColorNoInvalidHex { ctx })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct ColorNoInvalidHex {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<()>,
|
||||
}
|
||||
|
||||
impl Visit for ColorNoInvalidHex {
|
||||
fn visit_hex_color(&mut self, hex_color: &HexColor) {
|
||||
let HexColor { span, value, .. } = hex_color;
|
||||
let HexColor { value, .. } = hex_color;
|
||||
let length = value.len();
|
||||
if (length == 3 || length == 4 || length == 6 || length == 8)
|
||||
&& value.chars().all(|c| c.is_ascii_hexdigit())
|
||||
@ -30,11 +24,7 @@ impl Visit for ColorNoInvalidHex {
|
||||
}
|
||||
|
||||
let message = format!("Unexpected invalid hex color '#{}'.", value);
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler.struct_span_err(*span, &message).emit(),
|
||||
LintRuleReaction::Warning => handler.struct_span_warn(*span, &message).emit(),
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(hex_color, message);
|
||||
|
||||
hex_color.visit_children_with(self);
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
use swc_common::{errors::HANDLER, Span};
|
||||
use swc_common::Span;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn declaration_no_important(config: &RuleConfig<()>) -> Box<dyn LintRule> {
|
||||
pub fn declaration_no_important(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(DeclarationNoImportant {
|
||||
reaction: config.get_rule_reaction(),
|
||||
ctx,
|
||||
keyframe_rules: vec![],
|
||||
})
|
||||
}
|
||||
@ -18,7 +15,7 @@ const MESSAGE: &str = "Unexpected '!important'.";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct DeclarationNoImportant {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<()>,
|
||||
|
||||
// rule interal
|
||||
keyframe_rules: Vec<Span>,
|
||||
@ -38,17 +35,7 @@ impl Visit for DeclarationNoImportant {
|
||||
Some(span) if span.contains(important_flag.span) => {
|
||||
// This rule doesn't check `!important` flag inside `@keyframe`.
|
||||
}
|
||||
_ => {
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(important_flag.span, MESSAGE).emit()
|
||||
}
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(important_flag.span, MESSAGE)
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
_ => self.ctx.report(important_flag, MESSAGE),
|
||||
}
|
||||
|
||||
important_flag.visit_children_with(self);
|
||||
|
@ -1,15 +1,12 @@
|
||||
use swc_common::{errors::HANDLER, Span};
|
||||
use swc_common::Span;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn keyframe_declaration_no_important(config: &RuleConfig<()>) -> Box<dyn LintRule> {
|
||||
pub fn keyframe_declaration_no_important(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(KeyframeDeclarationNoImportant {
|
||||
reaction: config.get_rule_reaction(),
|
||||
ctx,
|
||||
keyframe_rules: vec![],
|
||||
})
|
||||
}
|
||||
@ -18,9 +15,9 @@ const MESSAGE: &str = "Unexpected '!important'.";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct KeyframeDeclarationNoImportant {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<()>,
|
||||
|
||||
// rule interal
|
||||
// rule internal
|
||||
keyframe_rules: Vec<Span>,
|
||||
}
|
||||
|
||||
@ -36,15 +33,7 @@ impl Visit for KeyframeDeclarationNoImportant {
|
||||
fn visit_important_flag(&mut self, important_flag: &ImportantFlag) {
|
||||
match self.keyframe_rules.last() {
|
||||
Some(span) if span.contains(important_flag.span) => {
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(important_flag.span, MESSAGE).emit()
|
||||
}
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(important_flag.span, MESSAGE)
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(important_flag, MESSAGE);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -31,42 +31,28 @@ pub fn get_rules(LintParams { lint_config }: &LintParams) -> Vec<Box<dyn LintRul
|
||||
let mut rules = vec![];
|
||||
let rules_config = &lint_config.rules;
|
||||
|
||||
if rules_config.block_no_empty.is_enabled() {
|
||||
rules.push(block_no_empty(&rules_config.block_no_empty));
|
||||
}
|
||||
if rules_config.at_rule_no_unknown.is_enabled() {
|
||||
rules.push(at_rule_no_unknown(&rules_config.at_rule_no_unknown));
|
||||
}
|
||||
if rules_config.no_empty_source.is_enabled() {
|
||||
rules.push(no_empty_source(&rules_config.no_empty_source));
|
||||
}
|
||||
if rules_config.declaration_no_important.is_enabled() {
|
||||
rules.push(block_no_empty((&rules_config.block_no_empty).into()));
|
||||
rules.push(at_rule_no_unknown(
|
||||
(&rules_config.at_rule_no_unknown).into(),
|
||||
));
|
||||
rules.push(no_empty_source((&rules_config.no_empty_source).into()));
|
||||
rules.push(declaration_no_important(
|
||||
&rules_config.declaration_no_important,
|
||||
(&rules_config.declaration_no_important).into(),
|
||||
));
|
||||
}
|
||||
if rules_config.keyframe_declaration_no_important.is_enabled() {
|
||||
rules.push(keyframe_declaration_no_important(
|
||||
&rules_config.keyframe_declaration_no_important,
|
||||
(&rules_config.keyframe_declaration_no_important).into(),
|
||||
));
|
||||
}
|
||||
if rules_config.no_invalid_position_at_import_rule.is_enabled() {
|
||||
rules.push(no_invalid_position_at_import_rule(
|
||||
&rules_config.no_invalid_position_at_import_rule,
|
||||
(&rules_config.no_invalid_position_at_import_rule).into(),
|
||||
));
|
||||
}
|
||||
if rules_config.selector_max_class.is_enabled() {
|
||||
rules.push(selector_max_class(&rules_config.selector_max_class));
|
||||
}
|
||||
if rules_config.color_hex_length.is_enabled() {
|
||||
rules.push(color_hex_length(&rules_config.color_hex_length));
|
||||
}
|
||||
if rules_config.color_no_invalid_hex.is_enabled() {
|
||||
rules.push(color_no_invalid_hex(&rules_config.color_no_invalid_hex));
|
||||
}
|
||||
if rules_config.unit_no_unknown.is_enabled() {
|
||||
rules.push(unit_no_unknown(&rules_config.unit_no_unknown));
|
||||
}
|
||||
rules.push(selector_max_class(
|
||||
(&rules_config.selector_max_class).into(),
|
||||
));
|
||||
rules.push(color_hex_length((&rules_config.color_hex_length).into()));
|
||||
rules.push(color_no_invalid_hex(
|
||||
(&rules_config.color_no_invalid_hex).into(),
|
||||
));
|
||||
rules.push(unit_no_unknown((&rules_config.unit_no_unknown).into()));
|
||||
|
||||
rules
|
||||
}
|
||||
|
@ -1,23 +1,17 @@
|
||||
use swc_common::errors::HANDLER;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn no_empty_source(config: &RuleConfig<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(NoEmptySource {
|
||||
reaction: config.get_rule_reaction(),
|
||||
})
|
||||
pub fn no_empty_source(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
|
||||
visitor_rule(NoEmptySource { ctx })
|
||||
}
|
||||
|
||||
const MESSAGE: &str = "Unexpected empty source.";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct NoEmptySource {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<()>,
|
||||
}
|
||||
|
||||
impl Visit for NoEmptySource {
|
||||
@ -25,13 +19,7 @@ impl Visit for NoEmptySource {
|
||||
// TODO: we should allow comments here,
|
||||
// but parser doesn't handle comments currently.
|
||||
if stylesheet.rules.is_empty() {
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler.struct_span_err(stylesheet.span, MESSAGE).emit(),
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(stylesheet.span, MESSAGE).emit()
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(stylesheet, MESSAGE);
|
||||
}
|
||||
|
||||
stylesheet.visit_children_with(self);
|
||||
|
@ -1,12 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{errors::HANDLER, Spanned};
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
const MESSAGE: &str = "Unexpected invalid position '@import' rule.";
|
||||
|
||||
@ -17,21 +13,15 @@ pub struct NoInvalidPositionAtImportRuleConfig {
|
||||
}
|
||||
|
||||
pub fn no_invalid_position_at_import_rule(
|
||||
config: &RuleConfig<NoInvalidPositionAtImportRuleConfig>,
|
||||
ctx: LintRuleContext<NoInvalidPositionAtImportRuleConfig>,
|
||||
) -> Box<dyn LintRule> {
|
||||
visitor_rule(NoInvalidPositionAtImportRule {
|
||||
reaction: config.get_rule_reaction(),
|
||||
ignored: config
|
||||
.get_rule_config()
|
||||
.ignore_at_rules
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
let ignored = ctx.config().ignore_at_rules.clone().unwrap_or_default();
|
||||
visitor_rule(NoInvalidPositionAtImportRule { ctx, ignored })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct NoInvalidPositionAtImportRule {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<NoInvalidPositionAtImportRuleConfig>,
|
||||
ignored: Vec<String>,
|
||||
}
|
||||
|
||||
@ -39,13 +29,7 @@ impl Visit for NoInvalidPositionAtImportRule {
|
||||
fn visit_stylesheet(&mut self, stylesheet: &Stylesheet) {
|
||||
stylesheet.rules.iter().fold(false, |seen, rule| {
|
||||
if seen && matches!(rule, Rule::AtRule(AtRule::Import(..))) {
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler.struct_span_err(rule.span(), MESSAGE).emit(),
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(rule.span(), MESSAGE).emit()
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(rule, MESSAGE);
|
||||
}
|
||||
|
||||
match rule {
|
||||
|
@ -1,22 +1,18 @@
|
||||
use swc_common::errors::HANDLER;
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
pub fn selector_max_class(config: &RuleConfig<Option<usize>>) -> Box<dyn LintRule> {
|
||||
visitor_rule(SelectorMaxClass {
|
||||
reaction: config.get_rule_reaction(),
|
||||
max: config.get_rule_config().unwrap_or(3),
|
||||
})
|
||||
pub(crate) type SelectorMaxClassConfig = Option<usize>;
|
||||
|
||||
pub fn selector_max_class(ctx: LintRuleContext<SelectorMaxClassConfig>) -> Box<dyn LintRule> {
|
||||
let max = ctx.config().unwrap_or(3);
|
||||
visitor_rule(SelectorMaxClass { ctx, max })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct SelectorMaxClass {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<SelectorMaxClassConfig>,
|
||||
max: usize,
|
||||
}
|
||||
|
||||
@ -51,15 +47,7 @@ impl Visit for SelectorMaxClass {
|
||||
|
||||
if count > self.max {
|
||||
let message = self.build_message(count);
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler
|
||||
.struct_span_err(complex_selector.span, &message)
|
||||
.emit(),
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(complex_selector.span, &message)
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(complex_selector, message);
|
||||
}
|
||||
|
||||
complex_selector.visit_children_with(self);
|
||||
|
@ -1,12 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_common::{errors::HANDLER, Spanned};
|
||||
use swc_css_ast::*;
|
||||
use swc_css_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, LintRule},
|
||||
};
|
||||
use crate::rule::{visitor_rule, LintRule, LintRuleContext};
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@ -14,20 +10,14 @@ pub struct UnitNoUnknownConfig {
|
||||
ignore_units: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
pub fn unit_no_unknown(config: &RuleConfig<UnitNoUnknownConfig>) -> Box<dyn LintRule> {
|
||||
visitor_rule(UnitNoUnknown {
|
||||
reaction: config.get_rule_reaction(),
|
||||
ignored_units: config
|
||||
.get_rule_config()
|
||||
.ignore_units
|
||||
.clone()
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
pub fn unit_no_unknown(ctx: LintRuleContext<UnitNoUnknownConfig>) -> Box<dyn LintRule> {
|
||||
let ignored_units = ctx.config().ignore_units.clone().unwrap_or_default();
|
||||
visitor_rule(UnitNoUnknown { ctx, ignored_units })
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct UnitNoUnknown {
|
||||
reaction: LintRuleReaction,
|
||||
ctx: LintRuleContext<UnitNoUnknownConfig>,
|
||||
ignored_units: Vec<String>,
|
||||
}
|
||||
|
||||
@ -37,16 +27,7 @@ impl Visit for UnitNoUnknown {
|
||||
|
||||
if self.ignored_units.iter().all(|item| unit != item) {
|
||||
let message = format!("Unexpected unknown unit \"{}\".", unit);
|
||||
|
||||
HANDLER.with(|handler| match self.reaction {
|
||||
LintRuleReaction::Error => handler
|
||||
.struct_span_err(unknown_dimension.unit.span(), &message)
|
||||
.emit(),
|
||||
LintRuleReaction::Warning => handler
|
||||
.struct_span_warn(unknown_dimension.unit.span(), &message)
|
||||
.emit(),
|
||||
_ => {}
|
||||
});
|
||||
self.ctx.report(&unknown_dimension.unit, message);
|
||||
}
|
||||
|
||||
unknown_dimension.visit_children_with(self);
|
||||
|
Loading…
Reference in New Issue
Block a user