NumericalExpressionDataToNodeConverter.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import * as ESTree from 'estree';
  2. import { TNumericalExpressionDataToNodeConverterLiteralNodeGetter } from '../types/node/TNumericalExpressionDataToNodeConverterLiteralNodeGetter';
  3. import { TNumberNumericalExpressionData } from '../types/analyzers/number-numerical-expression-analyzer/TNumberNumericalExpressionData';
  4. import { NodeFactory } from './NodeFactory';
  5. import { NumberUtils } from '../utils/NumberUtils';
  6. /**
  7. * Converts NumberNumericalExpressionData to node
  8. */
  9. export class NumericalExpressionDataToNodeConverter {
  10. /**
  11. * @param {TNumberNumericalExpressionData} numberNumericalExpressionData
  12. * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
  13. * @returns {Expression}
  14. */
  15. public static convertIntegerNumberData (
  16. numberNumericalExpressionData: TNumberNumericalExpressionData,
  17. literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
  18. ): ESTree.Expression {
  19. return NumericalExpressionDataToNodeConverter.convertNumericalExpressionDataToNode(
  20. numberNumericalExpressionData,
  21. literalNodeGetter
  22. );
  23. }
  24. /**
  25. * @param {TNumberNumericalExpressionData} integerNumberNumericalExpressionData
  26. * @param {number} decimalPart
  27. * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
  28. * @returns {Expression}
  29. */
  30. public static convertFloatNumberData (
  31. integerNumberNumericalExpressionData: TNumberNumericalExpressionData,
  32. decimalPart: number,
  33. literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
  34. ): ESTree.Expression {
  35. const integerNumberNumericalExpressionNode: ESTree.Expression = NumericalExpressionDataToNodeConverter
  36. .convertNumericalExpressionDataToNode(
  37. integerNumberNumericalExpressionData,
  38. literalNodeGetter
  39. );
  40. return NodeFactory.binaryExpressionNode(
  41. '+',
  42. integerNumberNumericalExpressionNode,
  43. NodeFactory.literalNode(decimalPart)
  44. );
  45. }
  46. /**
  47. * @param {TNumberNumericalExpressionData} numberNumericalExpressionData
  48. * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
  49. * @param {BinaryOperator} operator
  50. * @returns {Expression}
  51. */
  52. private static convertNumericalExpressionDataToNode (
  53. numberNumericalExpressionData: TNumberNumericalExpressionData,
  54. literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter,
  55. operator: ESTree.BinaryOperator = '+'
  56. ): ESTree.Expression {
  57. const numberNumericalExpressionDataLength: number = numberNumericalExpressionData.length;
  58. const leftParts: TNumberNumericalExpressionData = numberNumericalExpressionDataLength > 1
  59. ? numberNumericalExpressionData.slice(0, numberNumericalExpressionDataLength - 1)
  60. : [numberNumericalExpressionData[0]];
  61. const rightParts: TNumberNumericalExpressionData = numberNumericalExpressionDataLength > 1
  62. ? numberNumericalExpressionData.slice(-1)
  63. : [];
  64. // trailing iterations
  65. if (rightParts.length) {
  66. return NumericalExpressionDataToNodeConverter
  67. .convertPartsToBinaryExpression(operator, leftParts, rightParts, literalNodeGetter);
  68. }
  69. const firstLeftPartOrNumber: number | number[] | null = leftParts[0] ?? null;
  70. // last iteration when only single left part is left
  71. return Array.isArray(firstLeftPartOrNumber)
  72. ? NumericalExpressionDataToNodeConverter.convertNumericalExpressionDataToNode(
  73. firstLeftPartOrNumber,
  74. literalNodeGetter,
  75. '*'
  76. )
  77. : NumericalExpressionDataToNodeConverter.convertPartOrNumberToLiteralNode(
  78. firstLeftPartOrNumber,
  79. literalNodeGetter
  80. );
  81. }
  82. /**
  83. * @param {BinaryOperator} operator
  84. * @param {TNumberNumericalExpressionData} leftParts
  85. * @param {TNumberNumericalExpressionData} rightParts
  86. * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
  87. * @returns {BinaryExpression}
  88. */
  89. private static convertPartsToBinaryExpression (
  90. operator: ESTree.BinaryOperator,
  91. leftParts: TNumberNumericalExpressionData,
  92. rightParts: TNumberNumericalExpressionData,
  93. literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
  94. ): ESTree.BinaryExpression {
  95. const rightPartOrNumber: number | number[] = rightParts[0];
  96. if (Array.isArray(rightPartOrNumber)) {
  97. // right part is array with multiply numbers
  98. return NodeFactory.binaryExpressionNode(
  99. operator,
  100. NumericalExpressionDataToNodeConverter.convertNumericalExpressionDataToNode(
  101. leftParts,
  102. literalNodeGetter
  103. ),
  104. NumericalExpressionDataToNodeConverter.convertNumericalExpressionDataToNode(
  105. rightPartOrNumber,
  106. literalNodeGetter,
  107. '*'
  108. )
  109. );
  110. } else {
  111. // right part is number
  112. return NodeFactory.binaryExpressionNode(
  113. operator,
  114. NumericalExpressionDataToNodeConverter.convertNumericalExpressionDataToNode(
  115. leftParts,
  116. literalNodeGetter
  117. ),
  118. this.convertPartOrNumberToLiteralNode(
  119. rightPartOrNumber,
  120. literalNodeGetter
  121. )
  122. );
  123. }
  124. }
  125. /**
  126. * @param {number | number[]} partOrNumber
  127. * @param {TNumericalExpressionDataToNodeConverterLiteralNodeGetter} literalNodeGetter
  128. * @returns {Expression}
  129. */
  130. private static convertPartOrNumberToLiteralNode (
  131. partOrNumber: number | number[],
  132. literalNodeGetter: TNumericalExpressionDataToNodeConverterLiteralNodeGetter
  133. ): ESTree.Expression {
  134. const number: number = Array.isArray(partOrNumber)
  135. ? partOrNumber[0]
  136. : partOrNumber;
  137. const isPositiveNumber: boolean = NumberUtils.isPositive(number);
  138. const absoluteNumber: number = Math.abs(number);
  139. return literalNodeGetter(absoluteNumber, isPositiveNumber);
  140. }
  141. }