Exemplo n.º 1
0
 protected virtual IExpressionNode ParseConstantExpression()
 {
     object value = null;
     if (Tokenizer.Token == TokenType.IntegerLiteral)
         value = ParseIntegerLiteral();
     else if (Tokenizer.Token == TokenType.RealLiteral)
         value = ParseRealLiteral();
     else if (Tokenizer.Token == TokenType.StringLiteral)
         value = ParseStringLiteral();
     else if (Tokenizer.Value.Equals(TrueLiteral, StringComparison.OrdinalIgnoreCase))
     {
         value = Empty.TrueObject;
         NextToken(true);
     }
     else if (Tokenizer.Value.Equals(FalseLiteral, StringComparison.OrdinalIgnoreCase))
     {
         value = Empty.FalseObject;
         NextToken(true);
     }
     else
         NextToken(true);
     var expr = new ConstantExpressionNode(value);
     return expr;
 }
        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 resourceObject = BindingServiceProvider
                        .ResourceResolver
                        .ResolveObject(firstMember, Context, true);
                    var dynamicObject = resourceObject.Value as IDynamicObject;
                    if (dynamicObject == null || path.Parts.Count <= 1)
                        staticValue = new ConstantExpressionNode(resourceObject.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 = 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;
        }
        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, 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;
        }