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; } } } } }
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; } } } } }
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(")"); } }
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('}'); } }
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(")"); }
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 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); } }
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 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(")"); } }
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); } }
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(")"); } }
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); } }
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("]"); } } }
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; } } } }
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}"); } } }
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 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) { 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; } } } } }
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"); } }
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); } } }
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(")"); } }
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"); } } }
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(")"); }
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); } } } } }