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 GetArgsScript(MethodCallExpression expression, DataContextStack dataContext)
        {
            var arguments = (expression.Object == null ? new Expression[0] : new[] { expression.Object })
                            .Concat(expression.Arguments).Select(a => JavascriptTranslator.CompileToJavascript(a, dataContext, vmMapper));

            return(new JsArrayExpression(arguments));
        }
        public static string GetArgsScript(MethodCallExpression expression, DataContextStack dataContext)
        {
            var target = expression.Object == null ? "null" : JavascriptTranslator.CompileToJavascript(expression.Object, dataContext);
            var arguments = new[] { target }.Concat(expression.Arguments.Select(a => JavascriptTranslator.CompileToJavascript(a, dataContext)));

            return("[" + String.Join(", ", arguments) + "]");
        }
Beispiel #4
0
        /// <summary>
        /// Builds a <see cref="ViewModelValidationError.PropertyPath"/> from a LINQ expression
        /// </summary>
        public static string BuildPath <TValidationTarget>(Expression <Func <TValidationTarget, object> > propertyAccessor, DotvvmConfiguration configuration)
        {
            var context = DataContextStack.Create(typeof(TValidationTarget));
            var js      = JavascriptTranslator.CompileToJavascript(propertyAccessor, context,
                                                                   configuration.ServiceLocator.GetService <IViewModelSerializationMapper>());

            js.AcceptVisitor(new KnockoutObservableHandlingVisitor(true));
            var propertyPathExtractingVisitor = new PropertyPathExtractingVisitor();

            js.AcceptVisitor(propertyPathExtractingVisitor);
            return(propertyPathExtractingVisitor.ExtractedPropertyPath);
        }
Beispiel #5
0
        public string CompileBinding(string expression, Type[] contexts, Type expectedType)
        {
            var context = new DataContextStack(contexts.FirstOrDefault() ?? typeof(object), rootControlType: typeof(DotvvmControl));

            for (int i = 1; i < contexts.Length; i++)
            {
                context = new DataContextStack(contexts[i], context);
            }
            var parser         = new BindingExpressionBuilder();
            var expressionTree = TypeConversion.ImplicitConversion(parser.Parse(expression, context, BindingParserOptions.Create <ValueBindingExpression>()), expectedType, true, true);

            return(JavascriptTranslator.CompileToJavascript(expressionTree, context));
        }
        public override string CompileToJs(ResolvedBinding binding, CompiledBindingExpression compiledExpression)
        {
            var expression = binding.GetExpression();

            var visitor      = new ExtractExpressionVisitor(ex => ex.NodeType == ExpressionType.Call);
            var rootCallback = visitor.Visit(expression);
            var js           = SouldCompileCallback(rootCallback) ? JavascriptTranslator.CompileToJavascript(rootCallback, binding.DataContextTypeStack) : null;

            foreach (var param in visitor.ParameterOrder)
            {
                var callback = js == null ? null : $"function({param.Name}){{{js}}}";
                var method   = visitor.Replaced[param] as MethodCallExpression;
                js = CompileMethodCall(method, binding.DataContextTypeStack, callback);
            }
            return("var $context = ko.contextFor(this);var sender = this;(function(i_pageArea){with($context){" + js + "}})");
        }
        public string CompileBinding(Func <Dictionary <string, Expression>, Expression> expr, Type[] contexts)
        {
            var context = DataContextStack.Create(contexts.FirstOrDefault() ?? typeof(object), extensionParameters: new BindingExtensionParameter[] {
                new BindingPageInfoExtensionParameter()
            });

            for (int i = 1; i < contexts.Length; i++)
            {
                context = DataContextStack.Create(contexts[i], context);
            }
            var expressionTree = expr(BindingExpressionBuilder.GetParameters(context).ToDictionary(e => e.Name, e => (Expression)e));
            var jsExpression   = new JsParenthesizedExpression(JavascriptTranslator.CompileToJavascript(expressionTree, context,
                                                                                                        DotvvmConfiguration.CreateDefault().ServiceLocator.GetService <IViewModelSerializationMapper>()));

            jsExpression.AcceptVisitor(new KnockoutObservableHandlingVisitor(true));
            JsTemporaryVariableResolver.ResolveVariables(jsExpression);
            return(JavascriptTranslator.FormatKnockoutScript(jsExpression.Expression));
        }
        public string CompileBinding(string expression, Type[] contexts, Type expectedType)
        {
            var context = DataContextStack.Create(contexts.FirstOrDefault() ?? typeof(object), extenstionParameters: new BindingExtensionParameter[] {
                new BindingPageInfoExtensionParameter()
            });

            for (int i = 1; i < contexts.Length; i++)
            {
                context = DataContextStack.Create(contexts[i], context);
            }
            var parser         = new BindingExpressionBuilder();
            var expressionTree = TypeConversion.ImplicitConversion(parser.Parse(expression, context, BindingParserOptions.Create <ValueBindingExpression>()), expectedType, true, true);
            var jsExpression   = new JsParenthesizedExpression(JavascriptTranslator.CompileToJavascript(expressionTree, context,
                                                                                                        DotvvmConfiguration.CreateDefault().ServiceLocator.GetService <IViewModelSerializationMapper>()));

            jsExpression.AcceptVisitor(new KnockoutObservableHandlingVisitor(true));
            JsTemporaryVariableResolver.ResolveVariables(jsExpression);
            return(JavascriptTranslator.FormatKnockoutScript(jsExpression.Expression));
        }
