private QilNode CreateAggregator(QilUnary ndAgg, string aggName, XmlILStorageMethods methods, MethodInfo methAgg, MethodInfo methResult) {
Label lblOnEnd = this.helper.DefineLabel();
Type typAgg = methAgg.DeclaringType;
LocalBuilder locAgg;
// Aggregate agg;
// agg.Create();
locAgg = this.helper.DeclareLocal(aggName, typAgg);
this.helper.Emit(OpCodes.Ldloca, locAgg);
this.helper.Call(methods.AggCreate);
// foreach (num in expr) {
StartNestedIterator(ndAgg.Child, lblOnEnd);
this.helper.Emit(OpCodes.Ldloca, locAgg);
Visit(ndAgg.Child);
// agg.Aggregate(num);
this.iterCurr.EnsureStackNoCache();
this.iterCurr.EnsureItemStorageType(ndAgg.XmlType, GetItemStorageType(ndAgg));
this.helper.Call(methAgg);
this.helper.Emit(OpCodes.Ldloca, locAgg);
// }
this.iterCurr.LoopToEnd(lblOnEnd);
// End nested iterator
EndNestedIterator(ndAgg.Child);
// If aggregate might be empty sequence, then generate code to handle this possibility
if (ndAgg.XmlType.MaybeEmpty) {
// if (agg.IsEmpty) goto LabelNextCtxt;
this.helper.Call(methods.AggIsEmpty);
this.helper.Emit(OpCodes.Brtrue, this.iterCurr.GetLabelNext());
this.helper.Emit(OpCodes.Ldloca, locAgg);
}
// result = agg.Result;
this.helper.Call(methResult);
this.iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndAgg), false);
return ndAgg;
}