NodeGuards.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. import * as ESTree from 'estree';
  2. import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
  3. import { TNodeWithScope } from '../types/node/TNodeWithScope';
  4. import { NodeType } from '../enums/node/NodeType';
  5. export class NodeGuards {
  6. /**
  7. * @type {string[]}
  8. */
  9. private static readonly nodesWithBlockScope: string[] = [
  10. NodeType.ArrowFunctionExpression,
  11. NodeType.FunctionDeclaration,
  12. NodeType.FunctionExpression,
  13. NodeType.MethodDefinition,
  14. ];
  15. /**
  16. * @param {Node} node
  17. * @returns {boolean}
  18. */
  19. public static isArrayPatternNode (node: ESTree.Node): node is ESTree.ArrayPattern {
  20. return node.type === NodeType.ArrayPattern;
  21. }
  22. /**
  23. * @param {Node} node
  24. * @returns {boolean}
  25. */
  26. public static isArrowFunctionExpressionNode (node: ESTree.Node): node is ESTree.ArrowFunctionExpression {
  27. return node.type === NodeType.ArrowFunctionExpression;
  28. }
  29. /**
  30. * @param {Node} node
  31. * @returns {boolean}
  32. */
  33. public static isAssignmentPatternNode (node: ESTree.Node): node is ESTree.AssignmentPattern {
  34. return node.type === NodeType.AssignmentPattern;
  35. }
  36. /**
  37. * @param {Node} node
  38. * @returns {boolean}
  39. */
  40. public static isAwaitExpressionNode (node: ESTree.Node): node is ESTree.AwaitExpression {
  41. return node.type === NodeType.AwaitExpression;
  42. }
  43. /**
  44. * @param {Node} node
  45. * @returns {boolean}
  46. */
  47. public static isBlockStatementNode (node: ESTree.Node): node is ESTree.BlockStatement {
  48. return node.type === NodeType.BlockStatement;
  49. }
  50. /**
  51. * @param {Node} node
  52. * @returns {boolean}
  53. */
  54. public static isBreakStatementNode (node: ESTree.Node): node is ESTree.BreakStatement {
  55. return node.type === NodeType.BreakStatement;
  56. }
  57. /**
  58. * @param {Node} node
  59. * @returns {boolean}
  60. */
  61. public static isCallExpressionNode (node: ESTree.Node): node is ESTree.CallExpression {
  62. return node.type === NodeType.CallExpression;
  63. }
  64. /**
  65. * @param {Node} node
  66. * @returns {boolean}
  67. */
  68. public static isCatchClauseNode (node: ESTree.Node): node is ESTree.CatchClause {
  69. return node.type === NodeType.CatchClause;
  70. }
  71. /**
  72. * @param {Node} node
  73. * @returns {boolean}
  74. */
  75. public static isClassDeclarationNode (node: ESTree.Node): node is ESTree.ClassDeclaration {
  76. return node.type === NodeType.ClassDeclaration;
  77. }
  78. /**
  79. * @param {Node} node
  80. * @returns {boolean}
  81. */
  82. public static isContinueStatementNode (node: ESTree.Node): node is ESTree.ContinueStatement {
  83. return node.type === NodeType.ContinueStatement;
  84. }
  85. /**
  86. * @param {Node} node
  87. * @returns {boolean}
  88. */
  89. public static isExpressionStatementNode (node: ESTree.Node): node is ESTree.ExpressionStatement {
  90. return node.type === NodeType.ExpressionStatement;
  91. }
  92. /**
  93. * @param {Node} node
  94. * @returns {boolean}
  95. */
  96. public static isFunctionDeclarationNode (node: ESTree.Node): node is ESTree.FunctionDeclaration {
  97. return node.type === NodeType.FunctionDeclaration;
  98. }
  99. /**
  100. * @param {Node} node
  101. * @returns {boolean}
  102. */
  103. public static isFunctionExpressionNode (node: ESTree.Node): node is ESTree.FunctionExpression {
  104. return node.type === NodeType.FunctionExpression;
  105. }
  106. /**
  107. * @param {Node} node
  108. * @returns {boolean}
  109. */
  110. public static isIdentifierNode (node: ESTree.Node): node is ESTree.Identifier {
  111. return node.type === NodeType.Identifier;
  112. }
  113. /**
  114. * @param {Node} node
  115. * @returns {boolean}
  116. */
  117. public static isIfStatementNode (node: ESTree.Node): node is ESTree.IfStatement {
  118. return node.type === NodeType.IfStatement;
  119. }
  120. /**
  121. * @param {Node} node
  122. * @param {Node} parentNode
  123. * @returns {boolean}
  124. */
  125. public static isLabelIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier {
  126. const parentNodeIsLabeledStatementNode: boolean = NodeGuards.isLabeledStatementNode(parentNode) && parentNode.label === node;
  127. const parentNodeIsContinueStatementNode: boolean = NodeGuards.isContinueStatementNode(parentNode) && parentNode.label === node;
  128. const parentNodeIsBreakStatementNode: boolean = NodeGuards.isBreakStatementNode(parentNode) && parentNode.label === node;
  129. return parentNodeIsLabeledStatementNode || parentNodeIsContinueStatementNode || parentNodeIsBreakStatementNode;
  130. }
  131. /**
  132. * @param {Node} node
  133. * @returns {boolean}
  134. */
  135. public static isLabeledStatementNode (node: ESTree.Node): node is ESTree.LabeledStatement {
  136. return node.type === NodeType.LabeledStatement;
  137. }
  138. /**
  139. * @param {Node} node
  140. * @returns {boolean}
  141. */
  142. public static isLiteralNode (node: ESTree.Node): node is ESTree.Literal {
  143. return node.type === NodeType.Literal;
  144. }
  145. /**
  146. * @param {Node} node
  147. * @returns {boolean}
  148. */
  149. public static isMemberExpressionNode (node: ESTree.Node): node is ESTree.MemberExpression {
  150. return node.type === NodeType.MemberExpression;
  151. }
  152. /**
  153. * @param {Node} node
  154. * @returns {boolean}
  155. */
  156. public static isMethodDefinitionNode (node: ESTree.Node): node is ESTree.MethodDefinition {
  157. return node.type === NodeType.MethodDefinition;
  158. }
  159. /**
  160. * @param {Object} object
  161. * @returns {boolean}
  162. */
  163. public static isNode (object: Object & { type?: string }): object is ESTree.Node {
  164. return object && !object.type !== undefined;
  165. }
  166. /**
  167. * @param {Node} node
  168. * @param {Node} parentNode
  169. * @returns {boolean}
  170. */
  171. public static isNodeHasBlockScope (node: ESTree.Node, parentNode: ESTree.Node): node is TNodeWithBlockScope {
  172. return NodeGuards.isProgramNode(node) || (
  173. NodeGuards.isBlockStatementNode(node)
  174. && NodeGuards.nodesWithBlockScope.includes(parentNode.type)
  175. );
  176. }
  177. /**
  178. * @param {Node} node
  179. * @returns {boolean}
  180. */
  181. public static isNodeHasScope (node: ESTree.Node): node is TNodeWithScope {
  182. return NodeGuards.isProgramNode(node)
  183. || NodeGuards.isBlockStatementNode(node)
  184. || NodeGuards.isSwitchCaseNode(node);
  185. }
  186. /**
  187. * @param {Node} node
  188. * @returns {boolean}
  189. */
  190. public static isNodeWithComments (node: ESTree.Node): node is ESTree.Node {
  191. return Boolean(node.leadingComments) || Boolean(node.trailingComments);
  192. }
  193. /**
  194. * @param {Node} node
  195. * @returns {boolean}
  196. */
  197. public static isObjectPatternNode (node: ESTree.Node): node is ESTree.ObjectPattern {
  198. return node.type === NodeType.ObjectPattern;
  199. }
  200. /**
  201. * @param {Node} node
  202. * @returns {boolean}
  203. */
  204. public static isObjectExpressionNode (node: ESTree.Node): node is ESTree.ObjectExpression {
  205. return node.type === NodeType.ObjectExpression;
  206. }
  207. /**
  208. * @param {Node} node
  209. * @returns {boolean}
  210. */
  211. public static isProgramNode (node: ESTree.Node): node is ESTree.Program {
  212. return node.type === NodeType.Program;
  213. }
  214. /**
  215. * @param {Node} node
  216. * @returns {boolean}
  217. */
  218. public static isPropertyNode (node: ESTree.Node): node is ESTree.Property {
  219. return node.type === NodeType.Property;
  220. }
  221. /**
  222. * @param {Node} node
  223. * @param {Node} parentNode
  224. * @returns {boolean}
  225. */
  226. public static isReplaceableIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier {
  227. if (!NodeGuards.isIdentifierNode(node)) {
  228. return false;
  229. }
  230. const parentNodeIsPropertyNode: boolean = NodeGuards.isPropertyNode(parentNode) &&
  231. !parentNode.computed &&
  232. parentNode.key === node;
  233. const parentNodeIsMemberExpressionNode: boolean = (
  234. NodeGuards.isMemberExpressionNode(parentNode) &&
  235. !parentNode.computed &&
  236. parentNode.property === node
  237. );
  238. const parentNodeIsMethodDefinitionNode: boolean = NodeGuards.isMethodDefinitionNode(parentNode) &&
  239. !parentNode.computed;
  240. const isLabelIdentifierNode: boolean = NodeGuards.isLabelIdentifierNode(node, parentNode);
  241. return !parentNodeIsPropertyNode &&
  242. !parentNodeIsMemberExpressionNode &&
  243. !parentNodeIsMethodDefinitionNode &&
  244. !isLabelIdentifierNode;
  245. }
  246. /**
  247. * @param {Node} node
  248. * @returns {boolean}
  249. */
  250. public static isRestElementNode (node: ESTree.Node): node is ESTree.RestElement {
  251. return node.type === NodeType.RestElement;
  252. }
  253. /**
  254. * @param {Node} node
  255. * @returns {boolean}
  256. */
  257. public static isReturnStatementNode (node: ESTree.Node): node is ESTree.ReturnStatement {
  258. return node.type === NodeType.ReturnStatement;
  259. }
  260. /**
  261. * @param {Node} node
  262. * @returns {boolean}
  263. */
  264. public static isSuperNode (node: ESTree.Node): node is ESTree.Super {
  265. return node.type === NodeType.Super;
  266. }
  267. /**
  268. * @param {Node} node
  269. * @returns {boolean}
  270. */
  271. public static isSwitchCaseNode (node: ESTree.Node): node is ESTree.SwitchCase {
  272. return node.type === NodeType.SwitchCase;
  273. }
  274. /**
  275. * @param {Node} node
  276. * @returns {boolean}
  277. */
  278. public static isTemplateLiteralNode (node: ESTree.Node): node is ESTree.TemplateLiteral {
  279. return node.type === NodeType.TemplateLiteral;
  280. }
  281. /**
  282. * @param {Node} node
  283. * @returns {boolean}
  284. */
  285. public static isUnaryExpressionNode (node: ESTree.Node): node is ESTree.UnaryExpression {
  286. return node.type === NodeType.UnaryExpression;
  287. }
  288. /**
  289. * @param {Node} node
  290. * @returns {boolean}
  291. */
  292. public static isUseStrictOperator (node: ESTree.Node): node is ESTree.ExpressionStatement {
  293. return node.type === NodeType.ExpressionStatement && node.directive === 'use strict';
  294. }
  295. /**
  296. * @param {Node} node
  297. * @returns {boolean}
  298. */
  299. public static isVariableDeclarationNode (node: ESTree.Node): node is ESTree.VariableDeclaration {
  300. return node.type === NodeType.VariableDeclaration;
  301. }
  302. /**
  303. * @param {Node} node
  304. * @returns {boolean}
  305. */
  306. public static isVariableDeclaratorNode (node: ESTree.Node): node is ESTree.VariableDeclarator {
  307. return node.type === NodeType.VariableDeclarator;
  308. }
  309. /**
  310. * @param {Node} node
  311. * @returns {boolean}
  312. */
  313. public static isWhileStatementNode (node: ESTree.Node): node is ESTree.WhileStatement {
  314. return node.type === NodeType.WhileStatement;
  315. }
  316. }