Beispiel #1
0
        public void JsFormatter_AssignmentExpression()
        {
            var expr = new JsBinaryExpression(new JsAssignmentExpression(new JsIdentifierExpression("a"), new JsIdentifierExpression("c")), BinaryOperatorType.Equal, new JsIdentifierExpression("b"));

            Assert.AreEqual("(a=c)==b", expr.FormatScript());
            Assert.AreEqual("(a = c) == b", expr.FormatScript(niceMode: true));
        }
        public virtual JsExpression VisitBinaryExpression(JsBinaryExpression expression, TData data)
        {
            var left  = VisitExpression(expression.Left, data);
            var right = VisitExpression(expression.Right, data);

            return(ReferenceEquals(left, expression.Left) && ReferenceEquals(right, expression.Right) ? expression : JsExpression.Binary(expression.NodeType, left, right));
        }
Beispiel #3
0
        public object VisitBinaryExpression(JsBinaryExpression expression, bool parenthesized)
        {
            int expressionPrecedence = GetPrecedence(expression.NodeType);

            if (expression.NodeType == ExpressionNodeType.Index)
            {
                VisitExpression(expression.Left, GetPrecedence(expression.Left.NodeType) > expressionPrecedence);
                _cb.Append("[");
                VisitExpression(expression.Right, false);
                _cb.Append("]");
            }
            else
            {
                bool   isRightAssociative = expression.NodeType >= ExpressionNodeType.AssignFirst && expression.NodeType <= ExpressionNodeType.AssignLast;
                string spaceBefore        = expression.NodeType == ExpressionNodeType.InstanceOf || expression.NodeType == ExpressionNodeType.In ? " " : _space;
                // If minifying, we need to beware of a + +b and a - -b.
                string spaceAfter = (expression.NodeType == ExpressionNodeType.Add && expression.Right.NodeType == ExpressionNodeType.Positive) || (expression.NodeType == ExpressionNodeType.Subtract && expression.Right.NodeType == ExpressionNodeType.Negate) ? " " : spaceBefore;

                VisitExpression(expression.Left, GetPrecedence(expression.Left.NodeType) > expressionPrecedence - (isRightAssociative ? 1 : 0));
                _cb.Append(spaceBefore)
                .Append(GetBinaryOperatorString(expression.NodeType))
                .Append(spaceAfter);
                VisitExpression(expression.Right, GetPrecedence(expression.Right.NodeType) > expressionPrecedence - (isRightAssociative ? 0 : 1));
            }
            return(null);
        }
Beispiel #4
0
 public override void VisitBinaryExpression(JsBinaryExpression node)
 {
     node.Left.Accept(this);
     output.Append(" ");
     output.Append(node.Operator.GetToken());
     output.Append(" ");
     node.Right.Accept(this);
 }
Beispiel #5
0
 public virtual JsNode Visit(JsBinaryExpression node)
 {
     return(DefaultVisit(node, x =>
     {
         x.Left = (JsExpression)x.Left.Accept(this);
         x.Right = (JsExpression)x.Right.Accept(this);
         return x;
     }));
 }
Beispiel #6
0
        public void JsFormatter_KeywordUnaryExpression()
        {
            var expr = new JsBinaryExpression(
                new JsIdentifierExpression("a").Unary(UnaryOperatorType.TypeOf),
                BinaryOperatorType.Plus,
                new JsLiteral(0).Unary(UnaryOperatorType.Void).Unary(UnaryOperatorType.Minus));

            Assert.AreEqual("typeof a+-void 0", expr.FormatScript());
            Assert.AreEqual("typeof a + -void 0", expr.FormatScript(niceMode: true));
        }
Beispiel #7
0
        public void JsFormatter_LessThanOperator()
        {
            var expr = new JsBinaryExpression(
                new JsIdentifierExpression("a"),
                BinaryOperatorType.LessOrEqual,
                new JsIdentifierExpression("b"));

            Assert.AreEqual("a<=b", expr.FormatScript());
            Assert.AreEqual("a <= b", expr.FormatScript(niceMode: true));
        }
Beispiel #8
0
        public void JsTree_FrozenBlocksMutations()
        {
            var tree = new JsBinaryExpression(new JsIdentifierExpression("a").Member("b"), BinaryOperatorType.Plus, new JsLiteral(5));
            var left = tree.Left.CastTo <JsMemberAccessExpression>();

            left.MemberName = "lol";
            tree.Freeze();
            Assert.ThrowsException <InvalidOperationException>(() => left.MemberName = "omg");
            Assert.AreEqual(left.MemberName, "lol");
            Assert.ThrowsException <InvalidOperationException>(() => tree.Right.CastTo <JsLiteral>().Value = 8);
        }
