| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | 'use strict';const {	isIdentifierName,	isStrictReservedWord,	isKeyword,} = require('@babel/helper-validator-identifier');const resolveVariableName = require('./resolve-variable-name.js');const getReferences = require('./get-references.js');// https://github.com/microsoft/TypeScript/issues/2536#issuecomment-87194347const typescriptReservedWords = new Set([	'break',	'case',	'catch',	'class',	'const',	'continue',	'debugger',	'default',	'delete',	'do',	'else',	'enum',	'export',	'extends',	'false',	'finally',	'for',	'function',	'if',	'import',	'in',	'instanceof',	'new',	'null',	'return',	'super',	'switch',	'this',	'throw',	'true',	'try',	'typeof',	'var',	'void',	'while',	'with',	'as',	'implements',	'interface',	'let',	'package',	'private',	'protected',	'public',	'static',	'yield',	'any',	'boolean',	'constructor',	'declare',	'get',	'module',	'require',	'number',	'set',	'string',	'symbol',	'type',	'from',	'of',]);// Copied from https://github.com/babel/babel/blob/fce35af69101c6b316557e28abf60bdbf77d6a36/packages/babel-types/src/validators/isValidIdentifier.ts#L7// Use this function instead of `require('@babel/types').isIdentifier`, since `@babel/helper-validator-identifier` package is much smallerconst isValidIdentifier = name =>	typeof name === 'string'	&& !isKeyword(name)	&& !isStrictReservedWord(name, true)	&& isIdentifierName(name)	&& name !== 'arguments'	&& !typescriptReservedWords.has(name);/*Unresolved reference is probably from the global scope. We should avoid using that name.For example, like `foo` and `bar` below.```function unicorn() {	return foo;}function unicorn() {	return function() {		return bar;	};}```*/const isUnresolvedName = (name, scope) =>	getReferences(scope).some(({identifier, resolved}) => identifier?.name === name && !resolved);const isSafeName = (name, scopes) =>	!scopes.some(scope => resolveVariableName(name, scope) || isUnresolvedName(name, scope));const alwaysTrue = () => true;/**Rule-specific name check function.@callback isSafe@param {string} name - The generated candidate name.@param {Scope[]} scopes - The same list of scopes you pass to `avoidCapture`.@returns {boolean} - `true` if the `name` is ok.*//**Generates a unique name prefixed with `name` such that:- it is not defined in any of the `scopes`,- it is not a reserved word,- it is not `arguments` in strict scopes (where `arguments` is not allowed),- it does not collide with the actual `arguments` (which is always defined in function scopes).Useful when you want to rename a variable (or create a new variable) while being sure not to shadow any other variables in the code.@param {string} name - The desired name for a new variable.@param {Scope[]} scopes - The list of scopes the new variable will be referenced in.@param {isSafe} [isSafe] - Rule-specific name check function.@returns {string} - Either `name` as is, or a string like `${name}_` suffixed with underscores to make the name unique.*/module.exports = (name, scopes, isSafe = alwaysTrue) => {	if (!isValidIdentifier(name)) {		name += '_';		if (!isValidIdentifier(name)) {			return;		}	}	while (!isSafeName(name, scopes) || !isSafe(name, scopes)) {		name += '_';	}	return name;};
 |