System.Xml.Xsl.IlGen.XmlILVisitor.VisitSort C# (CSharp) Method

VisitSort() protected method

Generate code for QilNodeType.Sort.
protected VisitSort ( QilLoop ndSort ) : QilNode
ndSort QilLoop
return QilNode
        protected override QilNode VisitSort(QilLoop ndSort) {
            Type itemStorageType = GetItemStorageType(ndSort);
            LocalBuilder locCache, locKeys;
            Label lblOnEndSort = this.helper.DefineLabel();
            Debug.Assert(ndSort.Variable.NodeType == QilNodeType.For);

            // XmlQuerySequence<T> cache;
            // cache = XmlQuerySequence.CreateOrReuse(cache);
            XmlILStorageMethods methods = XmlILMethods.StorageMethods[itemStorageType];
            locCache = this.helper.DeclareLocal("$$$cache", methods.SeqType);
            this.helper.Emit(OpCodes.Ldloc, locCache);
            this.helper.CallToken(methods.SeqReuse);
            this.helper.Emit(OpCodes.Stloc, locCache);
            this.helper.Emit(OpCodes.Ldloc, locCache);
  
            // XmlSortKeyAccumulator keys;
            // keys.Create(runtime);
            locKeys = this.helper.DeclareLocal("$$$keys", typeof(XmlSortKeyAccumulator));
            this.helper.Emit(OpCodes.Ldloca, locKeys);
            this.helper.Call(XmlILMethods.SortKeyCreate);

            // Construct nested iterator
            // foreach (item in sort-expr) {
            StartNestedIterator(ndSort.Variable, lblOnEndSort);
            StartBinding(ndSort.Variable);
            Debug.Assert(!this.iterNested.Storage.IsCached);

            // cache.Add(item);
            this.iterCurr.EnsureStackNoCache();
            this.iterCurr.EnsureItemStorageType(ndSort.Variable.XmlType, GetItemStorageType(ndSort.Variable));
            this.helper.Call(methods.SeqAdd);

            this.helper.Emit(OpCodes.Ldloca, locKeys);

            // Add keys to accumulator (there may be several keys)
            foreach (QilSortKey ndKey in ndSort.Body)
                VisitSortKey(ndKey, locKeys);

            // keys.FinishSortKeys();
            this.helper.Call(XmlILMethods.SortKeyFinish);

            // }
            this.helper.Emit(OpCodes.Ldloc, locCache);
            this.iterCurr.LoopToEnd(lblOnEndSort);

            // Remove cache reference from stack
            this.helper.Emit(OpCodes.Pop);

            // cache.SortByKeys(keys.Keys);
            this.helper.Emit(OpCodes.Ldloc, locCache);
            this.helper.Emit(OpCodes.Ldloca, locKeys);
            this.helper.Call(XmlILMethods.SortKeyKeys);
            this.helper.Call(methods.SeqSortByKeys);

            // End nested iterator
            this.iterCurr.Storage = StorageDescriptor.Local(locCache, itemStorageType, true);
            EndBinding(ndSort.Variable);
            EndNestedIterator(ndSort.Variable);
            this.iterCurr.SetIterator(this.iterNested);

            return ndSort;
        }
XmlILVisitor