예제 #1
0
        protected internal static JintExpression Build(Engine engine, Expression expression)
        {
            switch (expression.Type)
            {
            case Nodes.AssignmentExpression: return(JintAssignmentExpression.Build(engine, (AssignmentExpression)expression));

            case Nodes.ArrayExpression: return(new JintArrayExpression(engine, (ArrayExpression)expression));

            case Nodes.ArrowFunctionExpression: return(new JintArrowFunctionExpression(engine, (IFunction)expression));

            case Nodes.BinaryExpression: return(JintBinaryExpression.Build(engine, (BinaryExpression)expression));

            case Nodes.CallExpression: return(new JintCallExpression(engine, (CallExpression)expression));

            case Nodes.ConditionalExpression: return(new JintConditionalExpression(engine, (ConditionalExpression)expression));

            case Nodes.FunctionExpression: return(new JintFunctionExpression(engine, (IFunction)expression));

            case Nodes.Identifier: return(new JintIdentifierExpression(engine, (Identifier)expression));

            case Nodes.Literal: return(JintLiteralExpression.Build(engine, (Literal)expression));

            case Nodes.LogicalExpression:
                switch (((BinaryExpression)expression).Operator)
                {
                case BinaryOperator.LogicalAnd: return(new JintLogicalAndExpression(engine, (BinaryExpression)expression));

                case BinaryOperator.LogicalOr: return(new JintLogicalOrExpression(engine, (BinaryExpression)expression));

                default: return(ExceptionHelper.ThrowArgumentOutOfRangeException <JintExpression>());
                }

            case Nodes.MemberExpression: return(new JintMemberExpression(engine, (MemberExpression)expression));

            case Nodes.NewExpression: return(new JintNewExpression(engine, (NewExpression)expression));

            case Nodes.ObjectExpression: return(new JintObjectExpression(engine, (ObjectExpression)expression));

            case Nodes.SequenceExpression: return(new JintSequenceExpression(engine, (SequenceExpression)expression));

            case Nodes.ThisExpression: return(new JintThisExpression(engine, (ThisExpression)expression));

            case Nodes.UpdateExpression: return(new JintUpdateExpression(engine, (UpdateExpression)expression));

            case Nodes.UnaryExpression: return(JintUnaryExpression.Build(engine, (UnaryExpression)expression));

            case Nodes.SpreadElement: return(new JintSpreadExpression(engine, (SpreadElement)expression));

            case Nodes.TemplateLiteral: return(new JintTemplateLiteralExpression(engine, (TemplateLiteral)expression));

            case Nodes.TaggedTemplateExpression: return(new JintTaggedTemplateExpression(engine, (TaggedTemplateExpression)expression));

            default:
                return(ExceptionHelper.ThrowArgumentOutOfRangeException <JintExpression>(nameof(expression), $"unsupported expression type '{expression.Type}'"));
            }
        }
예제 #2
0
        public NullishCoalescingExpression(Engine engine, BinaryExpression expression) : base(expression)
        {
            _left = Build(engine, expression.Left);

            // we can create a fast path for common literal case like variable ?? 0
            if (expression.Right is Literal l)
            {
                _constant = JintLiteralExpression.ConvertToJsValue(l);
            }
            else
            {
                _right = Build(engine, expression.Right);
            }
        }
        internal static JintExpression Build(Engine engine, UnaryExpression expression)
        {
            if (expression.Operator == UnaryOperator.Minus &&
                expression.Argument is Literal literal)
            {
                var value = JintLiteralExpression.ConvertToJsValue(literal);
                if (!(value is null))
                {
                    // valid for caching
                    return(new JintConstantExpression(engine, expression, EvaluateMinus(value)));
                }
            }

            return(new JintUnaryExpression(engine, expression));
        }
