System.Xml.Xsl.IlGen.XmlILVisitor.HandleFilterPatterns C# (CSharp) Метод

HandleFilterPatterns() приватный Метод

There are a number of path patterns that can be rooted at Filter nodes. Determine whether one of these patterns has been previously matched on "ndFilter". If so, generate code for the pattern and return true. Otherwise, just return false.
private HandleFilterPatterns ( QilLoop ndFilter ) : bool
ndFilter System.Xml.Xsl.Qil.QilLoop
Результат bool
        private bool HandleFilterPatterns(QilLoop ndFilter) {
            OptimizerPatterns patt = OptimizerPatterns.Read(ndFilter);
            LocalBuilder locIter;
            XmlNodeKindFlags kinds;
            QilName name;
            QilNode input, step;
            bool isFilterElements;

            // Handle FilterElements and FilterContentKind patterns
            isFilterElements = patt.MatchesPattern(OptimizerPatternName.FilterElements);
            if (isFilterElements || patt.MatchesPattern(OptimizerPatternName.FilterContentKind)) {
                if (isFilterElements) {
                    // FilterElements pattern, so Kind = Element and Name = Argument
                    kinds = XmlNodeKindFlags.Element;
                    name = (QilName) patt.GetArgument(OptimizerPatternArgument.ElementQName);
                }
                else {
                    // FilterKindTest pattern, so Kind = Argument and Name = null
                    kinds = ((XmlQueryType) patt.GetArgument(OptimizerPatternArgument.KindTestType)).NodeKinds;
                    name = null;
                }

                step = (QilNode) patt.GetArgument(OptimizerPatternArgument.StepNode);
                input = (QilNode) patt.GetArgument(OptimizerPatternArgument.StepInput);
                switch (step.NodeType) {
                    case QilNodeType.Content:
                        if (isFilterElements) {
                            // Iterator iter;
                            locIter = this.helper.DeclareLocal("$$$iterElemContent", typeof(ElementContentIterator));

                            // iter.Create(navCtxt, locName, ns);
                            this.helper.Emit(OpCodes.Ldloca, locIter);
                            NestedVisitEnsureStack(input);
                            this.helper.CallGetAtomizedName(this.helper.StaticData.DeclareName(name.LocalName));
                            this.helper.CallGetAtomizedName(this.helper.StaticData.DeclareName(name.NamespaceUri));
                            this.helper.Call(XmlILMethods.ElemContentCreate);

                            GenerateSimpleIterator(typeof(XPathNavigator), locIter, XmlILMethods.ElemContentNext);
                        }
                        else {
                            if (kinds == XmlNodeKindFlags.Content) {
                                CreateSimpleIterator(input, "$$$iterContent", typeof(ContentIterator), XmlILMethods.ContentCreate, XmlILMethods.ContentNext);
                            }
                            else {
                                // Iterator iter;
                                locIter = this.helper.DeclareLocal("$$$iterContent", typeof(NodeKindContentIterator));

                                // iter.Create(navCtxt, nodeType);
                                this.helper.Emit(OpCodes.Ldloca, locIter);
                                NestedVisitEnsureStack(input);
                                this.helper.LoadInteger((int) QilXmlToXPathNodeType(kinds));
                                this.helper.Call(XmlILMethods.KindContentCreate);

                                GenerateSimpleIterator(typeof(XPathNavigator), locIter, XmlILMethods.KindContentNext);
                            }
                        }
                        return true;

                    case QilNodeType.Parent:
                        CreateFilteredIterator(input, "$$$iterPar", typeof(ParentIterator), XmlILMethods.ParentCreate, XmlILMethods.ParentNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    case QilNodeType.Ancestor:
                    case QilNodeType.AncestorOrSelf:
                        CreateFilteredIterator(input, "$$$iterAnc", typeof(AncestorIterator), XmlILMethods.AncCreate, XmlILMethods.AncNext,
                                               kinds, name, (step.NodeType == QilNodeType.Ancestor) ? TriState.False : TriState.True, null);
                        return true;

                    case QilNodeType.Descendant:
                    case QilNodeType.DescendantOrSelf:
                        CreateFilteredIterator(input, "$$$iterDesc", typeof(DescendantIterator), XmlILMethods.DescCreate, XmlILMethods.DescNext,
                                               kinds, name, (step.NodeType == QilNodeType.Descendant) ? TriState.False : TriState.True, null);
                        return true;

                    case QilNodeType.Preceding:
                        CreateFilteredIterator(input, "$$$iterPrec", typeof(PrecedingIterator), XmlILMethods.PrecCreate, XmlILMethods.PrecNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    case QilNodeType.FollowingSibling:
                        CreateFilteredIterator(input, "$$$iterFollSib", typeof(FollowingSiblingIterator), XmlILMethods.FollSibCreate, XmlILMethods.FollSibNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    case QilNodeType.PrecedingSibling:
                        CreateFilteredIterator(input, "$$$iterPreSib", typeof(PrecedingSiblingIterator), XmlILMethods.PreSibCreate, XmlILMethods.PreSibNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    case QilNodeType.NodeRange:
                        CreateFilteredIterator(input, "$$$iterRange", typeof(NodeRangeIterator), XmlILMethods.NodeRangeCreate, XmlILMethods.NodeRangeNext,
                                               kinds, name, TriState.Unknown, ((QilBinary) step).Right);
                        return true;

                    case QilNodeType.XPathFollowing:
                        CreateFilteredIterator(input, "$$$iterFoll", typeof(XPathFollowingIterator), XmlILMethods.XPFollCreate, XmlILMethods.XPFollNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    case QilNodeType.XPathPreceding:
                        CreateFilteredIterator(input, "$$$iterPrec", typeof(XPathPrecedingIterator), XmlILMethods.XPPrecCreate, XmlILMethods.XPPrecNext,
                                               kinds, name, TriState.Unknown, null);
                        return true;

                    default:
                        Debug.Assert(false, "Pattern " + step.NodeType + " should have been handled.");
                        break;
                }
            }
            else if (patt.MatchesPattern(OptimizerPatternName.FilterAttributeKind)) {
                // Handle FilterAttributeKind pattern
                input = (QilNode) patt.GetArgument(OptimizerPatternArgument.StepInput);
                CreateSimpleIterator(input, "$$$iterAttr", typeof(AttributeIterator), XmlILMethods.AttrCreate, XmlILMethods.AttrNext);
                return true;
            }
            else if (patt.MatchesPattern(OptimizerPatternName.EqualityIndex)) {
                // Handle EqualityIndex pattern
                Label lblOnEnd = this.helper.DefineLabel();
                Label lblLookup = this.helper.DefineLabel();
                QilIterator nodes = (QilIterator) patt.GetArgument(OptimizerPatternArgument.IndexedNodes);
                QilNode keys = (QilNode) patt.GetArgument(OptimizerPatternArgument.KeyExpression);

                // XmlILIndex index;
                // if (runtime.FindIndex(navCtxt, indexId, out index)) goto LabelLookup;
                LocalBuilder locIndex = this.helper.DeclareLocal("$$$index", typeof(XmlILIndex));
                this.helper.LoadQueryRuntime();
                this.helper.Emit(OpCodes.Ldarg_1);
                this.helper.LoadInteger(this.indexId);
                this.helper.Emit(OpCodes.Ldloca, locIndex);
                this.helper.Call(XmlILMethods.FindIndex);
                this.helper.Emit(OpCodes.Brtrue, lblLookup);

                // runtime.AddNewIndex(navCtxt, indexId, [build index]);
                this.helper.LoadQueryRuntime();
                this.helper.Emit(OpCodes.Ldarg_1);
                this.helper.LoadInteger(this.indexId);
                this.helper.Emit(OpCodes.Ldloc, locIndex);

                // Generate code to iterate over the the nodes which are being indexed ($iterNodes in the pattern)
                StartNestedIterator(nodes, lblOnEnd);
                StartBinding(nodes);

                // Generate code to iterate over the keys for each node ($bindingKeys in the pattern)
                Visit(keys);

                // index.Add(key, value);
                this.iterCurr.EnsureStackNoCache();
                VisitFor(nodes);
                this.iterCurr.EnsureStackNoCache();
                this.iterCurr.EnsureItemStorageType(nodes.XmlType, typeof(XPathNavigator));
                this.helper.Call(XmlILMethods.IndexAdd);
                this.helper.Emit(OpCodes.Ldloc, locIndex);

                // LabelOnEnd:
                this.iterCurr.LoopToEnd(lblOnEnd);
                EndBinding(nodes);
                EndNestedIterator(nodes);

                // runtime.AddNewIndex(navCtxt, indexId, [build index]);
                this.helper.Call(XmlILMethods.AddNewIndex);

                // LabelLookup:
                // results = index.Lookup(keyValue);
                this.helper.MarkLabel(lblLookup);
                this.helper.Emit(OpCodes.Ldloc, locIndex);
                this.helper.Emit(OpCodes.Ldarg_2);
                this.helper.Call(XmlILMethods.IndexLookup);
                this.iterCurr.Storage = StorageDescriptor.Stack(typeof(XPathNavigator), true);

                this.indexId++;

                return true;
            }

            return false;
        }
XmlILVisitor