コード例 #1
0
		public static string GetArgsScript(MethodCallExpression expression, DataContextStack dataContext)
		{
			var target = expression.Object == null ? null : JavascriptTranslator.CompileToJavascript(expression.Object, dataContext);
			var arguments = (target == null ? new string[0] : new[] { target })
				.Concat(expression.Arguments.Select(a => JavascriptTranslator.CompileToJavascript(a, dataContext)));
			return "[" + String.Join(", ", arguments) + "]";
		}
コード例 #2
0
 public static string CompileToJavascript(Expression binding, DataContextStack dataContext)
 {
     var translator = new JavascriptTranslator();
     translator.DataContexts = dataContext;
     var script = translator.Translate(binding).Trim();
     if (binding.NodeType == ExpressionType.MemberAccess && script.EndsWith("()", StringComparison.Ordinal)) script = script.Remove(script.Length - 2);
     return script;
 }
コード例 #3
0
 public virtual Expression<CompiledBindingExpression.BindingDelegate> CompileToDelegate(Expression binding, DataContextStack dataContext, Type expectedType)
 {
     var viewModelsParameter = Expression.Parameter(typeof(object[]), "vm");
     var controlRootParameter = Expression.Parameter(typeof(DotvvmBindableObject), "controlRoot");
     var expr = ExpressionUtils.Replace(ConvertExpressionToType(binding, expectedType), BindingCompiler.GetParameters(dataContext, viewModelsParameter, Expression.Convert(controlRootParameter, dataContext.RootControlType)));
     expr = ExpressionUtils.ConvertToObject(expr);
     return Expression.Lambda<CompiledBindingExpression.BindingDelegate>(expr, viewModelsParameter, controlRootParameter);
 }
コード例 #4
0
 public virtual Expression<CompiledBindingExpression.BindingUpdateDelegate> CompileToUpdateDelegate(Expression binding, DataContextStack dataContext)
 {
     var viewModelsParameter = Expression.Parameter(typeof(object[]), "vm");
     var controlRootParameter = Expression.Parameter(typeof(DotvvmBindableObject), "controlRoot");
     var valueParameter = Expression.Parameter(typeof(object), "value");
     var expr = ExpressionUtils.Replace(binding, BindingCompiler.GetParameters(dataContext, viewModelsParameter, Expression.Convert(controlRootParameter, dataContext.RootControlType)));
     var assignment = Expression.Assign(expr, Expression.Convert(valueParameter, expr.Type));
     return Expression.Lambda<CompiledBindingExpression.BindingUpdateDelegate>(assignment, viewModelsParameter, controlRootParameter, valueParameter);
 }
コード例 #5
0
 protected override IDataContextStack CreateDataContextTypeStack(ITypeDescriptor viewModelType, ITypeDescriptor wrapperType = null, IDataContextStack parentDataContextStack = null)
 {
     var dataContextTypeStack = new DataContextStack(ResolvedTypeDescriptor.ToSystemType(viewModelType), parentDataContextStack as DataContextStack);
     if (wrapperType != null)
     {
         dataContextTypeStack.RootControlType = ResolvedTypeDescriptor.ToSystemType(wrapperType);
     }
     return dataContextTypeStack;
 }
コード例 #6
0
 public object CompileBinding(string expression, params Type[] contexts)
 {
     var context = new DataContextStack(contexts.FirstOrDefault() ?? typeof(object));
     context.RootControlType = typeof(DotvvmControl);
     for (int i = 1; i < contexts.Length; i++)
     {
         context = new DataContextStack(contexts[i], context);
     }
     var parser = new BindingExpressionBuilder();
     var expressionTree = parser.Parse(expression, context, BindingParserOptions.Create<ValueBindingExpression>());
     return JavascriptTranslator.CompileToJavascript(expressionTree, context);
 }
コード例 #7
0
		protected virtual string CompileMethodCall(MethodCallExpression methodExpression, DataContextStack dataContext, string callbackFunction = null)
		{
			if (!Attribute.IsDefined(methodExpression.Method, typeof(AllowStaticCommandAttribute)))
				throw new Exception($"Method '{methodExpression.Method.DeclaringType.Name}.{methodExpression.Method.Name}' used in static command has to be marked with [AllowStaticCommand] attribute.");

			if (callbackFunction == null) callbackFunction = "null";
			if (methodExpression == null)
			{
				throw new NotSupportedException("Static command binding must be a method call!");
			}
			var argsScript = GetArgsScript(methodExpression, dataContext);
			return $"dotvvm.staticCommandPostback(i_pageArea, sender, '{GetMethodName(methodExpression)}', { argsScript }, {callbackFunction})";
		}
コード例 #8
0
        public override void VisitControl(ResolvedControl control)
        {
            var position = control.DothtmlNode.StartPosition;
            var returnType = CurrentType;
            if (CurrentType != control.DataContextTypeStack)
            {
                CurrentType = control.DataContextTypeStack;
                Result.Controls.Add(position, new ControlCompilationInfo
                {
                    DataContext = control.DataContextTypeStack.DataContextType.ToString()
                });
            }

            base.VisitControl(control);
            CurrentType = returnType;
        }
