getFunctionExpression.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("estree").Expression} Expression */
  7. /** @typedef {import("estree").SpreadElement} SpreadElement */
  8. /**
  9. * @param {Expression} expr expressions
  10. * @returns {{fn: TODO, expressions: (Expression | SpreadElement)[], needThis: boolean | undefined }} function expression with additional information
  11. */
  12. module.exports = expr => {
  13. // <FunctionExpression>
  14. if (
  15. expr.type === "FunctionExpression" ||
  16. expr.type === "ArrowFunctionExpression"
  17. ) {
  18. return {
  19. fn: expr,
  20. expressions: [],
  21. needThis: false
  22. };
  23. }
  24. // <FunctionExpression>.bind(<Expression>)
  25. if (
  26. expr.type === "CallExpression" &&
  27. expr.callee.type === "MemberExpression" &&
  28. expr.callee.object.type === "FunctionExpression" &&
  29. expr.callee.property.type === "Identifier" &&
  30. expr.callee.property.name === "bind" &&
  31. expr.arguments.length === 1
  32. ) {
  33. return {
  34. fn: expr.callee.object,
  35. expressions: [expr.arguments[0]],
  36. needThis: undefined
  37. };
  38. }
  39. // (function(_this) {return <FunctionExpression>})(this) (Coffeescript)
  40. if (
  41. expr.type === "CallExpression" &&
  42. expr.callee.type === "FunctionExpression" &&
  43. expr.callee.body.type === "BlockStatement" &&
  44. expr.arguments.length === 1 &&
  45. expr.arguments[0].type === "ThisExpression" &&
  46. expr.callee.body.body &&
  47. expr.callee.body.body.length === 1 &&
  48. expr.callee.body.body[0].type === "ReturnStatement" &&
  49. expr.callee.body.body[0].argument &&
  50. expr.callee.body.body[0].argument.type === "FunctionExpression"
  51. ) {
  52. return {
  53. fn: expr.callee.body.body[0].argument,
  54. expressions: [],
  55. needThis: true
  56. };
  57. }
  58. };