public override PhpTypeCode Emit(LinqBuilder codeGenerator) { ILEmitter il = codeGenerator.IL; // NEW Func[object,object](<linq context>, <&lambda>); codeGenerator.EmitLoadLinqContext(); il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Selector_{0}>", codeGenerator.GetNextSelectorNum()), valueVar, byExpr, PhpTypeCode.Object)); il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor); DirectVarUse groupByVar = groupExpr as DirectVarUse; if ((groupByVar != null) && (groupByVar.VarName == valueVar.VarName)) { // LOAD Select[object,object](<source>, <delegate>); // Simplified version - no element selector il.Emit(OpCodes.Call, LinqExterns.GroupBy); } else { // with element selector codeGenerator.EmitLoadLinqContext(); il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Selector_{0}>", codeGenerator.GetNextSelectorNum()), valueVar, groupExpr, PhpTypeCode.Object)); il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor); il.Emit(OpCodes.Call, LinqExterns.GroupByElementSel); } // Conversion from IEnumerable<IGrouping<..>> to IEnumerable<object> il.Emit(OpCodes.Call, Methods.ClrObject_WrapRealObject); codeGenerator.CodeGenerator.EmitLoadClassContext(); il.Emit(OpCodes.Call, Methods.Convert.ObjectToLinqSource); return(base.Emit(codeGenerator)); }
/// <summary> /// Emit lambda function that implements projection and call to /// IEnumerable.Select function (with current LINQ context as /// first and generated lambda as a second parameter) /// </summary> public override PhpTypeCode Emit(LinqBuilder /*!*/ builder) { ILEmitter il = builder.IL; // source expected on stack // NEW Func[object,object](<linq context>, <&lambda>); builder.EmitLoadLinqContext(); il.Emit(OpCodes.Ldftn, builder.EmitLambda(string.Format("<Selector_{0}>", builder.GetNextSelectorNum()), valueVar, selector, PhpTypeCode.Object)); il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor); // LOAD Select[object,object](<source>, <delegate>); il.Emit(OpCodes.Call, LinqExterns.Select); //il.Emit(OpCodes.Call, Methods.Operators.Select); return(base.Emit(builder)); }