Beispiel #9
0
        public virtual string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression expression)
        {
            var javascript = JavascriptTranslator.CompileToJavascript(binding.GetExpression(), binding.DataContextTypeStack);

            if (javascript == "$data")
            {
                javascript = "$rawData";
            }
            else if (javascript.StartsWith("$data.", StringComparison.Ordinal))
            {
                javascript = javascript.Substring("$data.".Length);
            }

            // do not produce try/eval on single properties
            if (javascript.Contains(".") || javascript.Contains("("))
            {
                return("dotvvm.evaluator.tryEval(function(){return " + javascript + "})");
            }
            else
            {
                return(javascript);
            }
        }
Beispiel #10
0
 public KnockoutJsExpressionBindingProperty CompileToJavascript(CastedExpressionBindingProperty expression,
                                                                DataContextStack dataContext)
 {
     return(new KnockoutJsExpressionBindingProperty(
                javascriptTranslator.CompileToJavascript(expression.Expression, dataContext).ApplyAction(a => a.Freeze())));
 }
Beispiel #11
0
        public static string GetArgsScript(MethodCallExpression expression, DataContextStack dataContext, IViewModelSerializationMapper vmMapper)
        {
            var target    = expression.Object == null ? null : JavascriptTranslator.FormatKnockoutScript(JavascriptTranslator.CompileToJavascript(expression.Object, dataContext, vmMapper), allowDataGlobal: false);
            var arguments = (target == null ? new string[0] : new[] { target })
                            .Concat(expression.Arguments.Select(a => JavascriptTranslator.FormatKnockoutScript(JavascriptTranslator.CompileToJavascript(a, dataContext, vmMapper), allowDataGlobal: true)));

            return("[" + String.Join(", ", arguments) + "]");
        }
Beispiel #12
0
        public new string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression compiledExpression, DotvvmConfiguration config)
        {
            var vmMapper   = config.ServiceLocator.GetService <IViewModelSerializationMapper>();
            var expression = binding.GetExpression();

            var visitor      = new ExtractExpressionVisitor(ex => ex.NodeType == ExpressionType.Call);
            var rootCallback = visitor.Visit(expression);
            var js           = SouldCompileCallback(rootCallback) ? "resultPromise.resolve(" + JavascriptTranslator.FormatKnockoutScript(JavascriptTranslator.CompileToJavascript(rootCallback, binding.DataContextTypeStack, vmMapper), allowDataGlobal: false) + ")" : null;

            foreach (var param in visitor.ParameterOrder.Reverse <ParameterExpression>())
            {
                if (js == null)
                {
                    js = $"resultPromise.resolve({param.Name})";
                }
                var callback = $"function({param.Name}){{{js}}}";
                var method   = visitor.Replaced[param] as MethodCallExpression;
                js = CompileMethodCall(method, binding.DataContextTypeStack, vmMapper, callback);
            }
            return("var $context = ko.contextFor(this);var sender = this;var resultPromise = new DotvvmPromise();(function(i_pageArea){with($context){" + js + "}})");
        }
        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);
            }