swc_ecma_usage_analyzer/analyzer/
ctx.rs

1#![allow(dead_code)]
2
3use std::ops::{Deref, DerefMut};
4
5use bitflags::bitflags;
6use swc_ecma_ast::VarDeclKind;
7use swc_ecma_utils::{Type, Value};
8
9use super::{storage::Storage, UsageAnalyzer};
10
11impl<S> UsageAnalyzer<S>
12where
13    S: Storage,
14{
15    pub(super) fn with_ctx(&mut self, ctx: Ctx) -> WithCtx<S> {
16        let orig_ctx = self.ctx;
17        self.ctx = ctx;
18        WithCtx {
19            analyzer: self,
20            orig_ctx,
21        }
22    }
23}
24
25#[derive(Debug, Default, Clone, Copy)]
26#[non_exhaustive]
27pub struct Ctx {
28    pub var_decl_kind_of_pat: Option<VarDeclKind>,
29    pub in_pat_of_var_decl_with_init: Option<Value<Type>>,
30    pub(crate) bit_ctx: BitContext,
31}
32
33impl Ctx {
34    #[inline]
35    pub(crate) fn with(mut self, flag: BitContext, value: bool) -> Self {
36        self.bit_ctx = self.bit_ctx.with(flag, value);
37        self
38    }
39
40    #[inline]
41    pub fn in_decl_with_no_side_effect_for_member_access(&self) -> bool {
42        self.bit_ctx
43            .contains(BitContext::InDeclWithNoSideEffectForMemberAccess)
44    }
45
46    #[inline]
47    pub fn in_pat_of_param(&self) -> bool {
48        self.bit_ctx.contains(BitContext::InPatOfParam)
49    }
50
51    #[inline]
52    pub fn in_catch_param(&self) -> bool {
53        self.bit_ctx.contains(BitContext::InCatchParam)
54    }
55
56    #[inline]
57    pub fn is_id_ref(&self) -> bool {
58        self.bit_ctx.contains(BitContext::IsIdRef)
59    }
60
61    #[inline]
62    pub fn inline_prevented(&self) -> bool {
63        self.bit_ctx.contains(BitContext::InlinePrevented)
64    }
65
66    #[inline]
67    pub fn in_cond(&self) -> bool {
68        self.bit_ctx.contains(BitContext::InCond)
69    }
70
71    #[inline]
72    pub fn executed_multiple_time(&self) -> bool {
73        self.bit_ctx.contains(BitContext::ExecutedMultipleTime)
74    }
75
76    #[inline]
77    pub fn is_top_level(&self) -> bool {
78        self.bit_ctx.contains(BitContext::IsTopLevel)
79    }
80}
81
82bitflags! {
83    #[derive(Debug, Clone, Copy, Default)]
84    pub(crate) struct BitContext: u16 {
85        const InDeclWithNoSideEffectForMemberAccess = 1 << 0;
86        const InPatOfVarDecl = 1 << 1;
87        const InPatOfParam = 1 << 2;
88        const InCatchParam = 1 << 3;
89        const IsIdRef = 1 << 4;
90        const InAwaitArg = 1 << 5;
91        const InLeftOfForLoop = 1 << 6;
92        const ExecutedMultipleTime = 1 << 7;
93        const InCond = 1 << 8;
94        const InlinePrevented = 1 << 9;
95        const IsTopLevel = 1 << 10;
96    }
97}
98
99impl BitContext {
100    #[inline]
101    pub fn with(mut self, flag: Self, value: bool) -> Self {
102        self.set(flag, value);
103        self
104    }
105}
106
107pub(super) struct WithCtx<'a, S>
108where
109    S: Storage,
110{
111    analyzer: &'a mut UsageAnalyzer<S>,
112    orig_ctx: Ctx,
113}
114
115impl<S> Deref for WithCtx<'_, S>
116where
117    S: Storage,
118{
119    type Target = UsageAnalyzer<S>;
120
121    fn deref(&self) -> &Self::Target {
122        self.analyzer
123    }
124}
125
126impl<S> DerefMut for WithCtx<'_, S>
127where
128    S: Storage,
129{
130    fn deref_mut(&mut self) -> &mut Self::Target {
131        self.analyzer
132    }
133}
134
135impl<S> Drop for WithCtx<'_, S>
136where
137    S: Storage,
138{
139    fn drop(&mut self) {
140        self.analyzer.ctx = self.orig_ctx;
141    }
142}