swc_ecma_lexer/common/parser/
util.rs

1use swc_atoms::{atom, Atom};
2use swc_common::{Span, Spanned};
3use swc_ecma_ast::{
4    BindingIdent, BlockStmt, Decl, Expr, Ident, IdentName, JSXElementName, JSXMemberExpr,
5    JSXNamespacedName, JSXObject, Key, Param, Pat, PropName, Str,
6};
7
8pub fn unwrap_ts_non_null(mut expr: &Expr) -> &Expr {
9    while let Expr::TsNonNull(ts_non_null) = expr {
10        expr = &ts_non_null.expr;
11    }
12    expr
13}
14
15pub fn is_not_this(p: &Param) -> bool {
16    !matches!(
17        &p.pat,
18        Pat::Ident(BindingIdent {
19            id: Ident{ sym: this, .. },
20            ..
21        }) if atom!("this").eq(this)
22    )
23}
24
25pub fn has_use_strict(block: &BlockStmt) -> Option<Span> {
26    block
27        .stmts
28        .iter()
29        .take_while(|s| s.can_precede_directive())
30        .find_map(|s| {
31            if s.is_use_strict() {
32                Some(s.span())
33            } else {
34                None
35            }
36        })
37}
38
39pub fn is_constructor(key: &Key) -> bool {
40    if let Key::Public(PropName::Ident(IdentName { sym, .. })) = key {
41        sym.eq("constructor")
42    } else if let Key::Public(PropName::Str(Str { value, .. })) = key {
43        value.eq("constructor")
44    } else {
45        false
46    }
47}
48
49pub fn get_qualified_jsx_name(name: &JSXElementName) -> Atom {
50    fn get_qualified_obj_name(obj: &JSXObject) -> Atom {
51        match *obj {
52            JSXObject::Ident(ref i) => i.sym.clone(),
53            JSXObject::JSXMemberExpr(ref member) => format!(
54                "{}.{}",
55                get_qualified_obj_name(&member.obj),
56                member.prop.sym
57            )
58            .into(),
59            #[cfg(swc_ast_unknown)]
60            _ => unreachable!(),
61        }
62    }
63    match *name {
64        JSXElementName::Ident(ref i) => i.sym.clone(),
65        JSXElementName::JSXNamespacedName(JSXNamespacedName {
66            ref ns, ref name, ..
67        }) => format!("{}:{}", ns.sym, name.sym).into(),
68        JSXElementName::JSXMemberExpr(JSXMemberExpr {
69            ref obj, ref prop, ..
70        }) => format!("{}.{}", get_qualified_obj_name(obj), prop.sym).into(),
71        #[cfg(swc_ast_unknown)]
72        _ => unreachable!(),
73    }
74}
75
76/// Mark as declare
77pub fn make_decl_declare(mut decl: Decl) -> Decl {
78    match decl {
79        Decl::Class(ref mut c) => c.declare = true,
80        Decl::Fn(ref mut f) => f.declare = true,
81        Decl::Var(ref mut v) => v.declare = true,
82        Decl::TsInterface(ref mut i) => i.declare = true,
83        Decl::TsTypeAlias(ref mut a) => a.declare = true,
84        Decl::TsEnum(ref mut e) => e.declare = true,
85        Decl::TsModule(ref mut m) => m.declare = true,
86        Decl::Using(..) => unreachable!("Using is not a valid declaration for `declare` keyword"),
87        #[cfg(swc_ast_unknown)]
88        _ => unreachable!(),
89    }
90    decl
91}