FunctionExpressionCalleeDataExtractor.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { injectable } from 'inversify';
  2. import * as estraverse from '@javascript-obfuscator/estraverse';
  3. import * as ESTree from 'estree';
  4. import { ICalleeData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
  5. import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
  6. import { NodeGuards } from '../../../node/NodeGuards';
  7. import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
  8. @injectable()
  9. export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor {
  10. /**
  11. * @param {NodeGuards[]} blockScopeBody
  12. * @param {Identifier} callee
  13. * @returns {ICalleeData}
  14. */
  15. public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier | ESTree.FunctionExpression): ICalleeData | null {
  16. let calleeName: string | null = null;
  17. let calleeBlockStatement: ESTree.BlockStatement | null = null;
  18. if (NodeGuards.isIdentifierNode(callee)) {
  19. calleeName = callee.name;
  20. calleeBlockStatement = this.getCalleeBlockStatement(
  21. NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
  22. callee.name
  23. );
  24. } else if (NodeGuards.isFunctionExpressionNode(callee)) {
  25. calleeName = null;
  26. calleeBlockStatement = callee.body;
  27. }
  28. if (!calleeBlockStatement) {
  29. return null;
  30. }
  31. return {
  32. callee: calleeBlockStatement,
  33. name: calleeName
  34. };
  35. }
  36. /**
  37. * @param {NodeGuards} targetNode
  38. * @param {string} name
  39. * @returns {BlockStatement}
  40. */
  41. private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement | null {
  42. let calleeBlockStatement: ESTree.BlockStatement | null = null;
  43. estraverse.traverse(targetNode, {
  44. enter: (node: ESTree.Node, parentNode: ESTree.Node | null): estraverse.VisitorOption | void => {
  45. if (
  46. NodeGuards.isFunctionExpressionNode(node) &&
  47. parentNode &&
  48. NodeGuards.isVariableDeclaratorNode(parentNode) &&
  49. NodeGuards.isIdentifierNode(parentNode.id) &&
  50. parentNode.id.name === name
  51. ) {
  52. calleeBlockStatement = node.body;
  53. return estraverse.VisitorOption.Break;
  54. }
  55. }
  56. });
  57. return calleeBlockStatement;
  58. }
  59. }