static NullConditionalOperatorVisitor()
 {
     Instance            = new NullConditionalOperatorVisitor();
     TypeConstantNode    = new ConstantExpressionNode(typeof(NullConditionalOperatorVisitor));
     LambdaParameterNode = new MemberExpressionNode(null, "x");
     LambdaParameters    = new[] { LambdaParameterNode.Member };
 }
        IExpressionNode IExpressionVisitor.Visit(IExpressionNode node)
        {
            var methodCallExpressionNode = node as IMethodCallExpressionNode;

            if (methodCallExpressionNode == null)
            {
                return(node);
            }
            if (methodCallExpressionNode.Method == GetErrorsMethod &&
                methodCallExpressionNode.Target is ResourceExpressionNode)
            {
                var paths = methodCallExpressionNode.Arguments
                            .OfType <IConstantExpressionNode>()
                            .Where(expressionNode => expressionNode.Type == typeof(string))
                            .Select(expressionNode => expressionNode.Value as string ?? string.Empty);
                Guid id = Guid.NewGuid();
                _errorPathNames[id] = paths.ToArray();
                var idNode = new ConstantExpressionNode(id, typeof(Guid));

                var args = methodCallExpressionNode.Arguments.ToList();
                //Adding binding source member if the expression does not contain members.
                if (args.Count == 0)
                {
                    args.Add(new MemberExpressionNode(ResourceExpressionNode.DynamicInstance,
                                                      BindingServiceProvider.ResourceResolver.BindingSourceResourceName));
                }
                args.Insert(0, idNode);
                return(new MethodCallExpressionNode(methodCallExpressionNode.Target, methodCallExpressionNode.Method, args, methodCallExpressionNode.TypeArgs));
            }
            return(node);
        }
        protected override Expression VisitConstant(ConstantExpression node)
        {
            var queryable = node.Value as IQueryable;
            ConstantExpressionNode constantExpression;

            if (queryable != null)
            {
                constantExpression = new ConstantExpressionNode(ConstantKind.QuerySource, node.Type, node.Value);
            }
            else if (node.Value == null)
            {
                constantExpression = new ConstantExpressionNode(ConstantKind.Null);
            }
            else
            {
                var valueType = node.Value.GetType();
                var field     = valueType.GetFields().Single();
                var value     = field.GetValue(node.Value);

                constantExpression = new ConstantExpressionNode(ConstantKind.ClosureState, valueType, value);
            }

            AddChild(constantExpression);

            return(node);
        }
