NodeUtils.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import { IBlockStatementNode } from "./interfaces/nodes/IBlockStatementNode";
  2. import { ICatchClauseNode } from "./interfaces/nodes/ICatchClauseNode";
  3. import { IFunctionNode } from "./interfaces/nodes/IFunctionNode";
  4. import { IIdentifierNode } from "./interfaces/nodes/IIdentifierNode";
  5. import { ILiteralNode } from "./interfaces/nodes/ILiteralNode";
  6. import { IMemberExpressionNode } from "./interfaces/nodes/IMemberExpressionNode";
  7. import { IProgramNode } from "./interfaces/nodes/IProgramNode";
  8. import { IPropertyNode } from "./interfaces/nodes/IPropertyNode";
  9. import { ITreeNode } from './interfaces/nodes/ITreeNode';
  10. import { IVariableDeclaratorNode } from "./interfaces/nodes/IVariableDeclaratorNode";
  11. import { NodeType } from "./enums/NodeType";
  12. import { Utils } from "./Utils";
  13. export class NodeUtils {
  14. /**
  15. * @type {string[]}
  16. */
  17. private static scopeNodes: string[] = [
  18. NodeType.ArrowFunctionExpression,
  19. NodeType.FunctionDeclaration,
  20. NodeType.FunctionExpression,
  21. NodeType.MethodDefinition
  22. ];
  23. /**
  24. * @param blockScopeBody
  25. * @param node
  26. */
  27. public static appendNode (blockScopeBody: ITreeNode[], node: ITreeNode): void {
  28. if (!NodeUtils.validateNode(node)) {
  29. return;
  30. }
  31. blockScopeBody.push(node);
  32. }
  33. /**
  34. * @param node
  35. * @param index
  36. * @returns {ITreeNode}
  37. */
  38. public static getBlockScopeNodeByIndex (node: ITreeNode, index: number = 0): ITreeNode {
  39. if (NodeUtils.isNodeHasBlockScope(node) && node.body[index]) {
  40. return node.body[index];
  41. }
  42. return node;
  43. }
  44. /**
  45. * @param node
  46. * @param depth
  47. * @returns {ITreeNode}
  48. */
  49. public static getScopeOfNode (node: ITreeNode, depth: number = 0): ITreeNode {
  50. if (node.parentNode.type === NodeType.Program) {
  51. return node.parentNode;
  52. }
  53. if (!Utils.arrayContains(NodeUtils.scopeNodes, node.parentNode.type)) {
  54. return NodeUtils.getScopeOfNode(node.parentNode, depth);
  55. }
  56. if (depth > 0) {
  57. return NodeUtils.getScopeOfNode(node.parentNode, --depth);
  58. }
  59. if (node.type !== NodeType.BlockStatement) {
  60. return NodeUtils.getScopeOfNode(node.parentNode);
  61. }
  62. return node; // blocks statement of scopeNodes
  63. }
  64. /**
  65. * @param node
  66. * @param types
  67. * @param limitNodeTypes
  68. * @param depth
  69. * @returns {ITreeNode}
  70. */
  71. public static getParentNodeWithType (
  72. node: ITreeNode,
  73. types: string[],
  74. limitNodeTypes: string[] = [],
  75. depth: number = 0
  76. ): ITreeNode {
  77. if (node.parentNode.type === NodeType.Program || Utils.arrayContains(limitNodeTypes, node.parentNode.type)) {
  78. return node.parentNode;
  79. }
  80. if (!Utils.arrayContains(types, node.parentNode.type)) {
  81. return NodeUtils.getParentNodeWithType(node.parentNode, types, limitNodeTypes, depth);
  82. }
  83. if (depth > 0) {
  84. return NodeUtils.getParentNodeWithType(node.parentNode, types, limitNodeTypes, --depth);
  85. }
  86. return node.parentNode;
  87. }
  88. /**
  89. * @param blockScopeBody
  90. * @param node
  91. * @param index
  92. */
  93. public static insertNodeAtIndex (blockScopeBody: ITreeNode[], node: ITreeNode, index: number): void {
  94. if (!NodeUtils.validateNode(node)) {
  95. return;
  96. }
  97. blockScopeBody.splice(index, 0, node);
  98. }
  99. /**
  100. * @param node
  101. * @returns {boolean}
  102. */
  103. public static isBlockStatementNode (node: ITreeNode): node is IBlockStatementNode {
  104. return node.type === NodeType.BlockStatement;
  105. }
  106. /**
  107. * @param node
  108. * @returns {boolean}
  109. */
  110. public static isIdentifierNode (node: ITreeNode): node is IIdentifierNode {
  111. return node.type === NodeType.Identifier;
  112. }
  113. /**
  114. * @param node
  115. * @returns {boolean}
  116. */
  117. public static isLiteralNode (node: ITreeNode): node is ILiteralNode {
  118. return node.type === NodeType.Literal;
  119. }
  120. /**
  121. * @param node
  122. * @returns {boolean}
  123. */
  124. public static isMemberExpressionNode (node: ITreeNode): node is IMemberExpressionNode {
  125. return node.type === NodeType.MemberExpression;
  126. }
  127. /**
  128. * @param node
  129. * @returns {boolean}
  130. */
  131. public static isNodeHasBlockScope (
  132. node: ITreeNode
  133. ): node is IBlockStatementNode|ICatchClauseNode|IFunctionNode|IProgramNode {
  134. return node.hasOwnProperty('body');
  135. }
  136. /**
  137. *
  138. * @param node
  139. * @returns {boolean}
  140. */
  141. public static isProgramNode (node: ITreeNode): node is IProgramNode {
  142. return node.type === NodeType.Program;
  143. }
  144. /**
  145. *
  146. * @param node
  147. * @returns {boolean}
  148. */
  149. public static isPropertyNode (node: ITreeNode): node is IPropertyNode {
  150. return node.type === NodeType.Property;
  151. }
  152. /**
  153. *
  154. * @param node
  155. * @returns {boolean}
  156. */
  157. public static isVariableDeclaratorNode (node: ITreeNode): node is IVariableDeclaratorNode {
  158. return node.type === NodeType.VariableDeclarator;
  159. }
  160. /**
  161. * @param blockScopeBody
  162. * @param node
  163. */
  164. public static prependNode (blockScopeBody: ITreeNode[], node: ITreeNode): void {
  165. if (!NodeUtils.validateNode(node)) {
  166. return;
  167. }
  168. blockScopeBody.unshift(node);
  169. }
  170. /**
  171. * @param node
  172. * @returns {boolean}
  173. */
  174. private static validateNode (node: ITreeNode): boolean {
  175. return !!node;
  176. }
  177. }