1pub const PYTHON_KEYWORDS: &[&str] = &[
19 "False", "None", "True", "and", "as", "assert", "async", "await", "break", "class", "continue", "def", "del",
20 "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal",
21 "not", "or", "pass", "raise", "return", "try", "type", "while", "with", "yield",
22];
23
24pub const JAVA_KEYWORDS: &[&str] = &[
26 "abstract",
27 "assert",
28 "boolean",
29 "break",
30 "byte",
31 "case",
32 "catch",
33 "char",
34 "class",
35 "const",
36 "continue",
37 "default",
38 "do",
39 "double",
40 "else",
41 "enum",
42 "extends",
43 "final",
44 "finally",
45 "float",
46 "for",
47 "goto",
48 "if",
49 "implements",
50 "import",
51 "instanceof",
52 "int",
53 "interface",
54 "long",
55 "native",
56 "new",
57 "package",
58 "private",
59 "protected",
60 "public",
61 "return",
62 "short",
63 "static",
64 "strictfp",
65 "super",
66 "switch",
67 "synchronized",
68 "this",
69 "throw",
70 "throws",
71 "transient",
72 "try",
73 "void",
74 "volatile",
75 "while",
76];
77
78pub const CSHARP_KEYWORDS: &[&str] = &[
80 "abstract",
81 "as",
82 "base",
83 "bool",
84 "break",
85 "byte",
86 "case",
87 "catch",
88 "char",
89 "checked",
90 "class",
91 "const",
92 "continue",
93 "decimal",
94 "default",
95 "delegate",
96 "do",
97 "double",
98 "else",
99 "enum",
100 "event",
101 "explicit",
102 "extern",
103 "false",
104 "finally",
105 "fixed",
106 "float",
107 "for",
108 "foreach",
109 "goto",
110 "if",
111 "implicit",
112 "in",
113 "int",
114 "interface",
115 "internal",
116 "is",
117 "lock",
118 "long",
119 "namespace",
120 "new",
121 "null",
122 "object",
123 "operator",
124 "out",
125 "override",
126 "params",
127 "private",
128 "protected",
129 "public",
130 "readonly",
131 "ref",
132 "return",
133 "sbyte",
134 "sealed",
135 "short",
136 "sizeof",
137 "stackalloc",
138 "static",
139 "string",
140 "struct",
141 "switch",
142 "this",
143 "throw",
144 "true",
145 "try",
146 "typeof",
147 "uint",
148 "ulong",
149 "unchecked",
150 "unsafe",
151 "ushort",
152 "using",
153 "virtual",
154 "void",
155 "volatile",
156 "while",
157];
158
159pub const PHP_KEYWORDS: &[&str] = &[
161 "abstract",
162 "and",
163 "as",
164 "break",
165 "callable",
166 "case",
167 "catch",
168 "class",
169 "clone",
170 "const",
171 "continue",
172 "declare",
173 "default",
174 "die",
175 "do",
176 "echo",
177 "else",
178 "elseif",
179 "empty",
180 "enddeclare",
181 "endfor",
182 "endforeach",
183 "endif",
184 "endswitch",
185 "endwhile",
186 "eval",
187 "exit",
188 "extends",
189 "final",
190 "finally",
191 "fn",
192 "for",
193 "foreach",
194 "function",
195 "global",
196 "goto",
197 "if",
198 "implements",
199 "include",
200 "instanceof",
201 "insteadof",
202 "interface",
203 "isset",
204 "list",
205 "match",
206 "namespace",
207 "new",
208 "or",
209 "print",
210 "private",
211 "protected",
212 "public",
213 "readonly",
214 "require",
215 "return",
216 "static",
217 "switch",
218 "throw",
219 "trait",
220 "try",
221 "unset",
222 "use",
223 "var",
224 "while",
225 "xor",
226 "yield",
227];
228
229pub const RUBY_KEYWORDS: &[&str] = &[
231 "__ENCODING__",
232 "__FILE__",
233 "__LINE__",
234 "BEGIN",
235 "END",
236 "alias",
237 "and",
238 "begin",
239 "break",
240 "case",
241 "class",
242 "def",
243 "defined?",
244 "do",
245 "else",
246 "elsif",
247 "end",
248 "ensure",
249 "false",
250 "for",
251 "if",
252 "in",
253 "module",
254 "next",
255 "nil",
256 "not",
257 "or",
258 "redo",
259 "rescue",
260 "retry",
261 "return",
262 "self",
263 "super",
264 "then",
265 "true",
266 "undef",
267 "unless",
268 "until",
269 "when",
270 "while",
271 "yield",
272];
273
274pub const ELIXIR_KEYWORDS: &[&str] = &[
276 "after", "and", "catch", "do", "else", "end", "false", "fn", "in", "nil", "not", "or", "rescue", "true", "when",
277];
278
279pub const GO_KEYWORDS: &[&str] = &[
281 "break",
282 "case",
283 "chan",
284 "const",
285 "continue",
286 "default",
287 "defer",
288 "else",
289 "fallthrough",
290 "for",
291 "func",
292 "go",
293 "goto",
294 "if",
295 "import",
296 "interface",
297 "map",
298 "package",
299 "range",
300 "return",
301 "select",
302 "struct",
303 "switch",
304 "type",
305 "var",
306];
307
308pub const JS_KEYWORDS: &[&str] = &[
310 "abstract",
311 "arguments",
312 "await",
313 "boolean",
314 "break",
315 "byte",
316 "case",
317 "catch",
318 "char",
319 "class",
320 "const",
321 "continue",
322 "debugger",
323 "default",
324 "delete",
325 "do",
326 "double",
327 "else",
328 "enum",
329 "eval",
330 "export",
331 "extends",
332 "false",
333 "final",
334 "finally",
335 "float",
336 "for",
337 "function",
338 "goto",
339 "if",
340 "implements",
341 "import",
342 "in",
343 "instanceof",
344 "int",
345 "interface",
346 "let",
347 "long",
348 "native",
349 "new",
350 "null",
351 "package",
352 "private",
353 "protected",
354 "public",
355 "return",
356 "short",
357 "static",
358 "super",
359 "switch",
360 "synchronized",
361 "this",
362 "throw",
363 "throws",
364 "transient",
365 "true",
366 "try",
367 "typeof",
368 "var",
369 "void",
370 "volatile",
371 "while",
372 "with",
373 "yield",
374];
375
376pub const R_KEYWORDS: &[&str] = &[
378 "FALSE", "Inf", "NA", "NaN", "NULL", "TRUE", "break", "else", "for", "function", "if", "in", "next", "repeat",
379 "return", "while",
380];
381
382pub const KOTLIN_KEYWORDS: &[&str] = &[
384 "as",
385 "break",
386 "class",
387 "continue",
388 "do",
389 "else",
390 "false",
391 "for",
392 "fun",
393 "if",
394 "in",
395 "interface",
396 "is",
397 "null",
398 "object",
399 "package",
400 "return",
401 "super",
402 "this",
403 "throw",
404 "true",
405 "try",
406 "typealias",
407 "typeof",
408 "val",
409 "var",
410 "when",
411 "while",
412 "by",
414 "init",
415 "constructor",
416 "field",
417 "value",
418 "where",
419];
420
421pub const SWIFT_KEYWORDS: &[&str] = &[
423 "associatedtype",
424 "class",
425 "deinit",
426 "enum",
427 "extension",
428 "fileprivate",
429 "func",
430 "import",
431 "init",
432 "inout",
433 "internal",
434 "let",
435 "open",
436 "operator",
437 "private",
438 "protocol",
439 "public",
440 "rethrows",
441 "static",
442 "struct",
443 "subscript",
444 "typealias",
445 "var",
446 "break",
447 "case",
448 "continue",
449 "default",
450 "defer",
451 "do",
452 "else",
453 "fallthrough",
454 "for",
455 "guard",
456 "if",
457 "in",
458 "repeat",
459 "return",
460 "switch",
461 "where",
462 "while",
463 "as",
464 "Any",
465 "catch",
466 "false",
467 "is",
468 "nil",
469 "super",
470 "self",
471 "Self",
472 "throw",
473 "throws",
474 "true",
475 "try",
476 "_",
477];
478
479pub const DART_KEYWORDS: &[&str] = &[
481 "abstract",
482 "as",
483 "assert",
484 "async",
485 "await",
486 "break",
487 "case",
488 "catch",
489 "class",
490 "const",
491 "continue",
492 "covariant",
493 "default",
494 "deferred",
495 "do",
496 "dynamic",
497 "else",
498 "enum",
499 "export",
500 "extends",
501 "extension",
502 "external",
503 "factory",
504 "false",
505 "final",
506 "finally",
507 "for",
508 "Function",
509 "get",
510 "hide",
511 "if",
512 "implements",
513 "import",
514 "in",
515 "interface",
516 "is",
517 "late",
518 "library",
519 "mixin",
520 "new",
521 "null",
522 "of",
523 "on",
524 "operator",
525 "part",
526 "required",
527 "rethrow",
528 "return",
529 "set",
530 "show",
531 "static",
532 "super",
533 "switch",
534 "sync",
535 "this",
536 "throw",
537 "true",
538 "try",
539 "typedef",
540 "var",
541 "void",
542 "when",
543 "while",
544 "with",
545 "yield",
546];
547
548pub const GLEAM_KEYWORDS: &[&str] = &[
550 "as",
551 "assert",
552 "auto",
553 "case",
554 "const",
555 "delegate",
556 "derive",
557 "echo",
558 "else",
559 "fn",
560 "if",
561 "implement",
562 "import",
563 "let",
564 "macro",
565 "opaque",
566 "panic",
567 "pub",
568 "test",
569 "todo",
570 "type",
571 "use",
572];
573
574pub const ZIG_KEYWORDS: &[&str] = &[
576 "addrspace",
577 "align",
578 "allowzero",
579 "and",
580 "anyframe",
581 "anytype",
582 "asm",
583 "async",
584 "await",
585 "break",
586 "callconv",
587 "catch",
588 "comptime",
589 "const",
590 "continue",
591 "defer",
592 "else",
593 "enum",
594 "errdefer",
595 "error",
596 "export",
597 "extern",
598 "fn",
599 "for",
600 "if",
601 "inline",
602 "linksection",
603 "noalias",
604 "noinline",
605 "nosuspend",
606 "or",
607 "orelse",
608 "packed",
609 "pub",
610 "resume",
611 "return",
612 "struct",
613 "suspend",
614 "switch",
615 "test",
616 "threadlocal",
617 "try",
618 "union",
619 "unreachable",
620 "usingnamespace",
621 "var",
622 "volatile",
623 "while",
624];
625
626pub fn python_safe_name(name: &str) -> Option<String> {
634 if PYTHON_KEYWORDS.contains(&name) {
635 Some(format!("{name}_"))
636 } else {
637 None
638 }
639}
640
641pub fn python_ident(name: &str) -> String {
644 python_safe_name(name).unwrap_or_else(|| name.to_string())
645}
646
647pub fn kotlin_safe_name(name: &str) -> Option<String> {
649 if KOTLIN_KEYWORDS.contains(&name) {
650 Some(format!("{name}_"))
651 } else {
652 None
653 }
654}
655
656pub fn kotlin_ident(name: &str) -> String {
658 kotlin_safe_name(name).unwrap_or_else(|| name.to_string())
659}
660
661pub fn swift_safe_name(name: &str) -> Option<String> {
663 if SWIFT_KEYWORDS.contains(&name) {
664 Some(format!("{name}_"))
665 } else {
666 None
667 }
668}
669
670pub fn swift_ident(name: &str) -> String {
672 swift_safe_name(name).unwrap_or_else(|| name.to_string())
673}
674
675pub fn swift_case_safe_name(name: &str) -> Option<String> {
684 if SWIFT_KEYWORDS.contains(&name) {
685 Some(format!("`{name}`"))
686 } else {
687 None
688 }
689}
690
691pub fn swift_case_ident(name: &str) -> String {
698 swift_case_safe_name(name).unwrap_or_else(|| name.to_string())
699}
700
701pub fn dart_safe_name(name: &str) -> Option<String> {
703 if DART_KEYWORDS.contains(&name) {
704 Some(format!("{name}_"))
705 } else {
706 None
707 }
708}
709
710pub fn dart_ident(name: &str) -> String {
712 dart_safe_name(name).unwrap_or_else(|| name.to_string())
713}
714
715pub fn gleam_safe_name(name: &str) -> Option<String> {
717 if GLEAM_KEYWORDS.contains(&name) {
718 Some(format!("{name}_"))
719 } else {
720 None
721 }
722}
723
724pub fn gleam_ident(name: &str) -> String {
726 gleam_safe_name(name).unwrap_or_else(|| name.to_string())
727}
728
729pub fn zig_safe_name(name: &str) -> Option<String> {
731 if ZIG_KEYWORDS.contains(&name) {
732 Some(format!("{name}_"))
733 } else {
734 None
735 }
736}
737
738pub fn zig_ident(name: &str) -> String {
740 zig_safe_name(name).unwrap_or_else(|| name.to_string())
741}
742
743#[cfg(test)]
744mod tests {
745 use super::*;
746
747 #[test]
748 fn python_class_is_reserved() {
749 assert_eq!(python_safe_name("class"), Some("class_".to_string()));
750 }
751
752 #[test]
753 fn python_ordinary_name_is_none() {
754 assert_eq!(python_safe_name("layout_class"), None);
755 }
756
757 #[test]
758 fn python_ident_reserved() {
759 assert_eq!(python_ident("class"), "class_");
760 }
761
762 #[test]
763 fn python_ident_ordinary() {
764 assert_eq!(python_ident("layout_class"), "layout_class");
765 }
766
767 #[test]
768 fn kotlin_class_is_reserved() {
769 assert_eq!(kotlin_safe_name("class"), Some("class_".to_string()));
770 assert_eq!(kotlin_safe_name("fun"), Some("fun_".to_string()));
771 assert_eq!(kotlin_safe_name("ordinary"), None);
772 assert_eq!(kotlin_ident("typealias"), "typealias_");
773 }
774
775 #[test]
776 fn swift_init_is_reserved() {
777 assert_eq!(swift_safe_name("init"), Some("init_".to_string()));
778 assert_eq!(swift_safe_name("Self"), Some("Self_".to_string()));
779 assert_eq!(swift_safe_name("normal"), None);
780 assert_eq!(swift_ident("protocol"), "protocol_");
781 }
782
783 #[test]
784 fn swift_case_ident_backtick_escapes_reserved_keywords() {
785 assert_eq!(swift_case_ident("default"), "`default`");
791 assert_eq!(swift_case_ident("protocol"), "`protocol`");
792 assert_eq!(swift_case_ident("init"), "`init`");
793 assert_eq!(swift_case_ident("Self"), "`Self`");
794 assert_eq!(swift_case_ident("Any"), "`Any`");
795 assert_eq!(swift_case_ident("class"), "`class`");
796 assert_eq!(swift_case_ident("inout"), "`inout`");
797 assert_eq!(swift_case_ident("rethrows"), "`rethrows`");
798 assert_eq!(swift_case_ident("gitHub"), "gitHub");
800 assert_eq!(swift_case_ident("normal"), "normal");
801 assert_eq!(swift_case_ident("dracula"), "dracula");
802 }
803
804 #[test]
805 fn swift_case_safe_name_returns_some_for_reserved() {
806 assert_eq!(swift_case_safe_name("default"), Some("`default`".to_string()));
807 assert_eq!(swift_case_safe_name("normal"), None);
808 }
809
810 #[test]
811 fn dart_async_is_reserved() {
812 assert_eq!(dart_safe_name("async"), Some("async_".to_string()));
813 assert_eq!(dart_safe_name("late"), Some("late_".to_string()));
814 assert_eq!(dart_safe_name("normal"), None);
815 assert_eq!(dart_ident("required"), "required_");
816 }
817
818 #[test]
819 fn gleam_pub_is_reserved() {
820 assert_eq!(gleam_safe_name("pub"), Some("pub_".to_string()));
821 assert_eq!(gleam_safe_name("opaque"), Some("opaque_".to_string()));
822 assert_eq!(gleam_safe_name("normal"), None);
823 assert_eq!(gleam_ident("type"), "type_");
824 }
825
826 #[test]
827 fn zig_comptime_is_reserved() {
828 assert_eq!(zig_safe_name("comptime"), Some("comptime_".to_string()));
829 assert_eq!(zig_safe_name("errdefer"), Some("errdefer_".to_string()));
830 assert_eq!(zig_safe_name("normal"), None);
831 assert_eq!(zig_ident("usingnamespace"), "usingnamespace_");
832 }
833
834 #[test]
835 fn python_keywords_covers_common_cases() {
836 for kw in &[
837 "def", "return", "yield", "pass", "import", "from", "type", "None", "True", "False",
838 ] {
839 assert!(
840 python_safe_name(kw).is_some(),
841 "expected {kw:?} to be a Python reserved keyword"
842 );
843 }
844 }
845}