|
| 1 | +//! Shared sanitization utilities for code generation. |
| 2 | +//! |
| 3 | +//! Contains reserved word handling and name sanitization used by both |
| 4 | +//! schema codegen and ABI codegen. |
| 5 | +
|
| 6 | +/// Reserved words in AssemblyScript that need to be escaped. |
| 7 | +/// |
| 8 | +/// This is a superset of reserved words from ECMAScript plus AssemblyScript-specific |
| 9 | +/// additions. When a field or parameter name matches one of these, it gets |
| 10 | +/// an underscore appended. |
| 11 | +pub const RESERVED_WORDS: &[&str] = &[ |
| 12 | + "await", |
| 13 | + "break", |
| 14 | + "case", |
| 15 | + "catch", |
| 16 | + "class", |
| 17 | + "const", |
| 18 | + "continue", |
| 19 | + "debugger", |
| 20 | + "default", |
| 21 | + "delete", |
| 22 | + "do", |
| 23 | + "else", |
| 24 | + "enum", |
| 25 | + "export", |
| 26 | + "extends", |
| 27 | + "false", |
| 28 | + "finally", |
| 29 | + "for", |
| 30 | + "function", |
| 31 | + "if", |
| 32 | + "implements", |
| 33 | + "import", |
| 34 | + "in", |
| 35 | + "instanceof", |
| 36 | + "interface", |
| 37 | + "let", |
| 38 | + "new", |
| 39 | + "null", |
| 40 | + "package", |
| 41 | + "private", |
| 42 | + "protected", |
| 43 | + "public", |
| 44 | + "return", |
| 45 | + "static", |
| 46 | + "super", |
| 47 | + "switch", |
| 48 | + "this", |
| 49 | + "throw", |
| 50 | + "true", |
| 51 | + "try", |
| 52 | + "typeof", |
| 53 | + "var", |
| 54 | + "void", |
| 55 | + "while", |
| 56 | + "with", |
| 57 | + "yield", |
| 58 | +]; |
| 59 | + |
| 60 | +/// Handle reserved words by appending an underscore. |
| 61 | +/// |
| 62 | +/// If the given name is a reserved word in AssemblyScript, returns the name |
| 63 | +/// with an underscore appended. Otherwise returns the name unchanged. |
| 64 | +pub fn handle_reserved_word(name: &str) -> String { |
| 65 | + if RESERVED_WORDS.contains(&name) { |
| 66 | + format!("{}_", name) |
| 67 | + } else { |
| 68 | + name.to_string() |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +/// Capitalize the first letter of a string. |
| 73 | +/// |
| 74 | +/// Returns an empty string if the input is empty, otherwise returns the |
| 75 | +/// string with the first character uppercased. |
| 76 | +pub fn capitalize(s: &str) -> String { |
| 77 | + let mut chars = s.chars(); |
| 78 | + match chars.next() { |
| 79 | + None => String::new(), |
| 80 | + Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(), |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +#[cfg(test)] |
| 85 | +mod tests { |
| 86 | + use super::*; |
| 87 | + |
| 88 | + #[test] |
| 89 | + fn test_handle_reserved_word_reserved() { |
| 90 | + assert_eq!(handle_reserved_word("class"), "class_"); |
| 91 | + assert_eq!(handle_reserved_word("return"), "return_"); |
| 92 | + assert_eq!(handle_reserved_word("await"), "await_"); |
| 93 | + assert_eq!(handle_reserved_word("default"), "default_"); |
| 94 | + } |
| 95 | + |
| 96 | + #[test] |
| 97 | + fn test_handle_reserved_word_not_reserved() { |
| 98 | + assert_eq!(handle_reserved_word("myField"), "myField"); |
| 99 | + assert_eq!(handle_reserved_word("amount"), "amount"); |
| 100 | + assert_eq!(handle_reserved_word("value"), "value"); |
| 101 | + } |
| 102 | + |
| 103 | + #[test] |
| 104 | + fn test_capitalize() { |
| 105 | + assert_eq!(capitalize("hello"), "Hello"); |
| 106 | + assert_eq!(capitalize("world"), "World"); |
| 107 | + assert_eq!(capitalize(""), ""); |
| 108 | + assert_eq!(capitalize("a"), "A"); |
| 109 | + assert_eq!(capitalize("ALREADY"), "ALREADY"); |
| 110 | + } |
| 111 | +} |
0 commit comments