示例#1
0
                public CastedExpressionBindingProperty ConvertExpressionToType(ParsedExpressionBindingProperty exprP, ExpectedTypeBindingProperty expectedTypeP = null)
                {
                    var expr         = exprP.Expression;
                    var expectedType = expectedTypeP?.Type ?? typeof(object);

                    if (expectedType == typeof(object))
                    {
                        expectedType = typeof(Command);
                    }
                    if (!typeof(Delegate).IsAssignableFrom(expectedType))
                    {
                        throw new Exception($"Command bindings must be assigned to properties of Delegate type, not { expectedType }");
                    }

                    var normalConvert = TypeConversion.ImplicitConversion(expr, expectedType);

                    if (normalConvert != null && expr.Type != typeof(object))
                    {
                        return(new CastedExpressionBindingProperty(normalConvert));
                    }

                    // wrap expression into a lambda
                    if (typeof(Delegate).IsAssignableFrom(expectedType) && !typeof(Delegate).IsAssignableFrom(expr.Type))
                    {
                        var invokeMethod = expectedType.GetMethod("Invoke");
                        expr = TaskConversion(expr, invokeMethod.ReturnType);
                        return(new CastedExpressionBindingProperty(Expression.Lambda(
                                                                       expectedType,
                                                                       expr,
                                                                       invokeMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name))
                                                                       )));
                    }
                    // TODO: convert delegates to another delegates
                    throw new Exception($"Can not convert expression '{ expr }' to '{expectedType}'.");
                }
示例#2
0
        protected override Expression ConvertExpressionToType(Expression expr, Type expectedType)
        {
            if (expectedType == typeof(object))
            {
                expectedType = typeof(Command);
            }
            if (!typeof(Delegate).IsAssignableFrom(expectedType))
            {
                throw new Exception($"Command bindings must be assigned to properties with Delegate type, not { expectedType }");
            }
            var normalConvert = TypeConversion.ImplicitConversion(expr, expectedType);

            if (normalConvert != null && expr.Type != typeof(object))
            {
                return(normalConvert);
            }
            if (typeof(Delegate).IsAssignableFrom(expectedType) && !typeof(Delegate).IsAssignableFrom(expr.Type))
            {
                var invokeMethod = expectedType.GetMethod("Invoke");
                expr = TaskConversion(expr, invokeMethod.ReturnType);
                return(Expression.Lambda(
                           expectedType,
                           base.ConvertExpressionToType(expr, invokeMethod.ReturnType),
                           invokeMethod.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name))
                           ));
            }
            // TODO: convert delegates to another delegates
            throw new Exception($"Can not convert expression '{ expr }' to '{expectedType}'.");
        }
示例#3
0
 protected string EmitCreateControl(Type type, object[] arguments)
 {
     // if matching ctor exists, invoke it directly
     if (type.GetTypeInfo().GetCustomAttribute(typeof(DependencyInjection.RequireDependencyInjectionAttribute)) is DependencyInjection.RequireDependencyInjectionAttribute requireDiAttr)
     {
         return(emitter.EmitCustomInjectionFactoryInvocation(requireDiAttr.FactoryType, type));
     }
     else if (type.GetConstructors().Any(ctor =>
                                         ctor.GetParameters().Length == (arguments?.Length ?? 0) &&
                                         ctor.GetParameters().Zip(arguments ?? Enumerable.Empty <object>(),
                                                                  (p, a) => TypeConversion.ImplicitConversion(Expression.Constant(a), p.ParameterType))
                                         .All(a => a != null)))
     {
         return(emitter.EmitCreateObject(type, arguments));
     }
     // othervise invoke DI factory
     else
     {
         return(emitter.EmitInjectionFactoryInvocation(
                    type,
                    (arguments ?? Enumerable.Empty <object>()).Select(a => (a.GetType(), emitter.EmitValue(a))).ToArray(),
                    emitter.InvokeDefaultInjectionFactory
                    ));
     }
 }
示例#4
0
        /// <summary>
        /// Creates the binding by calling .ctor(BindingCompilationService service, object[] properties), does not wrap exceptions to TargetInvocationException.
        /// </summary>
        public static IBinding CreateBinding(this BindingCompilationService service, Type binding, object[] properties)
        {
            if (binding.GetTypeInfo().ContainsGenericParameters)
            {
                var nonGenericBase = binding.GetTypeInfo().BaseType;
                Debug.Assert(!nonGenericBase.GetTypeInfo().ContainsGenericParameters&& nonGenericBase.Name + "`1" == binding.Name);
                var tmpBinding = CreateBinding(service, nonGenericBase, properties);
                var type       = tmpBinding.GetProperty <ExpectedTypeBindingProperty>(ErrorHandlingMode.ReturnNull)?.Type ??
                                 tmpBinding.GetProperty <ResultTypeBindingProperty>(ErrorHandlingMode.ThrowException).Type;
                binding    = binding.MakeGenericType(new [] { type });
                properties = tmpBinding is ICloneableBinding cloneable?cloneable.GetAllComputedProperties().ToArray() : properties;
            }

            return(bindingCtorCache.GetOrAdd(binding, type => {
                var ctor = type.GetConstructor(new[] { typeof(BindingCompilationService), typeof(object[]) }) ??
                           type.GetConstructor(new[] { typeof(BindingCompilationService), typeof(IEnumerable <object>) });
                if (ctor == null)
                {
                    throw new NotSupportedException($"Could not find .ctor(BindingCompilationService service, object[] properties) on binding '{binding.FullName}'.");
                }
                var bindingServiceParam = Expression.Parameter(typeof(BindingCompilationService));
                var propertiesParam = Expression.Parameter(typeof(object[]));
                var expression = Expression.New(ctor, bindingServiceParam, TypeConversion.ImplicitConversion(propertiesParam, ctor.GetParameters()[1].ParameterType));
                return Expression.Lambda <Func <BindingCompilationService, object[], IBinding> >(expression, bindingServiceParam, propertiesParam).Compile();
            })(service, properties));
        }
