swc_ecma_usage_analyzer/analyzer/
ctx.rs1#![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}