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