View over a Qil operators that introduce iterators (Loop, Filter, etc.).
Don't construct QIL nodes directly; instead, use the QilFactory.
Inheritance: QilBinary
Beispiel #1
0
 public void AddTemplateMatch(Template template, QilLoop filter) {
     List<TemplateMatch> matchesForMode;
     if (!TemplateMatches.TryGetValue(template.Mode, out matchesForMode)) {
         matchesForMode = TemplateMatches[template.Mode] = new List<TemplateMatch>();
     }
     matchesForMode.Add(new TemplateMatch(template, filter));
 }
Beispiel #2
0
        //-----------------------------------------------
        // sorting
        //-----------------------------------------------
        public QilLoop Sort(QilNode variable, QilNode body)
        {
            QilLoop n = new QilLoop(QilNodeType.Sort, variable, body);

            n.XmlType = this.typeCheck.CheckSort(n);
            TraceNode(n);
            return(n);
        }
Beispiel #3
0
        //-----------------------------------------------
        // loops
        //-----------------------------------------------
        public QilLoop Loop(QilNode variable, QilNode body)
        {
            QilLoop n = new QilLoop(QilNodeType.Loop, variable, body);

            n.XmlType = _typeCheck.CheckLoop(n);
            TraceNode(n);
            return(n);
        }
Beispiel #4
0
        public QilLoop Filter(QilNode variable, QilNode body)
        {
            QilLoop n = new QilLoop(QilNodeType.Filter, variable, body);

            n.XmlType = this.typeCheck.CheckFilter(n);
            TraceNode(n);
            return(n);
        }
        //-----------------------------------------------
        // sorting
        //-----------------------------------------------
        public XmlQueryType CheckSort(QilLoop node)
        {
            XmlQueryType varType = node.Variable.Binding.XmlType;

            CheckClassAndNodeType(node[0], typeof(QilIterator), QilNodeType.For);
            CheckClassAndNodeType(node[1], typeof(QilList), QilNodeType.SortKeyList);

            // Sort does not preserve DocOrderDistinct
            return(XmlQueryTypeFactory.PrimeProduct(varType, varType.Cardinality));
        }
        //-----------------------------------------------
        // loops
        //-----------------------------------------------
        public XmlQueryType CheckLoop(QilLoop node)
        {
            CheckClass(node[0], typeof(QilIterator));
            Check(node.Variable.NodeType == QilNodeType.For || node.Variable.NodeType == QilNodeType.Let, node, "Loop variable must be a For or Let iterator");

            XmlQueryType        bodyType     = node.Body.XmlType;
            XmlQueryCardinality variableCard = node.Variable.NodeType == QilNodeType.Let ? XmlQueryCardinality.One : node.Variable.Binding.XmlType.Cardinality;

            // Loops do not preserve DocOrderDistinct
            return(XmlQueryTypeFactory.PrimeProduct(bodyType, variableCard * bodyType.Cardinality));
        }
Beispiel #7
0
        public XmlQueryType CheckFilter(QilLoop node)
        {
            CheckClass(node[0], typeof(QilIterator));
            Check(node.Variable.NodeType == QilNodeType.For || node.Variable.NodeType == QilNodeType.Let, node, "Filter variable must be a For or Let iterator");
            CheckXmlType(node.Body, XmlQueryTypeFactory.BooleanX);

            // Attempt to restrict filter's type by checking condition
            XmlQueryType filterType = FindFilterType(node.Variable, node.Body);

            if (filterType != null)
            {
                return(filterType);
            }

            return(XmlQueryTypeFactory.AtMost(node.Variable.Binding.XmlType, node.Variable.Binding.XmlType.Cardinality));
        }