Beispiel #4
0
        private IExpressionNode GetResourceMember(IExpressionNode node, string memberName, IList <IExpressionNode> nodes)
        {
            IExpressionNode staticValue;

            if (_staticNodes.TryGetValue(node, out staticValue))
            {
                return(staticValue);
            }

            IBindingPath path           = BindingServiceProvider.BindingPathFactory(memberName);
            string       firstMember    = path.Parts[0];
            Type         type           = BindingServiceProvider.ResourceResolver.ResolveType(firstMember, Context, false);
            var          resourceMember = (ResourceExpressionNode)nodes[0];

            if (resourceMember.Dynamic && type == null)
            {
                memberName = BindingExtensions.MergePath(path.Parts.Skip(1).ToArray());
                return(GetOrAddBindingMember("$" + path.Path, (s, i) => new BindingMemberExpressionNode(firstMember, memberName, s, i)));
            }

            bool            dynamicMember   = false;
            IExpressionNode firstMemberNode = nodes[1];

            if (!_staticNodes.TryGetValue(firstMemberNode, out staticValue))
            {
                if (type == null)
                {
                    var value = BindingServiceProvider
                                .ResourceResolver
                                .ResolveObject(firstMember, Context, true)
                                .Value;
                    var dynamicObject = value as IDynamicObject;
                    if (dynamicObject == null || path.Parts.Count <= 1)
                    {
                        staticValue = new ConstantExpressionNode(value);
                    }
                    else
                    {
                        staticValue   = new ConstantExpressionNode(dynamicObject.GetMember(path.Parts[1], Empty.Array <object>()));
                        dynamicMember = true;
                    }
                }
                else
                {
                    staticValue = new ConstantExpressionNode(type, typeof(Type));
                }
                _staticNodes[firstMemberNode] = staticValue;
                if (dynamicMember)
                {
                    _staticNodes[nodes[2]] = staticValue;
                }
            }
            if (firstMemberNode == node || (dynamicMember && node == nodes[2]))
            {
                return(staticValue);
            }
            return(node);
        }
        IExpressionNode IExpressionVisitor.Visit(IExpressionNode node)
        {
            var methodCallExpressionNode = node as IMethodCallExpressionNode;

            if (methodCallExpressionNode == null)
            {
                return(node);
            }

            if (methodCallExpressionNode.Method == GetErrorsMethod &&
                methodCallExpressionNode.Target is ResourceExpressionNode)
            {
                var  paths    = new List <string>();
                bool isDirect = false;
                var  args     = methodCallExpressionNode.Arguments.ToList();
                for (int i = 0; i < args.Count; i++)
                {
                    var arg  = args[i];
                    var path = (arg as IConstantExpressionNode)?.Value as string;
                    if (path != null)
                    {
                        paths.Add(path);
                        continue;
                    }
                    var methodExpr = arg as IMethodCallExpressionNode;
                    if (methodExpr?.Method == AttachedMemberConstants.AsErrorsSource && methodExpr.Target is IMemberExpressionNode)
                    {
                        arg     = new MemberExpressionNode(methodExpr.Target, AttachedMemberConstants.AsErrorsSource);
                        args[i] = arg;
                    }

                    if (!isDirect)
                    {
                        isDirect = (arg as IMemberExpressionNode)?.Member == AttachedMemberConstants.AsErrorsSource;
                    }
                }

                Guid id = Guid.NewGuid();
                _errorPathNames[id] = new KeyValuePair <string[], bool>(paths.ToArray(), isDirect);
                var idNode = new ConstantExpressionNode(id, typeof(Guid));

                //Adding binding source member if the expression does not contain members.
                if (args.Count == 0)
                {
                    args.Add(new MemberExpressionNode(ResourceExpressionNode.DynamicInstance,
                                                      BindingServiceProvider.ResourceResolver.BindingSourceResourceName));
                }
                args.Insert(0, idNode);
                return(new MethodCallExpressionNode(methodCallExpressionNode.Target, methodCallExpressionNode.Method, args, methodCallExpressionNode.TypeArgs));
            }
            return(node);
        }
Beispiel #6
0
 private void Write(ConstantExpressionNode exp)
 {
     if (exp.Value != null)
     {
         if (exp.Value is string)
         {
             _code.Append("'" + exp.Value.ToString() + "'");
         }
         else
         {
             _code.Append(exp.Value.ToString());
         }
     }
 }
        public IExpressionNode Visit(ConstantSyntaxNode node)
        {
            var type = _typesConverter.Convert(_typeInferenceResults.GetSyntaxNodeTypeOrNull(node.OrderNumber));

            //All integer values are encoded by ulong (if it is ulong) or long otherwise
            if (node.Value is long l)
            {
                return(ConstantExpressionNode.CreateConcrete(type, l, node.Interval));
            }
            else if (node.Value is ulong u)
            {
                return(ConstantExpressionNode.CreateConcrete(type, u, node.Interval));
            }
            else //other types have their own clr-types
            {
                return(new ConstantExpressionNode(node.Value, type, node.Interval));
            }
        }
        public IExpressionNode Visit(GenericIntSyntaxNode node)
        {
            var type = _typesConverter.Convert(_typeInferenceResults.GetSyntaxNodeTypeOrNull(node.OrderNumber));

            if (node.Value is long l)
            {
                return(ConstantExpressionNode.CreateConcrete(type, l, node.Interval));
            }
            else if (node.Value is ulong u)
            {
                return(ConstantExpressionNode.CreateConcrete(type, u, node.Interval));
            }
            else if (node.Value is double d)
            {
                return(new ConstantExpressionNode(node.Value, type, node.Interval));
            }
            else
            {
                throw new ImpossibleException($"Generic syntax node has wrong value type: {node.Value.GetType().Name}");
            }
        }
