//public static Type ParseType(this IParser parser, IEnumerable<string> namespaces, bool throwException) //{ // var tmpToken = parser.Token(); // string typeName = parser.Token().GetIdentifier(); // parser.NextToken(); // string methodName = null; // if (parser.Token().Identity == TokenId.Dot) // { // parser.NextToken(); // methodName = parser.Token().Text; // parser.NextToken(); // } // while (parser.Token().Identity == TokenId.Dot) // { // parser.NextToken(); // typeName = typeName + "." + methodName; // methodName = parser.Token().GetIdentifier(); // parser.NextToken(); // } // if(parser.Token().Identity != TokenId.OpenParen) // { // typeName = typeName + "." + methodName; // methodName = null; // } // if (namespaces == null) // namespaces = new string[0]; // var objectType = new TypeFinder(namespaces).FindType(typeName); // if (objectType != null) // return objectType; // if (throwException) // throw Error.CannotResolveNameToType(tmpToken, typeName); // parser.TokenCursor.MoveTo(tmpToken.Position); // return null; //} #endregion private static Expression ParseMethodAccess(this IParser parser, Type type, Expression instance, string methodName) { Expression[] args = null; Func <Expression[]> getArgs = delegate() { args = parser.ParseArgumentList(); return(args); }; var errorPos = parser.Token().Position; MethodBase mb; var methodsCount = ExpressionUtility.FindMethod(type, methodName, instance == null, getArgs, out mb); switch (methodsCount) { case 0: return(null); //throw Error.ParseError(errorPos, Res.NoApplicableMethod, methodName, TypeUtility.GetTypeName(type)); case 1: MethodInfo method = (MethodInfo)mb; if (method.ReturnType == typeof(void)) { throw Error.ParseError(errorPos, Res.MethodIsVoid, methodName, TypeUtility.GetTypeName(method.DeclaringType)); } Debug.Assert(args != null); return(Expression.Call(instance, (MethodInfo)method, args)); default: throw Error.ParseError(errorPos, Res.AmbiguousMethodInvocation, methodName, TypeUtility.GetTypeName(type)); } }
IQueryable IQueryProvider.CreateQuery(Expression expression) { var elementType = ExpressionUtility.ElementType(expression); var queryable = CreateQuery(expression, elementType); return(queryable); }
public static Expression ParseConstructor(this IParser parser, IEnumerable <string> namespaces) { var tmpToken = parser.Token(); var className = parser.Token().Text; parser.NextToken(); while (parser.Token().Identity == TokenId.Dot) { parser.NextToken(); className = className + "." + parser.Token().Text; parser.NextToken(); } var objectType = new TypeFinder().FindType(className, namespaces); if (objectType != null) { if (parser.Token().Identity != TokenId.OpenParen && parser.Token().Identity != TokenId.OpenCurlyBrace) { throw Error.Token1OrToken2Expected(parser.Token(), "(", "{"); } Expression[] args = new Expression[0]; //if (objectType != null) //{ if (parser.Token().Identity == TokenId.OpenParen) { args = parser.ParseArgumentList(); } var cons = ExpressionUtility.FindConstructor(objectType, args); if (cons == null) { throw Error.CanNotFindConstructor(parser.Token(), objectType, args.Select(o => o.Type).ToArray()); } var newExpr = Expression.New(cons, args); if (parser.Token().Identity == TokenId.OpenCurlyBrace) { var expr = parser.ParseMemberInit(newExpr); return(expr); } return(newExpr); } parser.TokenCursor.MoveTo(tmpToken.Position); return(null); }
protected override Expression VisitMethodCall(MethodCallExpression m) { var anonymousType = typeof(DataRow); if (m.Method.Name == "Cast") { var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]); var castTargetType = ExpressionUtility.ElementType(m); if (castTargetType.IsAssignableFrom(anonymousType)) { this.typePaires.Add(castSourceType, castTargetType); } } return(base.VisitMethodCall(m)); }
public static int FindIndexer(Type type, Expression[] args, out MethodBase method) { foreach (Type t in SelfAndBaseTypes(type)) { MemberInfo[] members = t.GetMembers();//t.GetDefaultMembers(); if (members.Length != 0) { IEnumerable <MethodBase> methods = members. OfType <PropertyInfo>(). Select(p => (MethodBase)p.GetGetMethod()). Where(m => m != null); int count = ExpressionUtility.FindBestMethod(methods, args, out method); if (count != 0) { return(count); } } } method = null; return(0); }
TResult IQueryProvider.Execute <TResult>(Expression expression) { expression = UpdateExpression(expression); var isSingleValue = !typeof(IEnumerable).IsAssignableFrom(expression.Type) || expression.Type == typeof(string); if (isSingleValue) { var obj = this.source.Execute <TResult>(expression); return(obj); } var castSourceType = ExpressionUtility.ElementType(expression); var castTargetType = GetElementType(typeof(TResult)); if (castSourceType != castTargetType) { expression = Expression.Call(typeof(Queryable), "Cast", new[] { castTargetType }, expression); } var items = this.source.Execute <TResult>(expression); return(items); }
static DataContext GetDataContext(IQueryable source) { var dc = ExpressionUtility.FindContext(source.Expression); return(dc); }
public Parser(IQueryable source, string predicate, params object[] parameters) : base(GetDataContext(source), predicate, ConvertToObjectParameters(parameters)) { p = ExpressionUtility.CreateParameter(source.ElementType); this.source = source; }
protected override Expression VisitMethodCall(MethodCallExpression m) { //============================================================== // 说明:将索引器字段转换为类的属性或字段 if (m.Method.Name == "get_Item" && m.Object != null && m.Object.Type == this.oldType) { Debug.Assert(m.Arguments.Count == 1); var arg = m.Arguments[0]; Debug.Assert(arg.NodeType == ExpressionType.Constant); Debug.Assert(arg.Type == typeof(string)); var name = (string)((ConstantExpression)arg).Value; var pf = TypeUtility.FindPropertyOrField(this.newType, name, false); if (pf == null) { throw Error.NoPublicPropertyOrField(name, newType); } Expression expr = Expression.MakeMemberAccess(this.parameter, pf); if (m.Type != expr.Type) { expr = Expression.Convert(expr, m.Type); } return(expr); } //============================================================== //============================================================== // 说明:如果序列的实际类型与 Cast 的目标类型一致,则直接返回序列,而不进行转换。 // 例如: // var q = db.CreateQuery("select p from Products as p").Cast<Product>(); // 由于序列的实际类型即是Product,因为,Cast 是多余的,直接除。即变为: // db.CreateQuery("select p from Products as p") //-------------------------------------------------------------- if (m.Method.Name == "Cast") { var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]); var castTargetType = ExpressionUtility.ElementType(m); if (this.newType == castSourceType && this.oldType == castTargetType) { return(m.Arguments[0]); } } //============================================================== Expression instance = Visit(m.Object); IEnumerable <Expression> arguments = VisitExpressionList(m.Arguments); if ((instance == m.Object) && (arguments == m.Arguments)) { return(m); } //============================================================== // 说明:替换掉原来的类型 // 例如: // var q = db.CreateQuery<IDataRecord>("select p from Products as p") // 变为 // q = db.CreateQuery<Product>() if (m.Method.IsGenericMethod) { var argTypes = m.Method.GetGenericArguments(); if (argTypes[0] == oldType) { var methodName = m.Method.Name; var declareType = m.Method.DeclaringType; argTypes[0] = newType; var expr = Expression.Call(declareType, methodName, argTypes, arguments.ToArray()); return(expr); } } //============================================================== return(Expression.Call(instance, m.Method, arguments)); }
public ActualTypeReplacer(Type oldType, Type newType) { this.newType = newType; this.oldType = oldType; this.parameter = ExpressionUtility.CreateParameter(newType); }