Skip to main content

big_code_analysis_ast/getter/
mozjs.rs

1//! `Getter` implementation for MozJS.
2#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
3
4use super::*;
5
6impl Getter for MozjsCode {
7    fn get_space_kind(node: &Node) -> SpaceKind {
8        use Mozjs::*;
9
10        match node.kind_id().into() {
11            // `ClassStaticBlock` is ES2022 `static { … }` (#1184).
12            FunctionExpression
13            | MethodDefinition
14            | GeneratorFunction
15            | FunctionDeclaration
16            | GeneratorFunctionDeclaration
17            | ArrowFunction
18            | ClassStaticBlock => SpaceKind::Function,
19            Class | ClassDeclaration => SpaceKind::Class,
20            Program => SpaceKind::Unit,
21            _ => SpaceKind::Unknown,
22        }
23    }
24
25    fn get_func_space_name<'a, 'tree>(
26        node: &Node<'tree>,
27        code: &'a [u8],
28        ancestors: Ancestors<'tree, '_>,
29    ) -> Option<&'a str> {
30        // A class static block has no name token and no naming parent to
31        // fall back on, so it would otherwise land on `<anonymous>`
32        // alongside every arrow and function expression (#1184).
33        if node.kind_id() == Mozjs::ClassStaticBlock as u16 {
34            return Some("<static-init>");
35        }
36        if let Some(name) = node.child_by_field_name("name") {
37            return node_text(code, &name);
38        }
39        // Otherwise the name comes from the binding site: a pair
40        // (`foo: function () {}`) or a variable declaration
41        // (`var aFun = function () {}`). The two differ only in which
42        // field carries the name, so they collapse to one lookup.
43        let bound_name = ancestors.parent(node).and_then(|parent| {
44            let field = match parent.kind_id().into() {
45                Mozjs::Pair => "key",
46                Mozjs::VariableDeclarator => "name",
47                _ => return None,
48            };
49            parent.child_by_field_name(field)
50        });
51        bound_name.map_or(Some("<anonymous>"), |name| node_text(code, &name))
52    }
53
54    // JSX closing / self-closing tag delimiters. See the macro's
55    // `$op_extras` note: they are per-language extras because
56    // TypeScript, which shares this macro, has no JSX (#1395).
57    // `jsx:` bills element text and its entities as operands, for the
58    // same reason (#1483). `Staticget`: see the JavaScript invocation
59    // (#1563).
60    impl_js_family_get_op_type!(
61        Mozjs,
62        op_extras: [OptionalChain, LTSLASH, SLASHGT, Staticget],
63        operand_extras: [Identifier2, String2],
64        jsx: [JsxText, HtmlCharacterReference],
65    );
66
67    get_operator!(Mozjs);
68}