public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCall = context.Node as MethodCallExpression;

                if (methodCall != null)
                {
                    if (methodCall.Method.DeclaringType == typeof(MyCustomClass))
                    {
                        switch (methodCall.Method.Name)
                        {
                        case "GetValue":
                        {
                            context.PreventDefault();
                            using (context.Operation(JavascriptOperationTypes.Call))
                            {
                                using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                    context.Write("Xpto").WriteAccessor("GetValue");

                                context.WriteManyIsolated('(', ')', ',', methodCall.Arguments);
                            }

                            return;
                        }
                        }
                    }
                }
            }
Beispiel #2
0
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (context.Node is MethodCallExpression methodCall)
            {
                if (methodCall.Method.DeclaringType == typeof(MyClassWithEnum))
                {
                    switch (methodCall.Method.Name)
                    {
                    case "SetGender":
                    {
                        context.PreventDefault();
                        using (context.Operation(JavascriptOperationTypes.Call))
                        {
                            using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                            {
                                context.WriteNode(methodCall.Object);
                                context.WriteAccessor("SetGender");
                            }

                            context.WriteManyIsolated('(', ')', ',', methodCall.Arguments);
                        }

                        return;
                    }
                    }
                }
            }
        }
Beispiel #3
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (!(context.Node is InvocationExpression invocationExpression))
                {
                    return;
                }

                context.PreventDefault();
                context.Visitor.Visit(invocationExpression.Expression);

                var writer = context.GetWriter();

                using (writer.Operation(invocationExpression))
                {
                    writer.Write("(");

                    for (var i = 0; i < invocationExpression.Arguments.Count; i++)
                    {
                        if (i != 0)
                        {
                            writer.Write(", ");
                        }

                        context.Visitor.Visit(invocationExpression.Arguments[i]);
                    }

                    writer.Write(")");
                }
            }
Beispiel #4
0
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (!(context.Node is MemberInitExpression initExpr))
            {
                return;
            }
            var typeOk1 = NewObjectTypes?.Contains(initExpr.Type) ?? false;
            var typeOk2 = TypePredicate?.Invoke(initExpr.Type) ?? false;
            var typeOk3 = NewObjectTypes == null && TypePredicate == null;

            if (!typeOk1 && !typeOk2 && !typeOk3)
            {
                return;
            }
            if (initExpr.NewExpression.Arguments.Count > 0)
            {
                return;
            }
            if (initExpr.Bindings.Any(mb => mb.BindingType != MemberBindingType.Assignment))
            {
                return;
            }

            context.PreventDefault();
            var writer = context.GetWriter();

            using (writer.Operation(0))
            {
                writer.Write('{');

                var posStart = writer.Length;
                foreach (var assignExpr in initExpr.Bindings.Cast <MemberAssignment>())
                {
                    if (writer.Length > posStart)
                    {
                        writer.Write(',');
                    }

                    var metadataProvider = context.Options.GetMetadataProvider();
                    var meta             = metadataProvider.GetMemberMetadata(assignExpr.Member);
                    var memberName       = meta?.MemberName;
                    Debug.Assert(!string.IsNullOrEmpty(memberName), "!string.IsNullOrEmpty(memberName)");
                    if (Regex.IsMatch(memberName, @"^\w[\d\w]*$"))
                    {
                        writer.Write(memberName);
                    }
                    else
                    {
                        writer.WriteLiteral(memberName);
                    }

                    writer.Write(':');
                    context.Visitor.Visit(assignExpr.Expression);
                }

                writer.Write('}');
            }
        }
Beispiel #5
0
 public override void ConvertToJavascript(JavascriptConversionContext context)
 {
     if (context.Node is MemberExpression me && me.Member.DeclaringType == typeof(string))
     {
         if (me.Member.Name == nameof(String.Empty.Length))
         {
             context.PreventDefault();
             context.Visitor.Visit(me.Expression);
             context.Write(".length");
         }
     }
 }
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCallExpression = context.Node as MethodCallExpression;

                var nameAttribute = methodCallExpression?
                                    .Method
                                    .GetCustomAttributes <JavascriptMethodNameAttribute>()
                                    .FirstOrDefault();

                if (nameAttribute == null)
                {
                    return;
                }

                context.PreventDefault();

                context.Visitor.Visit(methodCallExpression.Object);
                var javascriptWriter = context.GetWriter();

                javascriptWriter.Write(".");
                javascriptWriter.Write(nameAttribute.Name);
                javascriptWriter.Write("(");

                for (var i = 0; i < methodCallExpression.Arguments.Count; i++)
                {
                    var name = "arg_" + Parameters.Count;
                    if (i != 0)
                    {
                        javascriptWriter.Write(", ");
                    }

                    javascriptWriter.Write(name);
                    Parameters[name] = methodCallExpression.Arguments[i];
                }
                if (nameAttribute.PositionalArguments != null)
                {
                    for (var i = methodCallExpression.Arguments.Count;
                         i < nameAttribute.PositionalArguments.Length;
                         i++)
                    {
                        if (i != 0)
                        {
                            javascriptWriter.Write(", ");
                        }

                        context.Visitor.Visit(Expression.Constant(nameAttribute.PositionalArguments[i]));
                    }
                }

                javascriptWriter.Write(")");
            }
Beispiel #7
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (!(context.Node is ConstantExpression nodeAsConst) ||
                    nodeAsConst.Type != typeof(bool))
                {
                    return;
                }

                context.PreventDefault();
                var writer = context.GetWriter();
                var val    = (bool)nodeAsConst.Value ? "true" : "false";

                using (writer.Operation(nodeAsConst))
                {
                    writer.Write(val);
                }
            }
