123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import { inject, injectable, } from 'inversify';
- import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
- import * as ESTree from 'estree';
- import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
- import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
- import { IIdentifierNamesCacheStorage } from '../../../interfaces/storages/identifier-names-cache/IIdentifierNamesCacheStorage';
- import { IIdentifierNamesGenerator } from '../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
- import { IIdentifierReplacer } from '../../../interfaces/node-transformers/rename-identifiers-transformers/replacer/IIdentifierReplacer';
- import { IOptions } from '../../../interfaces/options/IOptions';
- import { NodeFactory } from '../../../node/NodeFactory';
- @injectable()
- export class IdentifierReplacer implements IIdentifierReplacer {
- /**
- * @type {IIdentifierNamesCacheStorage}
- */
- private readonly identifierNamesCacheStorage: IIdentifierNamesCacheStorage;
- /**
- * @type {IIdentifierNamesGenerator}
- */
- private readonly identifierNamesGenerator: IIdentifierNamesGenerator;
- /**
- * @type {Map<TNodeWithLexicalScope, Map<string, string>>}
- */
- private readonly blockScopesMap: Map<TNodeWithLexicalScope, Map<string, string>> = new Map();
- /**
- * @type {IOptions}
- */
- private readonly options: IOptions;
- /**
- * @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
- * @param {IIdentifierNamesCacheStorage} identifierNamesCacheStorage
- * @param {IOptions} options
- */
- public constructor (
- @inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
- identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
- @inject(ServiceIdentifiers.IIdentifierNamesCacheStorage)
- identifierNamesCacheStorage: IIdentifierNamesCacheStorage,
- @inject(ServiceIdentifiers.IOptions) options: IOptions
- ) {
- this.options = options;
- this.identifierNamesCacheStorage = identifierNamesCacheStorage;
- this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
- }
- /**
- * Store `nodeName` of global identifiers as key in map with random name as value.
- * Reserved name will be ignored.
- *
- * @param {Node} identifierNode
- * @param {TNodeWithLexicalScope} lexicalScopeNode
- */
- public storeGlobalName (identifierNode: ESTree.Identifier, lexicalScopeNode: TNodeWithLexicalScope): void {
- const identifierName: string = identifierNode.name;
- if (this.isReservedName(identifierName)) {
- return;
- }
- const valueFromIdentifierNamesCache: string | null = this.identifierNamesCacheStorage.get(identifierName) ?? null;
- let newIdentifierName: string;
- if (valueFromIdentifierNamesCache) {
- newIdentifierName = valueFromIdentifierNamesCache;
- } else {
- newIdentifierName = this.identifierNamesGenerator.generateForGlobalScope();
- }
- if (!this.blockScopesMap.has(lexicalScopeNode)) {
- this.blockScopesMap.set(lexicalScopeNode, new Map());
- }
- const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
- namesMap.set(identifierName, newIdentifierName);
- if (valueFromIdentifierNamesCache !== newIdentifierName) {
- this.identifierNamesCacheStorage.set(identifierName, newIdentifierName);
- }
- }
- /**
- * Store `nodeName` of local identifier as key in map with random name as value.
- * Reserved name will be ignored.
- *
- * @param {Identifier} identifierNode
- * @param {TNodeWithLexicalScope} lexicalScopeNode
- */
- public storeLocalName (identifierNode: ESTree.Identifier, lexicalScopeNode: TNodeWithLexicalScope): void {
- const identifierName: string = identifierNode.name;
- if (this.isReservedName(identifierName)) {
- return;
- }
- const newIdentifierName: string = this.identifierNamesGenerator.generateForLexicalScope(lexicalScopeNode);
- if (!this.blockScopesMap.has(lexicalScopeNode)) {
- this.blockScopesMap.set(lexicalScopeNode, new Map());
- }
- const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
- namesMap.set(identifierName, newIdentifierName);
- }
- /**
- * @param {Identifier} identifierNode
- * @param {TNodeWithLexicalScope} lexicalScopeNode
- * @returns {Identifier}
- */
- public replace (identifierNode: ESTree.Identifier, lexicalScopeNode: TNodeWithLexicalScope): ESTree.Identifier {
- let identifierName: string = identifierNode.name;
- if (this.blockScopesMap.has(lexicalScopeNode)) {
- const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
- if (namesMap.has(identifierName)) {
- identifierName = <string>namesMap.get(identifierName);
- }
- }
- return NodeFactory.identifierNode(identifierName);
- }
- /**
- * Preserve `name` to protect it from further using
- *
- * @param {Identifier} identifierNode
- */
- public preserveName (identifierNode: ESTree.Identifier): void {
- this.identifierNamesGenerator.preserveName(identifierNode.name);
- }
- /**
- * Preserve `name` to protect it from further using
- *
- * @param {Identifier} identifierNode
- * @param {TNodeWithLexicalScope} lexicalScopeNode
- */
- public preserveNameForLexicalScope (identifierNode: ESTree.Identifier, lexicalScopeNode: TNodeWithLexicalScope): void {
- this.identifierNamesGenerator.preserveNameForLexicalScope(identifierNode.name, lexicalScopeNode);
- }
- /**
- * @param {string} name
- * @returns {boolean}
- */
- private isReservedName (name: string): boolean {
- if (!this.options.reservedNames.length) {
- return false;
- }
- return this.options.reservedNames
- .some((reservedName: string) => {
- return new RegExp(reservedName, 'g').exec(name) !== null;
- });
- }
- }
|