Skip to main content

styled_components/visitors/
pure_annotation.rs

1//! Port of https://github.com/styled-components/babel-plugin-styled-components/blob/4e2eb388d9c90f2921c306c760657d059d01a518/src/visitors/pure.js
2
3use swc_common::{comments::Comments, Span};
4use swc_ecma_ast::*;
5use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith};
6
7use crate::utils::State;
8
9pub fn pure_annotation<'a, C>(comments: C, state: &'a State) -> impl 'a + Pass
10where
11    C: 'a + Comments,
12{
13    visit_mut_pass(PureAnnotation { comments, state })
14}
15
16#[derive(Debug)]
17struct PureAnnotation<'a, C>
18where
19    C: Comments,
20{
21    comments: C,
22    state: &'a State,
23}
24
25impl<C> VisitMut for PureAnnotation<'_, C>
26where
27    C: Comments,
28{
29    noop_visit_mut_type!(fail);
30
31    fn visit_mut_expr(&mut self, expr: &mut Expr) {
32        expr.visit_mut_children_with(self);
33
34        let (callee_or_tag, span) = match expr {
35            Expr::Call(CallExpr {
36                span,
37                callee: Callee::Expr(callee),
38                ..
39            }) => (callee, span),
40            Expr::TaggedTpl(TaggedTpl { span, tag, .. }) => (tag, span),
41            _ => return,
42        };
43        if !self.state.is_styled(callee_or_tag) && !self.state.is_pure_helper(callee_or_tag) {
44            return;
45        }
46
47        if span.is_dummy_ignoring_cmt() {
48            *span = Span::dummy_with_cmt();
49        }
50        if !self.comments.has_flag(span.lo, "PURE") {
51            self.comments.add_pure_comment(span.lo);
52        }
53    }
54}