Expression ParseMappedFunction(MappedMemberInfo mappedMember, int errorPos)
            {
                Type type = mappedMember.MappedType;
                string mappedMemberName = mappedMember.MemberName;
                Expression[] args;
                Expression instance = null;

                if (_token.id == TokenId.OpenParen)
                {
                    args = ParseArgumentList();

                    if (mappedMember.MapParams != null)
                    {
                        mappedMember.MapParams(args);
                    }

                    // static methods need to include the target
                    if (!mappedMember.IsStatic)
                    {
                        if (args.Length == 0)
                        {
                            throw ParseError(errorPos, SRResources.NoApplicableMethod, mappedMember.MemberName, mappedMember.MappedType);
                        }

                        instance = args[0];
                        args = args.Skip(1).ToArray();
                    }
                    else
                    {
                        instance = null;
                    }
                }
                else
                {
                    // If it is a function it should begin with a '('
                    throw ParseError(SRResources.OpenParenExpected);
                }

                if (mappedMember.IsMethod)
                {
                    MethodBase mb;

                    switch (FindMethod(type, mappedMemberName, mappedMember.IsStatic, args, out mb))
                    {
                        case 0:
                            throw ParseError(errorPos,
                                Error.Format(SRResources.NoApplicableMethod, mappedMemberName, GetTypeName(type)));
                        case 1:
                            MethodInfo method = (MethodInfo)mb;
                            if (method.ReturnType == typeof(void))
                            {
                                throw ParseError(errorPos,
                                    Error.Format(SRResources.MethodIsVoid, mappedMemberName, GetTypeName(method.DeclaringType)));
                            }

                            return Expression.Call(instance, (MethodInfo)method, args);
                        default:
                            throw ParseError(errorPos,
                                Error.Format(SRResources.AmbiguousMethodInvocation, mappedMemberName, GetTypeName(type)));
                    }
                }
                else
                {
                    // a mapped Property/Field
                    MemberInfo member = FindPropertyOrField(type, mappedMemberName, mappedMember.IsStatic);
                    if (member == null)
                    {
                        if (this._queryResolver != null)
                        {
                            MemberExpression mex = _queryResolver.ResolveMember(type, mappedMemberName, instance);
                            if (mex != null)
                            {
                                return mex;
                            }
                        }
                        throw ParseError(errorPos,
                            Error.Format(SRResources.UnknownPropertyOrField, mappedMemberName, GetTypeName(type)));
                    }

                    return member.MemberType == MemberTypes.Property ?
                        Expression.Property(instance, (PropertyInfo)member) :
                        Expression.Field(instance, (FieldInfo)member);
                }
            }
            static MappedMemberInfo MapStringFunction(string functionName)
            {
                if (functionName == "startswith")
                {
                    return new MappedMemberInfo(typeof(string), "StartsWith", false, true);
                }
                else if (functionName == "endswith")
                {
                    return new MappedMemberInfo(typeof(string), "EndsWith", false, true);
                }
                else if (functionName == "length")
                {
                    return new MappedMemberInfo(typeof(string), "Length", false, false);
                }
                else if (functionName == "toupper")
                {
                    return new MappedMemberInfo(typeof(string), "ToUpper", false, true);
                }
                else if (functionName == "tolower")
                {
                    return new MappedMemberInfo(typeof(string), "ToLower", false, true);
                }
                else if (functionName == "substringof")
                {
                    MappedMemberInfo memberInfo = new MappedMemberInfo(typeof(string), "Contains", false, true);
                    memberInfo.MapParams = (args) =>
                    {
                        // reverse the order of arguments for string.Contains
                        Expression tmp = args[0];
                        args[0] = args[1];
                        args[1] = tmp;
                    };
                    return memberInfo;
                }
                else if (functionName == "indexof")
                {
                    return new MappedMemberInfo(typeof(string), "IndexOf", false, true);
                }
                else if (functionName == "replace")
                {
                    return new MappedMemberInfo(typeof(string), "Replace", false, true);
                }
                else if (functionName == "substring")
                {
                    return new MappedMemberInfo(typeof(string), "Substring", false, true);
                }
                else if (functionName == "trim")
                {
                    return new MappedMemberInfo(typeof(string), "Trim", false, true);
                }
                else if (functionName == "concat")
                {
                    return new MappedMemberInfo(typeof(string), "Concat", true, true);
                }

                return null;
            }
示例#3
0
        private Expression ParseMappedFunction(MappedMemberInfo mappedMember)
        {
            Type mappedType = mappedMember.MappedType;
            string memberName = mappedMember.MemberName;
            int pos = this.token.pos;
            Expression[] expressionArray = null;
            Expression expression = null;
            Expression instance = null;
            this.NextToken();
            if (this.token.id == TokenId.OpenParen)
            {
                expressionArray = this.ParseArgumentList();
                if (mappedMember.MapParams != null)
                {
                    mappedMember.MapParams(expressionArray);
                }
                expression = expressionArray[0];
                instance = expression;
                if (!mappedMember.IsStatic)
                {
                    expressionArray = expressionArray.Skip<Expression>(1).ToArray<Expression>();
                }
                else
                {
                    instance = null;
                }
            }
            if (mappedMember.IsMethod)
            {
                MethodBase base2;
                switch (this.FindMethod(mappedType, memberName, mappedMember.IsStatic, expressionArray, out base2))
                {
                    case 0:
                        throw ParseError(pos, string.Format(CultureInfo.CurrentCulture, SR.NoApplicableMethod, new object[] { memberName, GetTypeName(mappedType) }), new object[0]);

                    case 1:
                        {
                            MethodInfo method = (MethodInfo)base2;
                            if (method.ReturnType == typeof(void))
                            {
                                throw ParseError(pos, string.Format(CultureInfo.CurrentCulture, SR.MethodIsVoid, new object[] { memberName, GetTypeName(method.DeclaringType) }), new object[0]);
                            }
                            return Expression.Call(instance, method, expressionArray);
                        }
                }
                throw ParseError(pos, string.Format(CultureInfo.CurrentCulture, SR.AmbiguousMethodInvocation, new object[] { memberName, GetTypeName(mappedType) }), new object[0]);
            }
            MemberInfo info2 = FindPropertyOrField(mappedType, memberName, mappedMember.IsStatic);
            if (info2 == null)
            {
                if (this.queryResolver != null)
                {
                    MemberExpression expression3 = this.queryResolver.ResolveMember(mappedType, memberName, instance);
                    if (expression3 != null)
                    {
                        return expression3;
                    }
                }
                throw ParseError(pos, string.Format(CultureInfo.CurrentCulture, SR.UnknownPropertyOrField, new object[] { memberName, GetTypeName(mappedType) }), new object[0]);
            }
            if (info2 is PropertyInfo)
            {
                return Expression.Property(instance, (PropertyInfo)info2);
            }
            return Expression.Field(instance, (FieldInfo)info2);
        }