예제 #4
0
        protected override void Initialize(EvaluationContext context)
        {
            _memberExpression = (MemberExpression)_expression;
            _objectExpression = Build(context.Engine, _memberExpression.Object);

            if (!_memberExpression.Computed)
            {
                _determinedProperty = ((Identifier)_memberExpression.Property).Name;
            }
            else if (_memberExpression.Property.Type == Nodes.Literal)
            {
                _determinedProperty = JintLiteralExpression.ConvertToJsValue((Literal)_memberExpression.Property);
            }

            if (_determinedProperty is null)
            {
                _propertyExpression = Build(context.Engine, _memberExpression.Property);
            }
        }
 protected internal static JintExpression Build(Engine engine, Expression expression)
 {
     return(expression.Type switch
     {
         Nodes.AssignmentExpression => JintAssignmentExpression.Build(engine, (AssignmentExpression)expression),
         Nodes.ArrayExpression => new JintArrayExpression(engine, (ArrayExpression)expression),
         Nodes.ArrowFunctionExpression => new JintArrowFunctionExpression(engine, (IFunction)expression),
         Nodes.BinaryExpression => JintBinaryExpression.Build(engine, (BinaryExpression)expression),
         Nodes.CallExpression => new JintCallExpression(engine, (CallExpression)expression),
         Nodes.ConditionalExpression => new JintConditionalExpression(engine, (ConditionalExpression)expression),
         Nodes.FunctionExpression => new JintFunctionExpression(engine, (IFunction)expression),
         Nodes.Identifier => new JintIdentifierExpression(engine, (Identifier)expression),
         Nodes.Literal => JintLiteralExpression.Build(engine, (Literal)expression),
         Nodes.LogicalExpression => ((BinaryExpression)expression).Operator switch
         {
             BinaryOperator.LogicalAnd => new JintLogicalAndExpression(engine, (BinaryExpression)expression),
             BinaryOperator.LogicalOr => new JintLogicalOrExpression(engine, (BinaryExpression)expression),
             _ => ExceptionHelper.ThrowArgumentOutOfRangeException <JintExpression>()
         },
예제 #6
0
        protected override void Initialize()
        {
            var expression = (MemberExpression)_expression;

            _objectExpression           = Build(_engine, expression.Object);
            _objectIdentifierExpression = _objectExpression as JintIdentifierExpression;
            _objectThisExpression       = _objectExpression as JintThisExpression;

            if (!expression.Computed)
            {
                _determinedProperty = ((Identifier)expression.Property).Name;
            }
            else if (expression.Property.Type == Nodes.Literal)
            {
                _determinedProperty = JintLiteralExpression.ConvertToJsValue((Literal)expression.Property);
            }

            if (_determinedProperty is null)
            {
                _propertyExpression = Build(_engine, expression.Property);
            }
        }
예제 #7
0
        internal static JintExpression Build(Engine engine, BinaryExpression expression)
        {
            JintBinaryExpression result;

            switch (expression.Operator)
            {
            case BinaryOperator.StrictlyEqual:
                result = new StrictlyEqualBinaryExpression(engine, expression);
                break;

            case BinaryOperator.StricltyNotEqual:
                result = new StrictlyNotEqualBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Less:
                result = new LessBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Greater:
                result = new GreaterBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Plus:
                result = new PlusBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Minus:
                result = new MinusBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Times:
                result = new TimesBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Divide:
                result = new DivideBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Equal:
                result = new EqualBinaryExpression(engine, expression);
                break;

            case BinaryOperator.NotEqual:
                result = new EqualBinaryExpression(engine, expression, invert: true);
                break;

            case BinaryOperator.GreaterOrEqual:
                result = new CompareBinaryExpression(engine, expression, leftFirst: true);
                break;

            case BinaryOperator.LessOrEqual:
                result = new CompareBinaryExpression(engine, expression, leftFirst: false);
                break;

            case BinaryOperator.BitwiseAnd:
            case BinaryOperator.BitwiseOr:
            case BinaryOperator.BitwiseXOr:
            case BinaryOperator.LeftShift:
            case BinaryOperator.RightShift:
            case BinaryOperator.UnsignedRightShift:
                result = new BitwiseBinaryExpression(engine, expression);
                break;

            case BinaryOperator.InstanceOf:
                result = new InstanceOfBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Exponentiation:
                result = new ExponentiationBinaryExpression(engine, expression);
                break;

            case BinaryOperator.Modulo:
                result = new ModuloBinaryExpression(engine, expression);
                break;

            case BinaryOperator.In:
                result = new InBinaryExpression(engine, expression);
                break;

            default:
                result = ExceptionHelper.ThrowArgumentOutOfRangeException <JintBinaryExpression>(nameof(_operatorType), "cannot handle operator");
                break;
            }

            if (expression.Operator != BinaryOperator.InstanceOf &&
                expression.Operator != BinaryOperator.In &&
                expression.Left is Literal leftLiteral &&
                expression.Right is Literal rightLiteral)
            {
                var lval = JintLiteralExpression.ConvertToJsValue(leftLiteral);
                var rval = JintLiteralExpression.ConvertToJsValue(rightLiteral);

                if (!(lval is null) && !(rval is null))
                {
                    // we have fixed result
                    return(new JintConstantExpression(engine, expression, result.GetValue()));
                }
            }

            return(result);
        }