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; }