diff options
Diffstat (limited to 'dom/xslt/xpath/txExpr.h')
-rw-r--r-- | dom/xslt/xpath/txExpr.h | 847 |
1 files changed, 847 insertions, 0 deletions
diff --git a/dom/xslt/xpath/txExpr.h b/dom/xslt/xpath/txExpr.h new file mode 100644 index 0000000000..2622a3fe9f --- /dev/null +++ b/dom/xslt/xpath/txExpr.h @@ -0,0 +1,847 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "mozilla/UniquePtr.h" +#include "txExprResult.h" +#include "txCore.h" +#include "nsString.h" +#include "txOwningArray.h" +#include "nsAtom.h" + +#ifdef DEBUG +# define TX_TO_STRING +#endif + +/* + XPath class definitions. + Much of this code was ported from XSL:P. +*/ + +class nsAtom; +class txIMatchContext; +class txIEvalContext; +class txNodeSet; +class txXPathNode; +class txXPathTreeWalker; + +/** + * A Base Class for all XSL Expressions + **/ +class Expr { + public: + MOZ_COUNTED_DEFAULT_CTOR(Expr) + MOZ_COUNTED_DTOR_VIRTUAL(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. + */ + using ResultType = uint16_t; + 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; + } + + using ContextSensitivity = uint16_t; + 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_APPENDNAME void appendName(nsAString& aDest) override; +#else +# define TX_DECL_TOSTRING +# define TX_DECL_APPENDNAME +#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_APPENDNAME \ + 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) { \ + MOZ_ASSERT_UNREACHABLE("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.get(); \ + } \ + return nullptr; \ + } \ + void _class::setSubExprAt(uint32_t aPos, Expr* aExpr) { \ + NS_ASSERTION(aPos < 1, "setting bad subexpression index"); \ + mozilla::Unused << _Expr1.release(); \ + _Expr1 = mozilla::WrapUnique(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.get(); \ + case 1: \ + return _Expr2.get(); \ + default: \ + break; \ + } \ + return nullptr; \ + } \ + void _class::setSubExprAt(uint32_t aPos, Expr* aExpr) { \ + NS_ASSERTION(aPos < 2, "setting bad subexpression index"); \ + if (aPos == 0) { \ + mozilla::Unused << _Expr1.release(); \ + _Expr1 = mozilla::WrapUnique(aExpr); \ + } else { \ + mozilla::Unused << _Expr2.release(); \ + _Expr2 = mozilla::WrapUnique(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 + */ + void addParam(Expr* aExpr) { mParams.AppendElement(aExpr); } + + /** + * 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 + /* + * Appends the name of the function to `aStr`. + */ + virtual void appendName(nsAString& aStr) = 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(nsAtom* aName, eType& aType); + + private: + eType mType; +}; + +/* + * This class represents a NodeTest as defined by the XPath spec + */ +class txNodeTest { + public: + MOZ_COUNTED_DEFAULT_CTOR(txNodeTest) + MOZ_COUNTED_DTOR_VIRTUAL(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 nsresult matches(const txXPathNode& aNode, txIMatchContext* aContext, + bool& aMatched) = 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 \ + nsresult matches(const txXPathNode& aNode, txIMatchContext* aContext, \ + bool& aMatched) 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(nsAtom* aPrefix, nsAtom* aLocalName, int32_t aNSID, + uint16_t aNodeType); + + NodeTestType getType() override; + + TX_DECL_NODE_TEST + + RefPtr<nsAtom> mPrefix; + RefPtr<nsAtom> 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; + RefPtr<nsAtom> 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: + mozilla::UniquePtr<txNodeTest> mNodeTest; + mozilla::UniquePtr<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 + */ + void add(Expr* aExpr) { + NS_ASSERTION(aExpr, "missing expression"); + mPredicates.AppendElement(aExpr); + } + + 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.get(); } + void setNodeTest(txNodeTest* aNodeTest) { + mozilla::Unused << mNodeTest.release(); + mNodeTest = mozilla::WrapUnique(aNodeTest); + } + LocationStepType getAxisIdentifier() { return mAxisIdentifier; } + void setAxisIdentifier(LocationStepType aAxisIdentifier) { + mAxisIdentifier = aAxisIdentifier; + } + + private: + /** + * Append the current position of aWalker to aNodes if it matches mNodeTest, + * using aContext as the context for matching. + */ + nsresult appendIfMatching(const txXPathTreeWalker& aWalker, + txIMatchContext* aContext, txNodeSet* aNodes); + + /** + * Append the descendants of the current position of aWalker to aNodes if + * they match mNodeTest, using aContext as the context for matching. + */ + nsresult appendMatchingDescendants(const txXPathTreeWalker& aWalker, + txIMatchContext* aContext, + txNodeSet* aNodes); + + /** + * Append the descendants of the current position of aWalker to aNodes in + * reverse order if they match mNodeTest, using aContext as the context for + * matching. + */ + nsresult appendMatchingDescendantsRev(const txXPathTreeWalker& aWalker, + txIMatchContext* aContext, + txNodeSet* aNodes); + + mozilla::UniquePtr<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: + mozilla::UniquePtr<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: + mozilla::UniquePtr<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: + mozilla::UniquePtr<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: + mozilla::UniquePtr<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); + + mozilla::UniquePtr<Expr> mLeftExpr; + mozilla::UniquePtr<Expr> mRightExpr; + RelationalExprType mOp; +}; + +/** + * VariableRefExpr + * Represents a variable reference ($refname) + **/ +class VariableRefExpr : public Expr { + public: + VariableRefExpr(nsAtom* aPrefix, nsAtom* aLocalName, int32_t aNSID); + + TX_DECL_EXPR + + private: + RefPtr<nsAtom> mPrefix; + RefPtr<nsAtom> 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 + */ + void 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: + mozilla::UniquePtr<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 + */ + void addExpr(Expr* aExpr) { mExpressions.AppendElement(aExpr); } + + /** + * 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, nsAtom* aPrefix, nsAtom* aLocalName); + + TX_DECL_EXPR + + private: + int32_t mNamespace; + RefPtr<nsAtom> mPrefix; + RefPtr<nsAtom> mLocalName; +}; + +/** + * + */ +class txUnionNodeTest : public txNodeTest { + public: + void addNodeTest(txNodeTest* aNodeTest) { + mNodeTests.AppendElement(aNodeTest); + } + + 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 |