1pub const KEYWORDS: &[&str] = &[
10 "AUTOLOAD",
11 "BEGIN",
12 "CHECK",
13 "DESTROY",
14 "END",
15 "INIT",
16 "UNITCHECK",
17 "__FILE__",
18 "__LINE__",
19 "__PACKAGE__",
20 "abs",
21 "and",
22 "bless",
23 "blessed",
24 "break",
25 "catch",
26 "chomp",
27 "chop",
28 "chr",
29 "class",
30 "close",
31 "cmp",
32 "continue",
33 "default",
34 "defined",
35 "delete",
36 "die",
37 "do",
38 "each",
39 "else",
40 "elsif",
41 "eq",
42 "eval",
43 "exists",
44 "exit",
45 "finally",
46 "for",
47 "foreach",
48 "format",
49 "ge",
50 "given",
51 "goto",
52 "grep",
53 "gt",
54 "hex",
55 "if",
56 "index",
57 "int",
58 "join",
59 "keys",
60 "last",
61 "lc",
62 "lcfirst",
63 "le",
64 "length",
65 "local",
66 "lt",
67 "m",
68 "map",
69 "method",
70 "my",
71 "ne",
72 "next",
73 "no",
74 "not",
75 "oct",
76 "open",
77 "or",
78 "ord",
79 "our",
80 "pack",
81 "package",
82 "pop",
83 "print",
84 "printf",
85 "push",
86 "q",
87 "qq",
88 "qr",
89 "qw",
90 "qx",
91 "read",
92 "redo",
93 "ref",
94 "require",
95 "return",
96 "reverse",
97 "rindex",
98 "s",
99 "say",
100 "scalar",
101 "shift",
102 "sort",
103 "splice",
104 "split",
105 "sprintf",
106 "sqrt",
107 "state",
108 "sub",
109 "substr",
110 "tie",
111 "tr",
112 "try",
113 "uc",
114 "ucfirst",
115 "undef",
116 "unless",
117 "unpack",
118 "unshift",
119 "untie",
120 "until",
121 "use",
122 "values",
123 "wantarray",
124 "warn",
125 "when",
126 "while",
127 "write",
128 "xor",
129 "y",
130];
131
132pub const LSP_COMPLETION_KEYWORDS: &[&str] = &[
134 "AUTOLOAD",
135 "BEGIN",
136 "CHECK",
137 "DESTROY",
138 "END",
139 "INIT",
140 "UNITCHECK",
141 "__FILE__",
142 "__LINE__",
143 "__PACKAGE__",
144 "and",
145 "blessed",
146 "cmp",
147 "defined",
148 "die",
149 "do",
150 "else",
151 "elsif",
152 "eq",
153 "eval",
154 "exit",
155 "for",
156 "foreach",
157 "ge",
158 "goto",
159 "gt",
160 "if",
161 "last",
162 "le",
163 "local",
164 "lt",
165 "my",
166 "ne",
167 "next",
168 "not",
169 "or",
170 "our",
171 "package",
172 "redo",
173 "ref",
174 "require",
175 "return",
176 "scalar",
177 "state",
178 "sub",
179 "undef",
180 "unless",
181 "until",
182 "use",
183 "wantarray",
184 "warn",
185 "while",
186 "xor",
187];
188
189pub const DAP_COMPLETION_KEYWORDS: &[&str] = &[
191 "abs", "bless", "chomp", "chop", "chr", "close", "defined", "delete", "die", "do", "each",
192 "else", "elsif", "eval", "exists", "for", "foreach", "grep", "hex", "if", "index", "int",
193 "join", "keys", "last", "lc", "lcfirst", "length", "local", "map", "my", "next", "oct", "open",
194 "ord", "our", "pack", "package", "pop", "print", "printf", "push", "qw", "redo", "ref",
195 "require", "return", "reverse", "rindex", "say", "scalar", "shift", "sort", "splice", "split",
196 "sprintf", "sqrt", "sub", "substr", "tie", "uc", "ucfirst", "unless", "unpack", "unshift",
197 "untie", "until", "use", "values", "warn", "while",
198];
199
200pub const LSP_RUNTIME_COMPLETION_KEYWORDS: &[&str] = &[
202 "close", "default", "die", "else", "elsif", "for", "foreach", "given", "goto", "grep", "if",
203 "last", "local", "map", "my", "next", "open", "our", "package", "pop", "print", "push", "read",
204 "redo", "require", "return", "say", "shift", "sort", "splice", "state", "sub", "unless",
205 "unshift", "until", "use", "warn", "when", "while", "write",
206];
207
208pub const RENAME_KEYWORDS: &[&str] = &[
210 "and", "else", "elsif", "eq", "for", "foreach", "if", "last", "local", "my", "ne", "next",
211 "not", "or", "our", "package", "redo", "require", "return", "state", "sub", "unless", "until",
212 "use", "while",
213];
214
215pub const PARSER_LSP_KEYWORDS: &[&str] = &[
217 "break", "continue", "default", "die", "do", "else", "elsif", "eval", "for", "foreach",
218 "given", "goto", "if", "last", "local", "my", "next", "no", "our", "package", "redo",
219 "require", "return", "sub", "unless", "until", "use", "warn", "when", "while",
220];
221
222pub const LEXER_KEYWORDS: &[&str] = &[
224 "BEGIN",
225 "CHECK",
226 "END",
227 "INIT",
228 "UNITCHECK",
229 "and",
230 "break",
231 "catch",
232 "class",
233 "cmp",
234 "continue",
235 "default",
236 "die",
237 "do",
238 "else",
239 "elsif",
240 "eval",
241 "finally",
242 "for",
243 "foreach",
244 "format",
245 "given",
246 "goto",
247 "grep",
248 "if",
249 "last",
250 "local",
251 "m",
252 "map",
253 "method",
254 "my",
255 "next",
256 "not",
257 "or",
258 "our",
259 "package",
260 "print",
261 "q",
262 "qq",
263 "qr",
264 "qw",
265 "qx",
266 "redo",
267 "require",
268 "return",
269 "s",
270 "say",
271 "sort",
272 "split",
273 "state",
274 "sub",
275 "tr",
276 "try",
277 "undef",
278 "unless",
279 "until",
280 "use",
281 "warn",
282 "when",
283 "while",
284 "xor",
285 "y",
286];
287
288#[must_use]
290pub fn is_keyword(token: &str) -> bool {
291 KEYWORDS.binary_search(&token).is_ok()
292}
293
294#[must_use]
296pub fn is_lexer_keyword(token: &str) -> bool {
297 LEXER_KEYWORDS.binary_search(&token).is_ok()
298}
299
300#[must_use]
302pub fn is_lsp_completion_keyword(token: &str) -> bool {
303 LSP_COMPLETION_KEYWORDS.binary_search(&token).is_ok()
304}
305
306#[must_use]
308pub fn is_dap_completion_keyword(token: &str) -> bool {
309 DAP_COMPLETION_KEYWORDS.binary_search(&token).is_ok()
310}
311
312#[must_use]
314pub fn is_lsp_runtime_completion_keyword(token: &str) -> bool {
315 LSP_RUNTIME_COMPLETION_KEYWORDS.binary_search(&token).is_ok()
316}
317
318#[must_use]
320pub fn is_rename_keyword(token: &str) -> bool {
321 RENAME_KEYWORDS.binary_search(&token).is_ok()
322}
323
324#[must_use]
326pub fn is_parser_lsp_keyword(token: &str) -> bool {
327 PARSER_LSP_KEYWORDS.binary_search(&token).is_ok()
328}
329
330#[cfg(test)]
331mod tests {
332 use super::{
333 DAP_COMPLETION_KEYWORDS, KEYWORDS, LEXER_KEYWORDS, LSP_COMPLETION_KEYWORDS,
334 LSP_RUNTIME_COMPLETION_KEYWORDS, PARSER_LSP_KEYWORDS, RENAME_KEYWORDS,
335 is_dap_completion_keyword, is_keyword, is_lexer_keyword, is_lsp_completion_keyword,
336 is_lsp_runtime_completion_keyword, is_parser_lsp_keyword, is_rename_keyword,
337 };
338
339 fn assert_sorted_unique(name: &str, items: &[&str]) {
340 let mut last = "";
341 for &item in items {
342 assert!(item > last, "{name} must be sorted + unique: {item} after {last}");
343 last = item;
344 }
345 }
346
347 #[test]
348 fn keyword_lists_are_sorted_and_unique() {
349 assert_sorted_unique("KEYWORDS", KEYWORDS);
350 assert_sorted_unique("LSP_COMPLETION_KEYWORDS", LSP_COMPLETION_KEYWORDS);
351 assert_sorted_unique("DAP_COMPLETION_KEYWORDS", DAP_COMPLETION_KEYWORDS);
352 assert_sorted_unique("LSP_RUNTIME_COMPLETION_KEYWORDS", LSP_RUNTIME_COMPLETION_KEYWORDS);
353 assert_sorted_unique("RENAME_KEYWORDS", RENAME_KEYWORDS);
354 assert_sorted_unique("PARSER_LSP_KEYWORDS", PARSER_LSP_KEYWORDS);
355 assert_sorted_unique("LEXER_KEYWORDS", LEXER_KEYWORDS);
356 }
357
358 #[test]
359 fn known_keywords_are_present() {
360 assert!(is_keyword("my"));
361 assert!(is_keyword("foreach"));
362 assert!(is_keyword("print"));
363 assert!(is_keyword("__PACKAGE__"));
364 assert!(!is_keyword("definitely_not_a_perl_keyword"));
365 }
366
367 #[test]
368 fn lookup_helpers_match_bucket_membership() {
369 for &item in LSP_COMPLETION_KEYWORDS {
370 assert!(is_lsp_completion_keyword(item));
371 assert!(is_keyword(item));
372 }
373 for &item in DAP_COMPLETION_KEYWORDS {
374 assert!(is_dap_completion_keyword(item));
375 assert!(is_keyword(item));
376 }
377 for &item in LSP_RUNTIME_COMPLETION_KEYWORDS {
378 assert!(is_lsp_runtime_completion_keyword(item));
379 assert!(is_keyword(item));
380 }
381 for &item in RENAME_KEYWORDS {
382 assert!(is_rename_keyword(item));
383 assert!(is_keyword(item));
384 }
385 for &item in PARSER_LSP_KEYWORDS {
386 assert!(is_parser_lsp_keyword(item));
387 assert!(is_keyword(item));
388 }
389 for &item in LEXER_KEYWORDS {
390 assert!(is_lexer_keyword(item));
391 assert!(is_keyword(item));
392 }
393 }
394
395 #[test]
396 fn lookup_helpers_reject_unknown_tokens() {
397 assert!(!is_lsp_completion_keyword("print"));
398 assert!(!is_dap_completion_keyword("AUTOLOAD"));
399 assert!(!is_lsp_runtime_completion_keyword("AUTOLOAD"));
400 assert!(!is_rename_keyword("print"));
401 assert!(!is_parser_lsp_keyword("AUTOLOAD"));
402 assert!(!is_lexer_keyword("__PACKAGE__"));
403 }
404}