Beispiel #9
0
        public void JsFormatter_UnaryExpression()
        {
            var expr = new JsBinaryExpression(
                new JsIdentifierExpression("a").Unary(UnaryOperatorType.Increment, isPrefix: false),
                BinaryOperatorType.Plus,
                new JsIdentifierExpression("a").Unary(UnaryOperatorType.Increment, isPrefix: true))
                       .Unary(UnaryOperatorType.LogicalNot);

            Assert.AreEqual("!(a++ + ++a)", expr.FormatScript());
            Assert.AreEqual("!(a++ + ++a)", expr.FormatScript(niceMode: true));
        }
 public override JsExpression VisitBinaryExpression(JsBinaryExpression expression, object data)
 {
     if (expression.NodeType >= ExpressionNodeType.AssignFirst && expression.NodeType <= ExpressionNodeType.AssignLast)
     {
         _result = true;
         return(expression);
     }
     else
     {
         return(base.VisitBinaryExpression(expression, data));
     }
 }
            public override JsExpression VisitBinaryExpression(JsBinaryExpression expression, object data)
            {
                if (expression.NodeType >= ExpressionNodeType.AssignFirst && expression.NodeType <= ExpressionNodeType.AssignLast)
                {
                    if (expression.Left is JsIdentifierExpression)
                    {
                        string name = ((JsIdentifierExpression)expression.Left).Name;
                        if (expression.NodeType != ExpressionNodeType.Assign)
                        {
                            Result.LocalReadSet.Add(name);                              // Compound assignment means that we both read and write the state.
                        }
                        Result.LocalWriteSet.Add(name);
                        base.VisitExpression(expression.Right, data);
                        return(expression);
                    }
                    else
                    {
                        Result.UsesExternalState = true;                                // Assigning to something that is not a local. This counts as external state.
                    }
                }

                return(base.VisitBinaryExpression(expression, data));
            }
Beispiel #12
0
 public void VisitBinaryExpression(JsBinaryExpression binaryExpression)
 {
     VisitChildren(binaryExpression);
     switch (binaryExpression.Operator)
     {
         case BinaryOperatorType.Minus:
         case BinaryOperatorType.Times:
         case BinaryOperatorType.Divide:
         case BinaryOperatorType.Modulo:
         case BinaryOperatorType.Plus:
         case BinaryOperatorType.BitwiseAnd:
         case BinaryOperatorType.BitwiseOr:
         case BinaryOperatorType.BitwiseXOr:
         case BinaryOperatorType.LeftShift:
         case BinaryOperatorType.RightShift:
         case BinaryOperatorType.UnsignedRightShift:
             SetType(binaryExpression, JsTypeInfo.Number);
             break;
         case BinaryOperatorType.Equal:
         case BinaryOperatorType.NotEqual:
         case BinaryOperatorType.Greater:
         case BinaryOperatorType.GreaterOrEqual:
         case BinaryOperatorType.Less:
         case BinaryOperatorType.LessOrEqual:
         case BinaryOperatorType.StrictlyEqual:
         case BinaryOperatorType.StricltyNotEqual:
         case BinaryOperatorType.InstanceOf:
         case BinaryOperatorType.In:
             SetType(binaryExpression, JsTypeInfo.Boolean);
             break;
         case BinaryOperatorType.ConditionalAnd:
         case BinaryOperatorType.ConditionalOr:
             SetType(binaryExpression, binaryExpression.Right.ResultType());
             break;
         default: throw new NotSupportedException();
     }
 }
Beispiel #13
0
 public virtual void VisitBinaryExpression(JsBinaryExpression node)
 {
 }
Beispiel #14
0
 public virtual void Visit(JsBinaryExpression node)
 {
     DefaultVisit(node);
     node.Left.Accept(this);
     node.Right.Accept(this);
 }
Beispiel #15
0
 /// <summary>
 /// Equalses the specified other.
 /// </summary>
 /// <param name="other">The other.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 protected bool Equals(JsBinaryExpression other) =>
 Equals(Operator, other.Operator) && Equals(Left, other.Left) && Equals(Right, other.Right);
