summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xpath/txExpr.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xpath/txExpr.h')
-rw-r--r--dom/xslt/xpath/txExpr.h1004
1 files changed, 1004 insertions, 0 deletions
diff --git a/dom/xslt/xpath/txExpr.h b/dom/xslt/xpath/txExpr.h
new file mode 100644
index 000000000..562fca7a3
--- /dev/null
+++ b/dom/xslt/xpath/txExpr.h
@@ -0,0 +1,1004 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef TRANSFRMX_EXPR_H
+#define TRANSFRMX_EXPR_H
+
+#include "mozilla/Attributes.h"
+#include "nsAutoPtr.h"
+#include "txExprResult.h"
+#include "txCore.h"
+#include "nsString.h"
+#include "txOwningArray.h"
+#include "nsIAtom.h"
+
+#ifdef DEBUG
+#define TX_TO_STRING
+#endif
+
+/*
+ XPath class definitions.
+ Much of this code was ported from XSL:P.
+*/
+
+class nsIAtom;
+class txIMatchContext;
+class txIEvalContext;
+class txNodeSet;
+class txXPathNode;
+
+/**
+ * A Base Class for all XSL Expressions
+**/
+class Expr
+{
+public:
+ Expr()
+ {
+ MOZ_COUNT_CTOR(Expr);
+ }
+ virtual ~Expr()
+ {
+ MOZ_COUNT_DTOR(Expr);
+ }
+
+ /**
+ * Evaluates this Expr based on the given context node and processor state
+ * @param context the context node for evaluation of this Expr
+ * @param ps the ContextState containing the stack information needed
+ * for evaluation
+ * @return the result of the evaluation
+ **/
+ virtual nsresult evaluate(txIEvalContext* aContext,
+ txAExprResult** aResult) = 0;
+
+
+ /**
+ * Returns the type of this expression.
+ */
+ enum ExprType {
+ LOCATIONSTEP_EXPR,
+ PATH_EXPR,
+ UNION_EXPR,
+ LITERAL_EXPR,
+ OTHER_EXPR
+ };
+ virtual ExprType getType()
+ {
+ return OTHER_EXPR;
+ }
+
+ /**
+ * Returns the type or types of results this Expr return.
+ */
+ typedef uint16_t ResultType;
+ enum {
+ NODESET_RESULT = 0x01,
+ BOOLEAN_RESULT = 0x02,
+ NUMBER_RESULT = 0x04,
+ STRING_RESULT = 0x08,
+ RTF_RESULT = 0x10,
+ ANY_RESULT = 0xFFFF
+ };
+ virtual ResultType getReturnType() = 0;
+ bool canReturnType(ResultType aType)
+ {
+ return (getReturnType() & aType) != 0;
+ }
+
+ typedef uint16_t ContextSensitivity;
+ enum {
+ NO_CONTEXT = 0x00,
+ NODE_CONTEXT = 0x01,
+ POSITION_CONTEXT = 0x02,
+ SIZE_CONTEXT = 0x04,
+ NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
+ VARIABLES_CONTEXT = 0x08,
+ PRIVATE_CONTEXT = 0x10,
+ ANY_CONTEXT = 0xFFFF
+ };
+
+ /**
+ * Returns true if this expression is sensitive to *any* of
+ * the requested contexts in aContexts.
+ */
+ virtual bool isSensitiveTo(ContextSensitivity aContexts) = 0;
+
+ /**
+ * Returns sub-expression at given position
+ */
+ virtual Expr* getSubExprAt(uint32_t aPos) = 0;
+
+ /**
+ * Replace sub-expression at given position. Does not delete the old
+ * expression, that is the responsibility of the caller.
+ */
+ virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
+
+ virtual nsresult evaluateToBool(txIEvalContext* aContext,
+ bool& aResult);
+
+ virtual nsresult evaluateToString(txIEvalContext* aContext,
+ nsString& aResult);
+
+#ifdef TX_TO_STRING
+ /**
+ * Returns the String representation of this Expr.
+ * @param dest the String to use when creating the String
+ * representation. The String representation will be appended to
+ * any data in the destination String, to allow cascading calls to
+ * other #toString() methods for Expressions.
+ * @return the String representation of this Expr.
+ **/
+ virtual void toString(nsAString& str) = 0;
+#endif
+}; //-- Expr
+
+#ifdef TX_TO_STRING
+#define TX_DECL_TOSTRING \
+ void toString(nsAString& aDest) override;
+#define TX_DECL_GETNAMEATOM \
+ nsresult getNameAtom(nsIAtom** aAtom) override;
+#else
+#define TX_DECL_TOSTRING
+#define TX_DECL_GETNAMEATOM
+#endif
+
+#define TX_DECL_EXPR_BASE \
+ nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult) override; \
+ ResultType getReturnType() override; \
+ bool isSensitiveTo(ContextSensitivity aContexts) override;
+
+#define TX_DECL_EXPR \
+ TX_DECL_EXPR_BASE \
+ TX_DECL_TOSTRING \
+ Expr* getSubExprAt(uint32_t aPos) override; \
+ void setSubExprAt(uint32_t aPos, Expr* aExpr) override;
+
+#define TX_DECL_OPTIMIZABLE_EXPR \
+ TX_DECL_EXPR \
+ ExprType getType() override;
+
+#define TX_DECL_FUNCTION \
+ TX_DECL_GETNAMEATOM \
+ TX_DECL_EXPR_BASE
+
+#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
+Expr::ResultType \
+_class::getReturnType() \
+{ \
+ return _ReturnType; \
+}
+
+#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType) \
+TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
+Expr* \
+_class::getSubExprAt(uint32_t aPos) \
+{ \
+ return nullptr; \
+} \
+void \
+_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
+{ \
+ NS_NOTREACHED("setting bad subexpression index"); \
+}
+
+#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1) \
+TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
+Expr* \
+_class::getSubExprAt(uint32_t aPos) \
+{ \
+ if (aPos == 0) { \
+ return _Expr1; \
+ } \
+ return nullptr; \
+} \
+void \
+_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
+{ \
+ NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
+ _Expr1.forget(); \
+ _Expr1 = aExpr; \
+}
+
+#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
+TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
+Expr* \
+_class::getSubExprAt(uint32_t aPos) \
+{ \
+ switch(aPos) { \
+ case 0: \
+ return _Expr1; \
+ case 1: \
+ return _Expr2; \
+ default: \
+ break; \
+ } \
+ return nullptr; \
+} \
+void \
+_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
+{ \
+ NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
+ if (aPos == 0) { \
+ _Expr1.forget(); \
+ _Expr1 = aExpr; \
+ } \
+ else { \
+ _Expr2.forget(); \
+ _Expr2 = aExpr; \
+ } \
+}
+
+#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
+TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
+Expr* \
+_class::getSubExprAt(uint32_t aPos) \
+{ \
+ return _ExprList.SafeElementAt(aPos); \
+} \
+void \
+_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
+{ \
+ NS_ASSERTION(aPos < _ExprList.Length(), \
+ "setting bad subexpression index"); \
+ _ExprList[aPos] = aExpr; \
+}
+
+
+/**
+ * This class represents a FunctionCall as defined by the XPath 1.0
+ * Recommendation.
+**/
+class FunctionCall : public Expr
+{
+public:
+ /**
+ * Adds the given parameter to this FunctionCall's parameter list.
+ * The ownership of the given Expr is passed over to the FunctionCall,
+ * even on failure.
+ * @param aExpr the Expr to add to this FunctionCall's parameter list
+ * @return nsresult indicating out of memory
+ */
+ nsresult addParam(Expr* aExpr)
+ {
+ return mParams.AppendElement(aExpr) ?
+ NS_OK : NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ /**
+ * Check if the number of parameters falls within a range.
+ *
+ * @param aParamCountMin minimum number of required parameters.
+ * @param aParamCountMax maximum number of parameters. If aParamCountMax
+ * is negative the maximum number is not checked.
+ * @return boolean representing whether the number of parameters falls
+ * within the expected range or not.
+ *
+ * XXX txIEvalContext should be txIParseContest, bug 143291
+ */
+ virtual bool requireParams(int32_t aParamCountMin,
+ int32_t aParamCountMax,
+ txIEvalContext* aContext);
+
+ TX_DECL_TOSTRING
+ Expr* getSubExprAt(uint32_t aPos) override;
+ void setSubExprAt(uint32_t aPos, Expr* aExpr) override;
+
+protected:
+
+ txOwningArray<Expr> mParams;
+
+ /*
+ * Evaluates the given Expression and converts its result to a number.
+ */
+ static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
+ double* aResult);
+
+ /*
+ * Evaluates the given Expression and converts its result to a NodeSet.
+ * If the result is not a NodeSet an error is returned.
+ */
+ static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
+ txNodeSet** aResult);
+
+ /**
+ * Returns true if any argument is sensitive to the given context.
+ */
+ bool argsSensitiveTo(ContextSensitivity aContexts);
+
+
+#ifdef TX_TO_STRING
+ /*
+ * Returns the name of the function as an atom.
+ */
+ virtual nsresult getNameAtom(nsIAtom** aAtom) = 0;
+#endif
+};
+
+class txCoreFunctionCall : public FunctionCall
+{
+public:
+
+ // This must be ordered in the same order as descriptTable in
+ // txCoreFunctionCall.cpp. If you change one, change the other.
+ enum eType {
+ COUNT = 0, // count()
+ ID, // id()
+ LAST, // last()
+ LOCAL_NAME, // local-name()
+ NAMESPACE_URI, // namespace-uri()
+ NAME, // name()
+ POSITION, // position()
+
+ CONCAT, // concat()
+ CONTAINS, // contains()
+ NORMALIZE_SPACE, // normalize-space()
+ STARTS_WITH, // starts-with()
+ STRING, // string()
+ STRING_LENGTH, // string-length()
+ SUBSTRING, // substring()
+ SUBSTRING_AFTER, // substring-after()
+ SUBSTRING_BEFORE, // substring-before()
+ TRANSLATE, // translate()
+
+ NUMBER, // number()
+ ROUND, // round()
+ FLOOR, // floor()
+ CEILING, // ceiling()
+ SUM, // sum()
+
+ BOOLEAN, // boolean()
+ _FALSE, // false()
+ LANG, // lang()
+ _NOT, // not()
+ _TRUE // true()
+ };
+
+ /*
+ * Creates a txCoreFunctionCall of the given type
+ */
+ explicit txCoreFunctionCall(eType aType) : mType(aType)
+ {
+ }
+
+ TX_DECL_FUNCTION
+
+ static bool getTypeFromAtom(nsIAtom* aName, eType& aType);
+
+private:
+ eType mType;
+};
+
+
+/*
+ * This class represents a NodeTest as defined by the XPath spec
+ */
+class txNodeTest
+{
+public:
+ txNodeTest()
+ {
+ MOZ_COUNT_CTOR(txNodeTest);
+ }
+ virtual ~txNodeTest()
+ {
+ MOZ_COUNT_DTOR(txNodeTest);
+ }
+
+ /*
+ * Virtual methods
+ * pretty much a txPattern, but not supposed to be used
+ * standalone. The NodeTest node() is different to the
+ * Pattern "node()" (document node isn't matched)
+ */
+ virtual bool matches(const txXPathNode& aNode,
+ txIMatchContext* aContext) = 0;
+ virtual double getDefaultPriority() = 0;
+
+ /**
+ * Returns the type of this nodetest.
+ */
+ enum NodeTestType {
+ NAME_TEST,
+ NODETYPE_TEST,
+ OTHER_TEST
+ };
+ virtual NodeTestType getType()
+ {
+ return OTHER_TEST;
+ }
+
+ /**
+ * Returns true if this expression is sensitive to *any* of
+ * the requested flags.
+ */
+ virtual bool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
+
+#ifdef TX_TO_STRING
+ virtual void toString(nsAString& aDest) = 0;
+#endif
+};
+
+#define TX_DECL_NODE_TEST \
+ TX_DECL_TOSTRING \
+ bool matches(const txXPathNode& aNode, txIMatchContext* aContext) override; \
+ double getDefaultPriority() override; \
+ bool isSensitiveTo(Expr::ContextSensitivity aContext) override;
+
+/*
+ * This class represents a NameTest as defined by the XPath spec
+ */
+class txNameTest : public txNodeTest
+{
+public:
+ /*
+ * Creates a new txNameTest with the given type and the given
+ * principal node type
+ */
+ txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID,
+ uint16_t aNodeType);
+
+ NodeTestType getType() override;
+
+ TX_DECL_NODE_TEST
+
+ nsCOMPtr<nsIAtom> mPrefix;
+ nsCOMPtr<nsIAtom> mLocalName;
+ int32_t mNamespace;
+private:
+ uint16_t mNodeType;
+};
+
+/*
+ * This class represents a NodeType as defined by the XPath spec
+ */
+class txNodeTypeTest : public txNodeTest
+{
+public:
+ enum NodeType {
+ COMMENT_TYPE,
+ TEXT_TYPE,
+ PI_TYPE,
+ NODE_TYPE
+ };
+
+ /*
+ * Creates a new txNodeTypeTest of the given type
+ */
+ explicit txNodeTypeTest(NodeType aNodeType)
+ : mNodeType(aNodeType)
+ {
+ }
+
+ /*
+ * Sets the name of the node to match. Only availible for pi nodes
+ */
+ void setNodeName(const nsAString& aName)
+ {
+ mNodeName = NS_Atomize(aName);
+ }
+
+ NodeType getNodeTestType()
+ {
+ return mNodeType;
+ }
+
+ NodeTestType getType() override;
+
+ TX_DECL_NODE_TEST
+
+private:
+ NodeType mNodeType;
+ nsCOMPtr<nsIAtom> mNodeName;
+};
+
+/**
+ * Class representing a nodetest combined with a predicate. May only be used
+ * if the predicate is not sensitive to the context-nodelist.
+ */
+class txPredicatedNodeTest : public txNodeTest
+{
+public:
+ txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
+ TX_DECL_NODE_TEST
+
+private:
+ nsAutoPtr<txNodeTest> mNodeTest;
+ nsAutoPtr<Expr> mPredicate;
+};
+
+/**
+ * Represents an ordered list of Predicates,
+ * for use with Step and Filter Expressions
+**/
+class PredicateList {
+public:
+ /**
+ * Adds the given Expr to the list.
+ * The ownership of the given Expr is passed over the PredicateList,
+ * even on failure.
+ * @param aExpr the Expr to add to the list
+ * @return nsresult indicating out of memory
+ */
+ nsresult add(Expr* aExpr)
+ {
+ NS_ASSERTION(aExpr, "missing expression");
+ return mPredicates.AppendElement(aExpr) ?
+ NS_OK : NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
+
+ /**
+ * Drops the first predicate without deleting it.
+ */
+ void dropFirst()
+ {
+ mPredicates.RemoveElementAt(0);
+ }
+
+ /**
+ * returns true if this predicate list is empty
+ **/
+ bool isEmpty()
+ {
+ return mPredicates.IsEmpty();
+ }
+
+#ifdef TX_TO_STRING
+ /**
+ * Returns the String representation of this PredicateList.
+ * @param dest the String to use when creating the String
+ * representation. The String representation will be appended to
+ * any data in the destination String, to allow cascading calls to
+ * other #toString() methods for Expressions.
+ * @return the String representation of this PredicateList.
+ **/
+ void toString(nsAString& dest);
+#endif
+
+protected:
+ bool isSensitiveTo(Expr::ContextSensitivity aContext);
+ Expr* getSubExprAt(uint32_t aPos)
+ {
+ return mPredicates.SafeElementAt(aPos);
+ }
+ void setSubExprAt(uint32_t aPos, Expr* aExpr)
+ {
+ NS_ASSERTION(aPos < mPredicates.Length(),
+ "setting bad subexpression index");
+ mPredicates[aPos] = aExpr;
+ }
+
+ //-- list of predicates
+ txOwningArray<Expr> mPredicates;
+}; //-- PredicateList
+
+class LocationStep : public Expr,
+ public PredicateList
+{
+public:
+ enum LocationStepType {
+ ANCESTOR_AXIS = 0,
+ ANCESTOR_OR_SELF_AXIS,
+ ATTRIBUTE_AXIS,
+ CHILD_AXIS,
+ DESCENDANT_AXIS,
+ DESCENDANT_OR_SELF_AXIS,
+ FOLLOWING_AXIS,
+ FOLLOWING_SIBLING_AXIS,
+ NAMESPACE_AXIS,
+ PARENT_AXIS,
+ PRECEDING_AXIS,
+ PRECEDING_SIBLING_AXIS,
+ SELF_AXIS
+ };
+
+ /**
+ * Creates a new LocationStep using the given NodeExpr and Axis Identifier
+ * @param nodeExpr the NodeExpr to use when matching Nodes
+ * @param axisIdentifier the Axis Identifier in which to search for nodes
+ **/
+ LocationStep(txNodeTest* aNodeTest,
+ LocationStepType aAxisIdentifier)
+ : mNodeTest(aNodeTest),
+ mAxisIdentifier(aAxisIdentifier)
+ {
+ }
+
+ TX_DECL_OPTIMIZABLE_EXPR
+
+ txNodeTest* getNodeTest()
+ {
+ return mNodeTest;
+ }
+ void setNodeTest(txNodeTest* aNodeTest)
+ {
+ mNodeTest.forget();
+ mNodeTest = aNodeTest;
+ }
+ LocationStepType getAxisIdentifier()
+ {
+ return mAxisIdentifier;
+ }
+ void setAxisIdentifier(LocationStepType aAxisIdentifier)
+ {
+ mAxisIdentifier = aAxisIdentifier;
+ }
+
+private:
+ void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
+ txNodeSet* aNodes);
+ void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs,
+ txNodeSet* aNodes);
+
+ nsAutoPtr<txNodeTest> mNodeTest;
+ LocationStepType mAxisIdentifier;
+};
+
+class FilterExpr : public Expr,
+ public PredicateList
+{
+public:
+
+ /**
+ * Creates a new FilterExpr using the given Expr
+ * @param expr the Expr to use for evaluation
+ */
+ explicit FilterExpr(Expr* aExpr)
+ : expr(aExpr)
+ {
+ }
+
+ TX_DECL_EXPR
+
+private:
+ nsAutoPtr<Expr> expr;
+
+}; //-- FilterExpr
+
+
+class txLiteralExpr : public Expr {
+public:
+ explicit txLiteralExpr(double aDbl)
+ : mValue(new NumberResult(aDbl, nullptr))
+ {
+ }
+ explicit txLiteralExpr(const nsAString& aStr)
+ : mValue(new StringResult(aStr, nullptr))
+ {
+ }
+ explicit txLiteralExpr(txAExprResult* aValue)
+ : mValue(aValue)
+ {
+ }
+
+ TX_DECL_EXPR
+
+private:
+ RefPtr<txAExprResult> mValue;
+};
+
+/**
+ * Represents an UnaryExpr. Returns the negative value of its expr.
+**/
+class UnaryExpr : public Expr {
+
+public:
+
+ explicit UnaryExpr(Expr* aExpr)
+ : expr(aExpr)
+ {
+ }
+
+ TX_DECL_EXPR
+
+private:
+ nsAutoPtr<Expr> expr;
+}; //-- UnaryExpr
+
+/**
+ * Represents a BooleanExpr, a binary expression that
+ * performs a boolean operation between its lvalue and rvalue.
+**/
+class BooleanExpr : public Expr
+{
+public:
+
+ //-- BooleanExpr Types
+ enum _BooleanExprType { AND = 1, OR };
+
+ BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
+ : leftExpr(aLeftExpr),
+ rightExpr(aRightExpr),
+ op(aOp)
+ {
+ }
+
+ TX_DECL_EXPR
+
+private:
+ nsAutoPtr<Expr> leftExpr, rightExpr;
+ short op;
+}; //-- BooleanExpr
+
+/**
+ * Represents a MultiplicativeExpr, a binary expression that
+ * performs a multiplicative operation between its lvalue and rvalue:
+ * * : multiply
+ * mod : modulus
+ * div : divide
+ *
+**/
+class txNumberExpr : public Expr
+{
+public:
+
+ enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
+
+ txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
+ : mLeftExpr(aLeftExpr),
+ mRightExpr(aRightExpr),
+ mOp(aOp)
+ {
+ }
+
+ TX_DECL_EXPR
+
+private:
+ nsAutoPtr<Expr> mLeftExpr, mRightExpr;
+ eOp mOp;
+}; //-- MultiplicativeExpr
+
+/**
+ * Represents a RelationalExpr, an expression that compares its lvalue
+ * to its rvalue using:
+ * = : equal to
+ * < : less than
+ * > : greater than
+ * <= : less than or equal to
+ * >= : greater than or equal to
+ *
+**/
+class RelationalExpr : public Expr
+{
+public:
+ enum RelationalExprType {
+ EQUAL,
+ NOT_EQUAL,
+ LESS_THAN,
+ GREATER_THAN,
+ LESS_OR_EQUAL,
+ GREATER_OR_EQUAL
+ };
+
+ RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
+ : mLeftExpr(aLeftExpr),
+ mRightExpr(aRightExpr),
+ mOp(aOp)
+ {
+ }
+
+
+ TX_DECL_EXPR
+
+private:
+ bool compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
+ txAExprResult* aRight);
+
+ nsAutoPtr<Expr> mLeftExpr;
+ nsAutoPtr<Expr> mRightExpr;
+ RelationalExprType mOp;
+};
+
+/**
+ * VariableRefExpr
+ * Represents a variable reference ($refname)
+**/
+class VariableRefExpr : public Expr {
+
+public:
+
+ VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID);
+
+ TX_DECL_EXPR
+
+private:
+ nsCOMPtr<nsIAtom> mPrefix;
+ nsCOMPtr<nsIAtom> mLocalName;
+ int32_t mNamespace;
+};
+
+/**
+ * Represents a PathExpr
+**/
+class PathExpr : public Expr {
+
+public:
+
+ //-- Path Operators
+ //-- RELATIVE_OP is the default
+ //-- LF, changed from static const short to enum
+ enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
+
+ /**
+ * Adds the Expr to this PathExpr
+ * The ownership of the given Expr is passed over the PathExpr,
+ * even on failure.
+ * @param aExpr the Expr to add to this PathExpr
+ * @return nsresult indicating out of memory
+ */
+ nsresult addExpr(Expr* aExpr, PathOperator pathOp);
+
+ /**
+ * Removes and deletes the expression at the given index.
+ */
+ void deleteExprAt(uint32_t aPos)
+ {
+ NS_ASSERTION(aPos < mItems.Length(),
+ "killing bad expression index");
+ mItems.RemoveElementAt(aPos);
+ }
+
+ TX_DECL_OPTIMIZABLE_EXPR
+
+ PathOperator getPathOpAt(uint32_t aPos)
+ {
+ NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
+ return mItems[aPos].pathOp;
+ }
+ void setPathOpAt(uint32_t aPos, PathOperator aPathOp)
+ {
+ NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
+ mItems[aPos].pathOp = aPathOp;
+ }
+
+private:
+ class PathExprItem {
+ public:
+ nsAutoPtr<Expr> expr;
+ PathOperator pathOp;
+ };
+
+ nsTArray<PathExprItem> mItems;
+
+ /*
+ * Selects from the descendants of the context node
+ * all nodes that match the Expr
+ */
+ nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode,
+ txIMatchContext* aContext,
+ txNodeSet* resNodes);
+};
+
+/**
+ * This class represents a RootExpr, which only matches the Document node
+**/
+class RootExpr : public Expr {
+public:
+ /**
+ * Creates a new RootExpr
+ */
+ RootExpr()
+#ifdef TX_TO_STRING
+ : mSerialize(true)
+#endif
+ {
+ }
+
+ TX_DECL_EXPR
+
+#ifdef TX_TO_STRING
+public:
+ void setSerialize(bool aSerialize)
+ {
+ mSerialize = aSerialize;
+ }
+
+private:
+ // When a RootExpr is used in a PathExpr it shouldn't be serialized
+ bool mSerialize;
+#endif
+}; //-- RootExpr
+
+/**
+ * Represents a UnionExpr
+**/
+class UnionExpr : public Expr {
+public:
+ /**
+ * Adds the PathExpr to this UnionExpr
+ * The ownership of the given Expr is passed over the UnionExpr,
+ * even on failure.
+ * @param aExpr the Expr to add to this UnionExpr
+ * @return nsresult indicating out of memory
+ */
+ nsresult addExpr(Expr* aExpr)
+ {
+ return mExpressions.AppendElement(aExpr) ?
+ NS_OK : NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ /**
+ * Removes and deletes the expression at the given index.
+ */
+ void deleteExprAt(uint32_t aPos)
+ {
+ NS_ASSERTION(aPos < mExpressions.Length(),
+ "killing bad expression index");
+
+ delete mExpressions[aPos];
+ mExpressions.RemoveElementAt(aPos);
+ }
+
+ TX_DECL_OPTIMIZABLE_EXPR
+
+private:
+
+ txOwningArray<Expr> mExpressions;
+
+}; //-- UnionExpr
+
+/**
+ * Class specializing in executing expressions like "@foo" where we are
+ * interested in different result-types, and expressions like "@foo = 'hi'"
+ */
+class txNamedAttributeStep : public Expr
+{
+public:
+ txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix,
+ nsIAtom* aLocalName);
+
+ TX_DECL_EXPR
+
+private:
+ int32_t mNamespace;
+ nsCOMPtr<nsIAtom> mPrefix;
+ nsCOMPtr<nsIAtom> mLocalName;
+};
+
+/**
+ *
+ */
+class txUnionNodeTest : public txNodeTest
+{
+public:
+ nsresult addNodeTest(txNodeTest* aNodeTest)
+ {
+ return mNodeTests.AppendElement(aNodeTest) ?
+ NS_OK : NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ TX_DECL_NODE_TEST
+
+private:
+ txOwningArray<txNodeTest> mNodeTests;
+};
+
+/**
+ * Expression that failed to parse
+ */
+class txErrorExpr : public Expr
+{
+public:
+#ifdef TX_TO_STRING
+ explicit txErrorExpr(const nsAString& aStr)
+ : mStr(aStr)
+ {
+ }
+#endif
+
+ TX_DECL_EXPR
+
+#ifdef TX_TO_STRING
+private:
+ nsString mStr;
+#endif
+};
+
+#endif
+
+