NodeFactory.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /* eslint-disable max-lines */
  2. import * as escodegen from 'escodegen';
  3. import * as ESTree from 'estree';
  4. import { TStatement } from '../types/node/TStatement';
  5. import { NodeType } from '../enums/node/NodeType';
  6. export class NodeFactory {
  7. /**
  8. * @param {TStatement[]} body
  9. * @returns {Program}
  10. */
  11. public static programNode (body: TStatement[] = []): ESTree.Program {
  12. return {
  13. type: NodeType.Program,
  14. body,
  15. sourceType: 'script',
  16. metadata: { ignoredNode: false }
  17. };
  18. }
  19. /**
  20. * @param {(Expression | SpreadElement)[]} elements
  21. * @returns {ArrayExpression}
  22. */
  23. public static arrayExpressionNode (
  24. elements: (ESTree.Expression | ESTree.SpreadElement)[] = []
  25. ): ESTree.ArrayExpression {
  26. return {
  27. type: NodeType.ArrayExpression,
  28. elements,
  29. metadata: { ignoredNode: false }
  30. };
  31. }
  32. /**
  33. * @param {AssignmentOperator} operator
  34. * @param {Pattern | MemberExpression} left
  35. * @param {Expression} right
  36. * @returns {AssignmentExpression}
  37. */
  38. public static assignmentExpressionNode (
  39. operator: ESTree.AssignmentOperator,
  40. left: ESTree.Pattern | ESTree.MemberExpression,
  41. right: ESTree.Expression
  42. ): ESTree.AssignmentExpression {
  43. return {
  44. type: NodeType.AssignmentExpression,
  45. operator,
  46. left,
  47. right,
  48. metadata: { ignoredNode: false }
  49. };
  50. }
  51. /**
  52. * @param {BinaryOperator} operator
  53. * @param {Expression} left
  54. * @param {Expression} right
  55. * @returns {BinaryExpression}
  56. */
  57. public static binaryExpressionNode (
  58. operator: ESTree.BinaryOperator,
  59. left: ESTree.Expression,
  60. right: ESTree.Expression,
  61. ): ESTree.BinaryExpression {
  62. return {
  63. type: NodeType.BinaryExpression,
  64. operator,
  65. left,
  66. right,
  67. metadata: { ignoredNode: false }
  68. };
  69. }
  70. /**
  71. * @param {Statement[]} body
  72. * @returns {BlockStatement}
  73. */
  74. public static blockStatementNode (body: ESTree.Statement[] = []): ESTree.BlockStatement {
  75. return {
  76. type: NodeType.BlockStatement,
  77. body,
  78. metadata: { ignoredNode: false }
  79. };
  80. }
  81. /**
  82. * @param {Identifier} label
  83. * @returns {BreakStatement}
  84. */
  85. public static breakStatement (label?: ESTree.Identifier): ESTree.BreakStatement {
  86. return {
  87. type: NodeType.BreakStatement,
  88. label,
  89. metadata: { ignoredNode: false }
  90. };
  91. }
  92. /**
  93. * @param {Expression} callee
  94. * @param {(Expression | SpreadElement)[]} args
  95. * @returns {CallExpression}
  96. */
  97. public static callExpressionNode (
  98. callee: ESTree.Expression,
  99. args: (ESTree.Expression | ESTree.SpreadElement)[] = []
  100. ): ESTree.CallExpression {
  101. return {
  102. type: NodeType.CallExpression,
  103. callee,
  104. arguments: args,
  105. metadata: { ignoredNode: false }
  106. };
  107. }
  108. /**
  109. * @param {ESTree.Expression} test
  110. * @param {ESTree.Expression} consequent
  111. * @param {ESTree.Expression} alternate
  112. * @returns {ESTree.ConditionalExpression}
  113. */
  114. public static conditionalExpressionNode (
  115. test: ESTree.Expression,
  116. consequent: ESTree.Expression,
  117. alternate: ESTree.Expression
  118. ): ESTree.ConditionalExpression {
  119. return {
  120. type: NodeType.ConditionalExpression,
  121. test,
  122. consequent,
  123. alternate,
  124. metadata: { ignoredNode: false }
  125. };
  126. }
  127. /**
  128. * @param {Identifier} label
  129. * @returns {ContinueStatement}
  130. */
  131. public static continueStatement (label?: ESTree.Identifier): ESTree.ContinueStatement {
  132. return {
  133. type: NodeType.ContinueStatement,
  134. label,
  135. metadata: { ignoredNode: false }
  136. };
  137. }
  138. /**
  139. * @param {Literal} expression
  140. * @param {string} directive
  141. * @returns {Directive}
  142. */
  143. public static directiveNode (
  144. expression: ESTree.Literal,
  145. directive: string
  146. ): ESTree.Directive {
  147. return {
  148. type: NodeType.ExpressionStatement,
  149. expression,
  150. directive,
  151. metadata: { ignoredNode: false }
  152. };
  153. }
  154. /**
  155. * @param {Expression} expression
  156. * @returns {ExpressionStatement}
  157. */
  158. public static expressionStatementNode (expression: ESTree.Expression): ESTree.ExpressionStatement {
  159. return {
  160. type: NodeType.ExpressionStatement,
  161. expression,
  162. metadata: { ignoredNode: false }
  163. };
  164. }
  165. /**
  166. * @param {string} functionName
  167. * @param {Identifier[]} params
  168. * @param {BlockStatement} body
  169. * @returns {FunctionDeclaration}
  170. */
  171. public static functionDeclarationNode (
  172. functionName: string,
  173. params: ESTree.Identifier[],
  174. body: ESTree.BlockStatement
  175. ): ESTree.FunctionDeclaration {
  176. return {
  177. type: NodeType.FunctionDeclaration,
  178. id: NodeFactory.identifierNode(functionName),
  179. params,
  180. body,
  181. generator: false,
  182. metadata: { ignoredNode: false }
  183. };
  184. }
  185. /**
  186. * @param {Identifier[]} params
  187. * @param {BlockStatement} body
  188. * @returns {FunctionExpression}
  189. */
  190. public static functionExpressionNode (
  191. params: ESTree.Identifier[],
  192. body: ESTree.BlockStatement
  193. ): ESTree.FunctionExpression {
  194. return {
  195. type: NodeType.FunctionExpression,
  196. params,
  197. body,
  198. generator: false,
  199. metadata: { ignoredNode: false }
  200. };
  201. }
  202. /**
  203. * @param {ESTree.Expression} test
  204. * @param {ESTree.Statement} consequent
  205. * @param {ESTree.Statement | null} alternate
  206. * @returns {ESTree.IfStatement}
  207. */
  208. public static ifStatementNode (
  209. test: ESTree.Expression,
  210. consequent: ESTree.Statement,
  211. alternate?: ESTree.Statement | null
  212. ): ESTree.IfStatement {
  213. return {
  214. type: NodeType.IfStatement,
  215. test,
  216. consequent,
  217. ...alternate && { alternate },
  218. metadata: { ignoredNode: false }
  219. };
  220. }
  221. /**
  222. * @param {string} name
  223. * @returns {Identifier}
  224. */
  225. public static identifierNode (name: string): ESTree.Identifier {
  226. return {
  227. type: NodeType.Identifier,
  228. name,
  229. metadata: { ignoredNode: false }
  230. };
  231. }
  232. /**
  233. * @param {(ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[]} specifiers
  234. * @param {Literal} source
  235. * @returns {ImportDeclaration}
  236. */
  237. public static importDeclarationNode (
  238. specifiers: (ESTree.ImportSpecifier | ESTree.ImportDefaultSpecifier | ESTree.ImportNamespaceSpecifier)[],
  239. source: ESTree.Literal
  240. ): ESTree.ImportDeclaration {
  241. return {
  242. type: NodeType.ImportDeclaration,
  243. specifiers,
  244. source,
  245. metadata: { ignoredNode: false }
  246. };
  247. }
  248. /**
  249. * @param {boolean | number | string} value
  250. * @param {string} raw
  251. * @returns {Literal}
  252. */
  253. public static literalNode (value: boolean | number | string, raw?: string): ESTree.Literal {
  254. raw = raw !== undefined ? raw : `'${value}'`;
  255. return {
  256. type: NodeType.Literal,
  257. value,
  258. raw,
  259. 'x-verbatim-property': {
  260. content: raw,
  261. precedence: escodegen.Precedence.Primary
  262. },
  263. metadata: { ignoredNode: false }
  264. };
  265. }
  266. /**
  267. * @param {LogicalOperator} operator
  268. * @param {Expression} left
  269. * @param {Expression} right
  270. * @returns {LogicalExpression}
  271. */
  272. public static logicalExpressionNode (
  273. operator: ESTree.LogicalOperator,
  274. left: ESTree.Expression,
  275. right: ESTree.Expression,
  276. ): ESTree.LogicalExpression {
  277. return {
  278. type: NodeType.LogicalExpression,
  279. operator,
  280. left,
  281. right,
  282. metadata: { ignoredNode: false }
  283. };
  284. }
  285. /**
  286. * @param {Expression | Super} object
  287. * @param {Expression} property
  288. * @param {boolean} computed
  289. * @returns {MemberExpression}
  290. */
  291. public static memberExpressionNode (
  292. object: ESTree.Expression | ESTree.Super,
  293. property: ESTree.Expression,
  294. computed: boolean = false
  295. ): ESTree.MemberExpression {
  296. return {
  297. type: NodeType.MemberExpression,
  298. computed,
  299. object,
  300. property,
  301. metadata: { ignoredNode: false }
  302. };
  303. }
  304. /**
  305. * @param {(ESTree.Property | ESTree.SpreadElement)[]} properties
  306. * @returns {ESTree.ObjectExpression}
  307. */
  308. public static objectExpressionNode (properties: (ESTree.Property | ESTree.SpreadElement)[]): ESTree.ObjectExpression {
  309. return {
  310. type: NodeType.ObjectExpression,
  311. properties,
  312. metadata: { ignoredNode: false }
  313. };
  314. }
  315. /**
  316. * @param {Expression} key
  317. * @param {Expression | Pattern} value
  318. * @param {boolean} computed
  319. * @returns {Property}
  320. */
  321. public static propertyNode (
  322. key: ESTree.Expression,
  323. value: ESTree.Expression | ESTree.Pattern,
  324. computed: boolean = false
  325. ): ESTree.Property {
  326. return {
  327. type: NodeType.Property,
  328. key,
  329. value,
  330. kind: 'init',
  331. method: false,
  332. shorthand: false,
  333. computed,
  334. metadata: { ignoredNode: false }
  335. };
  336. }
  337. /**
  338. * @param {Expression} argument
  339. * @returns {ReturnStatement}
  340. */
  341. public static returnStatementNode (argument: ESTree.Expression): ESTree.ReturnStatement {
  342. return {
  343. type: NodeType.ReturnStatement,
  344. argument,
  345. metadata: { ignoredNode: false }
  346. };
  347. }
  348. /**
  349. * @param {ESTree.Expression[]} expressions
  350. * @returns {ESTree.SequenceExpression}
  351. */
  352. public static sequenceExpressionNode (expressions: ESTree.Expression[]): ESTree.SequenceExpression {
  353. return {
  354. type: NodeType.SequenceExpression,
  355. expressions,
  356. metadata: { ignoredNode: false }
  357. };
  358. }
  359. /**
  360. * @param {Expression} discriminant
  361. * @param {SwitchCase[]} cases
  362. * @returns {SwitchStatement}
  363. */
  364. public static switchStatementNode (
  365. discriminant: ESTree.Expression,
  366. cases: ESTree.SwitchCase[]
  367. ): ESTree.SwitchStatement {
  368. return {
  369. type: NodeType.SwitchStatement,
  370. discriminant,
  371. cases,
  372. metadata: { ignoredNode: false }
  373. };
  374. }
  375. /**
  376. * @param {Expression} test
  377. * @param {Statement[]} consequent
  378. * @returns {SwitchCase}
  379. */
  380. public static switchCaseNode (test: ESTree.Expression, consequent: ESTree.Statement[]): ESTree.SwitchCase {
  381. return {
  382. type: NodeType.SwitchCase,
  383. test,
  384. consequent,
  385. metadata: { ignoredNode: false }
  386. };
  387. }
  388. /**
  389. * @param {UnaryOperator} operator
  390. * @param {Expression} argument
  391. * @param {true} prefix
  392. * @returns {UnaryExpression}
  393. */
  394. public static unaryExpressionNode (
  395. operator: ESTree.UnaryOperator,
  396. argument: ESTree.Expression,
  397. prefix: true = true
  398. ): ESTree.UnaryExpression {
  399. return {
  400. type: NodeType.UnaryExpression,
  401. operator,
  402. argument,
  403. prefix,
  404. metadata: { ignoredNode: false }
  405. };
  406. }
  407. /**
  408. * @param {UpdateOperator} operator
  409. * @param {Expression} argumentExpr
  410. * @returns {UpdateExpression}
  411. */
  412. public static updateExpressionNode (operator: ESTree.UpdateOperator, argumentExpr: ESTree.Expression): ESTree.UpdateExpression {
  413. return {
  414. type: NodeType.UpdateExpression,
  415. operator,
  416. argument: argumentExpr,
  417. prefix: false,
  418. metadata: { ignoredNode: false }
  419. };
  420. }
  421. /**
  422. * @param {ESTree.TemplateElement["value"]} value
  423. * @param {boolean} tail
  424. * @returns {ESTree.TemplateElement}
  425. */
  426. public static templateElement (
  427. value: ESTree.TemplateElement['value'],
  428. tail: boolean
  429. ): ESTree.TemplateElement {
  430. return {
  431. type: NodeType.TemplateElement,
  432. value,
  433. tail,
  434. metadata: { ignoredNode: false }
  435. };
  436. }
  437. /**
  438. * @param {ESTree.Expression[]} expressions
  439. * @param {ESTree.TemplateElement[]} quasis
  440. * @returns {ESTree.TemplateLiteral}
  441. */
  442. public static templateLiteral (
  443. expressions: ESTree.Expression[],
  444. quasis: ESTree.TemplateElement[]
  445. ): ESTree.TemplateLiteral {
  446. return {
  447. type: NodeType.TemplateLiteral,
  448. expressions,
  449. quasis,
  450. metadata: { ignoredNode: false }
  451. };
  452. }
  453. /**
  454. * @param {VariableDeclarator[]} declarations
  455. * @param {string} kind
  456. * @returns {VariableDeclaration}
  457. */
  458. public static variableDeclarationNode (
  459. declarations: ESTree.VariableDeclarator[] = [],
  460. kind: 'var' | 'let' | 'const' = 'var'
  461. ): ESTree.VariableDeclaration {
  462. return {
  463. type: NodeType.VariableDeclaration,
  464. declarations,
  465. kind,
  466. metadata: { ignoredNode: false }
  467. };
  468. }
  469. /**
  470. * @param {Identifier} id
  471. * @param {Expression | null} init
  472. * @returns {VariableDeclarator}
  473. */
  474. public static variableDeclaratorNode (id: ESTree.Identifier, init: ESTree.Expression | null): ESTree.VariableDeclarator {
  475. return {
  476. type: NodeType.VariableDeclarator,
  477. id,
  478. init,
  479. metadata: { ignoredNode: false }
  480. };
  481. }
  482. /**
  483. * @param {Expression} test
  484. * @param {Statement} body
  485. * @returns {WhileStatement}
  486. */
  487. public static whileStatementNode (test: ESTree.Expression, body: ESTree.Statement): ESTree.WhileStatement {
  488. return {
  489. type: NodeType.WhileStatement,
  490. test,
  491. body,
  492. metadata: { ignoredNode: false }
  493. };
  494. }
  495. }