示例#1
0
        //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));
            }
        }
示例#2
0
        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            var elementType = ExpressionUtility.ElementType(expression);
            var queryable   = CreateQuery(expression, elementType);

            return(queryable);
        }
示例#3
0
        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);
        }
示例#4
0
            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));
            }
示例#5
0
 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);
 }
示例#6
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);
        }
示例#7
0
            static DataContext GetDataContext(IQueryable source)
            {
                var dc = ExpressionUtility.FindContext(source.Expression);

                return(dc);
            }
示例#8
0
 public Parser(IQueryable source, string predicate, params object[] parameters)
     : base(GetDataContext(source), predicate, ConvertToObjectParameters(parameters))
 {
     p           = ExpressionUtility.CreateParameter(source.ElementType);
     this.source = source;
 }
示例#9
0
            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));
            }
示例#10
0
 public ActualTypeReplacer(Type oldType, Type newType)
 {
     this.newType   = newType;
     this.oldType   = oldType;
     this.parameter = ExpressionUtility.CreateParameter(newType);
 }