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    matches!(
41        &key,
42        Key::Public(PropName::Ident(IdentName {
43            sym: constructor,
44            ..
45        })) | Key::Public(PropName::Str(Str {
46            value: constructor,
47            ..
48        })) if  atom!("constructor").eq(constructor)
49    )
50}
51
52pub fn get_qualified_jsx_name(name: &JSXElementName) -> Atom {
53    fn get_qualified_obj_name(obj: &JSXObject) -> Atom {
54        match *obj {
55            JSXObject::Ident(ref i) => i.sym.clone(),
56            JSXObject::JSXMemberExpr(ref member) => format!(
57                "{}.{}",
58                get_qualified_obj_name(&member.obj),
59                member.prop.sym
60            )
61            .into(),
62        }
63    }
64    match *name {
65        JSXElementName::Ident(ref i) => i.sym.clone(),
66        JSXElementName::JSXNamespacedName(JSXNamespacedName {
67            ref ns, ref name, ..
68        }) => format!("{}:{}", ns.sym, name.sym).into(),
69        JSXElementName::JSXMemberExpr(JSXMemberExpr {
70            ref obj, ref prop, ..
71        }) => format!("{}.{}", get_qualified_obj_name(obj), prop.sym).into(),
72    }
73}
74
75/// Mark as declare
76pub fn make_decl_declare(mut decl: Decl) -> Decl {
77    match decl {
78        Decl::Class(ref mut c) => c.declare = true,
79        Decl::Fn(ref mut f) => f.declare = true,
80        Decl::Var(ref mut v) => v.declare = true,
81        Decl::TsInterface(ref mut i) => i.declare = true,
82        Decl::TsTypeAlias(ref mut a) => a.declare = true,
83        Decl::TsEnum(ref mut e) => e.declare = true,
84        Decl::TsModule(ref mut m) => m.declare = true,
85        Decl::Using(..) => unreachable!("Using is not a valid declaration for `declare` keyword"),
86    }
87    decl
88}