NodeFactory.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /* eslint-disable max-lines */
  2. import * as escodegen from '@javascript-obfuscator/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. * @param {boolean} optional
  96. * @returns {CallExpression}
  97. */
  98. public static callExpressionNode (
  99. callee: ESTree.Expression,
  100. args: (ESTree.Expression | ESTree.SpreadElement)[] = [],
  101. optional: boolean = false,
  102. ): ESTree.CallExpression {
  103. return {
  104. type: NodeType.CallExpression,
  105. callee,
  106. optional,
  107. arguments: args,
  108. metadata: { ignoredNode: false }
  109. };
  110. }
  111. /**
  112. * @param {ESTree.Expression} test
  113. * @param {ESTree.Expression} consequent
  114. * @param {ESTree.Expression} alternate
  115. * @returns {ESTree.ConditionalExpression}
  116. */
  117. public static conditionalExpressionNode (
  118. test: ESTree.Expression,
  119. consequent: ESTree.Expression,
  120. alternate: ESTree.Expression
  121. ): ESTree.ConditionalExpression {
  122. return {
  123. type: NodeType.ConditionalExpression,
  124. test,
  125. consequent,
  126. alternate,
  127. metadata: { ignoredNode: false }
  128. };
  129. }
  130. /**
  131. * @param {Identifier} label
  132. * @returns {ContinueStatement}
  133. */
  134. public static continueStatement (label?: ESTree.Identifier): ESTree.ContinueStatement {
  135. return {
  136. type: NodeType.ContinueStatement,
  137. label,
  138. metadata: { ignoredNode: false }
  139. };
  140. }
  141. /**
  142. * @param {Literal} expression
  143. * @param {string} directive
  144. * @returns {Directive}
  145. */
  146. public static directiveNode (
  147. expression: ESTree.Literal,
  148. directive: string
  149. ): ESTree.Directive {
  150. return {
  151. type: NodeType.ExpressionStatement,
  152. expression,
  153. directive,
  154. metadata: { ignoredNode: false }
  155. };
  156. }
  157. /**
  158. * @param {Statement} body
  159. * @param {Expression} test
  160. * @returns {DoWhileStatement}
  161. */
  162. public static doWhileStatementNode (body: ESTree.Statement, test: ESTree.Expression): ESTree.DoWhileStatement {
  163. return {
  164. type: NodeType.DoWhileStatement,
  165. body,
  166. test,
  167. metadata: { ignoredNode: false }
  168. };
  169. }
  170. /**
  171. * @param {Literal} source
  172. * @returns {ExportAllDeclaration}
  173. */
  174. public static exportAllDeclarationNode (
  175. source: ESTree.Literal
  176. ): ESTree.ExportAllDeclaration {
  177. return {
  178. type: NodeType.ExportAllDeclaration,
  179. source,
  180. metadata: { ignoredNode: false }
  181. };
  182. }
  183. /**
  184. * @param {ExportSpecifier[]} specifiers
  185. * @param {Literal} source
  186. * @returns {ExportNamedDeclaration}
  187. */
  188. public static exportNamedDeclarationNode (
  189. specifiers: ESTree.ExportSpecifier[],
  190. source: ESTree.Literal
  191. ): ESTree.ExportNamedDeclaration {
  192. return {
  193. type: NodeType.ExportNamedDeclaration,
  194. specifiers,
  195. source,
  196. metadata: { ignoredNode: false }
  197. };
  198. }
  199. /**
  200. * @param {Expression} expression
  201. * @returns {ExpressionStatement}
  202. */
  203. public static expressionStatementNode (expression: ESTree.Expression): ESTree.ExpressionStatement {
  204. return {
  205. type: NodeType.ExpressionStatement,
  206. expression,
  207. metadata: { ignoredNode: false }
  208. };
  209. }
  210. /**
  211. * @param {VariableDeclaration | Expression | null} init
  212. * @param {Expression | null} test
  213. * @param {Expression | null} update
  214. * @param {Statement} body
  215. * @returns {ForStatement}
  216. */
  217. public static forStatementNode (
  218. init: ESTree.VariableDeclaration | ESTree.Expression | null,
  219. test: ESTree.Expression | null,
  220. update: ESTree.Expression | null,
  221. body: ESTree.Statement
  222. ): ESTree.ForStatement {
  223. return {
  224. type: NodeType.ForStatement,
  225. init,
  226. test,
  227. update,
  228. body,
  229. metadata: { ignoredNode: false }
  230. };
  231. }
  232. /**
  233. * @param {VariableDeclaration | Pattern} left
  234. * @param {Expression} right
  235. * @param {Statement} body
  236. * @returns {ForInStatement}
  237. */
  238. public static forInStatementNode (
  239. left: ESTree.VariableDeclaration | ESTree.Pattern,
  240. right: ESTree.Expression,
  241. body: ESTree.Statement
  242. ): ESTree.ForInStatement {
  243. return {
  244. type: NodeType.ForInStatement,
  245. left,
  246. right,
  247. body,
  248. metadata: { ignoredNode: false }
  249. };
  250. }
  251. /**
  252. * @param {boolean} await
  253. * @param {VariableDeclaration | Pattern} left
  254. * @param {Expression} right
  255. * @param {Statement} body
  256. * @returns {ForOfStatement}
  257. */
  258. public static forOfStatementNode (
  259. await: boolean,
  260. left: ESTree.VariableDeclaration | ESTree.Pattern,
  261. right: ESTree.Expression,
  262. body: ESTree.Statement
  263. ): ESTree.ForOfStatement {
  264. return {
  265. type: NodeType.ForOfStatement,
  266. await,
  267. left,
  268. right,
  269. body,
  270. metadata: { ignoredNode: false }
  271. };
  272. }
  273. /**
  274. * @param {string} functionName
  275. * @param {Identifier[]} params
  276. * @param {BlockStatement} body
  277. * @returns {FunctionDeclaration}
  278. */
  279. public static functionDeclarationNode (
  280. functionName: string,
  281. params: ESTree.Identifier[],
  282. body: ESTree.BlockStatement
  283. ): ESTree.FunctionDeclaration {
  284. return {
  285. type: NodeType.FunctionDeclaration,
  286. id: NodeFactory.identifierNode(functionName),
  287. params,
  288. body,
  289. generator: false,
  290. metadata: { ignoredNode: false }
  291. };
  292. }
  293. /**
  294. * @param {Identifier[]} params
  295. * @param {BlockStatement} body
  296. * @returns {FunctionExpression}
  297. */
  298. public static functionExpressionNode (
  299. params: ESTree.Pattern[],
  300. body: ESTree.BlockStatement
  301. ): ESTree.FunctionExpression {
  302. return {
  303. type: NodeType.FunctionExpression,
  304. params,
  305. body,
  306. generator: false,
  307. metadata: { ignoredNode: false }
  308. };
  309. }
  310. /**
  311. * @param {ESTree.Expression} test
  312. * @param {ESTree.Statement} consequent
  313. * @param {ESTree.Statement | null} alternate
  314. * @returns {ESTree.IfStatement}
  315. */
  316. public static ifStatementNode (
  317. test: ESTree.Expression,
  318. consequent: ESTree.Statement,
  319. alternate?: ESTree.Statement | null
  320. ): ESTree.IfStatement {
  321. return {
  322. type: NodeType.IfStatement,
  323. test,
  324. consequent,
  325. ...alternate && { alternate },
  326. metadata: { ignoredNode: false }
  327. };
  328. }
  329. /**
  330. * @param {string} name
  331. * @returns {Identifier}
  332. */
  333. public static identifierNode (name: string): ESTree.Identifier {
  334. return {
  335. type: NodeType.Identifier,
  336. name,
  337. metadata: { ignoredNode: false }
  338. };
  339. }
  340. /**
  341. * @param {(ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[]} specifiers
  342. * @param {Literal} source
  343. * @returns {ImportDeclaration}
  344. */
  345. public static importDeclarationNode (
  346. specifiers: (ESTree.ImportSpecifier | ESTree.ImportDefaultSpecifier | ESTree.ImportNamespaceSpecifier)[],
  347. source: ESTree.Literal
  348. ): ESTree.ImportDeclaration {
  349. return {
  350. type: NodeType.ImportDeclaration,
  351. specifiers,
  352. source,
  353. metadata: { ignoredNode: false }
  354. };
  355. }
  356. /**
  357. * @param {Identifier} label
  358. * @param {Statement} body
  359. * @returns {LabeledStatement}
  360. */
  361. public static labeledStatementNode (
  362. label: ESTree.Identifier,
  363. body: ESTree.Statement
  364. ): ESTree.LabeledStatement {
  365. return {
  366. type: NodeType.LabeledStatement,
  367. label,
  368. body,
  369. metadata: { ignoredNode: false }
  370. };
  371. }
  372. /**
  373. * @param {boolean | number | string} value
  374. * @param {string} raw
  375. * @returns {Literal}
  376. */
  377. public static literalNode (value: boolean | number | string, raw?: string): ESTree.Literal {
  378. raw = raw !== undefined ? raw : `'${value}'`;
  379. return {
  380. type: NodeType.Literal,
  381. value,
  382. raw,
  383. 'x-verbatim-property': {
  384. content: raw,
  385. precedence: escodegen.Precedence.Primary
  386. },
  387. metadata: { ignoredNode: false }
  388. };
  389. }
  390. /**
  391. * @param {LogicalOperator} operator
  392. * @param {Expression} left
  393. * @param {Expression} right
  394. * @returns {LogicalExpression}
  395. */
  396. public static logicalExpressionNode (
  397. operator: ESTree.LogicalOperator,
  398. left: ESTree.Expression,
  399. right: ESTree.Expression,
  400. ): ESTree.LogicalExpression {
  401. return {
  402. type: NodeType.LogicalExpression,
  403. operator,
  404. left,
  405. right,
  406. metadata: { ignoredNode: false }
  407. };
  408. }
  409. /**
  410. * @param {Expression | Super} object
  411. * @param {Expression} property
  412. * @param {boolean} computed
  413. * @param {boolean} optional
  414. * @returns {MemberExpression}
  415. */
  416. public static memberExpressionNode (
  417. object: ESTree.Expression | ESTree.Super,
  418. property: ESTree.Expression,
  419. computed: boolean = false,
  420. optional: boolean = false,
  421. ): ESTree.MemberExpression {
  422. return {
  423. type: NodeType.MemberExpression,
  424. computed,
  425. object,
  426. optional,
  427. property,
  428. metadata: { ignoredNode: false }
  429. };
  430. }
  431. /**
  432. * @param {(ESTree.Property | ESTree.SpreadElement)[]} properties
  433. * @returns {ESTree.ObjectExpression}
  434. */
  435. public static objectExpressionNode (properties: (ESTree.Property | ESTree.SpreadElement)[]): ESTree.ObjectExpression {
  436. return {
  437. type: NodeType.ObjectExpression,
  438. properties,
  439. metadata: { ignoredNode: false }
  440. };
  441. }
  442. /**
  443. * @param {Expression} key
  444. * @param {Expression | Pattern} value
  445. * @param {boolean} computed
  446. * @returns {Property}
  447. */
  448. public static propertyNode (
  449. key: ESTree.Expression,
  450. value: ESTree.Expression | ESTree.Pattern,
  451. computed: boolean = false
  452. ): ESTree.Property {
  453. return {
  454. type: NodeType.Property,
  455. key,
  456. value,
  457. kind: 'init',
  458. method: false,
  459. shorthand: false,
  460. computed,
  461. metadata: { ignoredNode: false }
  462. };
  463. }
  464. /**
  465. * @param {Pattern} argument
  466. * @returns {SpreadElement}
  467. */
  468. public static restElementNode (argument: ESTree.Pattern): ESTree.RestElement {
  469. return {
  470. type: NodeType.RestElement,
  471. argument,
  472. metadata: { ignoredNode: false }
  473. };
  474. }
  475. /**
  476. * @param {Expression} argument
  477. * @returns {ReturnStatement}
  478. */
  479. public static returnStatementNode (argument: ESTree.Expression): ESTree.ReturnStatement {
  480. return {
  481. type: NodeType.ReturnStatement,
  482. argument,
  483. metadata: { ignoredNode: false }
  484. };
  485. }
  486. /**
  487. * @param {ESTree.Expression[]} expressions
  488. * @returns {ESTree.SequenceExpression}
  489. */
  490. public static sequenceExpressionNode (expressions: ESTree.Expression[]): ESTree.SequenceExpression {
  491. return {
  492. type: NodeType.SequenceExpression,
  493. expressions,
  494. metadata: { ignoredNode: false }
  495. };
  496. }
  497. /**
  498. * @param {Expression} argument
  499. * @returns {SpreadElement}
  500. */
  501. public static spreadElementNode (argument: ESTree.Expression): ESTree.SpreadElement {
  502. return {
  503. type: NodeType.SpreadElement,
  504. argument,
  505. metadata: { ignoredNode: false }
  506. };
  507. }
  508. /**
  509. * @param {Expression} discriminant
  510. * @param {SwitchCase[]} cases
  511. * @returns {SwitchStatement}
  512. */
  513. public static switchStatementNode (
  514. discriminant: ESTree.Expression,
  515. cases: ESTree.SwitchCase[]
  516. ): ESTree.SwitchStatement {
  517. return {
  518. type: NodeType.SwitchStatement,
  519. discriminant,
  520. cases,
  521. metadata: { ignoredNode: false }
  522. };
  523. }
  524. /**
  525. * @param {Expression} test
  526. * @param {Statement[]} consequent
  527. * @returns {SwitchCase}
  528. */
  529. public static switchCaseNode (test: ESTree.Expression, consequent: ESTree.Statement[]): ESTree.SwitchCase {
  530. return {
  531. type: NodeType.SwitchCase,
  532. test,
  533. consequent,
  534. metadata: { ignoredNode: false }
  535. };
  536. }
  537. /**
  538. * @param {UnaryOperator} operator
  539. * @param {Expression} argument
  540. * @param {true} prefix
  541. * @returns {UnaryExpression}
  542. */
  543. public static unaryExpressionNode (
  544. operator: ESTree.UnaryOperator,
  545. argument: ESTree.Expression,
  546. prefix: true = true
  547. ): ESTree.UnaryExpression {
  548. return {
  549. type: NodeType.UnaryExpression,
  550. operator,
  551. argument,
  552. prefix,
  553. metadata: { ignoredNode: false }
  554. };
  555. }
  556. /**
  557. * @param {UpdateOperator} operator
  558. * @param {Expression} argumentExpr
  559. * @returns {UpdateExpression}
  560. */
  561. public static updateExpressionNode (operator: ESTree.UpdateOperator, argumentExpr: ESTree.Expression): ESTree.UpdateExpression {
  562. return {
  563. type: NodeType.UpdateExpression,
  564. operator,
  565. argument: argumentExpr,
  566. prefix: false,
  567. metadata: { ignoredNode: false }
  568. };
  569. }
  570. /**
  571. * @param {VariableDeclarator[]} declarations
  572. * @param {string} kind
  573. * @returns {VariableDeclaration}
  574. */
  575. public static variableDeclarationNode (
  576. declarations: ESTree.VariableDeclarator[] = [],
  577. kind: 'var' | 'let' | 'const' = 'var'
  578. ): ESTree.VariableDeclaration {
  579. return {
  580. type: NodeType.VariableDeclaration,
  581. declarations,
  582. kind,
  583. metadata: { ignoredNode: false }
  584. };
  585. }
  586. /**
  587. * @param {Identifier} id
  588. * @param {Expression | null} init
  589. * @returns {VariableDeclarator}
  590. */
  591. public static variableDeclaratorNode (id: ESTree.Identifier, init: ESTree.Expression | null): ESTree.VariableDeclarator {
  592. return {
  593. type: NodeType.VariableDeclarator,
  594. id,
  595. init,
  596. metadata: { ignoredNode: false }
  597. };
  598. }
  599. /**
  600. * @param {Expression} test
  601. * @param {Statement} body
  602. * @returns {WhileStatement}
  603. */
  604. public static whileStatementNode (test: ESTree.Expression, body: ESTree.Statement): ESTree.WhileStatement {
  605. return {
  606. type: NodeType.WhileStatement,
  607. test,
  608. body,
  609. metadata: { ignoredNode: false }
  610. };
  611. }
  612. }