AbstractControlFlowReplacer.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { injectable, inject } from 'inversify';
  2. import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
  5. import { IControlFlowReplacer } from '../../../interfaces/node-transformers/IControlFlowReplacer';
  6. import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
  7. import { IOptions } from '../../../interfaces/options/IOptions';
  8. import { IStorage } from '../../../interfaces/storages/IStorage';
  9. import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
  10. @injectable()
  11. export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer {
  12. /**
  13. * @type {TCustomNodeFactory}
  14. */
  15. protected readonly customNodeFactory: TCustomNodeFactory;
  16. /**
  17. * @type {IOptions}
  18. */
  19. protected readonly options: IOptions;
  20. /**
  21. * @type {Map<string, Map<string, string[]>>}
  22. */
  23. protected readonly replacerDataByControlFlowStorageId: Map <string, Map<string, string[]>> = new Map();
  24. /**
  25. * @param customNodeFactory
  26. * @param options
  27. */
  28. constructor (
  29. @inject(ServiceIdentifiers.Factory__ICustomNode) customNodeFactory: TCustomNodeFactory,
  30. @inject(ServiceIdentifiers.IOptions) options: IOptions
  31. ) {
  32. this.customNodeFactory = customNodeFactory;
  33. this.options = options;
  34. }
  35. /**
  36. * @param identifierDataByControlFlowStorageId
  37. * @param controlFlowStorageId
  38. * @returns {Map<string, string[]>}
  39. */
  40. protected static getStorageKeysByIdForCurrentStorage (
  41. identifierDataByControlFlowStorageId: Map<string, Map<string, string[]>>,
  42. controlFlowStorageId: string
  43. ): Map<string, string[]> {
  44. let storageKeysById: Map<string, string[]>;
  45. if (identifierDataByControlFlowStorageId.has(controlFlowStorageId)) {
  46. storageKeysById = <Map<string, string[]>>identifierDataByControlFlowStorageId.get(controlFlowStorageId);
  47. } else {
  48. storageKeysById = new Map <string, string[]> ();
  49. }
  50. return storageKeysById;
  51. }
  52. /**
  53. * @param node
  54. * @param parentNode
  55. * @param controlFlowStorage
  56. * @returns {ESTree.Node}
  57. */
  58. public abstract replace (node: ESTree.Node, parentNode: ESTree.Node, controlFlowStorage: IStorage <ICustomNode>): ESTree.Node;
  59. /**
  60. * @param customNode
  61. * @param controlFlowStorage
  62. * @param replacerId
  63. * @param usingExistingIdentifierChance
  64. * @returns {string}
  65. */
  66. protected insertCustomNodeToControlFlowStorage (
  67. customNode: ICustomNode,
  68. controlFlowStorage: IStorage <ICustomNode>,
  69. replacerId: string,
  70. usingExistingIdentifierChance: number
  71. ): string {
  72. const controlFlowStorageId: string = controlFlowStorage.getStorageId();
  73. const storageKeysById: Map<string, string[]> = AbstractControlFlowReplacer
  74. .getStorageKeysByIdForCurrentStorage(this.replacerDataByControlFlowStorageId, controlFlowStorageId);
  75. const storageKeysForCurrentId: string[] | undefined = storageKeysById.get(replacerId);
  76. if (
  77. RandomGeneratorUtils.getMathRandom() > usingExistingIdentifierChance &&
  78. storageKeysForCurrentId &&
  79. storageKeysForCurrentId.length
  80. ) {
  81. return RandomGeneratorUtils.getRandomGenerator().pickone(storageKeysForCurrentId);
  82. }
  83. const generateStorageKey: (length: number) => string = (length: number) => {
  84. const storageKey: string = RandomGeneratorUtils.getRandomString(length);
  85. if (controlFlowStorage.getStorage().has(storageKey)) {
  86. return generateStorageKey(length);
  87. }
  88. return storageKey;
  89. };
  90. const storageKey: string = generateStorageKey(3);
  91. storageKeysById.set(replacerId, [storageKey]);
  92. this.replacerDataByControlFlowStorageId.set(controlFlowStorageId, storageKeysById);
  93. controlFlowStorage.set(storageKey, customNode);
  94. return storageKey;
  95. }
  96. }