Beispiel #9
0
        public IExpressionNode Visit(IExpressionNode node)
        {
            var member = node as IMemberExpressionNode;
            var resourceExpressionNode = member?.Target as ResourceExpressionNode;

            if (resourceExpressionNode != null)
            {
                //$self, $this --> $BindingServiceProvider.ResourceResolver.SelfResourceName
                if (member.Member == "self" || member.Member == "this")
                {
                    if (resourceExpressionNode.Dynamic)
                    {
                        return(new MemberExpressionNode(member.Target, BindingServiceProvider.ResourceResolver.SelfResourceName));
                    }
                    return(new MethodCallExpressionNode(member.Target, DefaultBindingParserHandler.GetSelfMethod, null, null));
                }
                //$context --> $BindingServiceProvider.ResourceResolver.DataContextResourceName
                if (member.Member == "context")
                {
                    return(new MemberExpressionNode(member.Target, BindingServiceProvider.ResourceResolver.DataContextResourceName));
                }
                //$args, $arg --> $GetEventArgs()
                if (member.Member == "args" || member.Member == "arg")
                {
                    return(new MethodCallExpressionNode(member.Target, DefaultBindingParserHandler.GetEventArgsMethod, null, null));
                }
                //$binding --> $GetBinding()
                if (member.Member == "binding")
                {
                    return(new MethodCallExpressionNode(member.Target, DefaultBindingParserHandler.GetBindingMethod, null, null));
                }
            }

            var methodCallExp = node as IMethodCallExpressionNode;

            if (methodCallExp != null && methodCallExp.Target is ResourceExpressionNode)
            {
                //$OneTime(Expression) --> oneTimeImpl.GetValue(GetBinding(), () => Expression)
                if (methodCallExp.Method == "OneTime" && methodCallExp.Arguments.Count == 1)
                {
                    DataConstant <object> constant = Guid.NewGuid().ToString("n");
                    var             idEx           = new ConstantExpressionNode(constant);
                    var             getBindEx      = new MethodCallExpressionNode(ResourceExpressionNode.DynamicInstance, DefaultBindingParserHandler.GetBindingMethod, null, null);
                    IExpressionNode getValueEx     = new LambdaExpressionNode(methodCallExp.Arguments[0], null);
                    return(new MethodCallExpressionNode(new ConstantExpressionNode(typeof(BindingExtensions)), "GetOrAddValue", new[]
                    {
                        getBindEx, idEx, getValueEx
                    }, null).Accept(this));
                }

                //Alias ($Format(), $MethodName, etc) --> type.Format()
                Type   type;
                string method;
                if (BindingServiceProvider.ResourceResolver.TryGetMethodAlias(methodCallExp.Method, out type, out method))
                {
                    return(new MethodCallExpressionNode(new ConstantExpressionNode(type), method, methodCallExp.Arguments, methodCallExp.TypeArgs).Accept(this));
                }
            }

            var    nodes      = new List <IExpressionNode>();
            var    members    = new List <string>();
            string memberName = node.TryGetMemberName(true, true, nodes, members);

            if (memberName == null)
            {
                var relativeExp = nodes[0] as IRelativeSourceExpressionNode;
                if (relativeExp != null)
                {
                    relativeExp.MergePath(BindingExtensions.MergePath(members));
                    return(relativeExp);
                }

                var methodCall = nodes[0] as IMethodCallExpressionNode;
                if (methodCall != null && methodCall.Target is ResourceExpressionNode)
                {
                    if (RelativeSourceAliases.Contains(methodCall.Method))
                    {
                        if ((methodCall.Arguments.Count == 1 || methodCall.Arguments.Count == 2) &&
                            methodCall.Arguments[0] is IMemberExpressionNode)
                        {
                            int level        = 1;
                            var relativeType = (IMemberExpressionNode)methodCall.Arguments[0];
                            if (methodCall.Arguments.Count == 2)
                            {
                                level = (int)((IConstantExpressionNode)methodCall.Arguments[1]).Value;
                            }
                            return(RelativeSourceExpressionNode.CreateRelativeSource(relativeType.Member, (uint)level,
                                                                                     BindingExtensions.MergePath(members)));
                        }
                    }

                    if (ElementSourceAliases.Contains(methodCall.Method))
                    {
                        if (methodCall.Arguments.Count == 1 && methodCall.Arguments[0] is IMemberExpressionNode)
                        {
                            var elementSource = (IMemberExpressionNode)methodCall.Arguments[0];
                            return(RelativeSourceExpressionNode.CreateElementSource(elementSource.Member,
                                                                                    BindingExtensions.MergePath(members)));
                        }
                    }
                }
            }
            return(node);
        }
