JintFunctionDefinition.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Esprima;
  2. using Esprima.Ast;
  3. using Jint.Runtime.Interpreter.Statements;
  4. namespace Jint.Runtime.Interpreter
  5. {
  6. internal sealed class JintFunctionDefinition
  7. {
  8. internal readonly IFunction _function;
  9. internal readonly string _name;
  10. internal readonly bool _strict;
  11. internal readonly string[] _parameterNames;
  12. internal readonly JintStatement _body;
  13. internal bool _hasRestParameter;
  14. public readonly HoistingScope _hoistingScope;
  15. public JintFunctionDefinition(Engine engine, IFunction function)
  16. {
  17. _function = function;
  18. _hoistingScope = function.HoistingScope;
  19. _name = !string.IsNullOrEmpty(function.Id?.Name) ? function.Id.Name : null;
  20. _strict = function.Strict;
  21. _parameterNames = GetParameterNames(function);
  22. Statement bodyStatement;
  23. if (function.Expression)
  24. {
  25. bodyStatement = new ReturnStatement((Expression) function.Body);
  26. }
  27. else
  28. {
  29. bodyStatement = (BlockStatement) function.Body;
  30. }
  31. _body = JintStatement.Build(engine, bodyStatement);
  32. }
  33. private string[] GetParameterNames(IFunction functionDeclaration)
  34. {
  35. var list = functionDeclaration.Params;
  36. var count = list.Count;
  37. if (count == 0)
  38. {
  39. return System.ArrayExt.Empty<string>();
  40. }
  41. var names = new string[count];
  42. for (var i = 0; i < count; ++i)
  43. {
  44. var node = list[i];
  45. if (node is Identifier identifier)
  46. {
  47. names[i] = identifier.Name;
  48. }
  49. else if (node is AssignmentPattern ap)
  50. {
  51. names[i] = ((Identifier) ap.Left).Name;
  52. }
  53. else if (node is RestElement re)
  54. {
  55. if (re.Argument is Identifier id)
  56. {
  57. names[i] = id.Name;
  58. }
  59. else
  60. {
  61. names[i] = "";
  62. }
  63. _hasRestParameter = true;
  64. }
  65. else if (node is BindingPattern)
  66. {
  67. names[i] = "";
  68. }
  69. else
  70. {
  71. ExceptionHelper.ThrowArgumentOutOfRangeException(
  72. nameof(functionDeclaration),
  73. "Unable to determine how to handle parameter of type " + node.GetType());
  74. }
  75. }
  76. return names;
  77. }
  78. }
  79. }