NodeFactory.ts 13 KB

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