protected IExpressionNode ParseLambda() { if (Tokenizer.Token == TokenType.EmptyParen) { ValidateToken(NextToken(true), TokenType.Lambda); NextToken(true); var item = new LambdaExpressionNode(ParseExpression(), null); return item; } if (Tokenizer.Token == TokenType.OpenParen) { NextToken(true); IExpressionNode node = ParseExpression(); var memberExp = node as IMemberExpressionNode; if (memberExp != null && memberExp.Target == null) { var nodes = new List<IExpressionNode> { memberExp }; if (Tokenizer.Token == TokenType.Comma) { NextToken(true); nodes.AddRange(ParseArguments()); ValidateToken(TokenType.CloseParen); } if (Tokenizer.Token == TokenType.CloseParen) { NextToken(true); if (nodes.Count > 1) ValidateToken(TokenType.Lambda); if (Tokenizer.Token == TokenType.Lambda) { NextToken(true); for (int index = 0; index < nodes.Count; index++) ValidateLambdaParameter(nodes[index]); return new LambdaExpressionNode(ParseExpression(), nodes.Cast<IMemberExpressionNode>().Select(expressionNode => expressionNode.Member)); } return ParseBinaryExpression(node); } } ValidateToken(TokenType.CloseParen); NextToken(true); return ParseBinaryExpression(node); } if (Tokenizer.Token == TokenType.Identifier) { IExpressionNode node = ParseExpression(); var memberExp = node as IMemberExpressionNode; if (memberExp != null && memberExp.Target == null && Tokenizer.Token == TokenType.Lambda) { NextToken(true); return new LambdaExpressionNode(ParseExpression(), new[] { memberExp.Member }); } return node; } return ParseExpression(); }
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; }