示例#5
0
 public void Conversion_ValidToString()
 {
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(DateTime)), typeof(string), throwException: true, allowToString: true);
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(int)), typeof(string), throwException: true, allowToString: true);
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(string)), typeof(string), throwException: true, allowToString: true);
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(double)), typeof(string), throwException: true, allowToString: true);
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(TimeSpan)), typeof(string), throwException: true, allowToString: true);
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(Tuple <int, int>)), typeof(string), throwException: true, allowToString: true);
 }
示例#6
0
 /// <summary>
 /// Creates the binding by calling .ctor(BindingCompilationService service, object[] properties), does not wrap exceptions to TargetInvocationException.
 /// </summary>
 public static IBinding CreateBinding(this BindingCompilationService service, Type binding, object[] properties) =>
 bindingCtorCache.GetOrAdd(binding, type => {
     var ctor = type.GetConstructor(new[] { typeof(BindingCompilationService), typeof(object[]) }) ??
                type.GetConstructor(new[] { typeof(BindingCompilationService), typeof(IEnumerable <object>) });
     if (ctor == null)
     {
         throw new NotSupportedException($"Could not find .ctor(BindingCompilationService service, object[] properties) on binding '{binding.FullName}'.");
     }
     var bindingServiceParam = Expression.Parameter(typeof(BindingCompilationService));
     var propertiesParam     = Expression.Parameter(typeof(object[]));
     var expression          = Expression.New(ctor, bindingServiceParam, TypeConversion.ImplicitConversion(propertiesParam, ctor.GetParameters()[1].ParameterType));
     return(Expression.Lambda <Func <BindingCompilationService, object[], IBinding> >(expression, bindingServiceParam, propertiesParam).Compile());
 })(service, properties);
示例#7
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));
        }
示例#8
0
        public string CompileBinding(string expression, Type[] contexts, Type expectedType)
        {
            var context = DataContextStack.Create(contexts.FirstOrDefault() ?? typeof(object), extensionParameters: new BindingExtensionParameter[] {
                new BindingPageInfoExtensionParameter(),
            }.Concat(configuration.Markup.DefaultExtensionParameters).ToArray());

            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(configuration.ServiceProvider.GetRequiredService <JavascriptTranslator>().CompileToJavascript(expressionTree, context));

            jsExpression.AcceptVisitor(new KnockoutObservableHandlingVisitor(true));
            JsTemporaryVariableResolver.ResolveVariables(jsExpression);
            return(JavascriptTranslator.FormatKnockoutScript(jsExpression.Expression));
        }
示例#9
0
 protected string EmitCreateControl(Type type, object[] arguments)
 {
     // if marked with [RequireDependencyInjection] attribute, invoke injected factory
     if (type.GetTypeInfo().GetCustomAttribute(typeof(DependencyInjection.RequireDependencyInjectionAttribute)) is DependencyInjection.RequireDependencyInjectionAttribute requireDiAttr)
     {
         return(emitter.EmitCustomInjectionFactoryInvocation(requireDiAttr.FactoryType, type));
     }
     // if matching ctor exists, invoke it directly
     else if (type.GetConstructors().FirstOrDefault(ctor =>
                                                    ctor.GetParameters().Count(p => !p.HasDefaultValue) <= (arguments?.Length ?? 0) &&
                                                    ctor.GetParameters().Length >= (arguments?.Length ?? 0) &&
                                                    ctor.GetParameters().Zip(arguments ?? Enumerable.Empty <object>(),
                                                                             (p, a) => TypeConversion.ImplicitConversion(Expression.Constant(a), p.ParameterType))
                                                    .All(a => a != null)) is ConstructorInfo constructor)
     {
         var optionalArguments =
             constructor.GetParameters().Skip(arguments?.Length ?? 0)
             .Select(a =>
                     a.ParameterType == typeof(bool) && a.Name == "allowImplicitLifecycleRequirements" ? false :
                     a.DefaultValue
                     );
         return(emitter.EmitCreateObject(type, arguments == null ? optionalArguments.ToArray() : arguments.Concat(optionalArguments).ToArray()));
     }
     // otherwise invoke DI factory
     else
     {
         return(emitter.EmitInjectionFactoryInvocation(
                    type,
                    (arguments ?? Enumerable.Empty <object>()).Select(a => (a.GetType(), emitter.EmitValue(a))).ToArray(),
                    emitter.InvokeDefaultInjectionFactory
                    ));
     }
 }
示例#10
0
 protected virtual Expression ConvertExpressionToType(Expression expr, Type expectedType)
 => TypeConversion.ImplicitConversion(expr, expectedType, throwException: true, allowToString: true);
示例#11
0
 public void Conversion_InvalidToString()
 {
     // System.Linq.Expression does not override ToString, so the conversion is invalid
     Assert.IsNull(TypeConversion.ImplicitConversion(Expression.Parameter(typeof(Expression)), typeof(string)));
     Assert.IsNull(TypeConversion.ImplicitConversion(Expression.Parameter(typeof(object)), typeof(string)));
 }
示例#12
0
 public void Conversion_IntToDouble()
 {
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(int)), typeof(double), throwException: true);
 }
示例#13
0
 public void Conversion_DoubleNullable()
 {
     TypeConversion.ImplicitConversion(Expression.Parameter(typeof(double)), typeof(double?), throwException: true);
 }