swc_ecma_parser/parser/
util.rs

1use swc_common::Span;
2use swc_ecma_ast::*;
3
4pub trait IsSimpleParameterList {
5    fn is_simple_parameter_list(&self) -> bool;
6}
7
8impl IsSimpleParameterList for Vec<Param> {
9    fn is_simple_parameter_list(&self) -> bool {
10        self.iter().all(|param| matches!(param.pat, Pat::Ident(_)))
11    }
12}
13
14impl IsSimpleParameterList for Vec<Pat> {
15    fn is_simple_parameter_list(&self) -> bool {
16        self.iter().all(|pat| matches!(pat, Pat::Ident(_)))
17    }
18}
19
20impl IsSimpleParameterList for Vec<ParamOrTsParamProp> {
21    fn is_simple_parameter_list(&self) -> bool {
22        self.iter().all(|param| {
23            matches!(
24                param,
25                ParamOrTsParamProp::TsParamProp(..)
26                    | ParamOrTsParamProp::Param(Param {
27                        pat: Pat::Ident(_),
28                        ..
29                    })
30            )
31        })
32    }
33}
34
35pub trait IsInvalidClassName {
36    fn invalid_class_name(&self) -> Option<Span>;
37}
38
39impl IsInvalidClassName for Ident {
40    fn invalid_class_name(&self) -> Option<Span> {
41        match &*self.sym {
42            "string" | "null" | "number" | "object" | "any" | "unknown" | "boolean" | "bigint"
43            | "symbol" | "void" | "never" | "intrinsic" => Some(self.span),
44            _ => None,
45        }
46    }
47}
48impl IsInvalidClassName for Option<Ident> {
49    fn invalid_class_name(&self) -> Option<Span> {
50        self.as_ref().and_then(|i| i.invalid_class_name())
51    }
52}
53
54pub trait ExprExt {
55    fn as_expr(&self) -> &Expr;
56
57    /// "IsValidSimpleAssignmentTarget" from spec.
58    fn is_valid_simple_assignment_target(&self, strict: bool) -> bool {
59        match self.as_expr() {
60            Expr::Ident(ident) => {
61                if strict && ident.is_reserved_in_strict_bind() {
62                    return false;
63                }
64                true
65            }
66
67            Expr::This(..)
68            | Expr::Lit(..)
69            | Expr::Array(..)
70            | Expr::Object(..)
71            | Expr::Fn(..)
72            | Expr::Class(..)
73            | Expr::Tpl(..)
74            | Expr::TaggedTpl(..) => false,
75            Expr::Paren(ParenExpr { expr, .. }) => expr.is_valid_simple_assignment_target(strict),
76
77            Expr::Member(MemberExpr { obj, .. }) => match obj.as_ref() {
78                Expr::Member(..) => obj.is_valid_simple_assignment_target(strict),
79                Expr::OptChain(..) => false,
80                _ => true,
81            },
82
83            Expr::SuperProp(..) => true,
84
85            Expr::New(..) | Expr::Call(..) => false,
86            // TODO: Spec only mentions `new.target`
87            Expr::MetaProp(..) => false,
88
89            Expr::Update(..) => false,
90
91            Expr::Unary(..) | Expr::Await(..) => false,
92
93            Expr::Bin(..) => false,
94
95            Expr::Cond(..) => false,
96
97            Expr::Yield(..) | Expr::Arrow(..) | Expr::Assign(..) => false,
98
99            Expr::Seq(..) => false,
100
101            Expr::OptChain(..) => false,
102
103            // MemberExpression is valid assignment target
104            Expr::PrivateName(..) => false,
105
106            // jsx
107            Expr::JSXMember(..)
108            | Expr::JSXNamespacedName(..)
109            | Expr::JSXEmpty(..)
110            | Expr::JSXElement(..)
111            | Expr::JSXFragment(..) => false,
112
113            // typescript
114            Expr::TsNonNull(TsNonNullExpr { ref expr, .. })
115            | Expr::TsTypeAssertion(TsTypeAssertion { ref expr, .. })
116            | Expr::TsAs(TsAsExpr { ref expr, .. })
117            | Expr::TsInstantiation(TsInstantiation { ref expr, .. })
118            | Expr::TsSatisfies(TsSatisfiesExpr { ref expr, .. }) => {
119                expr.is_valid_simple_assignment_target(strict)
120            }
121
122            Expr::TsConstAssertion(..) => false,
123
124            Expr::Invalid(..) => false,
125            #[cfg(swc_ast_unknown)]
126            _ => unreachable!(),
127        }
128    }
129}
130
131impl ExprExt for Box<Expr> {
132    #[inline(always)]
133    fn as_expr(&self) -> &Expr {
134        self
135    }
136}
137impl ExprExt for Expr {
138    #[inline(always)]
139    fn as_expr(&self) -> &Expr {
140        self
141    }
142}