1use stylex_constants::constants::{
2 common::{INVALID_METHODS, MUTATING_ARRAY_METHODS, MUTATING_OBJECT_METHODS, VALID_CALLEES},
3 messages::INVALID_UTF8,
4};
5use stylex_macros::stylex_panic;
6use swc_core::{
7 atoms::Atom,
8 ecma::ast::{AssignTarget, Expr, Lit, MemberProp, SimpleAssignTarget, UnaryOp},
9};
10
11pub fn is_valid_callee(callee: &Expr) -> bool {
12 if let Expr::Ident(ident) = callee {
13 VALID_CALLEES.contains(ident.sym.as_ref())
14 } else {
15 false
16 }
17}
18
19pub fn get_callee_name(callee: &Expr) -> &str {
20 match callee {
21 Expr::Ident(ident) => &ident.sym,
22 _ => stylex_panic!("The function being called must be a static identifier."),
23 }
24}
25
26pub fn is_invalid_method(prop: &MemberProp) -> bool {
27 match prop {
28 MemberProp::Ident(ident_prop) => INVALID_METHODS.contains(&*ident_prop.sym),
29 _ => false,
30 }
31}
32
33pub fn is_mutating_object_method(prop: &MemberProp) -> bool {
35 if let MemberProp::Ident(ident_prop) = prop {
36 MUTATING_OBJECT_METHODS.contains(&*ident_prop.sym)
37 } else {
38 false
39 }
40}
41
42pub fn is_mutating_array_method(prop: &MemberProp) -> bool {
44 if let MemberProp::Ident(ident_prop) = prop {
45 MUTATING_ARRAY_METHODS.contains(&*ident_prop.sym)
46 } else {
47 false
48 }
49}
50
51pub fn is_mutation_expr(expr: &Expr) -> bool {
57 match expr {
58 Expr::Assign(assign)
60 if matches!(
61 &assign.left,
62 AssignTarget::Simple(SimpleAssignTarget::Member(member)) if member.obj.is_ident()
63 ) =>
64 {
65 true
66 },
67
68 Expr::Update(update) if matches!(&*update.arg, Expr::Member(member) if member.obj.is_ident()) => {
70 true
71 },
72
73 Expr::Unary(unary)
75 if unary.op == UnaryOp::Delete
76 && matches!(&*unary.arg, Expr::Member(member) if member.obj.is_ident()) =>
77 {
78 true
79 },
80
81 _ => false,
82 }
83}
84
85pub fn get_method_name(prop: &MemberProp) -> &str {
86 match prop {
87 MemberProp::Ident(ident_prop) => &ident_prop.sym,
88 _ => stylex_panic!("The method name in a call expression must be a static identifier."),
89 }
90}
91
92pub fn is_id_prop(prop: &MemberProp) -> Option<&Atom> {
93 if let MemberProp::Computed(comp_prop) = prop
94 && let Expr::Lit(Lit::Str(strng)) = comp_prop.expr.as_ref()
95 {
96 return Some(match strng.value.as_atom() {
97 Some(a) => a,
98 None => stylex_panic!("{}", INVALID_UTF8),
99 });
100 }
101
102 None
103}