| 336 | } |
| 337 | |
| 338 | inline std::string makeSafeIdentifier (std::string s) |
| 339 | { |
| 340 | constexpr static std::string_view reservedWords[] = |
| 341 | { |
| 342 | "abstract", "arguments", "await", "boolean", "break", "byte", "case", "catch", |
| 343 | "char", "class", "const", "continue", "debugger", "default", "delete", "do", |
| 344 | "double", "else", "enum", "eval", "export", "extends", "false", "final", |
| 345 | "finally", "float", "for", "function", "goto", "if", "implements", "import", |
| 346 | "in", "instanceof", "int", "interface", "let", "long", "native", "new", |
| 347 | "null", "package", "private", "protected", "public", "return", "short", "static", |
| 348 | "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", |
| 349 | "try", "typeof", "var", "void", "volatile", "while", "with", "yield" |
| 350 | }; |
| 351 | |
| 352 | for (auto& c : s) |
| 353 | if (std::string_view (" ,./;:").find (c) != std::string_view::npos) |
| 354 | c = '_'; |
| 355 | |
| 356 | s.erase (std::remove_if (s.begin(), s.end(), [&] (char c) |
| 357 | { |
| 358 | return ! ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9')); |
| 359 | }), s.end()); |
| 360 | |
| 361 | if (s[0] >= '0' && s[0] <= '9') // Identifiers can't start with a digit |
| 362 | s = "_" + s; |
| 363 | |
| 364 | for (auto keyword : reservedWords) |
| 365 | if (s == keyword) |
| 366 | return s + "_"; |
| 367 | |
| 368 | return s; |
| 369 | } |
| 370 | |
| 371 | } // namespace choc::javascript |
| 372 | |