BasePropertiesExtractor.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { inject, injectable } from 'inversify';
  2. import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
  5. import { TObjectExpressionKeysTransformerCustomNodeFactory } from '../../../types/container/custom-nodes/TObjectExpressionKeysTransformerCustomNodeFactory';
  6. import { TStatement } from '../../../types/node/TStatement';
  7. import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
  8. import { TInitialData } from '../../../types/TInitialData';
  9. import { IOptions } from '../../../interfaces/options/IOptions';
  10. import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
  11. import { ObjectExpressionKeysTransformerCustomNode } from '../../../enums/custom-nodes/ObjectExpressionKeysTransformerCustomNode';
  12. import { AbstractPropertiesExtractor } from './AbstractPropertiesExtractor';
  13. import { BasePropertiesExtractorObjectExpressionHostNode } from '../../../custom-nodes/object-expression-keys-transformer-nodes/BasePropertiesExtractorObjectExpressionHostNode';
  14. import { NodeAppender } from '../../../node/NodeAppender';
  15. import { NodeGuards } from '../../../node/NodeGuards';
  16. @injectable()
  17. export class BasePropertiesExtractor extends AbstractPropertiesExtractor {
  18. /**
  19. * @type {TObjectExpressionKeysTransformerCustomNodeFactory}
  20. */
  21. private readonly objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory;
  22. /**
  23. * @param {IRandomGenerator} randomGenerator
  24. * @param {IOptions} options
  25. * @param {TObjectExpressionKeysTransformerCustomNodeFactory} objectExpressionKeysTransformerCustomNodeFactory
  26. */
  27. constructor (
  28. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
  29. @inject(ServiceIdentifiers.IOptions) options: IOptions,
  30. @inject(ServiceIdentifiers.Factory__IObjectExpressionKeysTransformerCustomNode)
  31. objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory,
  32. ) {
  33. super(randomGenerator, options);
  34. this.objectExpressionKeysTransformerCustomNodeFactory = objectExpressionKeysTransformerCustomNodeFactory;
  35. }
  36. /**
  37. * @param {ObjectExpression} objectExpressionNode
  38. * @param {Node} parentNode
  39. * @returns {Node}
  40. */
  41. public extract (
  42. objectExpressionNode: ESTree.ObjectExpression,
  43. parentNode: ESTree.Node
  44. ): ESTree.Node {
  45. return this.transformObjectExpressionNode(
  46. objectExpressionNode,
  47. parentNode
  48. );
  49. }
  50. /**
  51. * @param {ObjectExpression} objectExpressionNode
  52. * @param {Node} parentNode
  53. * @returns {Node}
  54. */
  55. protected transformObjectExpressionNode (
  56. objectExpressionNode: ESTree.ObjectExpression,
  57. parentNode: ESTree.Node
  58. ): ESTree.Node {
  59. const newObjectExpressionHostNode: ESTree.VariableDeclaration = this.getObjectExpressionHostNode();
  60. const newObjectExpressionIdentifier: ESTree.Identifier = this.getObjectExpressionIdentifierNode(newObjectExpressionHostNode);
  61. const properties: ESTree.Property[] = objectExpressionNode.properties;
  62. const [expressionStatements, removablePropertyIds]: [ESTree.ExpressionStatement[], number[]] = this
  63. .extractPropertiesToExpressionStatements(properties, newObjectExpressionIdentifier);
  64. const statementsToInsert: TStatement[] = [
  65. newObjectExpressionHostNode,
  66. ...expressionStatements
  67. ];
  68. const hostStatement: ESTree.Statement = this.getHostStatement(objectExpressionNode);
  69. const hostNodeWithStatements: TNodeWithStatements = this.getHostNodeWithStatements(
  70. objectExpressionNode,
  71. hostStatement
  72. );
  73. this.filterExtractedObjectExpressionProperties(objectExpressionNode, removablePropertyIds);
  74. NodeAppender.insertBefore(hostNodeWithStatements, statementsToInsert, hostStatement);
  75. return newObjectExpressionIdentifier;
  76. }
  77. /**
  78. * @returns {VariableDeclaration}
  79. */
  80. private getObjectExpressionHostNode (): ESTree.VariableDeclaration {
  81. const objectExpressionHostCustomNode: ICustomNode<TInitialData<BasePropertiesExtractorObjectExpressionHostNode>> =
  82. this.objectExpressionKeysTransformerCustomNodeFactory(
  83. ObjectExpressionKeysTransformerCustomNode.BasePropertiesExtractorObjectExpressionHostNode
  84. );
  85. objectExpressionHostCustomNode.initialize();
  86. const statementNode: TStatement = objectExpressionHostCustomNode.getNode()[0];
  87. if (
  88. !statementNode
  89. || !NodeGuards.isVariableDeclarationNode(statementNode)
  90. ) {
  91. throw new Error(`\`objectExpressionHostCustomNode.getNode()[0]\` should returns array with \`VariableDeclaration\` node`);
  92. }
  93. return statementNode;
  94. }
  95. /**
  96. * @param {VariableDeclaration} objectExpressionHostNode
  97. * @returns {Identifier}
  98. */
  99. private getObjectExpressionIdentifierNode (objectExpressionHostNode: ESTree.VariableDeclaration): ESTree.Identifier {
  100. const newObjectExpressionIdentifierNode: ESTree.Pattern = objectExpressionHostNode.declarations[0].id;
  101. if (!NodeGuards.isIdentifierNode(newObjectExpressionIdentifierNode)) {
  102. throw new Error(`\`objectExpressionHostNode\` should contain \`VariableDeclarator\` node with \`Identifier\` id property`);
  103. }
  104. return newObjectExpressionIdentifierNode;
  105. }
  106. }