示例#1
0
		static void Set(ConcurrentDictionary<Type,ConcurrentDictionary<Type,LambdaInfo>> expressions, Type from, Type to, LambdaInfo expr)
		{
			ConcurrentDictionary<Type,LambdaInfo> dic;

			if (!expressions.TryGetValue(from, out dic))
				expressions[from] = dic = new ConcurrentDictionary<Type, LambdaInfo>();

			dic[to] = expr;
		}
示例#2
0
		public LambdaInfo Create(MappingSchema mappingSchema, Type from, Type to)
		{
			var ex  = ConvertBuilder.GetConverter(mappingSchema, from, to);
			var lm  = ex.Item1.Compile();
			var ret = new LambdaInfo(ex.Item1, ex.Item2, lm, ex.Item3);

			Set(_expressions, from, to , ret);

			return ret;
		}
		SqlQuery.Condition ParseAnyCondition(SetType setType, Expression expr, LambdaInfo lambda, Expression inExpr)
		{
			throw new NotImplementedException();

			/*
			var sql = CurrentSql;
			var cs  = _convertSource;

			CurrentSql = new SqlQuery();

			var associationList = new Dictionary<QuerySource,QuerySource>();

			_convertSource = (s,l) =>
			{
				var t = s as QuerySource.Table;

				if (t != null && t.ParentAssociation != null)
				{
					if (ParentQueries.Count > 0)
					{
						foreach (var parentQuery in ParentQueries)
						{
							var parent = parentQuery.Parent;

							while (parent is QuerySource.SubQuerySourceColumn)
								parent = ((QuerySource.SubQuerySourceColumn)parent).SourceColumn;

							if (parent.Find(t.ParentAssociation))
							{
								var orig = t;
								t = CreateTable(new SqlQuery(), l);

								associationList.Add(t, orig);

								var csql = CurrentSql.From.Tables.Count == 0 ? t.SqlQuery : CurrentSql;

								foreach (var c in orig.ParentAssociationJoin.Condition.Conditions)
								{
									var predicate = (SqlQuery.Predicate.ExprExpr)c.Predicate;
									csql.Where
										.Expr(predicate.Expr1)
										.Equal
										.Field(t.Columns[((SqlField)predicate.Expr2).Name].Field);
								}

								s = t;

								break;
							}
						}
					}
				}
				else
					s = cs(s, l);

				return s;
			};

			var query = ParseSequence(expr)[0];
			var any   = CurrentSql;

			_convertSource = cs;

			if (lambda != null)
			{
				if (setType == SetType.All)
				{
					var e  = Expression.Not(lambda.Body);
					//var pi = new NotParseInfo(e, lambda.Body);

					lambda = new LambdaInfo(e, lambda.Parameters);
				}

				if (inExpr == null || query.Fields.Count != 1)
					ParseWhere(lambda, query);
			}

			any.ParentSql = sql;
			CurrentSql    = sql;

			SqlQuery.Condition cond;

			if (inExpr != null && query.Fields.Count == 1)
			{
				query.Select(this);
				var ex = ParseExpression(inExpr);
				cond = new SqlQuery.Condition(false, new SqlQuery.Predicate.InSubQuery(ex, false, any));
			}
			else
				cond = new SqlQuery.Condition(setType == SetType.All, new SqlQuery.Predicate.FuncLike(SqlFunction.CreateExists(any)));

			ParsingTracer.DecIndentLevel();
			return cond;

			*/
		}