Beispiel #8
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var parameter = context.Node as ParameterExpression;

                if (parameter == null || parameter != _parameter)
                {
                    return;
                }

                context.PreventDefault();
                var writer = context.GetWriter();

                using (writer.Operation(parameter))
                {
                    writer.Write(_newName);
                }
            }
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            var initExpr = context.Node as MemberInitExpression;
            if (initExpr == null)
                return;
            var typeOk1 = this.NewObjectTypes?.Contains(initExpr.Type) ?? false;
            var typeOk2 = this.TypePredicate?.Invoke(initExpr.Type) ?? false;
            var typeOk3 = this.NewObjectTypes == null && this.TypePredicate == null;
            if (!typeOk1 && !typeOk2 && !typeOk3)
                return;
            if (initExpr.NewExpression.Arguments.Count > 0)
                return;
            if (initExpr.Bindings.Any(mb => mb.BindingType != MemberBindingType.Assignment))
                return;

            var writer = context.GetWriter();
            using (writer.Operation(0))
            {
                writer.Write('{');

                var posStart = writer.Length;
                foreach (var assignExpr in initExpr.Bindings.Cast<MemberAssignment>())
                {
                    if (writer.Length > posStart)
                        writer.Write(',');

                    var metadataProvider = context.Options.GetMetadataProvider();
                    var meta = metadataProvider.GetMemberMetadata(assignExpr.Member);
                    var memberName = meta?.MemberName;
                    Debug.Assert(!string.IsNullOrEmpty(memberName), "!string.IsNullOrEmpty(memberName)");
                    if (Regex.IsMatch(memberName, @"^\w[\d\w]*$"))
                        writer.Write(memberName);
                    else
                        writer.WriteLiteral(memberName);

                    writer.Write(':');
                    context.Visitor.Visit(assignExpr.Expression);
                }

                writer.Write('}');
            }
        }
Beispiel #10
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCallExpression = context.Node as MethodCallExpression;

                if (methodCallExpression?.Method.Name != "Load")
                {
                    return;
                }

                if (methodCallExpression.Method.DeclaringType != typeof(RavenQuery) &&
                    (methodCallExpression.Object == null || methodCallExpression.Object.Type != typeof(IDocumentSession)))
                {
                    return;
                }

                HasLoad      = true;
                Arg          = methodCallExpression.Arguments[0];
                IsEnumerable = Arg.Type.IsArray || LinqMethodsSupport.IsCollection(Arg.Type);

                if (IsEnumerable && methodCallExpression.Object?.Type == typeof(IDocumentSession))
                {
                    throw new NotSupportedException("Using IDocumentSession.Load(IEnumerable<string> ids) inside a query is not supported. " +
                                                    "You should use RavenQuery.Load(IEnumerable<string> ids) instead");
                }

                context.PreventDefault();

                if (DoNotTranslate)
                {
                    return;
                }

                var writer = context.GetWriter();

                using (writer.Operation(methodCallExpression))
                {
                    writer.Write("load(");
                    context.Visitor.Visit(Arg);
                    writer.Write(")");
                }
            }
Beispiel #11
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (context.Node.NodeType != ExpressionType.Coalesce || !(context.Node is BinaryExpression binaryExpression))
                {
                    return;
                }

                context.PreventDefault();
                var writer = context.GetWriter();

                using (writer.Operation(binaryExpression))
                {
                    context.Visitor.Visit(binaryExpression.Left);
                    writer.Write(" !== null && ");
                    context.Visitor.Visit(binaryExpression.Left);
                    writer.Write(" !== undefined ? ");
                    context.Visitor.Visit(binaryExpression.Left);
                    writer.Write(" : ");
                    context.Visitor.Visit(binaryExpression.Right);
                }
            }
Beispiel #12
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCallExpression = context.Node as MethodCallExpression;
                var method = methodCallExpression?.Method;

                if (method == null || method.DeclaringType != typeof(Math))
                {
                    return;
                }

                if (SupportedNames.ContainsKey(method.Name) == false)
                {
                    throw new NotSupportedException($"Translation of System.Math.{method.Name} to JavaScript is not supported");
                }

                var writer = context.GetWriter();

                context.PreventDefault();

                using (writer.Operation(methodCallExpression))
                {
                    writer.Write("Math.");
                    writer.Write(SupportedNames[method.Name]);

                    writer.Write("(");

                    for (var i = 0; i < methodCallExpression.Arguments.Count; i++)
                    {
                        if (i != 0)
                        {
                            writer.Write(", ");
                        }

                        context.Visitor.Visit(methodCallExpression.Arguments[i]);
                    }

                    writer.Write(")");
                }
            }
Beispiel #13
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var cond = context.Node as ConditionalExpression;

                if (cond?.IfTrue is ConditionalExpression || cond?.IfFalse is ConditionalExpression == false)
                {
                    return;
                }

                var writer = context.GetWriter();

                context.PreventDefault();

                using (writer.Operation(cond))
                {
                    context.Visitor.Visit(cond.Test);
                    writer.Write(" ? ");
                    context.Visitor.Visit(cond.IfTrue);
                    writer.Write(" : ");
                    context.Visitor.Visit(cond.IfFalse);
                }
            }
