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

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

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

            // Handle JoinAndDod and DodReverse patterns
            isJoinAndDod = pattDod.MatchesPattern(OptimizerPatternName.JoinAndDod);
            if (isJoinAndDod || pattDod.MatchesPattern(OptimizerPatternName.DodReverse)) {
                OptimizerPatterns pattStep = OptimizerPatterns.Read((QilNode) pattDod.GetArgument(OptimizerPatternArgument.DodStep));

                if (pattStep.MatchesPattern(OptimizerPatternName.FilterElements)) {
                    // FilterElements pattern, so Kind = Element and Name = Argument
                    kinds = XmlNodeKindFlags.Element;
                    name = (QilName) pattStep.GetArgument(OptimizerPatternArgument.ElementQName);
                }
                else if (pattStep.MatchesPattern(OptimizerPatternName.FilterContentKind)) {
                    // FilterKindTest pattern, so Kind = Argument and Name = null
                    kinds = ((XmlQueryType) pattStep.GetArgument(OptimizerPatternArgument.KindTestType)).NodeKinds;
                    name = null;
                }
                else {
                    Debug.Assert(pattStep.MatchesPattern(OptimizerPatternName.Axis), "Dod patterns should only match if step is FilterElements or FilterKindTest or Axis");
                    kinds = ((ndDod.XmlType.NodeKinds & XmlNodeKindFlags.Attribute) != 0) ? XmlNodeKindFlags.Any : XmlNodeKindFlags.Content;
                    name = null;
                }

                step = (QilNode) pattStep.GetArgument(OptimizerPatternArgument.StepNode);
                if (isJoinAndDod) {
                    switch (step.NodeType) {
                        case QilNodeType.Content:
                            CreateContainerIterator(ndDod, "$$$iterContent", typeof(ContentMergeIterator), XmlILMethods.ContentMergeCreate, XmlILMethods.ContentMergeNext,
                                                    kinds, name, TriState.Unknown);
                            return true;

                        case QilNodeType.Descendant:
                        case QilNodeType.DescendantOrSelf:
                            CreateContainerIterator(ndDod, "$$$iterDesc", typeof(DescendantMergeIterator), XmlILMethods.DescMergeCreate, XmlILMethods.DescMergeNext,
                                                    kinds, name, (step.NodeType == QilNodeType.Descendant) ? TriState.False : TriState.True);
                            return true;

                        case QilNodeType.XPathFollowing:
                            CreateContainerIterator(ndDod, "$$$iterFoll", typeof(XPathFollowingMergeIterator), XmlILMethods.XPFollMergeCreate, XmlILMethods.XPFollMergeNext,
                                                    kinds, name, TriState.Unknown);
                            return true;

                        case QilNodeType.FollowingSibling:
                            CreateContainerIterator(ndDod, "$$$iterFollSib", typeof(FollowingSiblingMergeIterator), XmlILMethods.FollSibMergeCreate, XmlILMethods.FollSibMergeNext,
                                                    kinds, name, TriState.Unknown);
                            return true;

                        case QilNodeType.XPathPreceding:
                            CreateContainerIterator(ndDod, "$$$iterPrec", typeof(XPathPrecedingMergeIterator), XmlILMethods.XPPrecMergeCreate, XmlILMethods.XPPrecMergeNext,
                                                    kinds, name, TriState.Unknown);
                            return true;

                        default:
                            Debug.Assert(false, "Pattern " + step.NodeType + " should have been handled.");
                            break;
                    }
                }
                else {
                    input = (QilNode) pattStep.GetArgument(OptimizerPatternArgument.StepInput);
                    switch (step.NodeType) {
                        case QilNodeType.Ancestor:
                        case QilNodeType.AncestorOrSelf:
                            CreateFilteredIterator(input, "$$$iterAnc", typeof(AncestorDocOrderIterator), XmlILMethods.AncDOCreate, XmlILMethods.AncDONext,
                                                   kinds, name, (step.NodeType == QilNodeType.Ancestor) ? TriState.False : TriState.True, null);
                            return true;

                        case QilNodeType.PrecedingSibling:
                            CreateFilteredIterator(input, "$$$iterPreSib", typeof(PrecedingSiblingDocOrderIterator), XmlILMethods.PreSibDOCreate, XmlILMethods.PreSibDONext,
                                                   kinds, name, TriState.Unknown, null);
                            return true;

                        case QilNodeType.XPathPreceding:
                            CreateFilteredIterator(input, "$$$iterPrec", typeof(XPathPrecedingDocOrderIterator), XmlILMethods.XPPrecDOCreate, XmlILMethods.XPPrecDONext,
                                                   kinds, name, TriState.Unknown, null);
                            return true;

                        default:
                            Debug.Assert(false, "Pattern " + step.NodeType + " should have been handled.");
                            break;
                    }
                }
            }
            else if (pattDod.MatchesPattern(OptimizerPatternName.DodMerge)) {
                // DodSequenceMerge dodMerge;
                LocalBuilder locMerge = this.helper.DeclareLocal("$$$dodMerge", typeof(DodSequenceMerge));
                Label lblOnEnd = this.helper.DefineLabel();

                // dodMerge.Create(runtime);
                this.helper.Emit(OpCodes.Ldloca, locMerge);
                this.helper.LoadQueryRuntime();
                this.helper.Call(XmlILMethods.DodMergeCreate);
                this.helper.Emit(OpCodes.Ldloca, locMerge);

                StartNestedIterator(ndDod.Child, lblOnEnd);

                // foreach (seq in expr) {
                Visit(ndDod.Child);

                // dodMerge.AddSequence(seq);
                Debug.Assert(this.iterCurr.Storage.IsCached, "DodMerge pattern should only be matched when cached sequences are returned from loop");
                this.iterCurr.EnsureStack();
                this.helper.Call(XmlILMethods.DodMergeAdd);
                this.helper.Emit(OpCodes.Ldloca, locMerge);

                // }
                this.iterCurr.LoopToEnd(lblOnEnd);

                EndNestedIterator(ndDod.Child);

                // mergedSequence = dodMerge.MergeSequences();
                this.helper.Call(XmlILMethods.DodMergeSeq);

                this.iterCurr.Storage = StorageDescriptor.Stack(typeof(XPathNavigator), true);

                return true;
            }

            return false;
        }
XmlILVisitor