public void JsFormatter_FunctionExpression() { var expr = new JsFunctionExpression(new[] { new JsIdentifier("a") }, new JsBlockStatement(new JsReturnStatement(new JsBinaryExpression(new JsIdentifierExpression("a"), BinaryOperatorType.Plus, new JsLiteral(2))))); Assert.AreEqual("function(a){return a+2;}", expr.FormatScript()); Assert.AreEqual("function(a) {\n\treturn a + 2;\n}", expr.FormatScript(niceMode: true)); }
public JsExpression CompileToJavascript(DataContextStack dataContext, Expression expression) { var currentContextVariable = new JsTemporaryVariableParameter(new JsIdentifierExpression("ko").Member("contextFor").Invoke(new JsSymbolicParameter(CommandBindingExpression.SenderElementParameter))); var resultPromiseVariable = new JsTemporaryVariableParameter(new JsNewExpression("DotvvmPromise")); var senderVariable = new JsTemporaryVariableParameter(new JsSymbolicParameter(CommandBindingExpression.SenderElementParameter)); var visitor = new ExtractExpressionVisitor(ex => ex.NodeType == ExpressionType.Call && ex is MethodCallExpression methodCall && javascriptTranslator.TryTranslateMethodCall(methodCall.Object, methodCall.Arguments.ToArray(), methodCall.Method, dataContext) == null); var rootCallback = visitor.Visit(expression); var js = SouldCompileCallback(rootCallback) ? new JsSymbolicParameter(resultPromiseVariable).Member("resolve").Invoke(javascriptTranslator.CompileToJavascript(rootCallback, dataContext)) : null; foreach (var param in visitor.ParameterOrder.Reverse <ParameterExpression>()) { js = js ?? new JsSymbolicParameter(resultPromiseVariable).Member("resolve").Invoke(new JsIdentifierExpression(param.Name)); var callback = new JsFunctionExpression(new[] { new JsIdentifier(param.Name) }, new JsBlockStatement(new JsExpressionStatement(js))); var method = visitor.Replaced[param] as MethodCallExpression; js = CompileMethodCall(method, dataContext, callback); } foreach (var sp in js.Descendants.OfType <JsSymbolicParameter>()) { if (sp.Symbol == JavascriptTranslator.KnockoutContextParameter) { sp.Symbol = currentContextVariable; } else if (sp.Symbol == JavascriptTranslator.KnockoutViewModelParameter) { sp.ReplaceWith(new JsSymbolicParameter(currentContextVariable).Member("$data")); } else if (sp.Symbol == CommandBindingExpression.SenderElementParameter) { sp.Symbol = senderVariable; } } return(new JsBinaryExpression(js, BinaryOperatorType.Sequence, new JsSymbolicParameter(resultPromiseVariable))); }
public JsExpression CompileToJavascript(DataContextStack dataContext, Expression expression) { var currentContextVariable = new JsTemporaryVariableParameter(new JsIdentifierExpression("ko").Member("contextFor").Invoke(new JsSymbolicParameter(CommandBindingExpression.SenderElementParameter))); // var resultPromiseVariable = new JsNewExpression("DotvvmPromise")); var senderVariable = new JsTemporaryVariableParameter(new JsSymbolicParameter(CommandBindingExpression.SenderElementParameter)); var visitor = new ExtractExpressionVisitor(ex => { if (ex.NodeType == ExpressionType.Call && ex is MethodCallExpression methodCall) { if (javascriptTranslator.TryTranslateMethodCall(methodCall.Object, methodCall.Arguments.ToArray(), methodCall.Method, dataContext) is JsExpression jsTranslation) { if (jsTranslation.Annotation <ResultIsPromiseAnnotation>() is ResultIsPromiseAnnotation promiseAnnotation) { return(p => new BindingParameterAnnotation(extensionParameter: new JavascriptTranslationVisitor.FakeExtensionParameter(_ => new JsIdentifierExpression(p.Name).WithAnnotations(promiseAnnotation.ResultAnnotations), p.Name, new ResolvedTypeDescriptor(p.Type)))); } else { return(null); } } return(p => new BindingParameterAnnotation(extensionParameter: new JavascriptTranslationVisitor.FakeExtensionParameter(_ => new JsIdentifierExpression(p.Name).WithAnnotation(new ViewModelInfoAnnotation(p.Type)), p.Name, new ResolvedTypeDescriptor(p.Type)))); } return(null); }); var rootCallback = visitor.Visit(expression); var js = SouldCompileCallback(rootCallback) ? new JsIdentifierExpression("resolve").Invoke(javascriptTranslator.CompileToJavascript(rootCallback, dataContext)) : null; foreach (var param in visitor.ParameterOrder.Reverse <ParameterExpression>()) { js = js ?? new JsIdentifierExpression("resolve").Invoke(new JsIdentifierExpression(param.Name)); var callback = new JsFunctionExpression(new[] { new JsIdentifier(param.Name) }, new JsBlockStatement(new JsExpressionStatement(js))); var method = visitor.Replaced[param] as MethodCallExpression; js = CompileMethodCall(method, dataContext, callback); } foreach (var sp in js.Descendants.OfType <JsSymbolicParameter>()) { if (sp.Symbol == JavascriptTranslator.KnockoutContextParameter) { sp.Symbol = currentContextVariable; } else if (sp.Symbol == JavascriptTranslator.KnockoutViewModelParameter) { sp.ReplaceWith(new JsSymbolicParameter(currentContextVariable).Member("$data")); } else if (sp.Symbol == CommandBindingExpression.SenderElementParameter) { sp.Symbol = senderVariable; } } if (js is JsInvocationExpression invocation && invocation.Target is JsIdentifierExpression identifier && identifier.Identifier == "resolve") { // optimize `new Promise(function (resolve) { resolve(x) })` to `Promise.resolve(x)` identifier.ReplaceWith(new JsIdentifierExpression("Promise").Member("resolve")); return(js); }
private static string GenerateHandlerOptions(DotvvmBindableObject handler, Dictionary <string, object> options) { JsExpression optionsExpr = new JsObjectExpression( options.Where(o => o.Value != null).Select(o => new JsObjectProperty(o.Key, TransformOptionValueToExpression(handler, o.Value))) ); if (options.Any(o => o.Value is IValueBinding)) { optionsExpr = new JsFunctionExpression( new[] { new JsIdentifier("c"), new JsIdentifier("d") }, new JsBlockStatement(new JsReturnStatement(optionsExpr)) ); } optionsExpr.FixParenthesis(); var script = new JsFormattingVisitor().ApplyAction(optionsExpr.AcceptVisitor).GetParameterlessResult(); return(script); }
private static string GenerateHandlerOptions(DotvvmBindableObject handler, Dictionary <string, object> options) { JsExpression optionsExpr = new JsObjectExpression( options.Where(o => o.Value != null).Select(o => new JsObjectProperty(o.Key, o.Value is IValueBinding b ? (JsExpression) new JsIdentifierExpression( JavascriptTranslator.FormatKnockoutScript(b.GetParametrizedKnockoutExpression(handler, unwrapped: true), new ParametrizedCode("c"), new ParametrizedCode("d"))) : new JsLiteral(o.Value))) ); if (options.Any(o => o.Value is IValueBinding)) { optionsExpr = new JsFunctionExpression( new[] { new JsIdentifier("c"), new JsIdentifier("d") }, new JsBlockStatement(new JsReturnStatement(optionsExpr)) ); } optionsExpr.FixParenthesis(); var script = new JsFormattingVisitor().ApplyAction(optionsExpr.AcceptVisitor).GetParameterlessResult(); return(script); }