StringArrayScopeCallsWrapperFunctionNode.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 { IStringArrayScopeCallsWrapperData } from '../../interfaces/node-transformers/string-array-transformers/IStringArrayScopeCallsWrapperData';
  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 {IStringArrayScopeCallsWrapperData}
  21. */
  22. @initializable()
  23. private upperStringArrayCallsWrapperData!: IStringArrayScopeCallsWrapperData;
  24. /**
  25. * @type {IStringArrayScopeCallsWrapperData}
  26. */
  27. @initializable()
  28. private stringArrayScopeCallsWrapperData!: IStringArrayScopeCallsWrapperData;
  29. /**
  30. * @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
  31. * @param {TStringArrayIndexNodeFactory} stringArrayIndexNodeFactory
  32. * @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
  33. * @param {IStringArrayStorage} stringArrayStorage
  34. * @param {IArrayUtils} arrayUtils
  35. * @param {IRandomGenerator} randomGenerator
  36. * @param {IOptions} options
  37. */
  38. public constructor (
  39. @inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
  40. identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
  41. @inject(ServiceIdentifiers.Factory__IStringArrayIndexNode)
  42. stringArrayIndexNodeFactory: TStringArrayIndexNodeFactory,
  43. @inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
  44. @inject(ServiceIdentifiers.IStringArrayStorage) stringArrayStorage: IStringArrayStorage,
  45. @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils,
  46. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
  47. @inject(ServiceIdentifiers.IOptions) options: IOptions
  48. ) {
  49. super(
  50. identifierNamesGeneratorFactory,
  51. stringArrayIndexNodeFactory,
  52. customCodeHelperFormatter,
  53. stringArrayStorage,
  54. arrayUtils,
  55. randomGenerator,
  56. options
  57. );
  58. }
  59. /**
  60. * @param {IStringArrayScopeCallsWrapperData} stringArrayScopeCallsWrapperData
  61. * @param {IStringArrayScopeCallsWrapperData} upperStringArrayCallsWrapperData
  62. */
  63. public initialize (
  64. stringArrayScopeCallsWrapperData: IStringArrayScopeCallsWrapperData,
  65. upperStringArrayCallsWrapperData: IStringArrayScopeCallsWrapperData,
  66. ): void {
  67. this.stringArrayScopeCallsWrapperData = stringArrayScopeCallsWrapperData;
  68. this.upperStringArrayCallsWrapperData = upperStringArrayCallsWrapperData;
  69. }
  70. /**
  71. * @returns {TStatement[]}
  72. */
  73. protected getNodeStructure (): TStatement[] {
  74. // identifiers of function expression parameters
  75. // as a temporary names use random strings
  76. const stringArrayCallIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  77. const decodeKeyIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  78. const stringArrayCallNode: ESTree.Expression = this.getUpperStringArrayCallNode(
  79. stringArrayCallIdentifierNode,
  80. this.getStringArrayIndexNode(
  81. this.stringArrayScopeCallsWrapperData.index
  82. - this.upperStringArrayCallsWrapperData.index
  83. )
  84. );
  85. // stage 1: function expression node parameters
  86. // filling all parameters with a fake parameters first
  87. const parameters: ESTree.Identifier[] = this.arrayUtils.fillWithRange(
  88. !this.stringArrayScopeCallsWrapperData.parameterIndexesData
  89. // root string array calls wrapper
  90. ? AbstractStringArrayCallNode.stringArrayRootCallsWrapperParametersCount
  91. // scope string array calls wrapper
  92. : this.options.stringArrayWrappersParametersMaxCount,
  93. () => this.getFakeParameterNode()
  94. );
  95. parameters.splice(
  96. this.stringArrayScopeCallsWrapperData.parameterIndexesData?.valueIndexParameterIndex ?? 0,
  97. 1,
  98. stringArrayCallIdentifierNode
  99. );
  100. parameters.splice(
  101. this.stringArrayScopeCallsWrapperData.parameterIndexesData?.decodeKeyParameterIndex ?? 1,
  102. 1,
  103. decodeKeyIdentifierNode
  104. );
  105. // stage 2: upper string array call expression arguments
  106. // filling all call expression arguments with a fake string array calls
  107. const callExpressionArgs: ESTree.Expression[] = this.arrayUtils.fillWithRange(
  108. !this.upperStringArrayCallsWrapperData.parameterIndexesData
  109. // root string array calls wrapper
  110. ? AbstractStringArrayCallNode.stringArrayRootCallsWrapperParametersCount
  111. // scope string array calls wrapper
  112. : this.options.stringArrayWrappersParametersMaxCount,
  113. (index: number) => this.getUpperStringArrayCallNode(
  114. parameters[index],
  115. this.getFakeUpperStringArrayIndexNode()
  116. )
  117. );
  118. callExpressionArgs.splice(
  119. this.upperStringArrayCallsWrapperData.parameterIndexesData?.valueIndexParameterIndex ?? 0,
  120. 1,
  121. stringArrayCallNode
  122. );
  123. callExpressionArgs.splice(
  124. this.upperStringArrayCallsWrapperData.parameterIndexesData?.decodeKeyParameterIndex ?? 1,
  125. 1,
  126. decodeKeyIdentifierNode
  127. );
  128. // stage 3: function declaration node
  129. const functionDeclarationNode: ESTree.FunctionDeclaration = NodeFactory.functionDeclarationNode(
  130. this.stringArrayScopeCallsWrapperData.name,
  131. parameters,
  132. NodeFactory.blockStatementNode([
  133. NodeFactory.returnStatementNode(
  134. NodeFactory.callExpressionNode(
  135. NodeFactory.identifierNode(this.upperStringArrayCallsWrapperData.name),
  136. callExpressionArgs
  137. )
  138. )
  139. ])
  140. );
  141. const structure: TStatement = functionDeclarationNode;
  142. NodeUtils.parentizeAst(structure);
  143. // stage 4: rename
  144. // have to generate names for both parameter and call identifiers
  145. for (const parameter of parameters) {
  146. parameter.name = this.identifierNamesGenerator.generateForLexicalScope(functionDeclarationNode);
  147. }
  148. return [structure];
  149. }
  150. /**
  151. * @param {Identifier} indexParameterIdentifierNode
  152. * @param {Expression} indexShiftNode
  153. * @returns {Expression}
  154. */
  155. private getUpperStringArrayCallNode (
  156. indexParameterIdentifierNode: ESTree.Identifier,
  157. indexShiftNode: ESTree.Expression
  158. ): ESTree.Expression {
  159. return NodeFactory.binaryExpressionNode(
  160. '-',
  161. indexParameterIdentifierNode,
  162. indexShiftNode
  163. );
  164. }
  165. /**
  166. * @returns {Identifier}
  167. */
  168. private getFakeParameterNode (): ESTree.Identifier {
  169. return NodeFactory.identifierNode(this.randomGenerator.getRandomString(6));
  170. }
  171. /**
  172. * @returns {Expression}
  173. */
  174. private getFakeUpperStringArrayIndexNode (): ESTree.Expression {
  175. return this.getStringArrayIndexNode(this.randomGenerator.getRandomInteger(0, 500));
  176. }
  177. }