Beispiel #8
0
 protected override QilNode VisitSort(QilLoop n)
 {
     return(NoReplace(n));
 }
 protected override QilNode VisitSort(QilLoop local0) {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone]) {
         if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
             if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop( (QilNode) (local1)[0] )));
             }
         }
     }
     if (this[XmlILOptimization.EliminateSort]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( ( (local3).XmlType ).IsSingleton ) {
                 if (AllowReplace(XmlILOptimization.EliminateSort, local0)) {
                     return Replace(XmlILOptimization.EliminateSort, local0, VisitNop(f.Nop(local3)));
                 }
             }
         }
     }
     return NoReplace(local0);
 }
 private static void SetLastParent(QilNode node, QilLoop parent) {
     Debug.Assert(parent.NodeType == QilNodeType.Filter);
     Annotation ann = (Annotation)node.Annotation ?? new Annotation();
     ann.Parent = parent;
     node.Annotation = ann;
 }
 protected override QilNode VisitFilter(QilLoop local0)
 {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone])
     {
         if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None)
         {
             // PATTERN: [FoldNone] (Filter $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
             if (AllowReplace(XmlILOptimization.FoldNone, local0))
             {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop((QilNode)(local1)[0])));
             }
         }
     }
     if (this[XmlILOptimization.FoldNone])
     {
         if ((object)((local2).XmlType) == (object)XmlQueryTypeFactory.None)
         {
             // PATTERN: [FoldNone] (Filter $i:* $w:* ^ (None? (TypeOf $w))) => (Loop $i $w)
             if (AllowReplace(XmlILOptimization.FoldNone, local0))
             {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitLoop(f.Loop(local1, local2)));
             }
         }
     }
     if (this[XmlILOptimization.EliminateFilter])
     {
         if (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))
         {
             if (local2.NodeType == QilNodeType.False)
             {
                 // PATTERN: [EliminateFilter] (Filter $i:* ^ (NoSideEffects? $i) (False)) => (Sequence)
                 if (AllowReplace(XmlILOptimization.EliminateFilter, local0))
                 {
                     return Replace(XmlILOptimization.EliminateFilter, local0, VisitSequence(f.Sequence()));
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateFilter])
     {
         if (local2.NodeType == QilNodeType.True)
         {
             // PATTERN: [EliminateFilter] (Filter $i:* (True)) => (First $i)
             if (AllowReplace(XmlILOptimization.EliminateFilter, local0))
             {
                 return Replace(XmlILOptimization.EliminateFilter, local0, (QilNode)(local1)[0]);
             }
         }
     }
     if (this[XmlILOptimization.NormalizeAttribute])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Content)
             {
                 QilNode local4 = local3[0];
                 if (local2.NodeType == QilNodeType.And)
                 {
                     QilNode local5 = local2[0];
                     QilNode local9 = local2[1];
                     if (local5.NodeType == QilNodeType.IsType)
                     {
                         QilNode local6 = local5[0];
                         QilNode local7 = local5[1];
                         if (local6 == local1)
                         {
                             if (local7.NodeType == QilNodeType.LiteralType)
                             {
                                 XmlQueryType local8 = (XmlQueryType)((QilLiteral)local7).Value;
                                 if ((local8) == (XmlQueryTypeFactory.Attribute))
                                 {
                                     if (local9.NodeType == QilNodeType.Eq)
                                     {
                                         QilNode local10 = local9[0];
                                         QilNode local12 = local9[1];
                                         if (local10.NodeType == QilNodeType.NameOf)
                                         {
                                             QilNode local11 = local10[0];
                                             if (local11 == local1)
                                             {
                                                 if (local12.NodeType == QilNodeType.LiteralQName)
                                                 {
                                                     // PATTERN: [NormalizeAttribute] (Filter $iter:(For (Content $input:*)) (And (IsType $iter (LiteralType $typ:* ^ (Equal? $typ (ConstructType {Attribute})))) (Eq (NameOf $iter) $qname:(LiteralQName * * *)))) => (Attribute $input $qname)
                                                     if (AllowReplace(XmlILOptimization.NormalizeAttribute, local0))
                                                     {
                                                         return Replace(XmlILOptimization.NormalizeAttribute, local0, VisitAttribute(f.Attribute(local4, local12)));
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.CommuteFilterLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Loop)
             {
                 QilNode local4 = local3[0];
                 QilNode local5 = local3[1];
                 if ((NonPositional(local2, local1)) && (!(IsDocOrderDistinct(local3))))
                 {
                     // PATTERN: [CommuteFilterLoop] (Filter $iter:(For $loop:(Loop $iter2:* $ret2:*)) $cond:* ^ (NonPositional? $cond $iter) ^ ~((DocOrderDistinct? $loop))) => (Loop $iter2 (Filter $iter3:(For $ret2) (Subs $cond $iter $iter3)))
                     if (AllowReplace(XmlILOptimization.CommuteFilterLoop, local0))
                     {
                         QilNode local6 = VisitFor(f.For(local5));
                         return Replace(XmlILOptimization.CommuteFilterLoop, local0, VisitLoop(f.Loop(local4, VisitFilter(f.Filter(local6, Subs(local2, local1, local6))))));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopInvariant])
     {
         if ((!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects)) && (!(((QilNode)(local1)[0]).NodeType == QilNodeType.OptimizeBarrier)))
         {
             if ((!(DependsOn(local2, local1))) && (!OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.MaybeSideEffects)))
             {
                 // PATTERN: [NormalizeLoopInvariant] (Filter $iter:* ^ (NoSideEffects? $iter) ^ ~((NodeType? (First $iter) {OptimizeBarrier})) $cond:* ^ ~($cond >> $iter) ^ (NoSideEffects? $cond)) => (Conditional $cond (First $iter) (Sequence))
                 if (AllowReplace(XmlILOptimization.NormalizeLoopInvariant, local0))
                 {
                     return Replace(XmlILOptimization.NormalizeLoopInvariant, local0, VisitConditional(f.Conditional(local2, (QilNode)(local1)[0], VisitSequence(f.Sequence()))));
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionEq])
     {
         if (local2.NodeType == QilNodeType.Eq)
         {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf)
             {
                 QilNode local4 = local3[0];
                 if (local4 == local1)
                 {
                     if (local5.NodeType == QilNodeType.LiteralInt32)
                     {
                         int local6 = (int)((QilLiteral)local5).Value;
                         // PATTERN: [AnnotateMaxPositionEq] $outer:(Filter $iter:* (Eq (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { }
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionEq, local0))
                         {
                             OptimizerPatterns.Write((QilNode)(local1)).AddPattern(OptimizerPatternName.MaxPosition); OptimizerPatterns.Write((QilNode)(local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionLe])
     {
         if (local2.NodeType == QilNodeType.Le)
         {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf)
             {
                 QilNode local4 = local3[0];
                 if (local4 == local1)
                 {
                     if (local5.NodeType == QilNodeType.LiteralInt32)
                     {
                         int local6 = (int)((QilLiteral)local5).Value;
                         // PATTERN: [AnnotateMaxPositionLe] $outer:(Filter $iter:* (Le (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} $num) ^ { }
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLe, local0))
                         {
                             OptimizerPatterns.Write((QilNode)(local1)).AddPattern(OptimizerPatternName.MaxPosition); OptimizerPatterns.Write((QilNode)(local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionLt])
     {
         if (local2.NodeType == QilNodeType.Lt)
         {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf)
             {
                 QilNode local4 = local3[0];
                 if (local4 == local1)
                 {
                     if (local5.NodeType == QilNodeType.LiteralInt32)
                     {
                         int local6 = (int)((QilLiteral)local5).Value;
                         // PATTERN: [AnnotateMaxPositionLt] $outer:(Filter $iter:* (Lt (PositionOf $iter) (LiteralInt32 $num:*))) => (AddPattern $iter {MaxPosition}) ^ (AddArgument $iter {MaxPosition} { {$num} - 1 }) ^ { }
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLt, local0))
                         {
                             OptimizerPatterns.Write((QilNode)(local1)).AddPattern(OptimizerPatternName.MaxPosition); OptimizerPatterns.Write((QilNode)(local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6 - 1);
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilter])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             // PATTERN: [AnnotateFilter] $outer:(Filter $iter:(For $bind:*) *) => (InheritPattern $outer $bind {Step}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ (InheritPattern $outer $bind {SameDepth}) ^ { }
             if (AllowReplace(XmlILOptimization.AnnotateFilter, local0))
             {
                 OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.Step); OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.IsDocOrderDistinct); OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.SameDepth);
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterElements])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (OptimizerPatterns.Read((QilNode)(local3)).MatchesPattern(OptimizerPatternName.Axis))
             {
                 if (local2.NodeType == QilNodeType.And)
                 {
                     QilNode local4 = local2[0];
                     QilNode local8 = local2[1];
                     if (local4.NodeType == QilNodeType.IsType)
                     {
                         QilNode local5 = local4[0];
                         QilNode local6 = local4[1];
                         if (local5 == local1)
                         {
                             if (local6.NodeType == QilNodeType.LiteralType)
                             {
                                 XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
                                 if ((local7) == (XmlQueryTypeFactory.Element))
                                 {
                                     if (local8.NodeType == QilNodeType.Eq)
                                     {
                                         QilNode local9 = local8[0];
                                         QilNode local11 = local8[1];
                                         if (local9.NodeType == QilNodeType.NameOf)
                                         {
                                             QilNode local10 = local9[0];
                                             if (local10 == local1)
                                             {
                                                 if (local11.NodeType == QilNodeType.LiteralQName)
                                                 {
                                                     // PATTERN: [AnnotateFilterElements] $outer:(Filter $iter:(For $bind:* ^ (Pattern? $bind {Axis})) (And (IsType $iter (LiteralType $typ:* ^ (Equal? $typ (ConstructType {Element})))) (Eq (NameOf $iter) $qname:(LiteralQName * * *)))) => (AddPattern $outer {FilterElements}) ^ (AddArgument $outer {ElementQName} $qname) ^ { }
                                                     if (AllowReplace(XmlILOptimization.AnnotateFilterElements, local0))
                                                     {
                                                         OptimizerPatterns.Write((QilNode)(local0)).AddPattern(OptimizerPatternName.FilterElements); OptimizerPatterns.Write((QilNode)(local0)).AddArgument(OptimizerPatternArgument.ElementQName, local11);
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterContentKind])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (OptimizerPatterns.Read((QilNode)(local3)).MatchesPattern(OptimizerPatternName.Axis))
             {
                 if (local2.NodeType == QilNodeType.IsType)
                 {
                     QilNode local4 = local2[0];
                     QilNode local5 = local2[1];
                     if (local4 == local1)
                     {
                         if (local5.NodeType == QilNodeType.LiteralType)
                         {
                             XmlQueryType local6 = (XmlQueryType)((QilLiteral)local5).Value;
                             if (MatchesContentTest(local6))
                             {
                                 // PATTERN: [AnnotateFilterContentKind] $outer:(Filter $iter:(For $bind:* ^ (Pattern? $bind {Axis})) (IsType $iter (LiteralType $kind:* ^ (ContentTest? $kind)))) => (AddPattern $outer {FilterContentKind}) ^ (AddArgument $outer {KindTestType} $kind) ^ { }
                                 if (AllowReplace(XmlILOptimization.AnnotateFilterContentKind, local0))
                                 {
                                     OptimizerPatterns.Write((QilNode)(local0)).AddPattern(OptimizerPatternName.FilterContentKind); OptimizerPatterns.Write((QilNode)(local0)).AddArgument(OptimizerPatternArgument.KindTestType, local6);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterAttributeKind])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Content)
             {
                 if (local2.NodeType == QilNodeType.IsType)
                 {
                     QilNode local5 = local2[0];
                     QilNode local6 = local2[1];
                     if (local5 == local1)
                     {
                         if (local6.NodeType == QilNodeType.LiteralType)
                         {
                             XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
                             if ((local7) == (XmlQueryTypeFactory.Attribute))
                             {
                                 // PATTERN: [AnnotateFilterAttributeKind] $outer:(Filter $iter:(For (Content *)) (IsType $iter (LiteralType $kind:*) ^ (Equal? $kind (ConstructType {Attribute})))) => (AddPattern $outer {FilterAttributeKind}) ^ { }
                                 if (AllowReplace(XmlILOptimization.AnnotateFilterAttributeKind, local0))
                                 {
                                     OptimizerPatterns.Write((QilNode)(local0)).AddPattern(OptimizerPatternName.FilterAttributeKind);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return NoReplace(local0);
 }
 protected override QilNode VisitSort(QilLoop n) { return NoReplace(n); }
Beispiel #13
0
 // Filers that travers Content being converted to global travers:
 // Filter($j= ... Filter($i = Content(fixup), ...))  -> Filter($j= ... Filter($i = Loop($j = DesendentOrSelf(Root(fixup)), Content($j), ...)))
 protected override QilNode VisitLoop(QilLoop n) {
     if (n.Variable.Binding.NodeType == QilNodeType.Root || n.Variable.Binding.NodeType == QilNodeType.Deref) {
         // This is absolute path already. We shouldn't touch it
         return n;
     }
     if (n.Variable.Binding.NodeType == QilNodeType.Content) {
         // This is "begin" of reletive path. Let's rewrite it as absolute:
         QilUnary content = (QilUnary)n.Variable.Binding;
         Debug.Assert(content.Child == this.fixup, "Unexpected content node");
         QilIterator it = f.For(f.DescendantOrSelf(f.Root(this.fixup)));
         content.Child = it;
         n.Variable.Binding = f.Loop(it, content);
         return n;
     }
     n.Variable.Binding = Visit(n.Variable.Binding);
     return n;
 }
Beispiel #14
0
        /// <summary>
        /// Generate code for QilNodeType.Sort.
        /// </summary>
        protected override QilNode VisitSort(QilLoop ndSort)
        {
            Type itemStorageType = GetItemStorageType(ndSort);
            LocalBuilder locCache, locKeys;
            Label lblOnEndSort = _helper.DefineLabel();
            Debug.Assert(ndSort.Variable.NodeType == QilNodeType.For);

            // XmlQuerySequence<T> cache;
            // cache = XmlQuerySequence.CreateOrReuse(cache);
            XmlILStorageMethods methods = XmlILMethods.StorageMethods[itemStorageType];
            locCache = _helper.DeclareLocal("$$$cache", methods.SeqType);
            _helper.Emit(OpCodes.Ldloc, locCache);
            _helper.CallToken(methods.SeqReuse);
            _helper.Emit(OpCodes.Stloc, locCache);
            _helper.Emit(OpCodes.Ldloc, locCache);

            // XmlSortKeyAccumulator keys;
            // keys.Create(runtime);
            locKeys = _helper.DeclareLocal("$$$keys", typeof(XmlSortKeyAccumulator));
            _helper.Emit(OpCodes.Ldloca, locKeys);
            _helper.Call(XmlILMethods.SortKeyCreate);

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

            // cache.Add(item);
            _iterCurr.EnsureStackNoCache();
            _iterCurr.EnsureItemStorageType(ndSort.Variable.XmlType, GetItemStorageType(ndSort.Variable));
            _helper.Call(methods.SeqAdd);

            _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();
            _helper.Call(XmlILMethods.SortKeyFinish);

            // }
            _helper.Emit(OpCodes.Ldloc, locCache);
            _iterCurr.LoopToEnd(lblOnEndSort);

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

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

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

            return ndSort;
        }
 private void FixupFilterBinding(QilLoop filter, QilNode newBinding) {
     AssertFilter(filter);
     filter.Variable.Binding = newBinding;
 }
Beispiel #16
0
        /// <summary>
        /// Generate code for a QilNodeType.Filter.
        /// </summary>
        protected override QilNode VisitFilter(QilLoop ndFilter)
        {
            // Handle any special-case patterns that are rooted at Filter
            if (HandleFilterPatterns(ndFilter))
                return ndFilter;

            StartBinding(ndFilter.Variable);

            // Result of filter is the sequence bound to the iterator
            _iterCurr.SetIterator(_iterNested);

            // If filter is false, skip the current item
            StartNestedIterator(ndFilter.Body);
            _iterCurr.SetBranching(BranchingContext.OnFalse, _iterCurr.ParentIterator.GetLabelNext());
            Visit(ndFilter.Body);
            EndNestedIterator(ndFilter.Body);

            EndBinding(ndFilter.Variable);

            return ndFilter;
        }
Beispiel #17
0
        /// <summary>
        /// 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.
        /// </summary>
        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 = _helper.DeclareLocal("$$$iterElemContent", typeof(ElementContentIterator));

                            // iter.Create(navCtxt, locName, ns);
                            _helper.Emit(OpCodes.Ldloca, locIter);
                            NestedVisitEnsureStack(input);
                            _helper.CallGetAtomizedName(_helper.StaticData.DeclareName(name.LocalName));
                            _helper.CallGetAtomizedName(_helper.StaticData.DeclareName(name.NamespaceUri));
                            _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 = _helper.DeclareLocal("$$$iterContent", typeof(NodeKindContentIterator));

                                // iter.Create(navCtxt, nodeType);
                                _helper.Emit(OpCodes.Ldloca, locIter);
                                NestedVisitEnsureStack(input);
                                _helper.LoadInteger((int)QilXmlToXPathNodeType(kinds));
                                _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 = _helper.DefineLabel();
                Label lblLookup = _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 = _helper.DeclareLocal("$$$index", typeof(XmlILIndex));
                _helper.LoadQueryRuntime();
                _helper.Emit(OpCodes.Ldarg_1);
                _helper.LoadInteger(_indexId);
                _helper.Emit(OpCodes.Ldloca, locIndex);
                _helper.Call(XmlILMethods.FindIndex);
                _helper.Emit(OpCodes.Brtrue, lblLookup);

                // runtime.AddNewIndex(navCtxt, indexId, [build index]);
                _helper.LoadQueryRuntime();
                _helper.Emit(OpCodes.Ldarg_1);
                _helper.LoadInteger(_indexId);
                _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);
                _iterCurr.EnsureStackNoCache();
                VisitFor(nodes);
                _iterCurr.EnsureStackNoCache();
                _iterCurr.EnsureItemStorageType(nodes.XmlType, typeof(XPathNavigator));
                _helper.Call(XmlILMethods.IndexAdd);
                _helper.Emit(OpCodes.Ldloc, locIndex);

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

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

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

                _indexId++;

                return true;
            }

            return false;
        }
Beispiel #18
0
        /// <summary>
        /// Generate code for a QilNodeType.Loop.
        /// </summary>
        protected override QilNode VisitLoop(QilLoop ndLoop)
        {
            bool hasOnEnd;
            Label lblOnEnd;

            StartWriterLoop(ndLoop, out hasOnEnd, out lblOnEnd);

            StartBinding(ndLoop.Variable);

            // Unnest loop body as part of the current iterator
            Visit(ndLoop.Body);

            EndBinding(ndLoop.Variable);

            EndWriterLoop(ndLoop, hasOnEnd, lblOnEnd);

            return ndLoop;
        }
Beispiel #19
0
 //-----------------------------------------------
 // loops
 //-----------------------------------------------
 public QilLoop Loop(QilNode variable, QilNode body)
 {
     QilLoop n = new QilLoop(QilNodeType.Loop, variable, body);
     n.XmlType = _typeCheck.CheckLoop(n);
     TraceNode(n);
     return n;
 }
 protected override QilNode VisitSort(QilLoop local0)
 {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone])
     {
         if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None)
         {
             // PATTERN: [FoldNone] (Sort $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
             if (AllowReplace(XmlILOptimization.FoldNone, local0))
             {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop((QilNode)(local1)[0])));
             }
         }
     }
     if (this[XmlILOptimization.EliminateSort])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (((local3).XmlType).IsSingleton)
             {
                 // PATTERN: [EliminateSort] (Sort (For $bind:* ^ (Single? (TypeOf $bind))) *) => (Nop $bind)
                 if (AllowReplace(XmlILOptimization.EliminateSort, local0))
                 {
                     return Replace(XmlILOptimization.EliminateSort, local0, VisitNop(f.Nop(local3)));
                 }
             }
         }
     }
     return NoReplace(local0);
 }
 public void SetContext(QilLoop filter) {
     this.baseContext = filter;
 }
 protected virtual QilNode VisitSort(QilLoop n) { return VisitChildren(n); }
 protected override QilNode VisitFilter(QilLoop n) { return NoReplace(n); }
 public void AssertFilter(QilLoop filter) {
     Debug.Assert(filter.NodeType == QilNodeType.Filter, "XPathPatternBuilder expected to generate list of Filters on top level");
     Debug.Assert(filter.Variable.XmlType.IsSubtypeOf(T.NodeNotRtf));
     Debug.Assert(filter.Variable.Binding.NodeType == QilNodeType.Unknown);  // fixupNode
     Debug.Assert(filter.Body.XmlType.IsSubtypeOf(T.Boolean));
 }
Beispiel #25
0
 protected override QilNode VisitFilter(QilLoop n) {
     return VisitLoop(n);
 }
        public XmlQueryType CheckFilter(QilLoop node) {
            CheckClass(node[0], typeof(QilIterator));
            Check(node.Variable.NodeType == QilNodeType.For || node.Variable.NodeType == QilNodeType.Let, node, "Filter variable must be a For or Let iterator");
            CheckXmlType(node.Body, XmlQueryTypeFactory.BooleanX);

            // Attempt to restrict filter's type by checking condition
            XmlQueryType filterType = FindFilterType(node.Variable, node.Body);
            if (filterType != null)
                return filterType;

            return XmlQueryTypeFactory.AtMost(node.Variable.Binding.XmlType, node.Variable.Binding.XmlType.Cardinality);
        }
        /// <summary>
        /// Analyze loop.
        /// </summary>
        protected virtual void AnalyzeLoop(QilLoop ndLoop, XmlILConstructInfo info) {
            XmlQueryType typ = ndLoop.XmlType;

            // Ensure that construct method is Writer
            info.ConstructMethod = XmlILConstructMethod.Writer;

            if (!typ.IsSingleton)
                StartLoop(typ, info);
 
            // Body constructs content
            ndLoop.Body = AnalyzeContent(ndLoop.Body);

            if (!typ.IsSingleton)
                EndLoop(typ, info);
        }
 protected override QilNode VisitLoop(QilLoop local0)
 {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone])
     {
         if ((object)((local1).XmlType) == (object)XmlQueryTypeFactory.None)
         {
             // PATTERN: [FoldNone] (Loop $i:* ^ (None? (TypeOf $i)) *) => (Nop (First $i))
             if (AllowReplace(XmlILOptimization.FoldNone, local0))
             {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop((QilNode)(local1)[0])));
             }
         }
     }
     if (this[XmlILOptimization.EliminateIterator])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.For)
             {
                 if (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.IsPositional))
                 {
                     // PATTERN: [EliminateIterator] $outer:(Loop $iter:(For $iterRef:(For *)) ^ (NonPositionalIterator? $iter) $ret:*) => (Subs $ret $iter $iterRef)
                     if (AllowReplace(XmlILOptimization.EliminateIterator, local0))
                     {
                         return Replace(XmlILOptimization.EliminateIterator, local0, Subs(local2, local1, local3));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Sequence)
             {
                 if ((local3).Count == (0))
                 {
                     // PATTERN: [EliminateLoop] (Loop (For $x:(Sequence) ^ (Count? $x 0)) *) => (Sequence)
                     if (AllowReplace(XmlILOptimization.EliminateLoop, local0))
                     {
                         return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop])
     {
         if (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects))
         {
             if (local2.NodeType == QilNodeType.Sequence)
             {
                 if ((local2).Count == (0))
                 {
                     // PATTERN: [EliminateLoop] (Loop $i:* ^ (NoSideEffects? $i) $x:(Sequence) ^ (Count? $x 0)) => (Sequence)
                     if (AllowReplace(XmlILOptimization.EliminateLoop, local0))
                     {
                         return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop])
     {
         if (local2 == local1)
         {
             // PATTERN: [EliminateLoop] (Loop $iter:* $iter) => (First $iter)
             if (AllowReplace(XmlILOptimization.EliminateLoop, local0))
             {
                 return Replace(XmlILOptimization.EliminateLoop, local0, (QilNode)(local1)[0]);
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopText])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (((local3).XmlType).IsSingleton)
             {
                 if (local2.NodeType == QilNodeType.TextCtor)
                 {
                     QilNode local4 = local2[0];
                     // PATTERN: [NormalizeLoopText] (Loop $iter:(For $bind:* ^ (Single? (TypeOf $bind))) $ctor:(TextCtor $text:*)) => (TextCtor (Loop $iter $text))
                     if (AllowReplace(XmlILOptimization.NormalizeLoopText, local0))
                     {
                         return Replace(XmlILOptimization.NormalizeLoopText, local0, VisitTextCtor(f.TextCtor(VisitLoop(f.Loop(local1, local4)))));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateIteratorUsedAtMostOnce])
     {
         if ((((local1).NodeType == QilNodeType.Let) || ((((QilNode)(local1)[0]).XmlType).IsSingleton)) && (!OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects)))
         {
             if (_nodeCounter.Count(local2, local1) <= 1)
             {
                 // PATTERN: [EliminateIteratorUsedAtMostOnce] (Loop $iter:* ^ (NodeType? $iter {Let}) | (Single? (TypeOf (First $iter))) ^ (NoSideEffects? $iter) $ret:* ^ (RefCountZeroOrOne? $ret $iter)) => (Subs $ret $iter (First $iter))
                 if (AllowReplace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0))
                 {
                     return Replace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0, Subs(local2, local1, (QilNode)(local1)[0]));
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional])
     {
         if (local2.NodeType == QilNodeType.Conditional)
         {
             QilNode local3 = local2[0];
             QilNode local4 = local2[1];
             QilNode local5 = local2[2];
             if (local4.NodeType == QilNodeType.Sequence)
             {
                 if ((local4).Count == (0))
                 {
                     if (local5 == local1)
                     {
                         // PATTERN: [NormalizeLoopConditional] (Loop $iter:* (Conditional $cond:* $left:(Sequence) ^ (Count? $left 0) $iter)) => (Filter $iter (Not $cond))
                         if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0))
                         {
                             return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, VisitNot(f.Not(local3)))));
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional])
     {
         if (local2.NodeType == QilNodeType.Conditional)
         {
             QilNode local3 = local2[0];
             QilNode local4 = local2[1];
             QilNode local5 = local2[2];
             if (local4 == local1)
             {
                 if (local5.NodeType == QilNodeType.Sequence)
                 {
                     if ((local5).Count == (0))
                     {
                         // PATTERN: [NormalizeLoopConditional] (Loop $iter:* (Conditional $cond:* $iter $right:(Sequence) ^ (Count? $right 0))) => (Filter $iter $cond)
                         if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0))
                         {
                             return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, local3)));
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             if (local2.NodeType == QilNodeType.Conditional)
             {
                 QilNode local4 = local2[0];
                 QilNode local5 = local2[1];
                 QilNode local6 = local2[2];
                 if (local5.NodeType == QilNodeType.Sequence)
                 {
                     if ((local5).Count == (0))
                     {
                         if (NonPositional(local6, local1))
                         {
                             // PATTERN: [NormalizeLoopConditional] (Loop $iter:(For *) (Conditional $cond:* $left:(Sequence) ^ (Count? $left 0) $right:* ^ (NonPositional? $right $iter))) => (Loop $iter2:(For (Filter $iter (Not $cond))) (Subs $right $iter $iter2))
                             if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0))
                             {
                                 QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, VisitNot(f.Not(local4))))));
                                 return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7, Subs(local6, local1, local7))));
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             if (local2.NodeType == QilNodeType.Conditional)
             {
                 QilNode local4 = local2[0];
                 QilNode local5 = local2[1];
                 QilNode local6 = local2[2];
                 if (NonPositional(local5, local1))
                 {
                     if (local6.NodeType == QilNodeType.Sequence)
                     {
                         if ((local6).Count == (0))
                         {
                             // PATTERN: [NormalizeLoopConditional] (Loop $iter:(For *) (Conditional $cond:* $left:* ^ (NonPositional? $left $iter) $right:(Sequence) ^ (Count? $right 0))) => (Loop $iter2:(For (Filter $iter $cond)) (Subs $left $iter $iter2))
                             if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0))
                             {
                                 QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, local4))));
                                 return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7, Subs(local5, local1, local7))));
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopLoop])
     {
         if (local2.NodeType == QilNodeType.Loop)
         {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.For)
             {
                 QilNode local4 = local3[0];
                 if ((!(DependsOn(local5, local1))) && (NonPositional(local5, local3)))
                 {
                     // PATTERN: [NormalizeLoopLoop] (Loop $iter:* $ret:(Loop $iter2:(For $bind2:*) $ret2:* ^ ~($ret2 >> $iter) ^ (NonPositional? $ret2 $iter2))) => (Loop $iter3:(For (Loop $iter $bind2)) (Subs $ret2 $iter2 $iter3))
                     if (AllowReplace(XmlILOptimization.NormalizeLoopLoop, local0))
                     {
                         QilNode local6 = VisitFor(f.For(VisitLoop(f.Loop(local1, local4))));
                         return Replace(XmlILOptimization.NormalizeLoopLoop, local0, VisitLoop(f.Loop(local6, Subs(local5, local3, local6))));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateSingletonLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (!((local3).XmlType).MaybeMany)
             {
                 // PATTERN: [AnnotateSingletonLoop] $outer:(Loop (For $bind:* ^ (AtMostOne? (TypeOf $bind))) $ret:*) => (InheritPattern $outer $ret {IsDocOrderDistinct}) ^ (InheritPattern $outer $ret {SameDepth}) ^ { }
                 if (AllowReplace(XmlILOptimization.AnnotateSingletonLoop, local0))
                 {
                     OptimizerPatterns.Inherit((QilNode)(local2), (QilNode)(local0), OptimizerPatternName.IsDocOrderDistinct); OptimizerPatterns.Inherit((QilNode)(local2), (QilNode)(local0), OptimizerPatternName.SameDepth);
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateRootLoop])
     {
         if (IsStepPattern(local2, QilNodeType.Root))
         {
             // PATTERN: [AnnotateRootLoop] $outer:(Loop * $ret:* ^ (StepPattern? $ret {Root})) => (AddPattern $outer {SameDepth}) ^ { }
             if (AllowReplace(XmlILOptimization.AnnotateRootLoop, local0))
             {
                 OptimizerPatterns.Write((QilNode)(local0)).AddPattern(OptimizerPatternName.SameDepth);
             }
         }
     }
     if (this[XmlILOptimization.AnnotateContentLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (OptimizerPatterns.Read((QilNode)(local3)).MatchesPattern(OptimizerPatternName.SameDepth))
             {
                 if (((IsStepPattern(local2, QilNodeType.Content)) || (IsStepPattern(local2, QilNodeType.Union))) && ((local1) == (OptimizerPatterns.Read((QilNode)(local2)).GetArgument(OptimizerPatternArgument.StepInput))))
                 {
                     // PATTERN: [AnnotateContentLoop] $outer:(Loop $iter:(For $bind:* ^ (Pattern? $bind {SameDepth})) $ret:* ^ (StepPattern? $ret {Content}) | (StepPattern? $ret {Union}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (AddPattern $outer {SameDepth}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
                     if (AllowReplace(XmlILOptimization.AnnotateContentLoop, local0))
                     {
                         OptimizerPatterns.Write((QilNode)(local0)).AddPattern(OptimizerPatternName.SameDepth); OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.IsDocOrderDistinct);
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateAttrNmspLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if ((((IsStepPattern(local2, QilNodeType.Attribute)) || (IsStepPattern(local2, QilNodeType.XPathNamespace))) || (OptimizerPatterns.Read((QilNode)(local2)).MatchesPattern(OptimizerPatternName.FilterAttributeKind))) && ((local1) == (OptimizerPatterns.Read((QilNode)(local2)).GetArgument(OptimizerPatternArgument.StepInput))))
             {
                 // PATTERN: [AnnotateAttrNmspLoop] $outer:(Loop $iter:(For $bind:*) $ret:* ^ (StepPattern? $ret {Attribute}) | (StepPattern? $ret {XPathNamespace}) | (Pattern? $ret {FilterAttributeKind}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (InheritPattern $outer $bind {SameDepth}) ^ (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
                 if (AllowReplace(XmlILOptimization.AnnotateAttrNmspLoop, local0))
                 {
                     OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.SameDepth); OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.IsDocOrderDistinct);
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateDescendantLoop])
     {
         if (local1.NodeType == QilNodeType.For)
         {
             QilNode local3 = local1[0];
             if (OptimizerPatterns.Read((QilNode)(local3)).MatchesPattern(OptimizerPatternName.SameDepth))
             {
                 if (((IsStepPattern(local2, QilNodeType.Descendant)) || (IsStepPattern(local2, QilNodeType.DescendantOrSelf))) && ((local1) == (OptimizerPatterns.Read((QilNode)(local2)).GetArgument(OptimizerPatternArgument.StepInput))))
                 {
                     // PATTERN: [AnnotateDescendantLoop] $outer:(Loop $iter:(For $bind:* ^ (Pattern? $bind {SameDepth})) $ret:* ^ (StepPattern? $ret {Descendant}) | (StepPattern? $ret {DescendantOrSelf}) ^ (Equal? $iter (Argument $ret {StepInput}))) => (InheritPattern $outer $bind {IsDocOrderDistinct}) ^ { }
                     if (AllowReplace(XmlILOptimization.AnnotateDescendantLoop, local0))
                     {
                         OptimizerPatterns.Inherit((QilNode)(local3), (QilNode)(local0), OptimizerPatternName.IsDocOrderDistinct);
                     }
                 }
             }
         }
     }
     return NoReplace(local0);
 }
 protected virtual QilNode VisitFilter(QilLoop n) { return VisitChildren(n); }
        /// <summary>
        /// Analyze loop.
        /// </summary>
        protected override void AnalyzeLoop(QilLoop ndLoop, XmlILConstructInfo info) {
            // Constructing attributes/namespaces in a loop can cause duplicates, namespaces after attributes, etc.
            if (ndLoop.XmlType.MaybeMany)
                CheckAttributeNamespaceConstruct(ndLoop.XmlType);

            base.AnalyzeLoop(ndLoop, info);
        }
 public QilLoop Filter(QilNode variable, QilNode body) {
     QilLoop n = new QilLoop(QilNodeType.Filter, variable, body);
     n.XmlType = this.typeCheck.CheckFilter(n);
     TraceNode(n);
     return n;
 }
 //-----------------------------------------------
 // sorting
 //-----------------------------------------------
 public QilLoop Sort(QilNode variable, QilNode body) {
     QilLoop n = new QilLoop(QilNodeType.Sort, variable, body);
     n.XmlType = this.typeCheck.CheckSort(n);
     TraceNode(n);
     return n;
 }
        //-----------------------------------------------
        // loops
        //-----------------------------------------------
        public XmlQueryType CheckLoop(QilLoop node) {
            CheckClass(node[0], typeof(QilIterator));
            Check(node.Variable.NodeType == QilNodeType.For || node.Variable.NodeType == QilNodeType.Let, node, "Loop variable must be a For or Let iterator");

            XmlQueryType bodyType = node.Body.XmlType;
            XmlQueryCardinality variableCard = node.Variable.NodeType == QilNodeType.Let ? XmlQueryCardinality.One : node.Variable.Binding.XmlType.Cardinality;

            // Loops do not preserve DocOrderDistinct
            return XmlQueryTypeFactory.PrimeProduct(bodyType, variableCard * bodyType.Cardinality);
        }
 protected override QilNode VisitLoop(QilLoop local0) {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone]) {
         if ( (object) ( (local1).XmlType ) == (object) XmlQueryTypeFactory.None ) {
             if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitNop(f.Nop( (QilNode) (local1)[0] )));
             }
         }
     }
     if (this[XmlILOptimization.EliminateIterator]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.For) {
                 if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.IsPositional) ) {
                     if (AllowReplace(XmlILOptimization.EliminateIterator, local0)) {
                         return Replace(XmlILOptimization.EliminateIterator, local0,  Subs(local2, local1, local3) );
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Sequence) {
                 if ( (local3).Count == (0) ) {
                     if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
                         return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop]) {
         if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
             if (local2.NodeType == QilNodeType.Sequence) {
                 if ( (local2).Count == (0) ) {
                     if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
                         return Replace(XmlILOptimization.EliminateLoop, local0, VisitSequence(f.Sequence()));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateLoop]) {
         if (local2 == local1) {
             if (AllowReplace(XmlILOptimization.EliminateLoop, local0)) {
                 return Replace(XmlILOptimization.EliminateLoop, local0,  (QilNode) (local1)[0] );
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopText]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( ( (local3).XmlType ).IsSingleton ) {
                 if (local2.NodeType == QilNodeType.TextCtor) {
                     QilNode local4 = local2[0];
                     if (AllowReplace(XmlILOptimization.NormalizeLoopText, local0)) {
                         return Replace(XmlILOptimization.NormalizeLoopText, local0, VisitTextCtor(f.TextCtor(VisitLoop(f.Loop(local1, local4)))));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateIteratorUsedAtMostOnce]) {
         if ((( (local1).NodeType == QilNodeType.Let ) || ( ( ( (QilNode) (local1)[0] ).XmlType ).IsSingleton )) && ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
             if (( nodeCounter.Count(local2, local1) <= 1 ) && ( !OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
                 if (AllowReplace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0)) {
                     return Replace(XmlILOptimization.EliminateIteratorUsedAtMostOnce, local0,  Subs(local2, local1,  (QilNode) (local1)[0] ) );
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional]) {
         if (local2.NodeType == QilNodeType.Conditional) {
             QilNode local3 = local2[0];
             QilNode local4 = local2[1];
             QilNode local5 = local2[2];
             if (local4.NodeType == QilNodeType.Sequence) {
                 if ( (local4).Count == (0) ) {
                     if (local5 == local1) {
                         if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
                             return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, VisitNot(f.Not(local3)))));
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional]) {
         if (local2.NodeType == QilNodeType.Conditional) {
             QilNode local3 = local2[0];
             QilNode local4 = local2[1];
             QilNode local5 = local2[2];
             if (local4 == local1) {
                 if (local5.NodeType == QilNodeType.Sequence) {
                     if ( (local5).Count == (0) ) {
                         if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
                             return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitFilter(f.Filter(local1, local3)));
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional]) {
         if (local1.NodeType == QilNodeType.For) {
             if (local2.NodeType == QilNodeType.Conditional) {
                 QilNode local4 = local2[0];
                 QilNode local5 = local2[1];
                 QilNode local6 = local2[2];
                 if (local5.NodeType == QilNodeType.Sequence) {
                     if ( (local5).Count == (0) ) {
                         if ( NonPositional(local6, local1) ) {
                             if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
                                 QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, VisitNot(f.Not(local4))))));
                                 return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7,  Subs(local6, local1, local7) )));
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopConditional]) {
         if (local1.NodeType == QilNodeType.For) {
             if (local2.NodeType == QilNodeType.Conditional) {
                 QilNode local4 = local2[0];
                 QilNode local5 = local2[1];
                 QilNode local6 = local2[2];
                 if ( NonPositional(local5, local1) ) {
                     if (local6.NodeType == QilNodeType.Sequence) {
                         if ( (local6).Count == (0) ) {
                             if (AllowReplace(XmlILOptimization.NormalizeLoopConditional, local0)) {
                                 QilNode local7 = VisitFor(f.For(VisitFilter(f.Filter(local1, local4))));
                                 return Replace(XmlILOptimization.NormalizeLoopConditional, local0, VisitLoop(f.Loop(local7,  Subs(local5, local1, local7) )));
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopLoop]) {
         if (local2.NodeType == QilNodeType.Loop) {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.For) {
                 QilNode local4 = local3[0];
                 if ((!(DependsOn(local5,local1))) && ( NonPositional(local5, local3) )) {
                     if (AllowReplace(XmlILOptimization.NormalizeLoopLoop, local0)) {
                         QilNode local6 = VisitFor(f.For(VisitLoop(f.Loop(local1, local4))));
                         return Replace(XmlILOptimization.NormalizeLoopLoop, local0, VisitLoop(f.Loop(local6,  Subs(local5, local3, local6) )));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateSingletonLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( !( (local3).XmlType ).MaybeMany ) {
                 if (AllowReplace(XmlILOptimization.AnnotateSingletonLoop, local0)) {
                      OptimizerPatterns.Inherit((QilNode) (local2), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local2), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateRootLoop]) {
         if ( IsStepPattern(local2, QilNodeType.Root) ) {
             if (AllowReplace(XmlILOptimization.AnnotateRootLoop, local0)) {
                  OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  }
         }
     }
     if (this[XmlILOptimization.AnnotateContentLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.SameDepth) ) {
                 if ((( IsStepPattern(local2, QilNodeType.Content) ) || ( IsStepPattern(local2, QilNodeType.Union) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
                     if (AllowReplace(XmlILOptimization.AnnotateContentLoop, local0)) {
                          OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.SameDepth);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateAttrNmspLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (((( IsStepPattern(local2, QilNodeType.Attribute) ) || ( IsStepPattern(local2, QilNodeType.XPathNamespace) )) || ( OptimizerPatterns.Read((QilNode) (local2)).MatchesPattern(OptimizerPatternName.FilterAttributeKind) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
                 if (AllowReplace(XmlILOptimization.AnnotateAttrNmspLoop, local0)) {
                      OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.SameDepth);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateDescendantLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.SameDepth) ) {
                 if ((( IsStepPattern(local2, QilNodeType.Descendant) ) || ( IsStepPattern(local2, QilNodeType.DescendantOrSelf) )) && ( (local1) == ( OptimizerPatterns.Read((QilNode) (local2)).GetArgument(OptimizerPatternArgument.StepInput) ) )) {
                     if (AllowReplace(XmlILOptimization.AnnotateDescendantLoop, local0)) {
                          OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  }
                 }
             }
         }
     }
     return NoReplace(local0);
 }
        //-----------------------------------------------
        // sorting
        //-----------------------------------------------
        public XmlQueryType CheckSort(QilLoop node) {
            XmlQueryType varType = node.Variable.Binding.XmlType;

            CheckClassAndNodeType(node[0], typeof(QilIterator), QilNodeType.For);
            CheckClassAndNodeType(node[1], typeof(QilList), QilNodeType.SortKeyList);

            // Sort does not preserve DocOrderDistinct
            return XmlQueryTypeFactory.PrimeProduct(varType, varType.Cardinality);
        }
 protected override QilNode VisitFilter(QilLoop local0) {
     QilNode local1 = local0[0];
     QilNode local2 = local0[1];
     if (this[XmlILOptimization.FoldNone]) {
         if ( (object) ( (local2).XmlType ) == (object) XmlQueryTypeFactory.None ) {
             if (AllowReplace(XmlILOptimization.FoldNone, local0)) {
                 return Replace(XmlILOptimization.FoldNone, local0, VisitLoop(f.Loop(local1, local2)));
             }
         }
     }
     if (this[XmlILOptimization.EliminateFilter]) {
         if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
             if (local2.NodeType == QilNodeType.False) {
                 if (AllowReplace(XmlILOptimization.EliminateFilter, local0)) {
                     return Replace(XmlILOptimization.EliminateFilter, local0, VisitSequence(f.Sequence()));
                 }
             }
         }
     }
     if (this[XmlILOptimization.EliminateFilter]) {
         if (local2.NodeType == QilNodeType.True) {
             if (AllowReplace(XmlILOptimization.EliminateFilter, local0)) {
                 return Replace(XmlILOptimization.EliminateFilter, local0,  (QilNode) (local1)[0] );
             }
         }
     }
     if (this[XmlILOptimization.NormalizeAttribute]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Content) {
                 QilNode local4 = local3[0];
                 if (local2.NodeType == QilNodeType.And) {
                     QilNode local5 = local2[0];
                     QilNode local9 = local2[1];
                     if (local5.NodeType == QilNodeType.IsType) {
                         QilNode local6 = local5[0];
                         QilNode local7 = local5[1];
                         if (local6 == local1) {
                             if (local7.NodeType == QilNodeType.LiteralType) {
                                 XmlQueryType local8 = (XmlQueryType)((QilLiteral)local7).Value;
                                 if ( (local8) == ( XmlQueryTypeFactory.Attribute ) ) {
                                     if (local9.NodeType == QilNodeType.Eq) {
                                         QilNode local10 = local9[0];
                                         QilNode local12 = local9[1];
                                         if (local10.NodeType == QilNodeType.NameOf) {
                                             QilNode local11 = local10[0];
                                             if (local11 == local1) {
                                                 if (local12.NodeType == QilNodeType.LiteralQName) {
                                                     if (AllowReplace(XmlILOptimization.NormalizeAttribute, local0)) {
                                                         return Replace(XmlILOptimization.NormalizeAttribute, local0, VisitAttribute(f.Attribute(local4, local12)));
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.CommuteFilterLoop]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Loop) {
                 QilNode local4 = local3[0];
                 QilNode local5 = local3[1];
                 if ( NonPositional(local2, local1) ) {
                     if (AllowReplace(XmlILOptimization.CommuteFilterLoop, local0)) {
                         QilNode local6 = VisitFor(f.For(local5));
                         return Replace(XmlILOptimization.CommuteFilterLoop, local0, VisitLoop(f.Loop(local4, VisitFilter(f.Filter(local6,  Subs(local2, local1, local6) )))));
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.NormalizeLoopInvariant]) {
         if ( !OptimizerPatterns.Read(local1).MatchesPattern(OptimizerPatternName.MaybeSideEffects) ) {
             if ((!(DependsOn(local2,local1))) && ( !OptimizerPatterns.Read(local2).MatchesPattern(OptimizerPatternName.MaybeSideEffects) )) {
                 if (AllowReplace(XmlILOptimization.NormalizeLoopInvariant, local0)) {
                     return Replace(XmlILOptimization.NormalizeLoopInvariant, local0, VisitConditional(f.Conditional(local2,  (QilNode) (local1)[0] , VisitSequence(f.Sequence()))));
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionEq]) {
         if (local2.NodeType == QilNodeType.Eq) {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf) {
                 QilNode local4 = local3[0];
                 if (local4 == local1) {
                     if (local5.NodeType == QilNodeType.LiteralInt32) {
                         int local6 = (int)((QilLiteral)local5).Value;
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionEq, local0)) {
                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);  }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionLe]) {
         if (local2.NodeType == QilNodeType.Le) {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf) {
                 QilNode local4 = local3[0];
                 if (local4 == local1) {
                     if (local5.NodeType == QilNodeType.LiteralInt32) {
                         int local6 = (int)((QilLiteral)local5).Value;
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLe, local0)) {
                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition, local6);  }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateMaxPositionLt]) {
         if (local2.NodeType == QilNodeType.Lt) {
             QilNode local3 = local2[0];
             QilNode local5 = local2[1];
             if (local3.NodeType == QilNodeType.PositionOf) {
                 QilNode local4 = local3[0];
                 if (local4 == local1) {
                     if (local5.NodeType == QilNodeType.LiteralInt32) {
                         int local6 = (int)((QilLiteral)local5).Value;
                         if (AllowReplace(XmlILOptimization.AnnotateMaxPositionLt, local0)) {
                              OptimizerPatterns.Write((QilNode) (local1)).AddPattern(OptimizerPatternName.MaxPosition);  OptimizerPatterns.Write((QilNode) (local1)).AddArgument(OptimizerPatternArgument.MaxPosition,  local6 - 1 );  }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilter]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (AllowReplace(XmlILOptimization.AnnotateFilter, local0)) {
                  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.Step);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.IsDocOrderDistinct);  OptimizerPatterns.Inherit((QilNode) (local3), (QilNode) (local0), OptimizerPatternName.SameDepth);  }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterElements]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.Axis) ) {
                 if (local2.NodeType == QilNodeType.And) {
                     QilNode local4 = local2[0];
                     QilNode local8 = local2[1];
                     if (local4.NodeType == QilNodeType.IsType) {
                         QilNode local5 = local4[0];
                         QilNode local6 = local4[1];
                         if (local5 == local1) {
                             if (local6.NodeType == QilNodeType.LiteralType) {
                                 XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
                                 if ( (local7) == ( XmlQueryTypeFactory.Element ) ) {
                                     if (local8.NodeType == QilNodeType.Eq) {
                                         QilNode local9 = local8[0];
                                         QilNode local11 = local8[1];
                                         if (local9.NodeType == QilNodeType.NameOf) {
                                             QilNode local10 = local9[0];
                                             if (local10 == local1) {
                                                 if (local11.NodeType == QilNodeType.LiteralQName) {
                                                     if (AllowReplace(XmlILOptimization.AnnotateFilterElements, local0)) {
                                                          OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterElements);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.ElementQName, local11);  }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterContentKind]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if ( OptimizerPatterns.Read((QilNode) (local3)).MatchesPattern(OptimizerPatternName.Axis) ) {
                 if (local2.NodeType == QilNodeType.IsType) {
                     QilNode local4 = local2[0];
                     QilNode local5 = local2[1];
                     if (local4 == local1) {
                         if (local5.NodeType == QilNodeType.LiteralType) {
                             XmlQueryType local6 = (XmlQueryType)((QilLiteral)local5).Value;
                             if ( MatchesContentTest(local6) ) {
                                 if (AllowReplace(XmlILOptimization.AnnotateFilterContentKind, local0)) {
                                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterContentKind);  OptimizerPatterns.Write((QilNode) (local0)).AddArgument(OptimizerPatternArgument.KindTestType, local6);  }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (this[XmlILOptimization.AnnotateFilterAttributeKind]) {
         if (local1.NodeType == QilNodeType.For) {
             QilNode local3 = local1[0];
             if (local3.NodeType == QilNodeType.Content) {
                 if (local2.NodeType == QilNodeType.IsType) {
                     QilNode local5 = local2[0];
                     QilNode local6 = local2[1];
                     if (local5 == local1) {
                         if (local6.NodeType == QilNodeType.LiteralType) {
                             XmlQueryType local7 = (XmlQueryType)((QilLiteral)local6).Value;
                             if ( (local7) == ( XmlQueryTypeFactory.Attribute ) ) {
                                 if (AllowReplace(XmlILOptimization.AnnotateFilterAttributeKind, local0)) {
                                      OptimizerPatterns.Write((QilNode) (local0)).AddPattern(OptimizerPatternName.FilterAttributeKind);  }
                             }
                         }
                     }
                 }
             }
         }
     }
     return NoReplace(local0);
 }
Beispiel #37
0
 protected virtual QilNode VisitSort(QilLoop n)
 {
     return(VisitChildren(n));
 }
Beispiel #38
0
 protected override QilNode VisitFilter(QilLoop n) { return NoReplace(n); }