LogicalExpressionControlFlowReplacer.ts 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { inject, injectable, } from 'inversify';
  2. import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
  3. import * as ESTree from 'estree';
  4. import { TControlFlowCustomNodeFactory } from '../../../types/container/custom-nodes/TControlFlowCustomNodeFactory';
  5. import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
  6. import { IOptions } from '../../../interfaces/options/IOptions';
  7. import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
  8. import { IStorage } from '../../../interfaces/storages/IStorage';
  9. import { ControlFlowCustomNode } from '../../../enums/custom-nodes/ControlFlowCustomNode';
  10. import { ExpressionWithOperatorControlFlowReplacer } from './ExpressionWithOperatorControlFlowReplacer';
  11. import { NodeGuards } from '../../../node/NodeGuards';
  12. import { NodeUtils } from '../../../node/NodeUtils';
  13. @injectable()
  14. export class LogicalExpressionControlFlowReplacer extends ExpressionWithOperatorControlFlowReplacer {
  15. /**
  16. * @type {number}
  17. */
  18. private static readonly usingExistingIdentifierChance: number = 0.5;
  19. /**
  20. * @param {TControlFlowCustomNodeFactory} controlFlowCustomNodeFactory
  21. * @param {IRandomGenerator} randomGenerator
  22. * @param {IOptions} options
  23. */
  24. constructor (
  25. @inject(ServiceIdentifiers.Factory__IControlFlowCustomNode)
  26. controlFlowCustomNodeFactory: TControlFlowCustomNodeFactory,
  27. @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
  28. @inject(ServiceIdentifiers.IOptions) options: IOptions
  29. ) {
  30. super(controlFlowCustomNodeFactory, randomGenerator, options);
  31. }
  32. /**
  33. * @param {LogicalExpression} logicalExpressionNode
  34. * @param {NodeGuards} parentNode
  35. * @param {IStorage<ICustomNode>} controlFlowStorage
  36. * @returns {NodeGuards}
  37. */
  38. public replace (
  39. logicalExpressionNode: ESTree.LogicalExpression,
  40. parentNode: ESTree.Node,
  41. controlFlowStorage: IStorage <ICustomNode>
  42. ): ESTree.Node {
  43. if (this.checkForProhibitedExpressions(logicalExpressionNode.left, logicalExpressionNode.right)) {
  44. return logicalExpressionNode;
  45. }
  46. const replacerId: string = logicalExpressionNode.operator;
  47. const logicalExpressionFunctionCustomNode: ICustomNode = this.controlFlowCustomNodeFactory(
  48. ControlFlowCustomNode.LogicalExpressionFunctionNode
  49. );
  50. logicalExpressionFunctionCustomNode.initialize(replacerId);
  51. const storageKey: string = this.insertCustomNodeToControlFlowStorage(
  52. logicalExpressionFunctionCustomNode,
  53. controlFlowStorage,
  54. replacerId,
  55. LogicalExpressionControlFlowReplacer.usingExistingIdentifierChance
  56. );
  57. return this.getControlFlowStorageCallNode(
  58. controlFlowStorage.getStorageId(),
  59. storageKey,
  60. logicalExpressionNode.left,
  61. logicalExpressionNode.right
  62. );
  63. }
  64. /**
  65. * @param {Expression} leftExpression
  66. * @param {Expression} rightExpression
  67. * @returns {boolean}
  68. */
  69. private checkForProhibitedExpressions (leftExpression: ESTree.Expression, rightExpression: ESTree.Expression): boolean {
  70. return [leftExpression, rightExpression].some((expressionNode: ESTree.Node | ESTree.Expression): boolean => {
  71. let nodeForCheck: ESTree.Node | ESTree.Expression;
  72. if (!NodeGuards.isUnaryExpressionNode(expressionNode)) {
  73. nodeForCheck = expressionNode;
  74. } else {
  75. nodeForCheck = NodeUtils.getUnaryExpressionArgumentNode(expressionNode);
  76. }
  77. return !NodeGuards.isLiteralNode(nodeForCheck) &&
  78. !NodeGuards.isIdentifierNode(nodeForCheck) &&
  79. !NodeGuards.isObjectExpressionNode(nodeForCheck) &&
  80. !NodeGuards.isExpressionStatementNode(nodeForCheck);
  81. });
  82. }
  83. }