import { isIdentifierStart, isIdentifierChar } from 'acorn'; | |
import full_char_code_at from './full_char_code_at.js'; | |
import { regex_starts_with_underscore, regex_ends_with_underscore } from './patterns.js'; | |
export const reserved = new Set([ | |
'arguments', | |
'await', | |
'break', | |
'case', | |
'catch', | |
'class', | |
'const', | |
'continue', | |
'debugger', | |
'default', | |
'delete', | |
'do', | |
'else', | |
'enum', | |
'eval', | |
'export', | |
'extends', | |
'false', | |
'finally', | |
'for', | |
'function', | |
'if', | |
'implements', | |
'import', | |
'in', | |
'instanceof', | |
'interface', | |
'let', | |
'new', | |
'null', | |
'package', | |
'private', | |
'protected', | |
'public', | |
'return', | |
'static', | |
'super', | |
'switch', | |
'this', | |
'throw', | |
'true', | |
'try', | |
'typeof', | |
'var', | |
'void', | |
'while', | |
'with', | |
'yield' | |
]); | |
/** | |
* @param {string} str | |
* @returns {boolean} | |
*/ | |
export function is_valid(str) { | |
let i = 0; | |
while (i < str.length) { | |
const code = full_char_code_at(str, i); | |
if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true)) return false; | |
i += code <= 0xffff ? 1 : 2; | |
} | |
return true; | |
} | |
const regex_non_standard_characters = /[^a-zA-Z0-9_]+/g; | |
const regex_starts_with_number = /^[0-9]/; | |
/** | |
* @param {string} name | |
*/ | |
export function sanitize(name) { | |
return name | |
.replace(regex_non_standard_characters, '_') | |
.replace(regex_starts_with_underscore, '') | |
.replace(regex_ends_with_underscore, '') | |
.replace(regex_starts_with_number, '_$&'); | |
} | |