2
0

JintLiteralExpression.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Numerics;
  3. using Esprima;
  4. using Esprima.Ast;
  5. using Jint.Native;
  6. namespace Jint.Runtime.Interpreter.Expressions
  7. {
  8. internal sealed class JintLiteralExpression : JintExpression
  9. {
  10. private JintLiteralExpression(Literal expression) : base(expression)
  11. {
  12. }
  13. internal static JintExpression Build(Literal expression)
  14. {
  15. var constantValue = ConvertToJsValue(expression);
  16. if (constantValue is not null)
  17. {
  18. return new JintConstantExpression(expression, constantValue);
  19. }
  20. return new JintLiteralExpression(expression);
  21. }
  22. internal static JsValue ConvertToJsValue(Literal literal)
  23. {
  24. if (literal.TokenType == TokenType.BooleanLiteral)
  25. {
  26. return literal.NumericValue > 0.0 ? JsBoolean.True : JsBoolean.False;
  27. }
  28. if (literal.TokenType == TokenType.NullLiteral)
  29. {
  30. return JsValue.Null;
  31. }
  32. if (literal.TokenType == TokenType.NumericLiteral)
  33. {
  34. var intValue = (int) literal.NumericValue;
  35. return literal.NumericValue == intValue
  36. && (intValue != 0 || BitConverter.DoubleToInt64Bits(literal.NumericValue) != JsNumber.NegativeZeroBits)
  37. ? JsNumber.Create(intValue)
  38. : JsNumber.Create(literal.NumericValue);
  39. }
  40. if (literal.TokenType == TokenType.StringLiteral)
  41. {
  42. return JsString.Create((string) literal.Value);
  43. }
  44. if (literal.TokenType == TokenType.BigIntLiteral)
  45. {
  46. return JsBigInt.Create((BigInteger) literal.Value);
  47. }
  48. return null;
  49. }
  50. public override Completion GetValue(EvaluationContext context)
  51. {
  52. // need to notify correct node when taking shortcut
  53. context.LastSyntaxNode = _expression;
  54. return Completion.Normal(ResolveValue(context), _expression.Location);
  55. }
  56. protected override ExpressionResult EvaluateInternal(EvaluationContext context) => NormalCompletion(ResolveValue(context));
  57. private JsValue ResolveValue(EvaluationContext context)
  58. {
  59. var expression = (Literal) _expression;
  60. if (expression.TokenType == TokenType.RegularExpression)
  61. {
  62. return context.Engine.Realm.Intrinsics.RegExp.Construct((System.Text.RegularExpressions.Regex) expression.Value, expression.Regex.Pattern, expression.Regex.Flags);
  63. }
  64. return JsValue.FromObject(context.Engine, expression.Value);
  65. }
  66. }
  67. }