#ifndef XPathStep_h
#define XPathStep_h
#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
class Node;
namespace XPath {
class Expression;
class NodeSet;
class Step {
WTF_MAKE_FAST_ALLOCATED;
public:
enum Axis {
AncestorAxis, AncestorOrSelfAxis, AttributeAxis,
ChildAxis, DescendantAxis, DescendantOrSelfAxis,
FollowingAxis, FollowingSiblingAxis, NamespaceAxis,
ParentAxis, PrecedingAxis, PrecedingSiblingAxis,
SelfAxis
};
class NodeTest {
WTF_MAKE_FAST_ALLOCATED;
public:
enum Kind { TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest };
explicit NodeTest(Kind kind) : m_kind(kind) { }
NodeTest(Kind kind, const AtomicString& data) : m_kind(kind), m_data(data) { }
NodeTest(Kind kind, const AtomicString& data, const AtomicString& namespaceURI) : m_kind(kind), m_data(data), m_namespaceURI(namespaceURI) { }
#if COMPILER(MSVC)
NodeTest(const NodeTest&);
void operator=(const NodeTest&);
NodeTest(NodeTest&& other)
: m_kind(other.m_kind)
, m_data(WTF::move(other.m_data))
, m_namespaceURI(WTF::move(other.m_namespaceURI))
, m_mergedPredicates(WTF::move(other.m_mergedPredicates))
{
}
NodeTest& operator=(NodeTest&& other)
{
m_kind = other.m_kind;
m_data = WTF::move(other.m_data);
m_namespaceURI = WTF::move(other.m_namespaceURI);
m_mergedPredicates = WTF::move(other.m_mergedPredicates);
return *this;
}
#endif
private:
friend class Step;
friend void optimizeStepPair(Step&, Step&, bool&);
friend bool nodeMatchesBasicTest(Node&, Axis, const NodeTest&);
friend bool nodeMatches(Node&, Axis, const NodeTest&);
Kind m_kind;
AtomicString m_data;
AtomicString m_namespaceURI;
Vector<std::unique_ptr<Expression>> m_mergedPredicates;
};
Step(Axis, NodeTest);
Step(Axis, NodeTest, Vector<std::unique_ptr<Expression>>);
~Step();
void optimize();
void evaluate(Node& context, NodeSet&) const;
Axis axis() const { return m_axis; }
private:
friend void optimizeStepPair(Step&, Step&, bool&);
bool predicatesAreContextListInsensitive() const;
void parseNodeTest(const String&);
void nodesInAxis(Node& context, NodeSet&) const;
Axis m_axis;
NodeTest m_nodeTest;
Vector<std::unique_ptr<Expression>> m_predicates;
};
void optimizeStepPair(Step&, Step&, bool& dropSecondStep);
}
}
#endif // XPathStep_h