示例#4
0
            /// <summary>
            /// Visit lambda expression for scope tracking and closure emitting purposes.
            /// </summary>
            /// <typeparam name="T">The type of the delegate represented by the lambda expression.</typeparam>
            /// <param name="node">The lambda expression to rewrite.</param>
            /// <returns>The rewritten lambda expression.</returns>
            protected override Expression VisitLambda <T>(Expression <T> node)
            {
                //
                // Allocate a slot for information about the rewritten lambda expression and thunk
                // type. We add a temporary empty value to the dictionary slot here in order to
                // boost the count of entries. This causes the index to be logically numbered in
                // the order the lambda expressions were visited.
                //
                var index = _lambdas.Count;

                _lambdas[index] = default;

                //
                // Introduce a new scope and keep track of the original scope in order to restore
                // it after visiting child expressions.
                //
                var currentScope = _scope;

                try
                {
                    var scope = _analysis[node];
                    _scope = new CompilerScope(currentScope, scope);

                    var body = default(Expression);

                    if (!scope.HasHoistedLocals && !scope.NeedsClosure)
                    {
                        body = Visit(node.Body);
                    }
                    else
                    {
                        //
                        // Visit the body and append it to the builder. Note that hoisted locals
                        // (i.e. parameters) are copied into the closure.
                        //
                        var builder = _scope.Enter(count: 1, copyLocals: true);
                        builder.Append(Visit(node.Body));
                        body = builder.Finish(declareLocals: false);
                    }

                    //
                    // Use the closure parameter of the original scope (i.e. the parent to the
                    // scope representing the lambda) to derive information about the thunk type.
                    //
                    var closureParam      = currentScope.Closure;
                    var thunkType         = _thunkFactory.GetThunkType(typeof(T), closureParam.Type);
                    var innerDelegateType = GetInnerDelegateType(thunkType);

                    //
                    // Construct a lambda that's parameterized on the closure that's passed in,
                    // using the inner delegate type that the thunk expects. This becomes the
                    // rewritten lambda expression, which will be passed to the constructor of
                    // the thunk type in GetMethodTable.
                    //
                    var parameters = new ParameterExpression[node.Parameters.Count + 1];
                    parameters[0] = closureParam;
                    node.Parameters.CopyTo(parameters, index: 1);

                    var lambda = Expression.Lambda(innerDelegateType, body, parameters);
                    _lambdas[index] = new LambdaInfo(lambda, thunkType);

                    //
                    // Inside the expression tree, replace the lambda by a call to CreateDelegate
                    // on the thunk. The thunk is retrieved from the method table that's passed to
                    // the top-level lambda by indexing into the Thunks array.
                    //
                    var createDelegate = thunkType.GetMethod(nameof(ActionThunk <object> .CreateDelegate));
                    var methodTable    = currentScope.Bind(_methodTable);

                    var createDelegateCall =
                        Expression.Call(
                            Expression.Convert(
                                Expression.ArrayIndex(
                                    Expression.Field(
                                        methodTable,
                                        nameof(MethodTable.Thunks)
                                        ),
                                    Expression.Constant(index)
                                    ),
                                thunkType
                                ),
                            createDelegate,
                            closureParam
                            );

                    return(createDelegateCall);
                }
                finally
                {
                    _scope = currentScope;
                }
            }
示例#5
0
        static void Set(ConcurrentDictionary <Type, ConcurrentDictionary <Type, LambdaInfo> > expressions, Type from, Type to, LambdaInfo expr)
        {
            ConcurrentDictionary <Type, LambdaInfo> dic;

            if (!expressions.TryGetValue(from, out dic))
            {
                expressions[from] = dic = new ConcurrentDictionary <Type, LambdaInfo>();
            }

            dic[to] = expr;
        }
示例#6
0
 public void Set(Type from, Type to, LambdaInfo expr)
 {
     Set(_expressions, from, to, expr);
 }
示例#7
0
        static Expression ConverLetSubqueries(Expression expression)
        {
            var result = expression;

            do
            {
                expression = result;

                // Find let subqueries.
                //
                var dic = new Dictionary <MemberInfo, Expression>();

                expression.Visit(ex =>
                {
                    switch (ex.NodeType)
                    {
                    case ExpressionType.Call:
                        {
                            var me = (MethodCallExpression)ex;

                            LambdaInfo lambda = null;

                            if (me.Method.Name == "Select" &&
                                (me.IsQueryableMethod((_, l) => { lambda = l; return(true); }) ||
                                 me.IsQueryableMethod(null, 2, _ => { }, l => lambda = l)))
                            {
                                lambda.Body.Visit(e =>
                                {
                                    switch (e.NodeType)
                                    {
                                    case ExpressionType.New:
                                        {
                                            var ne = (NewExpression)e;

                                            if (ne.Members == null || ne.Arguments.Count != ne.Members.Count)
                                            {
                                                break;
                                            }

                                            var args = ne.Arguments.Zip(ne.Members, (a, m) => new { a, m }).ToList();

                                            var q =
                                                from a in args
                                                where
                                                a.a.NodeType == ExpressionType.Call &&
                                                a.a.Type != typeof(string) &&
                                                !a.a.Type.IsArray &&
                                                TypeHelper.GetGenericType(typeof(IEnumerable <>), a.a.Type) != null
                                                select a;

                                            foreach (var item in q)
                                            {
                                                dic.Add(item.m, item.a);
                                            }
                                        }

                                        break;
                                    }
                                });
                            }
                        }

                        break;
                    }
                });

                if (dic.Count == 0)
                {
                    return(expression);
                }

                result = expression.Convert(ex =>
                {
                    switch (ex.NodeType)
                    {
                    case ExpressionType.MemberAccess:
                        {
                            var me     = (MemberExpression)ex;
                            var member = me.Member;

                            if (member is PropertyInfo)
                            {
                                member = ((PropertyInfo)member).GetGetMethod();
                            }

                            Expression arg;

                            if (dic.TryGetValue(member, out arg))
                            {
                                return(arg);
                            }
                        }

                        break;
                    }

                    return(ex);
                });
            } while (result != expression);

            return(expression);
        }
示例#8
0
		public void Set(Type from, Type to, LambdaInfo expr)
		{
			Set(_expressions, from, to, expr);
		}