Beispiel #10
0
        public IExpressionNode Visit(IExpressionNode node)
        {
            var member = node as IMemberExpressionNode;

            if (member != null && member.Target is ResourceExpressionNode)
            {
                //$self, $this --> $BindingServiceProvider.ResourceResolver.SelfResourceName
                if (member.Member == "self" || member.Member == "this")
                {
                    return(new MemberExpressionNode(member.Target, BindingServiceProvider.ResourceResolver.SelfResourceName));
                }
                //$context --> $BindingServiceProvider.ResourceResolver.DataContextResourceName
                if (member.Member == "context")
                {
                    return(new MemberExpressionNode(member.Target, BindingServiceProvider.ResourceResolver.DataContextResourceName));
                }
                //$args, $arg --> $GetEventArgs()
                if (member.Member == "args" || member.Member == "arg")
                {
                    return(new MethodCallExpressionNode(member.Target, DefaultBindingParserHandler.GetEventArgsMethod, Empty.Array <IExpressionNode>(), Empty.Array <string>()));
                }
            }

            var methodCallExp = node as IMethodCallExpressionNode;

            if (methodCallExp != null && methodCallExp.Target is ResourceExpressionNode)
            {
                //$Format() --> string.Format()
                if (methodCallExp.Method == "Format")
                {
                    return(new MethodCallExpressionNode(new ConstantExpressionNode(typeof(string)), methodCallExp.Method, methodCallExp.Arguments, methodCallExp.TypeArgs));
                }
                //$OneTime(Expression) --> oneTimeImpl.GetValue(() => Expression)
                if (methodCallExp.Method == "OneTime" && methodCallExp.Arguments.Count == 1)
                {
                    var             item      = new ConstantExpressionNode(new OneTimeImpl());
                    IExpressionNode parameter = new LambdaExpressionNode(methodCallExp.Arguments[0], null);
                    return(new MethodCallExpressionNode(item, OneTimeImpl.GetValueMethodName, new[] { parameter }, null));
                }
            }

            var    nodes      = new List <IExpressionNode>();
            var    members    = new List <string>();
            string memberName = node.TryGetMemberName(true, true, nodes, members);

            if (memberName == null)
            {
                var relativeExp = nodes[0] as IRelativeSourceExpressionNode;
                if (relativeExp != null)
                {
                    relativeExp.MergePath(BindingExtensions.MergePath(members));
                    return(relativeExp);
                }

                var methodCall = nodes[0] as IMethodCallExpressionNode;
                if (methodCall != null && methodCall.Target is ResourceExpressionNode)
                {
                    if (RelativeSourceAliases.Contains(methodCall.Method))
                    {
                        if ((methodCall.Arguments.Count == 1 || methodCall.Arguments.Count == 2) &&
                            methodCall.Arguments[0] is IMemberExpressionNode)
                        {
                            int level        = 1;
                            var relativeType = (IMemberExpressionNode)methodCall.Arguments[0];
                            if (methodCall.Arguments.Count == 2)
                            {
                                level = (int)((IConstantExpressionNode)methodCall.Arguments[1]).Value;
                            }
                            return(RelativeSourceExpressionNode.CreateRelativeSource(relativeType.Member, (uint)level,
                                                                                     BindingExtensions.MergePath(members)));
                        }
                    }

                    if (ElementSourceAliases.Contains(methodCall.Method))
                    {
                        if (methodCall.Arguments.Count == 1 && methodCall.Arguments[0] is IMemberExpressionNode)
                        {
                            var elementSource = (IMemberExpressionNode)methodCall.Arguments[0];
                            return(RelativeSourceExpressionNode.CreateElementSource(elementSource.Member,
                                                                                    BindingExtensions.MergePath(members)));
                        }
                    }
                }
            }
            return(node);
        }