Beispiel #14
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (!(context.Node is MemberExpression member))
                {
                    return;
                }

                if (member.Expression is MemberExpression innerMember &&
                    innerMember.Member.Name.StartsWith("<>h__TransparentIdentifier"))
                {
                    context.PreventDefault();

                    var writer = context.GetWriter();
                    using (writer.Operation(innerMember))
                    {
                        writer.Write($"{member.Member.Name}");
                    }
                }

                if (member.Expression is ParameterExpression parameter && parameter.Name.StartsWith("<>h__TransparentIdentifier"))
                {
                    context.PreventDefault();

                    if (member.Member.Name.StartsWith("<>h__TransparentIdentifier"))
                    {
                        return;
                    }

                    var writer = context.GetWriter();

                    using (writer.Operation(parameter))
                    {
                        writer.Write($"{member.Member.Name}");
                    }
                }
            }
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (context.Node is MethodCallExpression methodCall)
            {
                if (methodCall.Method.DeclaringType == typeof(Math))
                {
                    if (membersMap.TryGetValue(methodCall.Method.Name, out var jsInfo))
                    {
                        if (methodCall.Arguments.Count == jsInfo.length)
                        {
                            context.PreventDefault();
                            using (context.Operation(JavascriptOperationTypes.Call))
                            {
                                using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                    context.Write("Math." + jsInfo.name);
                                context.WriteManyIsolated('(', ')', ',', methodCall.Arguments);
                            }

                            return;
                        }
                        else if (methodCall.Method.Name == "Log" &&
                                 methodCall.Arguments.Count == 2)
                        {
                            // JavaScript does not support `Math.log` with 2 parameters,
                            // But it is easy enough for us to give a little help!
                            context.PreventDefault();
                            using (context.Operation(JavascriptOperationTypes.MulDivMod))
                            {
                                using (context.Operation(JavascriptOperationTypes.Call))
                                {
                                    using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                        context.Write("Math.log");
                                    context.Write('(');
                                    using (context.Operation(0))
                                        context.Write(methodCall.Arguments[0]);
                                    context.Write(')');
                                }

                                context.Write('/');

                                using (context.Operation(JavascriptOperationTypes.Call))
                                {
                                    using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                        context.Write("Math.log");
                                    context.Write('(');
                                    using (context.Operation(0))
                                        context.Write(methodCall.Arguments[1]);
                                    context.Write(')');
                                }
                            }

                            return;
                        }
                        else if (methodCall.Method.Name == "Round" &&
                                 methodCall.Arguments.Count == 2 &&
                                 TypeHelpers.IsNumericType(methodCall.Arguments[1].Type))
                        {
                            // We won't support `Math.Round` with two parameters by default.
                            // To do it, we'd have to repeat an input value in the expression (unacceptable):
                            //      Math.Round(A, B) => Math.round(A * Math.pow(10, B)) / Math.pow(10, B)
                            // Or start helping with hacky things (acceptable, but not by default):
                            //      Math.Round(A, B) => (function(a, b) { return Math.round(a * b) / b; })(A, Math.pow(10, B));
                            if (round2)
                            {
                                context.PreventDefault();
                                using (context.Operation(JavascriptOperationTypes.Call))
                                {
                                    context.WriteLambda <Func <double, double, double> >((a, b) => Math.Round(a * b) / b);
                                    context.Write('(');
                                    using (context.Operation(0))
                                        context.Write(methodCall.Arguments[0]);
                                    context.Write(',');
                                    using (context.Operation(0))
                                        using (context.Operation(JavascriptOperationTypes.Call))
                                        {
                                            using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                                context.Write("Math.pow");
                                            context.Write('(');
                                            context.Write("10");
                                            context.Write(',');
                                            using (context.Operation(0))
                                                context.Write(methodCall.Arguments[1]);
                                            context.Write(')');
                                        }

                                    context.Write(')');

                                    return;
                                }
                            }
                        }
                    }
                }
            }

            // E and PI are constant values, they will never result in
            // a member access expression. We will have to catch the
            // exact numbers, and convert them instead.
            if (context.Node is ConstantExpression constVal)
            {
                if (constVal.Value.Equals(Math.E))
                {
                    context.PreventDefault();
                    using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                        context.Write("Math.E");
                }
                else if (constVal.Value.Equals(Math.PI))
                {
                    context.PreventDefault();
                    using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                        context.Write("Math.PI");
                }
            }
        }
Beispiel #16
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (!(context.Node is ConstantExpression nodeAsConst))
                {
                    return;
                }

                var writer = context.GetWriter();

                using (writer.Operation(nodeAsConst))
                {
                    if (nodeAsConst.Value == null)
                    {
                        context.PreventDefault();
                        writer.Write("null");
                        return;
                    }

                    if (nodeAsConst.Type == typeof(bool))
                    {
                        context.PreventDefault();

                        var val = (bool)nodeAsConst.Value ? "true" : "false";

                        using (writer.Operation(nodeAsConst))
                        {
                            writer.Write(val);
                        }

                        return;
                    }

                    if (nodeAsConst.Type == typeof(char))
                    {
                        context.PreventDefault();

                        writer.Write("\"");
                        writer.Write(nodeAsConst.Value);
                        writer.Write("\"");

                        return;
                    }

                    if (nodeAsConst.Type.IsArray || LinqMethodsSupport.IsCollection(nodeAsConst.Type))
                    {
                        var arr = nodeAsConst.Value as object[] ?? (nodeAsConst.Value as IEnumerable <object>)?.ToArray();
                        if (arr == null)
                        {
                            return;
                        }

                        context.PreventDefault();

                        writer.Write("[");

                        for (var i = 0; i < arr.Length; i++)
                        {
                            if (i != 0)
                            {
                                writer.Write(", ");
                            }
                            if (arr[i] is string || arr[i] is char)
                            {
                                writer.Write("\"");
                                writer.Write(arr[i]);
                                writer.Write("\"");
                            }

                            else
                            {
                                writer.Write(arr[i]);
                            }
                        }
                        writer.Write("]");
                    }
                }
            }
