StringArrayCallNode.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { inject, injectable, } from 'inversify';
  2. import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
  5. import { TStatement } from '../../types/node/TStatement';
  6. import { TStringArrayIndexNodeFactory } from '../../types/container/custom-nodes/string-array-index-nodes/TStringArrayIndexNodeFactory';
  7. import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
  8. import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
  9. import { IOptions } from '../../interfaces/options/IOptions';
  10. import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
  11. import { IStringArrayScopeCallsWrapperParameterIndexesData } from '../../interfaces/node-transformers/string-array-transformers/IStringArrayScopeCallsWrapperParameterIndexesData';
  12. import { IStringArrayStorage } from '../../interfaces/storages/string-array-transformers/IStringArrayStorage';
  13. import { initializable } from '../../decorators/Initializable';
  14. import { AbstractStringArrayCallNode } from './AbstractStringArrayCallNode';
  15. import { NodeFactory } from '../../node/NodeFactory';
  16. import { NodeUtils } from '../../node/NodeUtils';
  17. @injectable()
  18. export class StringArrayCallNode extends AbstractStringArrayCallNode {
  19. /**
  20. * @type {string | null}
  21. */
  22. @initializable()
  23. private decodeKey!: string | null;
  24. /**
  25. * @type {number}
  26. */
  27. @initializable()
  28. private index!: number;
  29. /**
  30. * @type {number}
  31. */
  32. @initializable()
  33. private indexShiftAmount!: number;
  34. /**
  35. * @type {string}
  36. */
  37. @initializable()
  38. private stringArrayCallsWrapperName!: string;
  39. /**
  40. * @type {IStringArrayScopeCallsWrapperParameterIndexesData | null}
  41. */
  42. @initializable()
  43. private stringArrayCallsWrapperParameterIndexesData!: IStringArrayScopeCallsWrapperParameterIndexesData | null;
  44. /**
  45. * @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
  46. * @param {TStringArrayIndexNodeFactory} stringArrayIndexNodeFactory
  47. * @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
  48. * @param {IStringArrayStorage} stringArrayStorage
  49. * @param {IArrayUtils} arrayUtils
  50. * @param {IRandomGenerator} randomGenerator
  51. * @param {IOptions} options
  52. */
  53. public constructor (
  54. @inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
  55. identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
  56. @inject(ServiceIdentifiers.Factory__IStringArrayIndexNode)
  57. stringArrayIndexNodeFactory: TStringArrayIndexNodeFactory,
  58. @inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
  59. @inject(ServiceIdentifiers.IStringArrayStorage) stringArrayStorage: IStringArrayStorage,
  60. @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils,
  61. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
  62. @inject(ServiceIdentifiers.IOptions) options: IOptions
  63. ) {
  64. super(
  65. identifierNamesGeneratorFactory,
  66. stringArrayIndexNodeFactory,
  67. customCodeHelperFormatter,
  68. stringArrayStorage,
  69. arrayUtils,
  70. randomGenerator,
  71. options
  72. );
  73. }
  74. /**
  75. * @param {string} stringArrayCallsWrapperName
  76. * @param {IStringArrayScopeCallsWrapperParameterIndexesData | null} stringArrayCallsWrapperParameterIndexesData
  77. * @param {number} index
  78. * @param {number} indexShiftAmount
  79. * @param {string | null} decodeKey
  80. */
  81. public initialize (
  82. stringArrayCallsWrapperName: string,
  83. stringArrayCallsWrapperParameterIndexesData: IStringArrayScopeCallsWrapperParameterIndexesData | null,
  84. index: number,
  85. indexShiftAmount: number,
  86. decodeKey: string | null
  87. ): void {
  88. this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
  89. this.stringArrayCallsWrapperParameterIndexesData = stringArrayCallsWrapperParameterIndexesData;
  90. this.index = index;
  91. this.indexShiftAmount = indexShiftAmount;
  92. this.decodeKey = decodeKey;
  93. }
  94. /**
  95. * @returns {TStatement[]}
  96. */
  97. protected getNodeStructure (): TStatement[] {
  98. const resultIndex: number = this.indexShiftAmount + this.index;
  99. const indexNode: ESTree.Expression = this.getStringArrayIndexNode(resultIndex);
  100. const rc4KeyLiteralNode: ESTree.Literal | null = this.decodeKey
  101. ? this.getRc4KeyLiteralNode(this.decodeKey)
  102. : null;
  103. // filling call expression arguments with a fake arguments first
  104. const callExpressionArgs: ESTree.Expression[] = this.arrayUtils.fillWithRange(
  105. !this.stringArrayCallsWrapperParameterIndexesData
  106. // root string array calls wrapper
  107. ? AbstractStringArrayCallNode.stringArrayRootCallsWrapperParametersCount
  108. // scope string array calls wrapper
  109. : this.options.stringArrayWrappersParametersMaxCount,
  110. () => this.getFakeStringArrayIndexNode(resultIndex)
  111. );
  112. callExpressionArgs.splice(
  113. this.stringArrayCallsWrapperParameterIndexesData?.valueIndexParameterIndex ?? 0,
  114. 1,
  115. indexNode
  116. );
  117. if (this.stringArrayCallsWrapperParameterIndexesData) {
  118. callExpressionArgs.splice(
  119. this.stringArrayCallsWrapperParameterIndexesData.decodeKeyParameterIndex,
  120. 1,
  121. // use rc4 key literal node if exists or a node with fake string array wrapper index
  122. rc4KeyLiteralNode ?? this.getFakeStringArrayIndexNode(resultIndex)
  123. );
  124. } else if (rc4KeyLiteralNode) {
  125. callExpressionArgs.splice(1, 1, rc4KeyLiteralNode);
  126. } else {
  127. // have to delete element
  128. callExpressionArgs.splice(1, 1);
  129. }
  130. const structure: TStatement = NodeFactory.expressionStatementNode(
  131. NodeFactory.callExpressionNode(
  132. NodeFactory.identifierNode(this.stringArrayCallsWrapperName),
  133. callExpressionArgs
  134. )
  135. );
  136. NodeUtils.parentizeAst(structure);
  137. return [structure];
  138. }
  139. /**
  140. * @param {number} actualIndex
  141. * @returns {Expression}
  142. */
  143. private getFakeStringArrayIndexNode (actualIndex: number): ESTree.Expression {
  144. return this.getStringArrayIndexNode(this.getFakeStringArrayIndex(actualIndex));
  145. }
  146. /**
  147. * @param {number} actualIndex
  148. * @returns {number}
  149. */
  150. private getFakeStringArrayIndex (actualIndex: number): number {
  151. const stringArrayStorageLength: number = this.stringArrayStorage.getLength();
  152. const fakeIndexOffset: number = stringArrayStorageLength / 2;
  153. const minimumIndex: number = actualIndex - fakeIndexOffset;
  154. const maximumIndex: number = actualIndex + fakeIndexOffset;
  155. return this.randomGenerator.getRandomInteger(minimumIndex, maximumIndex);
  156. }
  157. }