tsz_parser/parser/parse_rules/
utils.rs1use tsz_scanner::SyntaxKind;
6use tsz_scanner::scanner_impl::ScannerState;
7
8pub fn is_identifier_or_keyword(token: SyntaxKind) -> bool {
10 token == SyntaxKind::Identifier || tsz_scanner::token_is_keyword(token)
11}
12
13pub fn look_ahead_is<F>(scanner: &mut ScannerState, _current_token: SyntaxKind, check: F) -> bool
15where
16 F: FnOnce(SyntaxKind) -> bool,
17{
18 let snapshot = scanner.save_state();
19 let next = scanner.scan();
20
21 let result = check(next);
22
23 scanner.restore_state(snapshot);
24 result
25}
26
27pub fn look_ahead_is_on_same_line<F>(
30 scanner: &mut ScannerState,
31 _current_token: SyntaxKind,
32 check: F,
33) -> bool
34where
35 F: FnOnce(SyntaxKind) -> bool,
36{
37 let snapshot = scanner.save_state();
38 let next = scanner.scan();
39 let result = !scanner.has_preceding_line_break() && check(next);
40 scanner.restore_state(snapshot);
41 result
42}
43
44pub fn look_ahead_is_async_declaration(
46 scanner: &mut ScannerState,
47 current_token: SyntaxKind,
48) -> bool {
49 look_ahead_is(scanner, current_token, |token| {
50 matches!(
51 token,
52 SyntaxKind::ClassKeyword
53 | SyntaxKind::FunctionKeyword
54 | SyntaxKind::InterfaceKeyword
55 | SyntaxKind::EnumKeyword
56 | SyntaxKind::NamespaceKeyword
57 | SyntaxKind::ModuleKeyword
58 )
59 })
60}
61
62pub fn look_ahead_is_abstract_declaration(
64 scanner: &mut ScannerState,
65 current_token: SyntaxKind,
66) -> bool {
67 look_ahead_is(scanner, current_token, |token| {
68 matches!(
69 token,
70 SyntaxKind::ClassKeyword
71 | SyntaxKind::InterfaceKeyword
72 | SyntaxKind::EnumKeyword
73 | SyntaxKind::NamespaceKeyword
74 | SyntaxKind::ModuleKeyword
75 )
76 })
77}
78
79pub fn look_ahead_is_module_declaration(
82 scanner: &mut ScannerState,
83 current_token: SyntaxKind,
84) -> bool {
85 look_ahead_is_on_same_line(scanner, current_token, |token| {
86 matches!(
87 token,
88 SyntaxKind::StringLiteral | SyntaxKind::OpenBraceToken
89 ) || (token == SyntaxKind::Identifier
90 || (tsz_scanner::token_is_keyword(token)
91 && !tsz_scanner::token_is_reserved_word(token)))
92 })
93}
94
95pub fn look_ahead_is_type_alias_declaration(
98 scanner: &mut ScannerState,
99 current_token: SyntaxKind,
100) -> bool {
101 look_ahead_is_on_same_line(scanner, current_token, is_identifier_or_keyword)
102}
103
104pub fn look_ahead_is_const_enum(scanner: &mut ScannerState, current_token: SyntaxKind) -> bool {
106 look_ahead_is(scanner, current_token, |token| {
107 token == SyntaxKind::EnumKeyword
108 })
109}
110
111pub fn look_ahead_is_import_equals(
113 scanner: &mut ScannerState,
114 _current_token: SyntaxKind,
115 is_identifier_fn: impl Fn(SyntaxKind) -> bool,
116) -> bool {
117 let snapshot = scanner.save_state();
118
119 let next1 = scanner.scan();
120 if !is_identifier_fn(next1) {
121 scanner.restore_state(snapshot);
122 return false;
123 }
124
125 let next2 = scanner.scan();
126 if next2 == SyntaxKind::EqualsToken {
127 scanner.restore_state(snapshot);
128 return true;
129 }
130
131 if next1 == SyntaxKind::TypeKeyword && is_identifier_fn(next2) {
132 let next3 = scanner.scan();
133 if next3 == SyntaxKind::EqualsToken {
134 scanner.restore_state(snapshot);
135 return true;
136 }
137 }
138
139 scanner.restore_state(snapshot);
140 false
141}
142
143pub fn look_ahead_is_import_call(scanner: &mut ScannerState, current_token: SyntaxKind) -> bool {
145 look_ahead_is(scanner, current_token, |token| {
146 matches!(token, SyntaxKind::OpenParenToken | SyntaxKind::DotToken)
147 })
148}