Beispiel #17
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var newExp = context.Node as NewExpression;

                if (newExp != null && newExp.Type == typeof(DateTime))
                {
                    context.PreventDefault();
                    var writer = context.GetWriter();
                    using (writer.Operation(newExp))
                    {
                        writer.Write("new Date(");

                        for (int i = 0; i < newExp.Arguments.Count; i++)
                        {
                            var value = ((ConstantExpression)newExp.Arguments[i]).Value;
                            if (i == 1)
                            {
                                var month = (int)value;
                                writer.Write(month - 1);
                            }
                            else
                            {
                                writer.Write(value);
                            }
                            if (i < newExp.Arguments.Count - 1)
                            {
                                writer.Write(", ");
                            }
                        }
                        writer.Write(")");
                    }

                    return;
                }

                var node = context.Node as MemberExpression;

                if (node == null)
                {
                    return;
                }

                if (node.Type == typeof(DateTime))
                {
                    var writer = context.GetWriter();
                    context.PreventDefault();

                    using (writer.Operation(node))
                    {
                        //match DateTime expressions like user.DateOfBirth, order.ShipmentInfo.DeliveryDate, etc
                        if (node.Expression != null)
                        {
                            writer.Write("new Date(Date.parse(");
                            context.Visitor.Visit(node.Expression); //visit inner expression (user ,order.ShipmentInfo, etc)
                            writer.Write($".{node.Member.Name}))");
                            return;
                        }

                        //match DateTime.Now , DateTime.UtcNow, DateTime.Today
                        switch (node.Member.Name)
                        {
                        case "Now":
                            writer.Write("Date.now()");
                            break;

                        case "UtcNow":
                            writer.Write(
                                @"(function (date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());})(new Date()).getTime()");
                            break;

                        case "Today":
                            writer.Write("new Date().setHours(0,0,0,0)");
                            break;
                        }
                    }

                    return;
                }

                if (node.Expression.Type == typeof(DateTime) && node.Expression is MemberExpression memberExpression)
                {
                    var writer = context.GetWriter();
                    context.PreventDefault();

                    using (writer.Operation(node))
                    {
                        //match expressions like : DateTime.Today.Year , DateTime.Now.Day , user.Birthday.Month , etc

                        writer.Write("new Date(");

                        if (memberExpression.Member.DeclaringType != typeof(DateTime))
                        {
                            writer.Write("Date.parse(");
                            context.Visitor.Visit(memberExpression.Expression);
                            writer.Write($".{memberExpression.Member.Name}");
                            writer.Write(")");
                        }

                        writer.Write(")");

                        switch (node.Member.Name)
                        {
                        case "Year":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCFullYear()" : ".getFullYear()");
                            break;

                        case "Month":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCMonth()+1" : ".getMonth()+1");
                            break;

                        case "Day":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCDate()" : ".getDate()");
                            break;

                        case "Hour":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCHours()" : ".getHours()");
                            break;

                        case "Minute":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCMinutes()" : ".getMinutes()");
                            break;

                        case "Second":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCSeconds()" : ".getSeconds()");
                            break;

                        case "Millisecond":
                            writer.Write(memberExpression.Member.Name == "UtcNow" ? ".getUTCMilliseconds()" : ".getMilliseconds()");
                            break;

                        case "Ticks":
                            writer.Write(".getTime()*10000");
                            break;
                        }
                    }
                }
            }
Beispiel #18
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (context.Node is LambdaExpression lambdaExpression &&
                    lambdaExpression.Parameters.Count > 0 &&
                    lambdaExpression.Parameters[0].Name.StartsWith("<>h__TransparentIdentifier"))
                {
                    DoNotIgnore = true;

                    context.PreventDefault();

                    var writer = context.GetWriter();
                    using (writer.Operation(lambdaExpression))
                    {
                        writer.Write("function(");
                        writer.Write(lambdaExpression.Parameters[0].Name.Substring(2));
                        writer.Write("){return ");
                        context.Visitor.Visit(lambdaExpression.Body);
                        writer.Write(";}");
                    }

                    return;
                }

                if (!(context.Node is MemberExpression member))
                {
                    return;
                }

                if (member.Expression is MemberExpression innerMember &&
                    innerMember.Member.Name.StartsWith("<>h__TransparentIdentifier"))
                {
                    context.PreventDefault();

                    var writer = context.GetWriter();
                    using (writer.Operation(innerMember))
                    {
                        if (DoNotIgnore)
                        {
                            context.Visitor.Visit(member.Expression);
                        }
                        writer.Write($"{member.Member.Name}");
                    }
                }

                if (member.Expression is ParameterExpression parameter && parameter.Name.StartsWith("<>h__TransparentIdentifier"))
                {
                    context.PreventDefault();

                    var writer = context.GetWriter();
                    using (writer.Operation(parameter))
                    {
                        if (DoNotIgnore)
                        {
                            writer.Write(parameter.Name.Substring(2));
                            writer.Write(".");
                        }

                        writer.Write($"{member.Member.Name}");
                    }
                }
            }
Beispiel #19
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCallExpression = context.Node as MethodCallExpression;
                var methodName           = methodCallExpression?
                                           .Method.Name;

                if (methodName == null)
                {
                    return;
                }

                string newName;

                switch (methodName)
                {
                case "Any":
                    newName = "some";
                    break;

                case "All":
                    newName = "every";
                    break;

                case "Select":
                    newName = "map";
                    break;

                case "Where":
                    newName = "filter";
                    break;

                case "Contains":
                    newName = "indexOf";
                    break;

                default:
                    return;
                }
                var javascriptWriter = context.GetWriter();

                var obj = methodCallExpression.Arguments[0] as MemberExpression;

                if (obj == null)
                {
                    if (methodCallExpression.Arguments[0] is MethodCallExpression innerMethodCall)
                    {
                        context.PreventDefault();
                        context.Visitor.Visit(innerMethodCall);
                        javascriptWriter.Write($".{newName}");
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    context.PreventDefault();
                    javascriptWriter.Write($"this.{obj.Member.Name}.{newName}");
                }

                if (methodCallExpression.Arguments.Count < 2)
                {
                    return;
                }

                javascriptWriter.Write("(");
                context.Visitor.Visit(methodCallExpression.Arguments[1]);
                javascriptWriter.Write(")");

                if (newName == "indexOf")
                {
                    javascriptWriter.Write(">=0");
                }
            }
