private static LinqOpChain BuildSelectManyChain(List <Generator> /*!*/ generators, GroupByClause gbClause, Expression /*!*/ v, LinqOp lastOp) { // PATTERNs (Rules #6, #7): // from x1 in e1 from x2 in e3 ... from xk in ek [select v | group v by g] // // TRANSLATIONs: // ( e1 ) . SelectMany ( x1 => // ( e2 ) . SelectMany ( x2 => // ... // RESPECTIVELY: // ( ek ) . Select ( xk => v ) // ( ek ) . GroupBy ( xk => g, xk => v ) // ... // ) // ) // . [lastOp] int i = generators.Count - 1; LinqOp outer_op; // outer-most operator in the current chain if (gbClause != null) { outer_op = new LinqOp.GroupBy(generators[i].KeyVar, generators[i].ValueVar, gbClause.ByExpr, v); } else { outer_op = new LinqOp.Select(generators[i].KeyVar, generators[i].ValueVar, v); } // inner-most: LinqOpChain inner_chain = new LinqOpChain(generators[i].Expression, outer_op); while (--i >= 0) { inner_chain = new LinqOpChain( generators[i].Expression, outer_op = new LinqOp.SelectMany(generators[i].KeyVar, generators[i].ValueVar, inner_chain) ); } outer_op.Next = lastOp; return(inner_chain); }
internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator) { ILEmitter il = codeGenerator.IL; LinqBuilder builder = new LinqBuilder(codeGenerator); builder.DefineContextType(); builder.EmitNewLinqContext(); codeGenerator.LinqBuilder = builder; LinqOpChain chain = body.BuildChain(); var typecode = chain.Emit(codeGenerator); // the result is IEnumerable<object>, let's wrap it and pass out il.Emit(OpCodes.Call, Methods.ClrObject_WrapRealObject); builder.BakeContextType(); return(PhpTypeCode.Object); }
internal LinqOpChain BuildChain() { // PATTERN (Rule#1): // q1 into x1 (q2 into x2 ( ... (qm into xm q)...)) // // TRANSLATION: // from x1 in ( q1 ), x2 in ( q2 ), ..., xm in ( qm ) // q List <Generator> generators = new List <Generator>(); QueryBody query = this; while (query.into != null) { LinqOpChain subquery_chain = query.BuildSingleQueryChain(new List <Generator>()); generators.Add(new Generator(Position.Invalid, subquery_chain, query.into.KeyVar, query.into.ValueVar)); query = query.into.NextQuery; } return(query.BuildSingleQueryChain(generators)); }
public SelectMany(DirectVarUse keyVar, DirectVarUse valueVar, LinqOpChain innerChain) { this.keyVar = keyVar; this.valueVar = valueVar; this.innerChain = innerChain; }
private void FromWhereToGenerators(List <Generator> /*!*/ generators) { // query is the inner-most query - it will be converted to OpChain // int i = 0; for (; ;) { // convert from clauses to generators if there are any; // (the query can start with where-clause if there was an into-clause): while (i < fromWhere.Count && fromWhere[i].IsFromClause) { FromClause f = (FromClause)fromWhere[i]; // each from-clause contains at least one generator: Debug.Assert(f.Generators.Count > 0); // adds generators contained in the from clause (Rule #2): foreach (Generator generator in f.Generators) { generators.Add(generator); } i++; } // no more clauses: if (i == fromWhere.Count) { break; } // where-clause follows; at least one generator has been added: Debug.Assert(fromWhere[i].IsWhereClause && generators.Count > 0); Generator last_generator = generators[generators.Count - 1]; DirectVarUse x_key = last_generator.KeyVar; DirectVarUse x_value = last_generator.ValueVar; LinqOpChain chain = null; LinqOp last_op = null; // embeds where-clauses imediately preceded by a from-clause to // the last generator of the from-clause (Rule #3): do { LinqOp.Where where_op = new LinqOp.Where(x_key, x_value, ((WhereClause)fromWhere[i]).Expression); if (last_op == null) { chain = new LinqOpChain(last_generator.Expression, where_op); } else { last_op.Next = where_op; } last_op = where_op; i++; }while (i < fromWhere.Count && fromWhere[i].IsWhereClause); Debug.Assert(chain != null); last_generator.Expression = chain; // no more clauses: if (i == fromWhere.Count) { break; } } }
virtual internal void VisitLinqOpChain(Linq.LinqOpChain x) { VisitElement(x.Expression); }
private static LinqOpChain BuildSelectManyChain(List<Generator>/*!*/ generators, GroupByClause gbClause, Expression/*!*/ v, LinqOp lastOp) { // PATTERNs (Rules #6, #7): // from x1 in e1 from x2 in e3 ... from xk in ek [select v | group v by g] // // TRANSLATIONs: // ( e1 ) . SelectMany ( x1 => // ( e2 ) . SelectMany ( x2 => // ... // RESPECTIVELY: // ( ek ) . Select ( xk => v ) // ( ek ) . GroupBy ( xk => g, xk => v ) // ... // ) // ) // . [lastOp] int i = generators.Count - 1; LinqOp outer_op; // outer-most operator in the current chain if (gbClause != null) outer_op = new LinqOp.GroupBy(generators[i].KeyVar, generators[i].ValueVar, gbClause.ByExpr, v); else outer_op = new LinqOp.Select(generators[i].KeyVar, generators[i].ValueVar, v); // inner-most: LinqOpChain inner_chain = new LinqOpChain(generators[i].Expression, outer_op); while (--i >= 0) { inner_chain = new LinqOpChain( generators[i].Expression, outer_op = new LinqOp.SelectMany(generators[i].KeyVar, generators[i].ValueVar, inner_chain) ); } outer_op.Next = lastOp; return inner_chain; }
private void FromWhereToGenerators(List<Generator>/*!*/ generators) { // query is the inner-most query - it will be converted to OpChain // int i = 0; for (; ; ) { // convert from clauses to generators if there are any; // (the query can start with where-clause if there was an into-clause): while (i < fromWhere.Count && fromWhere[i].IsFromClause) { FromClause f = (FromClause)fromWhere[i]; // each from-clause contains at least one generator: Debug.Assert(f.Generators.Count > 0); // adds generators contained in the from clause (Rule #2): foreach (Generator generator in f.Generators) generators.Add(generator); i++; } // no more clauses: if (i == fromWhere.Count) break; // where-clause follows; at least one generator has been added: Debug.Assert(fromWhere[i].IsWhereClause && generators.Count > 0); Generator last_generator = generators[generators.Count - 1]; DirectVarUse x_key = last_generator.KeyVar; DirectVarUse x_value = last_generator.ValueVar; LinqOpChain chain = null; LinqOp last_op = null; // embeds where-clauses imediately preceded by a from-clause to // the last generator of the from-clause (Rule #3): do { LinqOp.Where where_op = new LinqOp.Where(x_key, x_value, ((WhereClause)fromWhere[i]).Expression); if (last_op == null) chain = new LinqOpChain(last_generator.Expression, where_op); else last_op.Next = where_op; last_op = where_op; i++; } while (i < fromWhere.Count && fromWhere[i].IsWhereClause); Debug.Assert(chain != null); last_generator.Expression = chain; // no more clauses: if (i == fromWhere.Count) break; } }