1/*
2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
3 * Copyright (C) 2006, 2009 Apple Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef XPathStep_h
28#define XPathStep_h
29
30#include <wtf/Vector.h>
31#include <wtf/text/AtomicString.h>
32
33namespace WebCore {
34
35class Node;
36
37namespace XPath {
38
39class Expression;
40class NodeSet;
41
42class Step {
43    WTF_MAKE_FAST_ALLOCATED;
44public:
45    enum Axis {
46        AncestorAxis, AncestorOrSelfAxis, AttributeAxis,
47        ChildAxis, DescendantAxis, DescendantOrSelfAxis,
48        FollowingAxis, FollowingSiblingAxis, NamespaceAxis,
49        ParentAxis, PrecedingAxis, PrecedingSiblingAxis,
50        SelfAxis
51    };
52
53    class NodeTest {
54        WTF_MAKE_FAST_ALLOCATED;
55    public:
56        enum Kind { TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest };
57
58        explicit NodeTest(Kind kind) : m_kind(kind) { }
59        NodeTest(Kind kind, const AtomicString& data) : m_kind(kind), m_data(data) { }
60        NodeTest(Kind kind, const AtomicString& data, const AtomicString& namespaceURI) : m_kind(kind), m_data(data), m_namespaceURI(namespaceURI) { }
61
62#if COMPILER(MSVC)
63        NodeTest(const NodeTest&);
64        void operator=(const NodeTest&);
65
66        NodeTest(NodeTest&& other)
67            : m_kind(other.m_kind)
68            , m_data(WTF::move(other.m_data))
69            , m_namespaceURI(WTF::move(other.m_namespaceURI))
70            , m_mergedPredicates(WTF::move(other.m_mergedPredicates))
71        {
72        }
73        NodeTest& operator=(NodeTest&& other)
74        {
75            m_kind = other.m_kind;
76            m_data = WTF::move(other.m_data);
77            m_namespaceURI = WTF::move(other.m_namespaceURI);
78            m_mergedPredicates = WTF::move(other.m_mergedPredicates);
79            return *this;
80        }
81#endif
82
83    private:
84        friend class Step;
85        friend void optimizeStepPair(Step&, Step&, bool&);
86        friend bool nodeMatchesBasicTest(Node&, Axis, const NodeTest&);
87        friend bool nodeMatches(Node&, Axis, const NodeTest&);
88
89        Kind m_kind;
90        AtomicString m_data;
91        AtomicString m_namespaceURI;
92        Vector<std::unique_ptr<Expression>> m_mergedPredicates;
93    };
94
95    Step(Axis, NodeTest);
96    Step(Axis, NodeTest, Vector<std::unique_ptr<Expression>>);
97    ~Step();
98
99    void optimize();
100
101    void evaluate(Node& context, NodeSet&) const;
102
103    Axis axis() const { return m_axis; }
104
105private:
106    friend void optimizeStepPair(Step&, Step&, bool&);
107
108    bool predicatesAreContextListInsensitive() const;
109
110    void parseNodeTest(const String&);
111    void nodesInAxis(Node& context, NodeSet&) const;
112
113    Axis m_axis;
114    NodeTest m_nodeTest;
115    Vector<std::unique_ptr<Expression>> m_predicates;
116};
117
118void optimizeStepPair(Step&, Step&, bool& dropSecondStep);
119
120} // namespace XPath
121
122} // namespace WebCore
123
124#endif // XPathStep_h
125