Beispiel #20
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var nodeAsConst = context.Node as ConstantExpression;

                if (nodeAsConst != null && nodeAsConst.Type == typeof(bool))
                {
                    context.PreventDefault();
                    var writer = context.GetWriter();
                    var val    = nodeAsConst.Value.ToString().ToLower();

                    using (writer.Operation(nodeAsConst))
                    {
                        writer.Write(val);
                    }

                    return;
                }

                var newExp = context.Node as NewExpression;

                if (newExp != null && newExp.Type == typeof(DateTime))
                {
                    context.PreventDefault();
                    var writer = context.GetWriter();
                    using (writer.Operation(newExp))
                    {
                        writer.Write("new Date(");

                        for (int i = 0; i < newExp.Arguments.Count; i++)
                        {
                            var value = ((ConstantExpression)newExp.Arguments[i]).Value;
                            if (i == 1)
                            {
                                var month = (int)value;
                                writer.Write(month - 1);
                            }
                            else
                            {
                                writer.Write(value);
                            }
                            if (i < newExp.Arguments.Count - 1)
                            {
                                writer.Write(", ");
                            }
                        }
                        writer.Write(")");
                    }

                    return;
                }

                var node = context.Node as MemberExpression;

                if (node == null)
                {
                    return;
                }

                context.PreventDefault();
                var javascriptWriter = context.GetWriter();

                using (javascriptWriter.Operation(node))
                {
                    if (node.Type == typeof(DateTime))
                    {
                        //match DateTime expressions like call.Started, user.DateOfBirth, etc
                        if (node.Expression == Parameter)
                        {
                            //translate it to Date.parse(this.Started)
                            javascriptWriter.Write($"Date.parse(this.{node.Member.Name})");
                            return;
                        }

                        //match expression where DateTime object is nested, like order.ShipmentInfo.DeliveryDate
                        if (node.Expression != null)
                        {
                            javascriptWriter.Write("Date.parse(");
                            context.Visitor.Visit(node.Expression); //visit inner expression (i.e order.ShipmentInfo)
                            javascriptWriter.Write($".{node.Member.Name})");
                            return;
                        }

                        //match DateTime.Now , DateTime.UtcNow, DateTime.Today
                        switch (node.Member.Name)
                        {
                        case "Now":
                            javascriptWriter.Write("Date.now()");
                            break;

                        case "UtcNow":
                            javascriptWriter.Write(@"(function (date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds());})(new Date()).getTime()");
                            break;

                        case "Today":
                            javascriptWriter.Write("new Date().setHours(0,0,0,0)");
                            break;
                        }
                        return;
                    }

                    if (node.Expression == Parameter)
                    {
                        javascriptWriter.Write($"this.{node.Member.Name}");
                        return;
                    }

                    switch (node.Expression)
                    {
                    case null:
                        return;

                    case MemberExpression member:
                        context.Visitor.Visit(member);
                        break;

                    default:
                        context.Visitor.Visit(node.Expression);
                        break;
                    }

                    javascriptWriter.Write(".");

                    if (node.Member.Name == "Count" && IsCollection(node.Member.DeclaringType))
                    {
                        javascriptWriter.Write("length");
                    }
                    else
                    {
                        javascriptWriter.Write(node.Member.Name);
                    }
                }
            }
