StringArrayScopeCallsWrapperFunctionNode.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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 StringArrayScopeCallsWrapperFunctionNode extends AbstractStringArrayCallNode {
  19. /**
  20. * @type {number}
  21. */
  22. @initializable()
  23. private shiftedIndex!: number;
  24. /**
  25. * @type {string}
  26. */
  27. @initializable()
  28. private upperStringArrayCallsWrapperName!: string;
  29. /**
  30. * @type {IStringArrayScopeCallsWrapperParameterIndexesData}
  31. */
  32. @initializable()
  33. private upperStringArrayCallsWrapperParameterIndexesData!: IStringArrayScopeCallsWrapperParameterIndexesData | null;
  34. /**
  35. * @type {string}
  36. */
  37. @initializable()
  38. private stringArrayScopeCallsWrapperName!: string;
  39. /**
  40. * @type {IStringArrayScopeCallsWrapperParameterIndexesData}
  41. */
  42. @initializable()
  43. private stringArrayScopeCallsWrapperParameterIndexesData!: 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} stringArrayScopeCallsWrapperName
  76. * @param {IStringArrayScopeCallsWrapperParameterIndexesData | null} stringArrayScopeCallsWrapperParameterIndexesData
  77. * @param {string} upperStringArrayCallsWrapperName
  78. * @param {IStringArrayScopeCallsWrapperParameterIndexesData | null} upperStringArrayCallsWrapperParameterIndexesData
  79. * @param {number} shiftedIndex
  80. */
  81. public initialize (
  82. stringArrayScopeCallsWrapperName: string,
  83. stringArrayScopeCallsWrapperParameterIndexesData: IStringArrayScopeCallsWrapperParameterIndexesData | null,
  84. upperStringArrayCallsWrapperName: string,
  85. upperStringArrayCallsWrapperParameterIndexesData: IStringArrayScopeCallsWrapperParameterIndexesData | null,
  86. shiftedIndex: number,
  87. ): void {
  88. this.stringArrayScopeCallsWrapperName = stringArrayScopeCallsWrapperName;
  89. this.stringArrayScopeCallsWrapperParameterIndexesData = stringArrayScopeCallsWrapperParameterIndexesData;
  90. this.upperStringArrayCallsWrapperName = upperStringArrayCallsWrapperName;
  91. this.upperStringArrayCallsWrapperParameterIndexesData = upperStringArrayCallsWrapperParameterIndexesData;
  92. this.shiftedIndex = shiftedIndex;
  93. }
  94. /**
  95. * @returns {TStatement[]}
  96. */
  97. protected getNodeStructure (): TStatement[] {
  98. // identifiers of function expression parameters
  99. // as a temporary names use random strings
  100. const stringArrayCallIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  101. const decodeKeyIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  102. const stringArrayCallNode: ESTree.Expression = this.getUpperStringArrayCallNode(
  103. stringArrayCallIdentifierNode,
  104. this.getStringArrayIndexNode(this.shiftedIndex)
  105. );
  106. // stage 1: function expression node parameters
  107. // filling all parameters with a fake parameters first
  108. const parameters: ESTree.Identifier[] = this.arrayUtils.fillWithRange(
  109. !this.stringArrayScopeCallsWrapperParameterIndexesData
  110. // root string array calls wrapper
  111. ? AbstractStringArrayCallNode.stringArrayRootCallsWrapperParametersCount
  112. // scope string array calls wrapper
  113. : this.options.stringArrayWrappersParametersMaxCount,
  114. () => this.getFakeParameterNode()
  115. );
  116. parameters.splice(
  117. this.stringArrayScopeCallsWrapperParameterIndexesData?.valueIndexParameterIndex ?? 0,
  118. 1,
  119. stringArrayCallIdentifierNode
  120. );
  121. parameters.splice(
  122. this.stringArrayScopeCallsWrapperParameterIndexesData?.decodeKeyParameterIndex ?? 1,
  123. 1,
  124. decodeKeyIdentifierNode
  125. );
  126. // stage 2: upper string array call expression arguments
  127. // filling all call expression arguments with a fake string array calls
  128. const callExpressionArgs: ESTree.Expression[] = this.arrayUtils.fillWithRange(
  129. !this.upperStringArrayCallsWrapperParameterIndexesData
  130. // root string array calls wrapper
  131. ? AbstractStringArrayCallNode.stringArrayRootCallsWrapperParametersCount
  132. // scope string array calls wrapper
  133. : this.options.stringArrayWrappersParametersMaxCount,
  134. (index: number) => this.getUpperStringArrayCallNode(
  135. parameters[index],
  136. this.getFakeUpperStringArrayIndexNode()
  137. )
  138. );
  139. callExpressionArgs.splice(
  140. this.upperStringArrayCallsWrapperParameterIndexesData?.valueIndexParameterIndex ?? 0,
  141. 1,
  142. stringArrayCallNode
  143. );
  144. callExpressionArgs.splice(
  145. this.upperStringArrayCallsWrapperParameterIndexesData?.decodeKeyParameterIndex ?? 1,
  146. 1,
  147. decodeKeyIdentifierNode
  148. );
  149. // stage 3: function declaration node
  150. const functionDeclarationNode: ESTree.FunctionDeclaration = NodeFactory.functionDeclarationNode(
  151. this.stringArrayScopeCallsWrapperName,
  152. parameters,
  153. NodeFactory.blockStatementNode([
  154. NodeFactory.returnStatementNode(
  155. NodeFactory.callExpressionNode(
  156. NodeFactory.identifierNode(this.upperStringArrayCallsWrapperName),
  157. callExpressionArgs
  158. )
  159. )
  160. ])
  161. );
  162. const structure: TStatement = functionDeclarationNode;
  163. NodeUtils.parentizeAst(structure);
  164. // stage 4: rename
  165. // have to generate names for both parameter and call identifiers
  166. for (const parameter of parameters) {
  167. parameter.name = this.identifierNamesGenerator.generateForLexicalScope(functionDeclarationNode);
  168. }
  169. return [structure];
  170. }
  171. /**
  172. * @param {Identifier} indexParameterIdentifierNode
  173. * @param {Expression} indexShiftNode
  174. * @returns {Expression}
  175. */
  176. private getUpperStringArrayCallNode (
  177. indexParameterIdentifierNode: ESTree.Identifier,
  178. indexShiftNode: ESTree.Expression
  179. ): ESTree.Expression {
  180. return NodeFactory.binaryExpressionNode(
  181. '-',
  182. indexParameterIdentifierNode,
  183. indexShiftNode
  184. );
  185. }
  186. /**
  187. * @returns {Identifier}
  188. */
  189. private getFakeParameterNode (): ESTree.Identifier {
  190. return NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  191. }
  192. /**
  193. * @returns {Expression}
  194. */
  195. private getFakeUpperStringArrayIndexNode (): ESTree.Expression {
  196. return this.getStringArrayIndexNode(this.randomGenerator.getRandomInteger(0, 500));
  197. }
  198. }