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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! `Checker` implementation for TypeScript.
#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
use super::*;
impl Checker for TypescriptCode {
fn is_comment(node: &Node) -> bool {
// See MozjsCode::is_comment — `html_comment` (Annex-B `<!-- -->`)
// is a comment kind for loc/tokens/find parity (#697).
matches!(
node.kind_id().into(),
Typescript::Comment | Typescript::HtmlComment
)
}
// tsc reads `/***` as JSDoc, so TypeScript follows tsc, not JSDoc.
impl_js_family_doc_comment!(Typescript, tsdoc_block);
// tsc's `getJSDocCommentsAndTags` takes the last `/**` before a
// declaration's first token, past every plain comment; a comment after
// a decorator is inside the declaration and documents nothing. TypeDoc
// withholds a `@module` or `@packageDocumentation` comment from the
// declaration and reads it as the file's (#1613). tsc reads a
// declaration's leading comments from the line break after the token
// before it, so a doc comment after code on its row documents nothing,
// except before a parameter, whose trailing comments it reads too.
impl_js_family_doc_binding!(
Typescript,
|node, code| Self::is_comment(node) && !Self::is_doc_comment(node, code),
crate::lang_helpers::doc_comment::tsdoc_module,
tsdoc_target,
|target| matches!(
target.kind_id().into(),
Typescript::RequiredParameter
| Typescript::RequiredParameter2
| Typescript::OptionalParameter
| Typescript::OptionalParameter2
)
);
fn is_func_space(node: &Node) -> bool {
matches!(
node.kind_id().into(),
Typescript::Program
| Typescript::FunctionExpression
| Typescript::Class
| Typescript::GeneratorFunction
| Typescript::FunctionDeclaration
| Typescript::MethodDefinition
| Typescript::GeneratorFunctionDeclaration
| Typescript::ClassDeclaration
| Typescript::AbstractClassDeclaration
| Typescript::InterfaceDeclaration
| Typescript::ArrowFunction
// ES2022 `static { … }`. Referenced nowhere
// outside the generated enum before #1184, so a
// class static block opened no space and its
// control flow was charged to the class.
| Typescript::ClassStaticBlock
)
}
is_js_func_and_closure_checker!(Typescript, PublicFieldDefinition);
fn is_call(node: &Node) -> bool {
node.kind_id() == Typescript::CallExpression
}
fn is_non_arg(node: &Node) -> bool {
matches!(
node.kind_id().into(),
Typescript::LPAREN | Typescript::COMMA | Typescript::RPAREN
)
}
// TS's only anonymous `"string"` alias, `String2` (kind_id 135),
// is the `: string` type-annotation keyword — not a literal — so
// it is deliberately excluded: `find string` / `count string`
// report literals, and `Getter::get_op_type` classifies the
// keyword's `predefined_type` wrapper as an operator (#1261,
// retiring the #313 parity that made the keyword an operand).
impl_js_family_is_string!(Typescript);
impl_is_else_if_parent_clause!(Typescript, IfStatement, ElseClause);
#[inline]
fn is_primitive(node: &Node) -> bool {
node.kind_id() == Typescript::PredefinedType
}
}