Beispiel #21
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var node = context.Node as MemberExpression;

                if (node != null && node.Member.Name == "Count" && IsCollection(node.Member.DeclaringType))
                {
                    var writer = context.GetWriter();
                    context.PreventDefault();

                    context.Visitor.Visit(node.Expression);

                    using (writer.Operation(node))
                    {
                        writer.Write(".");
                        writer.Write("length");
                    }

                    return;
                }

                var methodCallExpression = context.Node as MethodCallExpression;
                var methodName           = methodCallExpression?
                                           .Method.Name;

                if (methodName == null || IsCollection(methodCallExpression.Method.DeclaringType) == false)
                {
                    return;
                }

                string newName;

                switch (methodName)
                {
                case "Any":
                    newName = "some";
                    break;

                case "All":
                    newName = "every";
                    break;

                case "Select":
                    newName = "map";
                    break;

                case "Where":
                    newName = "filter";
                    break;

                case "Contains":
                    newName = "indexOf";
                    break;

                case "ToList":
                case "ToArray":
                    context.PreventDefault();
                    context.Visitor.Visit(methodCallExpression.Arguments[0]);
                    return;

                case "FirstOrDefault":
                case "First":
                    context.PreventDefault();
                    context.Visitor.Visit(methodCallExpression.Arguments[0]);
                    var writer = context.GetWriter();
                    using (writer.Operation(methodCallExpression))
                    {
                        if (methodCallExpression.Arguments.Count > 1)
                        {
                            writer.Write(".find");
                            context.Visitor.Visit(methodCallExpression.Arguments[1]);
                        }
                    }
                    return;

                default:
                    return;
                }

                var javascriptWriter = context.GetWriter();

                if (methodCallExpression.Object != null)
                {
                    context.PreventDefault();

                    context.Visitor.Visit(methodCallExpression.Object);
                    javascriptWriter.Write($".{newName}");
                    javascriptWriter.Write("(");
                    context.Visitor.Visit(methodCallExpression.Arguments[0]);
                    javascriptWriter.Write(")");
                }
                else
                {
                    context.PreventDefault();

                    context.Visitor.Visit(methodCallExpression.Arguments[0]);
                    javascriptWriter.Write($".{newName}");

                    if (methodCallExpression.Arguments.Count < 2)
                    {
                        return;
                    }

                    javascriptWriter.Write("(");
                    context.Visitor.Visit(methodCallExpression.Arguments[1]);
                    javascriptWriter.Write(")");
                }

                if (newName == "indexOf")
                {
                    javascriptWriter.Write(">=0");
                }
            }
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (context.Node is ConstantExpression cte && cte.Type.IsEnum)
            {
                context.PreventDefault();
                var writer        = context.GetWriter();
                var remaining     = Convert.ToInt64(cte.Value);
                var flagsAsString = (opts & EnumOptions.FlagsAsStringWithSeparator) != 0;
                var flagsAsOrs    = (opts & EnumOptions.FlagsAsNumericOrs) != 0;
                var flagsAsArray  = (opts & EnumOptions.FlagsAsArray) != 0;
                var isFlags       = cte.Type.IsDefined(typeof(FlagsAttribute), false);

                // when value is zero
                if (remaining == 0 && (!isFlags || !(flagsAsString || flagsAsOrs || flagsAsArray)))
                {
                    if (WriteSingleEnumItem(context, writer, 0, cte.Value, false))
                    {
                        return;
                    }
                }

                // reading enum composition
                var values   = Enum.GetValues(cte.Type);
                var selected = new List <int>();
                for (var itV = 0; itV < values.Length; itV++)
                {
                    var val = Convert.ToInt64(values.GetValue(values.Length - itV - 1));
                    if ((val & remaining) == val)
                    {
                        remaining &= ~val;
                        selected.Add(values.Length - itV - 1);

                        if (!isFlags)
                        {
                            break;
                        }
                    }
                }

                // selecting enum case
                if (isFlags)
                {
                    var cnt = selected.Count + (remaining != 0 ? 1 : 0);

                    PrecedenceController xpto = null;
                    var start     = "";
                    var separator = "";
                    var end       = "";

                    if (flagsAsString)
                    {
                        xpto      = writer.Operation(JavascriptOperationTypes.Literal);
                        start     = "\"";
                        separator = "|";
                        end       = "\"";
                    }
                    else if (flagsAsArray)
                    {
                        xpto      = writer.Operation(0);
                        start     = "[";
                        separator = ",";
                        end       = "]";
                    }
                    else if (flagsAsOrs && cnt > 1)
                    {
                        xpto      = writer.Operation(JavascriptOperationTypes.Or);
                        start     = "";
                        separator = "|";
                        end       = "";
                    }
                    else if (cnt > 1)
                    {
                        throw new NotSupportedException("When converting flags enums to JavaScript, a flags option must be specified.");
                    }

                    using (xpto)
                    {
                        writer.Write(start);
                        var pos0 = writer.Length;
                        for (var itIdx = 0; itIdx < selected.Count; itIdx++)
                        {
                            if (pos0 != writer.Length)
                            {
                                writer.Write(separator);
                            }

                            var index   = selected[itIdx];
                            var enumVal = values.GetValue(index);
                            var val     = Convert.ToInt64(enumVal);
                            WriteSingleEnumItem(context, writer, val, enumVal, flagsAsString);
                        }

                        if (remaining != 0)
                        {
                            if (pos0 != writer.Length)
                            {
                                writer.Write(separator);
                            }
                            WriteSingleEnumItem(context, writer, remaining, remaining, flagsAsString);
                        }
                        writer.Write(end);
                    }
                }
                else
                {
                    if (remaining != 0)
                    {
                        var enumVal = cte.Value;
                        var val     = Convert.ToInt64(cte.Value);
                        WriteSingleEnumItem(context, writer, val, enumVal, false);
                    }
                    else
                    {
                        foreach (var index in selected)
                        {
                            var enumVal = values.GetValue(index);
                            var val     = Convert.ToInt64(enumVal);
                            WriteSingleEnumItem(context, writer, val, enumVal, false);
                        }
                    }
                }
            }
        }
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (context.Node is MethodCallExpression methodCall)
            {
                if (methodCall.Method.DeclaringType == typeof(string))
                {
                    switch (methodCall.Method.Name)
                    {
                    // TODO: to support VB string concat operator `&` we must do this by default... so this code is not necessary
                    // TODO: decide whether this will be the default or not
                    //case "Concat":
                    //    {
                    //        context.PreventDefault();
                    //        var writer = context.GetWriter();
                    //        using (writer.Operation(JavascriptOperationTypes.Concat))
                    //        {
                    //            if (methodCall.Arguments.Count == 0)
                    //                writer.Write("''");
                    //            else
                    //            {
                    //                if (GetTypeOfExpression(methodCall.Arguments[0]) != typeof(string))
                    //                    writer.Write("''+");
                    //                context.WriteMany('+', methodCall.Arguments);
                    //            }
                    //        }

                    //        return;
                    //    }

                    case "Join":
                    {
                        context.PreventDefault();
                        var writer = context.GetWriter();
                        using (writer.Operation(JavascriptOperationTypes.Call))
                        {
                            using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                            {
                                var pars = methodCall.Method.GetParameters();
                                if (pars.Length == 4 && pars[1].ParameterType.IsArray && pars[2].ParameterType == typeof(int) && pars[3].ParameterType == typeof(int))
                                {
                                    throw new NotSupportedException("The `String.Join` method with start and count paramaters is not supported.");
                                }

                                if (pars.Length != 2 || !TypeHelpers.IsEnumerableType(pars[1].ParameterType))
                                {
                                    throw new NotSupportedException("This `String.Join` method is not supported.");
                                }

                                // if second parameter is an enumerable, render it directly
                                context.Visitor.Visit(methodCall.Arguments[1]);
                                writer.Write(".join");
                            }

                            writer.Write('(');

                            // separator
                            using (writer.Operation(0))
                                context.Visitor.Visit(methodCall.Arguments[0]);

                            writer.Write(')');
                        }

                        return;
                    }
                    }
                }
            }
        }
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCall = context.Node as MethodCallExpression;
                if (methodCall != null)
                    if (methodCall.Method.DeclaringType == typeof(MyCustomClass))
                    {
                        switch (methodCall.Method.Name)
                        {
                            case "GetValue":
                            {
                                using (context.Operation(JavascriptOperationTypes.Call))
                                {
                                    using (context.Operation(JavascriptOperationTypes.IndexerProperty))
                                        context.Write("Xpto").WriteAccessor("GetValue");

                                    context.WriteManyIsolated('(', ')', ',', methodCall.Arguments);
                                }

                                return;
                            }
                        }
                    }
            }
