ObjectExpressionKeysTransformer.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { inject, injectable } from 'inversify';
  2. import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TPropertiesExtractorFactory } from '../../types/container/node-transformers/TPropertiesExtractorFactory';
  5. import { IOptions } from '../../interfaces/options/IOptions';
  6. import { IPropertiesExtractor } from '../../interfaces/node-transformers/converting-transformers/properties-extractors/IPropertiesExtractor';
  7. import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
  8. import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
  9. import { NodeType } from '../../enums/node/NodeType';
  10. import { PropertiesExtractor } from '../../enums/node-transformers/converting-transformers/properties-extractors/PropertiesExtractor';
  11. import { TransformationStage } from '../../enums/node-transformers/TransformationStage';
  12. import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
  13. import { NodeGuards } from '../../node/NodeGuards';
  14. @injectable()
  15. export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
  16. /**
  17. * @type {Map<string, PropertiesExtractor>}
  18. */
  19. private static readonly propertiesExtractorsMap: Map <string, PropertiesExtractor> = new Map([
  20. [NodeType.AssignmentExpression, PropertiesExtractor.AssignmentExpressionPropertiesExtractor],
  21. [NodeType.VariableDeclarator, PropertiesExtractor.VariableDeclaratorPropertiesExtractor]
  22. ]);
  23. /**
  24. * @type {TPropertiesExtractorFactory}
  25. */
  26. private readonly propertiesExtractorFactory: TPropertiesExtractorFactory;
  27. /**
  28. * @param {TPropertiesExtractorFactory} propertiesExtractorFactory
  29. * @param {IRandomGenerator} randomGenerator
  30. * @param {IOptions} options
  31. */
  32. constructor (
  33. @inject(ServiceIdentifiers.Factory__IPropertiesExtractor)
  34. propertiesExtractorFactory: TPropertiesExtractorFactory,
  35. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
  36. @inject(ServiceIdentifiers.IOptions) options: IOptions
  37. ) {
  38. super(randomGenerator, options);
  39. this.propertiesExtractorFactory = propertiesExtractorFactory;
  40. }
  41. /**
  42. * @param {TransformationStage} transformationStage
  43. * @returns {IVisitor | null}
  44. */
  45. public getVisitor (transformationStage: TransformationStage): IVisitor | null {
  46. if (!this.options.transformObjectKeys) {
  47. return null;
  48. }
  49. if (transformationStage !== TransformationStage.Converting) {
  50. return null;
  51. }
  52. return {
  53. enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
  54. if (
  55. parentNode
  56. && NodeGuards.isObjectExpressionNode(node)
  57. ) {
  58. return this.transformNode(node, parentNode);
  59. }
  60. },
  61. leave: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
  62. if (
  63. parentNode
  64. && NodeGuards.isObjectExpressionNode(node)
  65. ) {
  66. return this.transformNodeWithBaseExtractor(node, parentNode);
  67. }
  68. }
  69. };
  70. }
  71. /**
  72. * replaces:
  73. * var object = {
  74. * foo: 1,
  75. * bar: 2
  76. * };
  77. *
  78. * on:
  79. * var object = {};
  80. * object['foo'] = 1;
  81. * object['bar'] = 2;
  82. *
  83. * @param {ObjectExpression} objectExpressionNode
  84. * @param {Node} parentNode
  85. * @returns {NodeGuards}
  86. */
  87. public transformNode (objectExpressionNode: ESTree.ObjectExpression, parentNode: ESTree.Node): ESTree.Node {
  88. if (!objectExpressionNode.properties.length) {
  89. return objectExpressionNode;
  90. }
  91. const propertiesExtractorName: PropertiesExtractor | undefined = ObjectExpressionKeysTransformer
  92. .propertiesExtractorsMap
  93. .get(parentNode.type);
  94. if (!propertiesExtractorName) {
  95. return objectExpressionNode;
  96. }
  97. const propertiesExtractor: IPropertiesExtractor = this.propertiesExtractorFactory(propertiesExtractorName);
  98. return propertiesExtractor.extract(objectExpressionNode, parentNode);
  99. }
  100. /**
  101. * replaces:
  102. * return {
  103. * foo: 1,
  104. * bar: 2
  105. * };
  106. *
  107. * on:
  108. * var object = {};
  109. * object['foo'] = 1;
  110. * object['bar'] = 2;
  111. * return object;
  112. *
  113. * @param {ObjectExpression} objectExpressionNode
  114. * @param {Node} parentNode
  115. * @returns {NodeGuards}
  116. */
  117. public transformNodeWithBaseExtractor (objectExpressionNode: ESTree.ObjectExpression, parentNode: ESTree.Node): ESTree.Node {
  118. if (!objectExpressionNode.properties.length) {
  119. return objectExpressionNode;
  120. }
  121. const isNodeWithConcreteExtractor: boolean = ObjectExpressionKeysTransformer.propertiesExtractorsMap.has(parentNode.type);
  122. if (isNodeWithConcreteExtractor) {
  123. return objectExpressionNode;
  124. }
  125. const propertiesExtractor: IPropertiesExtractor = this.propertiesExtractorFactory(PropertiesExtractor.BasePropertiesExtractor);
  126. return propertiesExtractor.extract(objectExpressionNode, parentNode);
  127. }
  128. }