Beispiel #16
0
 public void Visit(JsBinaryExpression node)
 {
     BeforeVisit(node);
     DefaultVisit(node, VisitBinaryExpression);
     AfterVisit(node);
 }
        private JsNode Binary(OperatorResolveResult res)
        {
            if (res.UserDefinedOperatorMethod != null && !Sk.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition))
            {
                var op2 = res.OperatorType.ExtractCompoundAssignment();
                if (op2 != null)
                {
                    var fakeRight  = new OperatorResolveResult(res.Type, op2.Value, res.UserDefinedOperatorMethod, res.IsLiftedOperator, res.Operands);
                    var fakeAssign = Cs.Assign(res.Operands[0], fakeRight);
                    return(Visit(fakeAssign));
                }

                var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0], res.Operands[1]);
                return(Visit(fake));
            }

            if (res.OperatorType == ExpressionType.Coalesce)
            {
                var fake  = Cs.Conditional(res.Operands[0].NotEqual(Cs.Null(), Project), res.Operands[0], res.Operands[1], res.Type);
                var fake2 = Visit(fake);
                fake2 = new JsParenthesizedExpression {
                    Expression = (JsExpression)fake2
                };
                return(fake2);
            }
            var mrr = res.Operands[0] as MemberResolveResult;

            if (mrr != null && mrr.Member.SymbolKind == SymbolKind.Event)
            {
                var pe = (IEvent)mrr.Member;
                if (res.OperatorType.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign))
                {
                    var accessor = res.OperatorType == ExpressionType.AddAssign ? pe.AddAccessor : pe.RemoveAccessor;
                    var fake     = new CSharpInvocationResolveResult(mrr.TargetResult, accessor, new List <ResolveResult>
                    {
                        res.Operands[1]
                    });
                    var node6 = Visit(fake);
                    return(node6);
                }
            }
            if (mrr != null && IsEntityFunctionProperty(mrr.Member, res))
            {
                var simpleOp = res.OperatorType.ExtractCompoundAssignment();

                var pe = (IProperty)mrr.Member;
                if (simpleOp != null)
                {
                    // x.Name += "Hello"    ->  x.Name = x.Name + "Hello"
                    // x.Dic["Hello"] += 7  ->  x.Dic["Hello"] = x.Dic["Hello"] + 7;
                    var fake  = res.Operands[0].Assign(res.Operands[0].Binary(simpleOp.Value, res.Operands[1], res.Type));
                    var node6 = Visit(fake);
                    return(node6);
                }
                else if (res.OperatorType == ExpressionType.Assign)
                {
                    var args = new List <ResolveResult>();
                    if (pe.IsIndexer)
                    {
                        var irrOp0 = (CSharpInvocationResolveResult)res.Operands[0];
                        args.AddRange(irrOp0.Arguments);
                    }
                    args.Add(res.Operands[1]);
                    var fake  = new CSharpInvocationResolveResult(mrr.TargetResult, pe.Setter, args).AssociateWithOriginal(res);
                    var node6 = Visit(fake);
                    node6 = WrapSetterToReturnValueIfNeeded(res, node6);
                    return(node6);
                }
            }
            if (res.Operands[0] is ConversionResolveResult && res.Operands[1] is ConstantResolveResult)
            {
                var leftConv   = (ConversionResolveResult)res.Operands[0];
                var rightConst = (ConstantResolveResult)res.Operands[1];
                if (leftConv.Conversion.IsNumericConversion && leftConv.Input.Type == Cs.CharType(Project))
                {
                    var value = ((char)(int)rightConst.ConstantValue).ToString();
                    var fake  = Cs.Binary(leftConv.Input, res.OperatorType, Cs.Value(value, Project), leftConv.Input.Type);
                    return(Visit(fake));
                }
            }
            if (res.Operands[0].Type.Kind == TypeKind.Delegate && res.Operands[1].Type.Kind == TypeKind.Delegate)
            {
                if (res.OperatorType.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign))
                {
                    var op    = res.OperatorType == ExpressionType.AddAssign ? ExpressionType.Add : ExpressionType.Subtract;
                    var fake  = Cs.Assign(res.Operands[0], Cs.Binary(res.Operands[0], op, res.Operands[1], res.Type));
                    var node6 = Visit(fake);
                    return(node6);
                }
                else if (res.OperatorType.IsAny(ExpressionType.Add, ExpressionType.Subtract))
                {
                    var combineMethod = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Combine").FirstOrDefault();
                    var removeMethod  = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Remove").FirstOrDefault();

                    var meOp = res.OperatorType == ExpressionType.Add ? combineMethod : removeMethod;

                    var fake  = Cs.Member(null, meOp).Invoke(res.Operands[0], res.Operands[1]);
                    var node6 = Visit(fake);
                    return(node6);
                }
            }

            var node5 = new JsBinaryExpression {
                Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]), Right = VisitExpression(res.Operands[1])
            };

            if (res.OperatorType == ExpressionType.Equal && node5.Operator == "==")
            {
                var att = Compiler.GetJsExportAttribute();
                if (att != null && att.UseExactEquals)
                {
                    node5.Operator = "===";
                }
            }
            if (res.OperatorType == ExpressionType.NotEqual && node5.Operator == "!=")
            {
                var att = Compiler.GetJsExportAttribute();
                if (att != null && att.UseExactEquals)
                {
                    node5.Operator = "!==";
                }
            }

            return(node5);
        }
Beispiel #18
0
 public override JsExpression VisitBinaryExpression(JsBinaryExpression expression, object data)
 {
     _result = true;
     return(expression);
 }