Beispiel #25
0
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            var methodCall = context.Node as MethodCallExpression;
            if (methodCall != null)
                if (methodCall.Method.DeclaringType == typeof(Enumerable))
                {
                    switch (methodCall.Method.Name)
                    {
                        case "Select":
                            {
                                var writer = context.GetWriter();
                                using (writer.Operation(JavascriptOperationTypes.Call))
                                {
                                    using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                                    {
                                        // public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
                                        // public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
                                        var pars = methodCall.Method.GetParameters();
                                        if (pars.Length != 2)
                                            throw new NotSupportedException("The `Enumerable.Select` method must have 2 parameters.");

                                        context.Visitor.Visit(methodCall.Arguments[0]);
                                        writer.Write(".map");
                                    }

                                    writer.Write('(');

                                    // separator
                                    using (writer.Operation(0))
                                        context.Visitor.Visit(methodCall.Arguments[1]);

                                    writer.Write(')');
                                }

                                return;
                            }

                        case "Where":
                            {
                                var writer = context.GetWriter();
                                using (writer.Operation(JavascriptOperationTypes.Call))
                                {
                                    using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                                    {
                                        // public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
                                        // public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
                                        var pars = methodCall.Method.GetParameters();
                                        if (pars.Length != 2)
                                            throw new NotSupportedException("The `Enumerable.Where` method must have 2 parameters.");

                                        context.Visitor.Visit(methodCall.Arguments[0]);
                                        writer.Write(".filter");
                                    }

                                    writer.Write('(');

                                    // separator
                                    using (writer.Operation(0))
                                        context.Visitor.Visit(methodCall.Arguments[1]);

                                    writer.Write(')');
                                }

                                return;
                            }

                        case "ToArray":
                            {
                                // Ecma Script 6+: use spread operator
                                // Other: use array `slice`
                                if (context.Options.ScriptVersion.Supports(JavascriptSyntax.ArraySpread))
                                {
                                    var writer = context.GetWriter();
                                    using (writer.Operation(0))
                                    {
                                        writer.Write('[');
                                        writer.Write("...");
                                        using (writer.Operation(JavascriptOperationTypes.ParamIsolatedLhs))
                                            context.Visitor.Visit(methodCall.Arguments[0]);
                                        writer.Write(']');
                                    }
                                }
                                else
                                {
                                    var writer = context.GetWriter();
                                    using (writer.Operation(JavascriptOperationTypes.Call))
                                    {
                                        using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                                        {
                                            context.Visitor.Visit(methodCall.Arguments[0]);
                                            writer.Write(".slice");
                                        }

                                        writer.Write('(');
                                        writer.Write(')');
                                    }
                                }

                                return;
                            }
                    }
                }
        }
Beispiel #26
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                if (!(context.Node is MethodCallExpression mce) || mce.Method.DeclaringType != typeof(string))
                {
                    return;
                }

                string newName;

                switch (mce.Method.Name)
                {
                case "PadLeft":
                    newName = "padStart";
                    break;

                case "PadRight":
                    newName = "padEnd";
                    break;

                case "Substring":
                    newName = "substr";
                    break;

                case "StartsWith":
                    newName = "startsWith";
                    break;

                case "EndsWith":
                    newName = "endsWith";
                    break;

                case "Join":
                    newName = "join";
                    break;

                default:
                    return;
                }

                var writer = context.GetWriter();

                context.PreventDefault();

                using (writer.Operation(mce))
                {
                    if (newName == "join")
                    {
                        if (mce.Arguments.Count > 2)
                        {
                            writer.Write("[");

                            for (int i = 1; i < mce.Arguments.Count; i++)
                            {
                                if (i != 1)
                                {
                                    writer.Write(", ");
                                }
                                context.Visitor.Visit(mce.Arguments[i]);
                            }

                            writer.Write("]");
                        }
                        else
                        {
                            context.Visitor.Visit(mce.Arguments[1]);
                        }
                    }
                    else
                    {
                        context.Visitor.Visit(mce.Object);
                    }
                    writer.Write($".{newName}(");
                    context.Visitor.Visit(mce.Arguments[0]);

                    if (mce.Arguments.Count > 1 && newName != "join")
                    {
                        writer.Write(", ");
                        context.Visitor.Visit(mce.Arguments[1]);
                    }

                    writer.Write(")");
                }
            }
