|
@@ -0,0 +1,128 @@
|
|
|
+import { inject, injectable } from 'inversify';
|
|
|
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
|
|
|
+
|
|
|
+import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
|
|
|
+import { IOptions } from '../../interfaces/options/IOptions';
|
|
|
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
|
|
|
+
|
|
|
+import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGenerator';
|
|
|
+
|
|
|
+@injectable()
|
|
|
+export class DictionaryIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
|
|
|
+ /**
|
|
|
+ * @type {IArrayUtils}
|
|
|
+ */
|
|
|
+ private readonly arrayUtils: IArrayUtils;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @type {string[]}
|
|
|
+ */
|
|
|
+ private identifierNames: string[] = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @type {IterableIterator<string>}
|
|
|
+ */
|
|
|
+ private identifiersIterator: IterableIterator<string>;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param {IRandomGenerator} randomGenerator
|
|
|
+ * @param {IOptions} options
|
|
|
+ * @param {IArrayUtils} arrayUtils
|
|
|
+ */
|
|
|
+ constructor (
|
|
|
+ @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
|
|
|
+ @inject(ServiceIdentifiers.IOptions) options: IOptions,
|
|
|
+ @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils,
|
|
|
+ ) {
|
|
|
+ super(randomGenerator, options);
|
|
|
+
|
|
|
+ this.arrayUtils = arrayUtils;
|
|
|
+ this.identifierNames = this.getInitialIdentifierNames(this.options.identifiersDictionary);
|
|
|
+ this.identifiersIterator = this.identifierNames.values();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param {string} identifierName
|
|
|
+ * @returns {string | null}
|
|
|
+ */
|
|
|
+ private static incrementIdentifierName (identifierName: string): string | null {
|
|
|
+ let newIdentifierName: string = '';
|
|
|
+ let isSuccess: boolean = false;
|
|
|
+
|
|
|
+ for (const character of identifierName) {
|
|
|
+ if (!isSuccess && character === character.toUpperCase()) {
|
|
|
+ newIdentifierName += character.toLowerCase();
|
|
|
+ } else if (!isSuccess && character === character.toLowerCase()) {
|
|
|
+ newIdentifierName += character.toUpperCase();
|
|
|
+ isSuccess = true;
|
|
|
+ } else {
|
|
|
+ newIdentifierName += character;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isSuccess) {
|
|
|
+ return newIdentifierName;
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public generate (): string {
|
|
|
+ if (!this.identifierNames.length) {
|
|
|
+ throw new Error('Too many identifiers in the code, add more words to identifiers dictionary');
|
|
|
+ }
|
|
|
+
|
|
|
+ const iteratorResult: IteratorResult<string> = this.identifiersIterator.next();
|
|
|
+
|
|
|
+ if (!iteratorResult.done) {
|
|
|
+ return iteratorResult.value;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.identifierNames = this.getIncrementedIdentifierNames(this.identifierNames);
|
|
|
+ this.identifiersIterator = this.identifierNames.values();
|
|
|
+
|
|
|
+ return this.generate();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @returns {string}
|
|
|
+ */
|
|
|
+ public generateWithPrefix (): string {
|
|
|
+ const prefix: string = this.options.identifiersPrefix ?
|
|
|
+ `${this.options.identifiersPrefix}_`
|
|
|
+ : '';
|
|
|
+ const identifierName: string = this.generate();
|
|
|
+
|
|
|
+ return `${prefix}${identifierName}`.replace('__', '_');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param {string[]} identifierNames
|
|
|
+ * @returns {string[]}
|
|
|
+ */
|
|
|
+ private getInitialIdentifierNames (identifierNames: string[]): string[] {
|
|
|
+ const formattedIdentifierNames: string[] = identifierNames
|
|
|
+ .map((identifierName: string) => identifierName.toLowerCase());
|
|
|
+
|
|
|
+ return this.arrayUtils.shuffle(formattedIdentifierNames);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param {string[]} identifierNames
|
|
|
+ * @returns {string[]}
|
|
|
+ */
|
|
|
+ private getIncrementedIdentifierNames (identifierNames: string[]): string[] {
|
|
|
+ const formattedIdentifierNames: string[] = [];
|
|
|
+
|
|
|
+ for (const identifierName of identifierNames) {
|
|
|
+ const newIdentifierName: string | null = DictionaryIdentifierNamesGenerator
|
|
|
+ .incrementIdentifierName(identifierName);
|
|
|
+
|
|
|
+ if (newIdentifierName) {
|
|
|
+ formattedIdentifierNames.push(newIdentifierName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.arrayUtils.shuffle(formattedIdentifierNames);
|
|
|
+ }
|
|
|
+}
|