Inheritance: ChildrenQuery
 private CacheChildrenQuery(CacheChildrenQuery other) : base(other)
 {
     this.nextInput   = Query.Clone(other.nextInput);
     this.elementStk  = other.elementStk.Clone();
     this.positionStk = other.positionStk.Clone();
     this.needInput   = other.needInput;
 }
        private CacheChildrenQuery(CacheChildrenQuery other) : base(other) {
            this.nextInput   = Clone(other.nextInput);
            this.elementStk  = other.elementStk.Clone();
            this.positionStk = other.positionStk.Clone();
            this.needInput   = other.needInput;
#if DEBUG
            this.lastNode    = Clone(other.lastNode);
#endif
        }
        private CacheChildrenQuery(CacheChildrenQuery other) : base(other)
        {
            _nextInput   = Clone(other._nextInput);
            _elementStk  = other._elementStk.Clone();
            _positionStk = other._positionStk.Clone();
            _needInput   = other._needInput;
#if DEBUG
            _lastNode = Clone(other._lastNode);
#endif
        }
Exemple #4
0
        private Query ProcessAxis(Axis root, Flags flags, out Props props)
        {
            Query result = null;

            if (root.Prefix.Length > 0)
            {
                needContext = true;
            }
            firstInput = null;
            Query qyInput; {
                if (root.Input != null)
                {
                    Flags inputFlags = Flags.None;
                    if ((flags & Flags.PosFilter) == 0)
                    {
                        Axis input = root.Input as Axis;
                        if (input != null)
                        {
                            if (
                                root.TypeOfAxis == Axis.AxisType.Child &&
                                input.TypeOfAxis == Axis.AxisType.DescendantOrSelf && input.NodeType == XPathNodeType.All
                                )
                            {
                                Query qyGrandInput;
                                if (input.Input != null)
                                {
                                    qyGrandInput = ProcessNode(input.Input, Flags.SmartDesc, out props);
                                }
                                else
                                {
                                    qyGrandInput = new ContextQuery();
                                    props        = Props.None;
                                }
                                result = new DescendantQuery(qyGrandInput, root.Name, root.Prefix, root.NodeType, false, input.AbbrAxis);
                                if ((props & Props.NonFlat) != 0)
                                {
                                    result = new DocumentOrderQuery(result);
                                }
                                props |= Props.NonFlat;
                                return(result);
                            }
                        }
                        if (root.TypeOfAxis == Axis.AxisType.Descendant || root.TypeOfAxis == Axis.AxisType.DescendantOrSelf)
                        {
                            inputFlags |= Flags.SmartDesc;
                        }
                    }

                    qyInput = ProcessNode(root.Input, inputFlags, out props);
                }
                else
                {
                    qyInput = new ContextQuery();
                    props   = Props.None;
                }
            }

            switch (root.TypeOfAxis)
            {
            case Axis.AxisType.Ancestor:
                result = new XPathAncestorQuery(qyInput, root.Name, root.Prefix, root.NodeType, false);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.AncestorOrSelf:
                result = new XPathAncestorQuery(qyInput, root.Name, root.Prefix, root.NodeType, true);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Child:
                if ((props & Props.NonFlat) != 0)
                {
                    result = new CacheChildrenQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                else
                {
                    result = new ChildrenQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                break;

            case Axis.AxisType.Parent:
                result = new ParentQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Descendant:
                if ((flags & Flags.SmartDesc) != 0)
                {
                    result = new DescendantOverDescendantQuery(qyInput, false, root.Name, root.Prefix, root.NodeType, /*abbrAxis:*/ false);
                }
                else
                {
                    result = new DescendantQuery(qyInput, root.Name, root.Prefix, root.NodeType, false, /*abbrAxis:*/ false);
                    if ((props & Props.NonFlat) != 0)
                    {
                        result = new DocumentOrderQuery(result);
                    }
                }
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.DescendantOrSelf:
                if ((flags & Flags.SmartDesc) != 0)
                {
                    result = new DescendantOverDescendantQuery(qyInput, true, root.Name, root.Prefix, root.NodeType, root.AbbrAxis);
                }
                else
                {
                    result = new DescendantQuery(qyInput, root.Name, root.Prefix, root.NodeType, true, root.AbbrAxis);
                    if ((props & Props.NonFlat) != 0)
                    {
                        result = new DocumentOrderQuery(result);
                    }
                }
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Preceding:
                result = new PrecedingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.Following:
                result = new FollowingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                props |= Props.NonFlat;
                break;

            case Axis.AxisType.FollowingSibling:
                result = new FollSiblingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                if ((props & Props.NonFlat) != 0)
                {
                    result = new DocumentOrderQuery(result);
                }
                break;

            case Axis.AxisType.PrecedingSibling:
                result = new PreSiblingQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Attribute:
                result = new AttributeQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Self:
                result = new XPathSelfQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                break;

            case Axis.AxisType.Namespace:
                if ((root.NodeType == XPathNodeType.All || root.NodeType == XPathNodeType.Element || root.NodeType == XPathNodeType.Attribute) && root.Prefix.Length == 0)
                {
                    result = new NamespaceQuery(qyInput, root.Name, root.Prefix, root.NodeType);
                }
                else
                {
                    result = new EmptyQuery();
                }
                break;

            default:
                throw XPathException.Create(Res.Xp_NotSupported, query);
            }

            return(result);
        }