You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

43 lines
1.1 KiB
JavaScript

"use strict";
const assert = require("assert");
const acceptableFirstCharacters = /^[a-zA-Z_]$/;
const acceptableSubsequentCharacters = /^[0-9a-zA-Z_]$/;
// This function deterministically and statelessly translates a name such that it is guaranteed to be valid in all identifier positions in JS.
// TODO: This can probably be made more performant...
function mangleCharacter(character) {
return (character === "$")
? "$$"
: `$${character.codePointAt(0)}`
}
module.exports = function mangleName(name) {
assert(name.length > 0);
// FIXME: Tag an identifier of this type with an internal property instead
if (name.startsWith("$$jsNix$")) {
return name;
} else {
let completedFirstCharacter = false;
return Array.from(name)
.map((character) => {
if (!completedFirstCharacter) {
completedFirstCharacter = true;
return (acceptableFirstCharacters.test(character))
? character
: mangleCharacter(character);
} else {
return (acceptableSubsequentCharacters.test(character))
? character
: mangleCharacter(character);
}
})
.join("");
}
};