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