Beispiel #27
0
            public override void ConvertToJavascript(JavascriptConversionContext context)
            {
                var methodCallExpression = context.Node as MethodCallExpression;

                var nameAttribute = methodCallExpression?
                                    .Method
                                    .GetCustomAttributes(typeof(JavascriptMethodNameAttribute), false)
                                    .OfType <JavascriptMethodNameAttribute>()
                                    .FirstOrDefault();

                if (nameAttribute == null)
                {
                    return;
                }
                context.PreventDefault();

                var javascriptWriter = context.GetWriter();

                javascriptWriter.Write(".");
                javascriptWriter.Write(nameAttribute.Name);
                javascriptWriter.Write("(");

                var args = new List <Expression>();

                foreach (var expr in methodCallExpression.Arguments)
                {
                    var expression = expr as NewArrayExpression;
                    if (expression != null)
                    {
                        args.AddRange(expression.Expressions);
                    }
                    else
                    {
                        args.Add(expr);
                    }
                }

                for (var i = 0; i < args.Count; i++)
                {
                    var name = $"arg_{Parameters.Count}_{Suffix}";
                    if (i != 0)
                    {
                        javascriptWriter.Write(", ");
                    }
                    javascriptWriter.Write("args.");
                    javascriptWriter.Write(name);
                    object val;
                    if (LinqPathProvider.GetValueFromExpressionWithoutConversion(args[i], out val))
                    {
                        Parameters[name] = val;
                    }
                }
                if (nameAttribute.PositionalArguments != null)
                {
                    for (int i = args.Count;
                         i < nameAttribute.PositionalArguments.Length;
                         i++)
                    {
                        if (i != 0)
                        {
                            javascriptWriter.Write(", ");
                        }
                        context.Visitor.Visit(Expression.Constant(nameAttribute.PositionalArguments[i]));
                    }
                }

                javascriptWriter.Write(")");
            }
        private bool WriteSingleEnumItem(
            JavascriptConversionContext context,
            JavascriptWriter writer,
            long numValue,
            object enumValue,
            bool inStringAlready)
        {
            if ((opts & EnumOptions.UseStrings) != 0)
            {
                if (inStringAlready)
                {
                    if ((opts & EnumOptions.UseNumbers) != 0)
                    {
                        writer.WriteLiteralStringContent(numValue.ToString());
                    }
                    else
                    {
                        var str = enumValue.ToString();
                        if (numValue == 0 && str == "0")
                        {
                            writer.WriteLiteralStringContent("");
                        }
                        else
                        {
                            writer.WriteLiteralStringContent(str);
                        }
                    }
                    return(true);
                }

                using (writer.Operation(JavascriptOperationTypes.Literal))
                {
                    if ((opts & EnumOptions.UseNumbers) != 0)
                    {
                        writer.WriteLiteral(numValue.ToString());
                    }
                    else
                    {
                        var str = enumValue.ToString();
                        if (numValue == 0 && str == "0")
                        {
                            writer.WriteLiteral("");
                        }
                        else
                        {
                            writer.WriteLiteral(str);
                        }
                    }
                    return(true);
                }
            }

            if ((opts & EnumOptions.UseNumbers) != 0)
            {
                using (writer.Operation(JavascriptOperationTypes.Literal))
                    writer.WriteLiteral(numValue);
                return(true);
            }

            if ((opts & EnumOptions.UseStaticFields) != 0)
            {
                using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                    context.Write(enumValue.GetType().Name).WriteAccessor(enumValue.ToString());
                return(true);
            }

            return(false);
        }
Beispiel #29
0
        public override void ConvertToJavascript(JavascriptConversionContext context)
        {
            if (context.Node is MethodCallExpression methodCall)
            {
                if (methodCall.Method.DeclaringType == typeof(Enumerable))
                {
                    switch (methodCall.Method.Name)
                    {
                    case "Select":
                    {
                        context.PreventDefault();
                        var writer = context.GetWriter();
                        using (writer.Operation(JavascriptOperationTypes.Call))
                        {
                            using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                            {
                                // public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
                                // public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
                                var pars = methodCall.Method.GetParameters();
                                if (pars.Length != 2)
                                {
                                    throw new NotSupportedException("The `Enumerable.Select` method must have 2 parameters.");
                                }

                                context.Visitor.Visit(methodCall.Arguments[0]);
                                writer.Write(".map");
                            }

                            writer.Write('(');

                            // separator
                            using (writer.Operation(0))
                                context.Visitor.Visit(methodCall.Arguments[1]);

                            writer.Write(')');
                        }

                        return;
                    }

                    case "Where":
                    {
                        context.PreventDefault();
                        var writer = context.GetWriter();
                        using (writer.Operation(JavascriptOperationTypes.Call))
                        {
                            using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                            {
                                // public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
                                // public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
                                var pars = methodCall.Method.GetParameters();
                                if (pars.Length != 2)
                                {
                                    throw new NotSupportedException("The `Enumerable.Where` method must have 2 parameters.");
                                }

                                context.Visitor.Visit(methodCall.Arguments[0]);
                                writer.Write(".filter");
                            }

                            writer.Write('(');

                            // separator
                            using (writer.Operation(0))
                                context.Visitor.Visit(methodCall.Arguments[1]);

                            writer.Write(')');
                        }

                        return;
                    }

                    case "ToArray":
                    {
                        // Ecma Script 6+: use spread operator
                        // Other: use array `slice`
                        if (context.Options.ScriptVersion.Supports(JavascriptSyntaxFeature.ArraySpread))
                        {
                            context.PreventDefault();
                            var writer = context.GetWriter();
                            using (writer.Operation(0))
                            {
                                writer.Write('[');
                                writer.Write("...");
                                using (writer.Operation(JavascriptOperationTypes.ParamIsolatedLhs))
                                    context.Visitor.Visit(methodCall.Arguments[0]);
                                writer.Write(']');
                            }
                        }
                        else
                        {
                            context.PreventDefault();
                            var writer = context.GetWriter();
                            using (writer.Operation(JavascriptOperationTypes.Call))
                            {
                                using (writer.Operation(JavascriptOperationTypes.IndexerProperty))
                                {
                                    context.Visitor.Visit(methodCall.Arguments[0]);
                                    writer.Write(".slice");
                                }

                                writer.Write('(');
                                writer.Write(')');
                            }
                        }

                        return;
                    }
                    }
                }
            }
        }