1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/xslt/xpath/txExpr.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1006 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef TRANSFRMX_EXPR_H 1.10 +#define TRANSFRMX_EXPR_H 1.11 + 1.12 +#include "mozilla/Attributes.h" 1.13 +#include "nsAutoPtr.h" 1.14 +#include "txExprResult.h" 1.15 +#include "txCore.h" 1.16 +#include "nsString.h" 1.17 +#include "txOwningArray.h" 1.18 +#include "nsIAtom.h" 1.19 + 1.20 +#ifdef DEBUG 1.21 +#define TX_TO_STRING 1.22 +#endif 1.23 + 1.24 +/* 1.25 + XPath class definitions. 1.26 + Much of this code was ported from XSL:P. 1.27 +*/ 1.28 + 1.29 +class nsIAtom; 1.30 +class txIParseContext; 1.31 +class txIMatchContext; 1.32 +class txIEvalContext; 1.33 +class txNodeSet; 1.34 +class txXPathNode; 1.35 + 1.36 +/** 1.37 + * A Base Class for all XSL Expressions 1.38 +**/ 1.39 +class Expr 1.40 +{ 1.41 +public: 1.42 + Expr() 1.43 + { 1.44 + MOZ_COUNT_CTOR(Expr); 1.45 + } 1.46 + virtual ~Expr() 1.47 + { 1.48 + MOZ_COUNT_DTOR(Expr); 1.49 + } 1.50 + 1.51 + /** 1.52 + * Evaluates this Expr based on the given context node and processor state 1.53 + * @param context the context node for evaluation of this Expr 1.54 + * @param ps the ContextState containing the stack information needed 1.55 + * for evaluation 1.56 + * @return the result of the evaluation 1.57 + **/ 1.58 + virtual nsresult evaluate(txIEvalContext* aContext, 1.59 + txAExprResult** aResult) = 0; 1.60 + 1.61 + 1.62 + /** 1.63 + * Returns the type of this expression. 1.64 + */ 1.65 + enum ExprType { 1.66 + LOCATIONSTEP_EXPR, 1.67 + PATH_EXPR, 1.68 + UNION_EXPR, 1.69 + LITERAL_EXPR, 1.70 + OTHER_EXPR 1.71 + }; 1.72 + virtual ExprType getType() 1.73 + { 1.74 + return OTHER_EXPR; 1.75 + } 1.76 + 1.77 + /** 1.78 + * Returns the type or types of results this Expr return. 1.79 + */ 1.80 + typedef uint16_t ResultType; 1.81 + enum { 1.82 + NODESET_RESULT = 0x01, 1.83 + BOOLEAN_RESULT = 0x02, 1.84 + NUMBER_RESULT = 0x04, 1.85 + STRING_RESULT = 0x08, 1.86 + RTF_RESULT = 0x10, 1.87 + ANY_RESULT = 0xFFFF 1.88 + }; 1.89 + virtual ResultType getReturnType() = 0; 1.90 + bool canReturnType(ResultType aType) 1.91 + { 1.92 + return (getReturnType() & aType) != 0; 1.93 + } 1.94 + 1.95 + typedef uint16_t ContextSensitivity; 1.96 + enum { 1.97 + NO_CONTEXT = 0x00, 1.98 + NODE_CONTEXT = 0x01, 1.99 + POSITION_CONTEXT = 0x02, 1.100 + SIZE_CONTEXT = 0x04, 1.101 + NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT, 1.102 + VARIABLES_CONTEXT = 0x08, 1.103 + PRIVATE_CONTEXT = 0x10, 1.104 + ANY_CONTEXT = 0xFFFF 1.105 + }; 1.106 + 1.107 + /** 1.108 + * Returns true if this expression is sensitive to *any* of 1.109 + * the requested contexts in aContexts. 1.110 + */ 1.111 + virtual bool isSensitiveTo(ContextSensitivity aContexts) = 0; 1.112 + 1.113 + /** 1.114 + * Returns sub-expression at given position 1.115 + */ 1.116 + virtual Expr* getSubExprAt(uint32_t aPos) = 0; 1.117 + 1.118 + /** 1.119 + * Replace sub-expression at given position. Does not delete the old 1.120 + * expression, that is the responsibility of the caller. 1.121 + */ 1.122 + virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0; 1.123 + 1.124 + virtual nsresult evaluateToBool(txIEvalContext* aContext, 1.125 + bool& aResult); 1.126 + 1.127 + virtual nsresult evaluateToString(txIEvalContext* aContext, 1.128 + nsString& aResult); 1.129 + 1.130 +#ifdef TX_TO_STRING 1.131 + /** 1.132 + * Returns the String representation of this Expr. 1.133 + * @param dest the String to use when creating the String 1.134 + * representation. The String representation will be appended to 1.135 + * any data in the destination String, to allow cascading calls to 1.136 + * other #toString() methods for Expressions. 1.137 + * @return the String representation of this Expr. 1.138 + **/ 1.139 + virtual void toString(nsAString& str) = 0; 1.140 +#endif 1.141 +}; //-- Expr 1.142 + 1.143 +#ifdef TX_TO_STRING 1.144 +#define TX_DECL_TOSTRING \ 1.145 + void toString(nsAString& aDest); 1.146 +#define TX_DECL_GETNAMEATOM \ 1.147 + nsresult getNameAtom(nsIAtom** aAtom); 1.148 +#else 1.149 +#define TX_DECL_TOSTRING 1.150 +#define TX_DECL_GETNAMEATOM 1.151 +#endif 1.152 + 1.153 +#define TX_DECL_EXPR_BASE \ 1.154 + nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \ 1.155 + ResultType getReturnType(); \ 1.156 + bool isSensitiveTo(ContextSensitivity aContexts); 1.157 + 1.158 +#define TX_DECL_EXPR \ 1.159 + TX_DECL_EXPR_BASE \ 1.160 + TX_DECL_TOSTRING \ 1.161 + Expr* getSubExprAt(uint32_t aPos); \ 1.162 + void setSubExprAt(uint32_t aPos, Expr* aExpr); 1.163 + 1.164 +#define TX_DECL_OPTIMIZABLE_EXPR \ 1.165 + TX_DECL_EXPR \ 1.166 + ExprType getType(); 1.167 + 1.168 + 1.169 +#define TX_DECL_FUNCTION \ 1.170 + TX_DECL_GETNAMEATOM \ 1.171 + TX_DECL_EXPR_BASE 1.172 + 1.173 +#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \ 1.174 +Expr::ResultType \ 1.175 +_class::getReturnType() \ 1.176 +{ \ 1.177 + return _ReturnType; \ 1.178 +} 1.179 + 1.180 +#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType) \ 1.181 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \ 1.182 +Expr* \ 1.183 +_class::getSubExprAt(uint32_t aPos) \ 1.184 +{ \ 1.185 + return nullptr; \ 1.186 +} \ 1.187 +void \ 1.188 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \ 1.189 +{ \ 1.190 + NS_NOTREACHED("setting bad subexpression index"); \ 1.191 +} 1.192 + 1.193 +#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1) \ 1.194 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \ 1.195 +Expr* \ 1.196 +_class::getSubExprAt(uint32_t aPos) \ 1.197 +{ \ 1.198 + if (aPos == 0) { \ 1.199 + return _Expr1; \ 1.200 + } \ 1.201 + return nullptr; \ 1.202 +} \ 1.203 +void \ 1.204 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \ 1.205 +{ \ 1.206 + NS_ASSERTION(aPos < 1, "setting bad subexpression index");\ 1.207 + _Expr1.forget(); \ 1.208 + _Expr1 = aExpr; \ 1.209 +} 1.210 + 1.211 +#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \ 1.212 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \ 1.213 +Expr* \ 1.214 +_class::getSubExprAt(uint32_t aPos) \ 1.215 +{ \ 1.216 + switch(aPos) { \ 1.217 + case 0: \ 1.218 + return _Expr1; \ 1.219 + case 1: \ 1.220 + return _Expr2; \ 1.221 + default: \ 1.222 + break; \ 1.223 + } \ 1.224 + return nullptr; \ 1.225 +} \ 1.226 +void \ 1.227 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \ 1.228 +{ \ 1.229 + NS_ASSERTION(aPos < 2, "setting bad subexpression index");\ 1.230 + if (aPos == 0) { \ 1.231 + _Expr1.forget(); \ 1.232 + _Expr1 = aExpr; \ 1.233 + } \ 1.234 + else { \ 1.235 + _Expr2.forget(); \ 1.236 + _Expr2 = aExpr; \ 1.237 + } \ 1.238 +} 1.239 + 1.240 +#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \ 1.241 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \ 1.242 +Expr* \ 1.243 +_class::getSubExprAt(uint32_t aPos) \ 1.244 +{ \ 1.245 + return _ExprList.SafeElementAt(aPos); \ 1.246 +} \ 1.247 +void \ 1.248 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr) \ 1.249 +{ \ 1.250 + NS_ASSERTION(aPos < _ExprList.Length(), \ 1.251 + "setting bad subexpression index"); \ 1.252 + _ExprList[aPos] = aExpr; \ 1.253 +} 1.254 + 1.255 + 1.256 +/** 1.257 + * This class represents a FunctionCall as defined by the XPath 1.0 1.258 + * Recommendation. 1.259 +**/ 1.260 +class FunctionCall : public Expr 1.261 +{ 1.262 +public: 1.263 + /** 1.264 + * Adds the given parameter to this FunctionCall's parameter list. 1.265 + * The ownership of the given Expr is passed over to the FunctionCall, 1.266 + * even on failure. 1.267 + * @param aExpr the Expr to add to this FunctionCall's parameter list 1.268 + * @return nsresult indicating out of memory 1.269 + */ 1.270 + nsresult addParam(Expr* aExpr) 1.271 + { 1.272 + return mParams.AppendElement(aExpr) ? 1.273 + NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.274 + } 1.275 + 1.276 + /** 1.277 + * Check if the number of parameters falls within a range. 1.278 + * 1.279 + * @param aParamCountMin minimum number of required parameters. 1.280 + * @param aParamCountMax maximum number of parameters. If aParamCountMax 1.281 + * is negative the maximum number is not checked. 1.282 + * @return boolean representing whether the number of parameters falls 1.283 + * within the expected range or not. 1.284 + * 1.285 + * XXX txIEvalContext should be txIParseContest, bug 143291 1.286 + */ 1.287 + virtual bool requireParams(int32_t aParamCountMin, 1.288 + int32_t aParamCountMax, 1.289 + txIEvalContext* aContext); 1.290 + 1.291 + TX_DECL_TOSTRING 1.292 + Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE; 1.293 + void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE; 1.294 + 1.295 +protected: 1.296 + 1.297 + txOwningArray<Expr> mParams; 1.298 + 1.299 + /* 1.300 + * Evaluates the given Expression and converts its result to a number. 1.301 + */ 1.302 + static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext, 1.303 + double* aResult); 1.304 + 1.305 + /* 1.306 + * Evaluates the given Expression and converts its result to a NodeSet. 1.307 + * If the result is not a NodeSet an error is returned. 1.308 + */ 1.309 + static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext, 1.310 + txNodeSet** aResult); 1.311 + 1.312 + /** 1.313 + * Returns true if any argument is sensitive to the given context. 1.314 + */ 1.315 + bool argsSensitiveTo(ContextSensitivity aContexts); 1.316 + 1.317 + 1.318 +#ifdef TX_TO_STRING 1.319 + /* 1.320 + * Returns the name of the function as an atom. 1.321 + */ 1.322 + virtual nsresult getNameAtom(nsIAtom** aAtom) = 0; 1.323 +#endif 1.324 +}; 1.325 + 1.326 +class txCoreFunctionCall : public FunctionCall 1.327 +{ 1.328 +public: 1.329 + 1.330 + // This must be ordered in the same order as descriptTable in 1.331 + // txCoreFunctionCall.cpp. If you change one, change the other. 1.332 + enum eType { 1.333 + COUNT = 0, // count() 1.334 + ID, // id() 1.335 + LAST, // last() 1.336 + LOCAL_NAME, // local-name() 1.337 + NAMESPACE_URI, // namespace-uri() 1.338 + NAME, // name() 1.339 + POSITION, // position() 1.340 + 1.341 + CONCAT, // concat() 1.342 + CONTAINS, // contains() 1.343 + NORMALIZE_SPACE, // normalize-space() 1.344 + STARTS_WITH, // starts-with() 1.345 + STRING, // string() 1.346 + STRING_LENGTH, // string-length() 1.347 + SUBSTRING, // substring() 1.348 + SUBSTRING_AFTER, // substring-after() 1.349 + SUBSTRING_BEFORE, // substring-before() 1.350 + TRANSLATE, // translate() 1.351 + 1.352 + NUMBER, // number() 1.353 + ROUND, // round() 1.354 + FLOOR, // floor() 1.355 + CEILING, // ceiling() 1.356 + SUM, // sum() 1.357 + 1.358 + BOOLEAN, // boolean() 1.359 + _FALSE, // false() 1.360 + LANG, // lang() 1.361 + _NOT, // not() 1.362 + _TRUE // true() 1.363 + }; 1.364 + 1.365 + /* 1.366 + * Creates a txCoreFunctionCall of the given type 1.367 + */ 1.368 + txCoreFunctionCall(eType aType) : mType(aType) 1.369 + { 1.370 + } 1.371 + 1.372 + TX_DECL_FUNCTION 1.373 + 1.374 + static bool getTypeFromAtom(nsIAtom* aName, eType& aType); 1.375 + 1.376 +private: 1.377 + eType mType; 1.378 +}; 1.379 + 1.380 + 1.381 +/* 1.382 + * This class represents a NodeTest as defined by the XPath spec 1.383 + */ 1.384 +class txNodeTest 1.385 +{ 1.386 +public: 1.387 + txNodeTest() 1.388 + { 1.389 + MOZ_COUNT_CTOR(txNodeTest); 1.390 + } 1.391 + virtual ~txNodeTest() 1.392 + { 1.393 + MOZ_COUNT_DTOR(txNodeTest); 1.394 + } 1.395 + 1.396 + /* 1.397 + * Virtual methods 1.398 + * pretty much a txPattern, but not supposed to be used 1.399 + * standalone. The NodeTest node() is different to the 1.400 + * Pattern "node()" (document node isn't matched) 1.401 + */ 1.402 + virtual bool matches(const txXPathNode& aNode, 1.403 + txIMatchContext* aContext) = 0; 1.404 + virtual double getDefaultPriority() = 0; 1.405 + 1.406 + /** 1.407 + * Returns the type of this nodetest. 1.408 + */ 1.409 + enum NodeTestType { 1.410 + NAME_TEST, 1.411 + NODETYPE_TEST, 1.412 + OTHER_TEST 1.413 + }; 1.414 + virtual NodeTestType getType() 1.415 + { 1.416 + return OTHER_TEST; 1.417 + } 1.418 + 1.419 + /** 1.420 + * Returns true if this expression is sensitive to *any* of 1.421 + * the requested flags. 1.422 + */ 1.423 + virtual bool isSensitiveTo(Expr::ContextSensitivity aContext) = 0; 1.424 + 1.425 +#ifdef TX_TO_STRING 1.426 + virtual void toString(nsAString& aDest) = 0; 1.427 +#endif 1.428 +}; 1.429 + 1.430 +#define TX_DECL_NODE_TEST \ 1.431 + TX_DECL_TOSTRING \ 1.432 + bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \ 1.433 + double getDefaultPriority(); \ 1.434 + bool isSensitiveTo(Expr::ContextSensitivity aContext); 1.435 + 1.436 +/* 1.437 + * This class represents a NameTest as defined by the XPath spec 1.438 + */ 1.439 +class txNameTest : public txNodeTest 1.440 +{ 1.441 +public: 1.442 + /* 1.443 + * Creates a new txNameTest with the given type and the given 1.444 + * principal node type 1.445 + */ 1.446 + txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID, 1.447 + uint16_t aNodeType); 1.448 + 1.449 + NodeTestType getType() MOZ_OVERRIDE; 1.450 + 1.451 + TX_DECL_NODE_TEST 1.452 + 1.453 + nsCOMPtr<nsIAtom> mPrefix; 1.454 + nsCOMPtr<nsIAtom> mLocalName; 1.455 + int32_t mNamespace; 1.456 +private: 1.457 + uint16_t mNodeType; 1.458 +}; 1.459 + 1.460 +/* 1.461 + * This class represents a NodeType as defined by the XPath spec 1.462 + */ 1.463 +class txNodeTypeTest : public txNodeTest 1.464 +{ 1.465 +public: 1.466 + enum NodeType { 1.467 + COMMENT_TYPE, 1.468 + TEXT_TYPE, 1.469 + PI_TYPE, 1.470 + NODE_TYPE 1.471 + }; 1.472 + 1.473 + /* 1.474 + * Creates a new txNodeTypeTest of the given type 1.475 + */ 1.476 + txNodeTypeTest(NodeType aNodeType) 1.477 + : mNodeType(aNodeType) 1.478 + { 1.479 + } 1.480 + 1.481 + /* 1.482 + * Sets the name of the node to match. Only availible for pi nodes 1.483 + */ 1.484 + void setNodeName(const nsAString& aName) 1.485 + { 1.486 + mNodeName = do_GetAtom(aName); 1.487 + } 1.488 + 1.489 + NodeType getNodeTestType() 1.490 + { 1.491 + return mNodeType; 1.492 + } 1.493 + 1.494 + NodeTestType getType() MOZ_OVERRIDE; 1.495 + 1.496 + TX_DECL_NODE_TEST 1.497 + 1.498 +private: 1.499 + NodeType mNodeType; 1.500 + nsCOMPtr<nsIAtom> mNodeName; 1.501 +}; 1.502 + 1.503 +/** 1.504 + * Class representing a nodetest combined with a predicate. May only be used 1.505 + * if the predicate is not sensitive to the context-nodelist. 1.506 + */ 1.507 +class txPredicatedNodeTest : public txNodeTest 1.508 +{ 1.509 +public: 1.510 + txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate); 1.511 + TX_DECL_NODE_TEST 1.512 + 1.513 +private: 1.514 + nsAutoPtr<txNodeTest> mNodeTest; 1.515 + nsAutoPtr<Expr> mPredicate; 1.516 +}; 1.517 + 1.518 +/** 1.519 + * Represents an ordered list of Predicates, 1.520 + * for use with Step and Filter Expressions 1.521 +**/ 1.522 +class PredicateList { 1.523 +public: 1.524 + /** 1.525 + * Adds the given Expr to the list. 1.526 + * The ownership of the given Expr is passed over the PredicateList, 1.527 + * even on failure. 1.528 + * @param aExpr the Expr to add to the list 1.529 + * @return nsresult indicating out of memory 1.530 + */ 1.531 + nsresult add(Expr* aExpr) 1.532 + { 1.533 + NS_ASSERTION(aExpr, "missing expression"); 1.534 + return mPredicates.AppendElement(aExpr) ? 1.535 + NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.536 + } 1.537 + 1.538 + nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext); 1.539 + 1.540 + /** 1.541 + * Drops the first predicate without deleting it. 1.542 + */ 1.543 + void dropFirst() 1.544 + { 1.545 + mPredicates.RemoveElementAt(0); 1.546 + } 1.547 + 1.548 + /** 1.549 + * returns true if this predicate list is empty 1.550 + **/ 1.551 + bool isEmpty() 1.552 + { 1.553 + return mPredicates.IsEmpty(); 1.554 + } 1.555 + 1.556 +#ifdef TX_TO_STRING 1.557 + /** 1.558 + * Returns the String representation of this PredicateList. 1.559 + * @param dest the String to use when creating the String 1.560 + * representation. The String representation will be appended to 1.561 + * any data in the destination String, to allow cascading calls to 1.562 + * other #toString() methods for Expressions. 1.563 + * @return the String representation of this PredicateList. 1.564 + **/ 1.565 + void toString(nsAString& dest); 1.566 +#endif 1.567 + 1.568 +protected: 1.569 + bool isSensitiveTo(Expr::ContextSensitivity aContext); 1.570 + Expr* getSubExprAt(uint32_t aPos) 1.571 + { 1.572 + return mPredicates.SafeElementAt(aPos); 1.573 + } 1.574 + void setSubExprAt(uint32_t aPos, Expr* aExpr) 1.575 + { 1.576 + NS_ASSERTION(aPos < mPredicates.Length(), 1.577 + "setting bad subexpression index"); 1.578 + mPredicates[aPos] = aExpr; 1.579 + } 1.580 + 1.581 + //-- list of predicates 1.582 + txOwningArray<Expr> mPredicates; 1.583 +}; //-- PredicateList 1.584 + 1.585 +class LocationStep : public Expr, 1.586 + public PredicateList 1.587 +{ 1.588 +public: 1.589 + enum LocationStepType { 1.590 + ANCESTOR_AXIS = 0, 1.591 + ANCESTOR_OR_SELF_AXIS, 1.592 + ATTRIBUTE_AXIS, 1.593 + CHILD_AXIS, 1.594 + DESCENDANT_AXIS, 1.595 + DESCENDANT_OR_SELF_AXIS, 1.596 + FOLLOWING_AXIS, 1.597 + FOLLOWING_SIBLING_AXIS, 1.598 + NAMESPACE_AXIS, 1.599 + PARENT_AXIS, 1.600 + PRECEDING_AXIS, 1.601 + PRECEDING_SIBLING_AXIS, 1.602 + SELF_AXIS 1.603 + }; 1.604 + 1.605 + /** 1.606 + * Creates a new LocationStep using the given NodeExpr and Axis Identifier 1.607 + * @param nodeExpr the NodeExpr to use when matching Nodes 1.608 + * @param axisIdentifier the Axis Identifier in which to search for nodes 1.609 + **/ 1.610 + LocationStep(txNodeTest* aNodeTest, 1.611 + LocationStepType aAxisIdentifier) 1.612 + : mNodeTest(aNodeTest), 1.613 + mAxisIdentifier(aAxisIdentifier) 1.614 + { 1.615 + } 1.616 + 1.617 + TX_DECL_OPTIMIZABLE_EXPR 1.618 + 1.619 + txNodeTest* getNodeTest() 1.620 + { 1.621 + return mNodeTest; 1.622 + } 1.623 + void setNodeTest(txNodeTest* aNodeTest) 1.624 + { 1.625 + mNodeTest.forget(); 1.626 + mNodeTest = aNodeTest; 1.627 + } 1.628 + LocationStepType getAxisIdentifier() 1.629 + { 1.630 + return mAxisIdentifier; 1.631 + } 1.632 + void setAxisIdentifier(LocationStepType aAxisIdentifier) 1.633 + { 1.634 + mAxisIdentifier = aAxisIdentifier; 1.635 + } 1.636 + 1.637 +private: 1.638 + void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs, 1.639 + txNodeSet* aNodes); 1.640 + void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs, 1.641 + txNodeSet* aNodes); 1.642 + 1.643 + nsAutoPtr<txNodeTest> mNodeTest; 1.644 + LocationStepType mAxisIdentifier; 1.645 +}; 1.646 + 1.647 +class FilterExpr : public Expr, 1.648 + public PredicateList 1.649 +{ 1.650 +public: 1.651 + 1.652 + /** 1.653 + * Creates a new FilterExpr using the given Expr 1.654 + * @param expr the Expr to use for evaluation 1.655 + */ 1.656 + FilterExpr(Expr* aExpr) 1.657 + : expr(aExpr) 1.658 + { 1.659 + } 1.660 + 1.661 + TX_DECL_EXPR 1.662 + 1.663 +private: 1.664 + nsAutoPtr<Expr> expr; 1.665 + 1.666 +}; //-- FilterExpr 1.667 + 1.668 + 1.669 +class txLiteralExpr : public Expr { 1.670 +public: 1.671 + txLiteralExpr(double aDbl) 1.672 + : mValue(new NumberResult(aDbl, nullptr)) 1.673 + { 1.674 + } 1.675 + txLiteralExpr(const nsAString& aStr) 1.676 + : mValue(new StringResult(aStr, nullptr)) 1.677 + { 1.678 + } 1.679 + txLiteralExpr(txAExprResult* aValue) 1.680 + : mValue(aValue) 1.681 + { 1.682 + } 1.683 + 1.684 + TX_DECL_EXPR 1.685 + 1.686 +private: 1.687 + nsRefPtr<txAExprResult> mValue; 1.688 +}; 1.689 + 1.690 +/** 1.691 + * Represents an UnaryExpr. Returns the negative value of its expr. 1.692 +**/ 1.693 +class UnaryExpr : public Expr { 1.694 + 1.695 +public: 1.696 + 1.697 + UnaryExpr(Expr* aExpr) 1.698 + : expr(aExpr) 1.699 + { 1.700 + } 1.701 + 1.702 + TX_DECL_EXPR 1.703 + 1.704 +private: 1.705 + nsAutoPtr<Expr> expr; 1.706 +}; //-- UnaryExpr 1.707 + 1.708 +/** 1.709 + * Represents a BooleanExpr, a binary expression that 1.710 + * performs a boolean operation between its lvalue and rvalue. 1.711 +**/ 1.712 +class BooleanExpr : public Expr 1.713 +{ 1.714 +public: 1.715 + 1.716 + //-- BooleanExpr Types 1.717 + enum _BooleanExprType { AND = 1, OR }; 1.718 + 1.719 + BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp) 1.720 + : leftExpr(aLeftExpr), 1.721 + rightExpr(aRightExpr), 1.722 + op(aOp) 1.723 + { 1.724 + } 1.725 + 1.726 + TX_DECL_EXPR 1.727 + 1.728 +private: 1.729 + nsAutoPtr<Expr> leftExpr, rightExpr; 1.730 + short op; 1.731 +}; //-- BooleanExpr 1.732 + 1.733 +/** 1.734 + * Represents a MultiplicativeExpr, a binary expression that 1.735 + * performs a multiplicative operation between its lvalue and rvalue: 1.736 + * * : multiply 1.737 + * mod : modulus 1.738 + * div : divide 1.739 + * 1.740 +**/ 1.741 +class txNumberExpr : public Expr 1.742 +{ 1.743 +public: 1.744 + 1.745 + enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS }; 1.746 + 1.747 + txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp) 1.748 + : mLeftExpr(aLeftExpr), 1.749 + mRightExpr(aRightExpr), 1.750 + mOp(aOp) 1.751 + { 1.752 + } 1.753 + 1.754 + TX_DECL_EXPR 1.755 + 1.756 +private: 1.757 + nsAutoPtr<Expr> mLeftExpr, mRightExpr; 1.758 + eOp mOp; 1.759 +}; //-- MultiplicativeExpr 1.760 + 1.761 +/** 1.762 + * Represents a RelationalExpr, an expression that compares its lvalue 1.763 + * to its rvalue using: 1.764 + * = : equal to 1.765 + * < : less than 1.766 + * > : greater than 1.767 + * <= : less than or equal to 1.768 + * >= : greater than or equal to 1.769 + * 1.770 +**/ 1.771 +class RelationalExpr : public Expr 1.772 +{ 1.773 +public: 1.774 + enum RelationalExprType { 1.775 + EQUAL, 1.776 + NOT_EQUAL, 1.777 + LESS_THAN, 1.778 + GREATER_THAN, 1.779 + LESS_OR_EQUAL, 1.780 + GREATER_OR_EQUAL 1.781 + }; 1.782 + 1.783 + RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp) 1.784 + : mLeftExpr(aLeftExpr), 1.785 + mRightExpr(aRightExpr), 1.786 + mOp(aOp) 1.787 + { 1.788 + } 1.789 + 1.790 + 1.791 + TX_DECL_EXPR 1.792 + 1.793 +private: 1.794 + bool compareResults(txIEvalContext* aContext, txAExprResult* aLeft, 1.795 + txAExprResult* aRight); 1.796 + 1.797 + nsAutoPtr<Expr> mLeftExpr; 1.798 + nsAutoPtr<Expr> mRightExpr; 1.799 + RelationalExprType mOp; 1.800 +}; 1.801 + 1.802 +/** 1.803 + * VariableRefExpr 1.804 + * Represents a variable reference ($refname) 1.805 +**/ 1.806 +class VariableRefExpr : public Expr { 1.807 + 1.808 +public: 1.809 + 1.810 + VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID); 1.811 + 1.812 + TX_DECL_EXPR 1.813 + 1.814 +private: 1.815 + nsCOMPtr<nsIAtom> mPrefix; 1.816 + nsCOMPtr<nsIAtom> mLocalName; 1.817 + int32_t mNamespace; 1.818 +}; 1.819 + 1.820 +/** 1.821 + * Represents a PathExpr 1.822 +**/ 1.823 +class PathExpr : public Expr { 1.824 + 1.825 +public: 1.826 + 1.827 + //-- Path Operators 1.828 + //-- RELATIVE_OP is the default 1.829 + //-- LF, changed from static const short to enum 1.830 + enum PathOperator { RELATIVE_OP, DESCENDANT_OP }; 1.831 + 1.832 + /** 1.833 + * Adds the Expr to this PathExpr 1.834 + * The ownership of the given Expr is passed over the PathExpr, 1.835 + * even on failure. 1.836 + * @param aExpr the Expr to add to this PathExpr 1.837 + * @return nsresult indicating out of memory 1.838 + */ 1.839 + nsresult addExpr(Expr* aExpr, PathOperator pathOp); 1.840 + 1.841 + /** 1.842 + * Removes and deletes the expression at the given index. 1.843 + */ 1.844 + void deleteExprAt(uint32_t aPos) 1.845 + { 1.846 + NS_ASSERTION(aPos < mItems.Length(), 1.847 + "killing bad expression index"); 1.848 + mItems.RemoveElementAt(aPos); 1.849 + } 1.850 + 1.851 + TX_DECL_OPTIMIZABLE_EXPR 1.852 + 1.853 + PathOperator getPathOpAt(uint32_t aPos) 1.854 + { 1.855 + NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index"); 1.856 + return mItems[aPos].pathOp; 1.857 + } 1.858 + void setPathOpAt(uint32_t aPos, PathOperator aPathOp) 1.859 + { 1.860 + NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index"); 1.861 + mItems[aPos].pathOp = aPathOp; 1.862 + } 1.863 + 1.864 +private: 1.865 + class PathExprItem { 1.866 + public: 1.867 + nsAutoPtr<Expr> expr; 1.868 + PathOperator pathOp; 1.869 + }; 1.870 + 1.871 + nsTArray<PathExprItem> mItems; 1.872 + 1.873 + /* 1.874 + * Selects from the descendants of the context node 1.875 + * all nodes that match the Expr 1.876 + */ 1.877 + nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode, 1.878 + txIMatchContext* aContext, 1.879 + txNodeSet* resNodes); 1.880 +}; 1.881 + 1.882 +/** 1.883 + * This class represents a RootExpr, which only matches the Document node 1.884 +**/ 1.885 +class RootExpr : public Expr { 1.886 +public: 1.887 + /** 1.888 + * Creates a new RootExpr 1.889 + */ 1.890 + RootExpr() 1.891 +#ifdef TX_TO_STRING 1.892 + : mSerialize(true) 1.893 +#endif 1.894 + { 1.895 + } 1.896 + 1.897 + TX_DECL_EXPR 1.898 + 1.899 +#ifdef TX_TO_STRING 1.900 +public: 1.901 + void setSerialize(bool aSerialize) 1.902 + { 1.903 + mSerialize = aSerialize; 1.904 + } 1.905 + 1.906 +private: 1.907 + // When a RootExpr is used in a PathExpr it shouldn't be serialized 1.908 + bool mSerialize; 1.909 +#endif 1.910 +}; //-- RootExpr 1.911 + 1.912 +/** 1.913 + * Represents a UnionExpr 1.914 +**/ 1.915 +class UnionExpr : public Expr { 1.916 +public: 1.917 + /** 1.918 + * Adds the PathExpr to this UnionExpr 1.919 + * The ownership of the given Expr is passed over the UnionExpr, 1.920 + * even on failure. 1.921 + * @param aExpr the Expr to add to this UnionExpr 1.922 + * @return nsresult indicating out of memory 1.923 + */ 1.924 + nsresult addExpr(Expr* aExpr) 1.925 + { 1.926 + return mExpressions.AppendElement(aExpr) ? 1.927 + NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.928 + } 1.929 + 1.930 + /** 1.931 + * Removes and deletes the expression at the given index. 1.932 + */ 1.933 + void deleteExprAt(uint32_t aPos) 1.934 + { 1.935 + NS_ASSERTION(aPos < mExpressions.Length(), 1.936 + "killing bad expression index"); 1.937 + 1.938 + delete mExpressions[aPos]; 1.939 + mExpressions.RemoveElementAt(aPos); 1.940 + } 1.941 + 1.942 + TX_DECL_OPTIMIZABLE_EXPR 1.943 + 1.944 +private: 1.945 + 1.946 + txOwningArray<Expr> mExpressions; 1.947 + 1.948 +}; //-- UnionExpr 1.949 + 1.950 +/** 1.951 + * Class specializing in executing expressions like "@foo" where we are 1.952 + * interested in different result-types, and expressions like "@foo = 'hi'" 1.953 + */ 1.954 +class txNamedAttributeStep : public Expr 1.955 +{ 1.956 +public: 1.957 + txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix, 1.958 + nsIAtom* aLocalName); 1.959 + 1.960 + TX_DECL_EXPR 1.961 + 1.962 +private: 1.963 + int32_t mNamespace; 1.964 + nsCOMPtr<nsIAtom> mPrefix; 1.965 + nsCOMPtr<nsIAtom> mLocalName; 1.966 +}; 1.967 + 1.968 +/** 1.969 + * 1.970 + */ 1.971 +class txUnionNodeTest : public txNodeTest 1.972 +{ 1.973 +public: 1.974 + nsresult addNodeTest(txNodeTest* aNodeTest) 1.975 + { 1.976 + return mNodeTests.AppendElement(aNodeTest) ? 1.977 + NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.978 + } 1.979 + 1.980 + TX_DECL_NODE_TEST 1.981 + 1.982 +private: 1.983 + txOwningArray<txNodeTest> mNodeTests; 1.984 +}; 1.985 + 1.986 +/** 1.987 + * Expression that failed to parse 1.988 + */ 1.989 +class txErrorExpr : public Expr 1.990 +{ 1.991 +public: 1.992 +#ifdef TX_TO_STRING 1.993 + txErrorExpr(const nsAString& aStr) 1.994 + : mStr(aStr) 1.995 + { 1.996 + } 1.997 +#endif 1.998 + 1.999 + TX_DECL_EXPR 1.1000 + 1.1001 +#ifdef TX_TO_STRING 1.1002 +private: 1.1003 + nsString mStr; 1.1004 +#endif 1.1005 +}; 1.1006 + 1.1007 +#endif 1.1008 + 1.1009 +