swc_css_lints/rules/
declaration_no_important.rs

1use swc_common::Span;
2use swc_css_ast::*;
3use swc_css_visit::{Visit, VisitWith};
4
5use crate::rule::{visitor_rule, LintRule, LintRuleContext};
6
7pub fn declaration_no_important(ctx: LintRuleContext<()>) -> Box<dyn LintRule> {
8    visitor_rule(
9        ctx.reaction(),
10        DeclarationNoImportant {
11            ctx,
12            keyframe_rules: Vec::new(),
13        },
14    )
15}
16
17const MESSAGE: &str = "Unexpected '!important'.";
18
19#[derive(Debug, Default)]
20struct DeclarationNoImportant {
21    ctx: LintRuleContext<()>,
22
23    // rule internal
24    keyframe_rules: Vec<Span>,
25}
26
27impl Visit for DeclarationNoImportant {
28    fn visit_at_rule(&mut self, keyframes_rule: &AtRule) {
29        if let Some(AtRulePrelude::KeyframesPrelude(_)) = keyframes_rule.prelude.as_deref() {
30            self.keyframe_rules.push(keyframes_rule.span);
31
32            keyframes_rule.visit_children_with(self);
33
34            self.keyframe_rules.pop();
35        }
36    }
37
38    fn visit_important_flag(&mut self, important_flag: &ImportantFlag) {
39        match self.keyframe_rules.last() {
40            Some(span) if span.contains(important_flag.span) => {
41                // This rule doesn't check `!important` flag inside `@keyframe`.
42            }
43            _ => self.ctx.report(important_flag, MESSAGE),
44        }
45
46        important_flag.visit_children_with(self);
47    }
48}