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.
|
|
|
"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("$")) {
|
|
|
|
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("");
|
|
|
|
}
|
|
|
|
};
|