コード例 #9
0
 public static TypeRegistry AddTypeSymbols(TypeRegistry reg, DataContextStack dataContext)
 {
     var namespaces = dataContext.Enumerable().Select(t => t.Namespace).Except(new[] { "System" }).Distinct();
     return reg.AddSymbols(new[]
     {
         // ViewModel is alias for current viewmodel type
         new KeyValuePair<string, Expression>("ViewModel", TypeRegistry.CreateStatic(dataContext.DataContextType)),
         // RootViewModel alias for root view model type
         new KeyValuePair<string, Expression>("RootViewModel", TypeRegistry.CreateStatic(dataContext.Enumerable().Last())),
     })
     // alias for any viewModel in hierarchy :
     .AddSymbols(dataContext.Enumerable()
         .Select((t, i) => new KeyValuePair<string, Expression>($"Parent{i}ViewModel", TypeRegistry.CreateStatic(t))))
     // import all viewModel namespaces
     .AddSymbols(namespaces.Select(ns => (Func<string, Expression>)(typeName => TypeRegistry.CreateStatic(ReflectionUtils.FindType(ns + "." + typeName)))));
 }
コード例 #10
0
        public Expression Parse(string expression, DataContextStack dataContexts, BindingParserOptions options)
        {
            try
            {
                var tokenizer = new BindingTokenizer();
                tokenizer.Tokenize(new StringReader(expression));

                var parser = new BindingParser();
                parser.Tokens = tokenizer.Tokens;
                var node = parser.ReadExpression();
                if (!parser.OnEnd())
                {
                    throw new BindingCompilationException(
                        $"Unexpected token '{expression.Substring(0, parser.Peek().StartPosition)} ---->{parser.Peek().Text}<---- {expression.Substring(parser.Peek().StartPosition + parser.Peek().Length)}'",
                        null, new TokenBase[] { parser.Peek() });
                }
                foreach (var n in node.EnumerateNodes())
                {
                    if (n.HasNodeErrors) throw new BindingCompilationException(string.Join(", ", n.NodeErrors), n);
                }

                var symbols = InitSymbols(dataContexts);
                symbols = options.AddTypes(symbols);

                var visitor = new ExpressionBuildingVisitor(symbols);
                visitor.Scope = symbols.Resolve(options.ScopeParameter);
                return visitor.Visit(node);
            }
            catch (Exception ex)
            {
                ex.ForInnerExceptions<BindingCompilationException>(bce =>
                {
                    if (bce.Expression == null) bce.Expression = expression;
                });
                throw;
            }
        }
コード例 #11
0
 public static IEnumerable<ParameterExpression> GetParameters(DataContextStack dataContext)
 {
     if (dataContext.RootControlType != null)
     {
         yield return Expression.Parameter(dataContext.RootControlType, "_control");
     }
     yield return Expression.Parameter(dataContext.DataContextType, "_this");
     yield return Expression.Parameter(typeof(BindingPageInfo), "_page");
     var index = 1;
     while (dataContext.Parent != null)
     {
         dataContext = dataContext.Parent;
         if (index == 1)
         {
             yield return Expression.Parameter(dataContext.DataContextType, "_parent");
         }
         else
         {
             yield return Expression.Parameter(dataContext.DataContextType, "_parent" + index);
         }
         index++;
     }
     yield return Expression.Parameter(dataContext.DataContextType, "_root");
 }
コード例 #12
0
 /// <summary>
 /// Emits value or binding and returns 
 /// </summary>
 protected ExpressionSyntax ProcessBindingOrValue(object obj, DataContextStack dataContext)
 {
     var binding = obj as ResolvedBinding;
     if (binding != null) return ProcessBinding(binding, typeof(object));
     else return emitter.EmitValue(obj);
 }
コード例 #13
0
 protected void ProcessHtmlAttributes(string controlName, IDictionary<string, object> attributes, DataContextStack dataContext)
 {
     foreach (var attr in attributes)
     {
         var value = ProcessBindingOrValue(attr.Value, dataContext);
         emitter.EmitAddHtmlAttribute(controlName, attr.Key, value);
     }
 }
コード例 #14
0
 public override void VisitView(ResolvedTreeRoot view)
 {
     CurrentType = view.DataContextTypeStack;
     base.VisitView(view);
 }
コード例 #15
0
ファイル: DataContextStack.cs プロジェクト: darilek/dotvvm
 public DataContextStack(Type type, DataContextStack parent = null)
 {
     Parent = parent;
     DataContextType = type;
     RootControlType = parent?.RootControlType;
 }
コード例 #16
0
 public static TypeRegistry InitSymbols(DataContextStack dataContext)
 {
     return AddTypeSymbols(TypeRegistry.Default.AddSymbols(GetParameters(dataContext).Select(d => new KeyValuePair<string, Expression>(d.Name, d))), dataContext);
 }