Пример #1
0
        public virtual QilNode?EndBuild(QilNode?result)
        {
            if (result == null)
            { // special door to clean builder state in exception handlers
                _inTheBuild = false;
                return(result);
            }
            Debug.Assert(_inTheBuild, "StartBuild() wasn't called");

            if (result.XmlType !.MaybeMany && result.XmlType.IsNode && result.XmlType.IsNotRtf)
            {
                result = _f.DocOrderDistinct(result);
            }
            result            = _fixupVisitor.Fixup(result, /*environment:*/ _environment);
            numFixupCurrent  -= _fixupVisitor.numCurrent;
            numFixupPosition -= _fixupVisitor.numPosition;
            numFixupLast     -= _fixupVisitor.numLast;

            // All these variables will be positive for "false() and (. = position() + last())"
            // since QilPatternFactory eliminates the right operand of 'and'
            Debug.Assert(numFixupCurrent >= 0, "Context fixup error");
            Debug.Assert(numFixupPosition >= 0, "Context fixup error");
            Debug.Assert(numFixupLast >= 0, "Context fixup error");
            _inTheBuild = false;
            return(result);
        }
Пример #2
0
        //also used by XPathPatternBuilder
        public static QilNode BuildOnePredicate(QilNode nodeset, QilNode predicate, bool isReverseStep,
                                                XPathQilFactory f, FixupVisitor fixupVisitor,
                                                ref int numFixupCurrent, ref int numFixupPosition, ref int numFixupLast)
        {
            nodeset = f.EnsureNodeSet(nodeset);

            // Mirgeing nodeset and predicate:
            // 1. Predicate contains 0 last() :
            //      for $i in nodeset
            //      where predicate
            //      return $i
            //   Note: Currently we are keepeing old output to minimize diff.
            // 2. Predicate contains 1 last()
            //      let $cach := nodeset return
            //          for $i in $cach
            //          where predicate(length($cach))
            //          return $i
            //   Suggestion: This is a little optimisation we can do or don't do.
            // 3. Predicate contains 2+ last()
            //      let $cash := nodeset return
            //          let $size := length($cash) return
            //              for $i in $cash
            //              where predicate($size)
            //              return $i

            QilNode result;

            if (numFixupLast != 0 && fixupVisitor.CountUnfixedLast(predicate) != 0)
            {
                // this subtree has unfixed last() nodes
                QilIterator cash = f.Let(nodeset);
                QilIterator size = f.Let(f.XsltConvert(f.Length(cash), T.DoubleX));
                QilIterator it   = f.For(cash);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ size);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Loop(cash, f.Loop(size, f.Filter(it, predicate)));
            }
            else
            {
                QilIterator it = f.For(nodeset);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ null);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Filter(it, predicate);
            }
            if (isReverseStep)
            {
                result = f.DocOrderDistinct(result);
            }
            return(result);
        }