dom/xslt/xpath/txExpr.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef TRANSFRMX_EXPR_H
michael@0 7 #define TRANSFRMX_EXPR_H
michael@0 8
michael@0 9 #include "mozilla/Attributes.h"
michael@0 10 #include "nsAutoPtr.h"
michael@0 11 #include "txExprResult.h"
michael@0 12 #include "txCore.h"
michael@0 13 #include "nsString.h"
michael@0 14 #include "txOwningArray.h"
michael@0 15 #include "nsIAtom.h"
michael@0 16
michael@0 17 #ifdef DEBUG
michael@0 18 #define TX_TO_STRING
michael@0 19 #endif
michael@0 20
michael@0 21 /*
michael@0 22 XPath class definitions.
michael@0 23 Much of this code was ported from XSL:P.
michael@0 24 */
michael@0 25
michael@0 26 class nsIAtom;
michael@0 27 class txIParseContext;
michael@0 28 class txIMatchContext;
michael@0 29 class txIEvalContext;
michael@0 30 class txNodeSet;
michael@0 31 class txXPathNode;
michael@0 32
michael@0 33 /**
michael@0 34 * A Base Class for all XSL Expressions
michael@0 35 **/
michael@0 36 class Expr
michael@0 37 {
michael@0 38 public:
michael@0 39 Expr()
michael@0 40 {
michael@0 41 MOZ_COUNT_CTOR(Expr);
michael@0 42 }
michael@0 43 virtual ~Expr()
michael@0 44 {
michael@0 45 MOZ_COUNT_DTOR(Expr);
michael@0 46 }
michael@0 47
michael@0 48 /**
michael@0 49 * Evaluates this Expr based on the given context node and processor state
michael@0 50 * @param context the context node for evaluation of this Expr
michael@0 51 * @param ps the ContextState containing the stack information needed
michael@0 52 * for evaluation
michael@0 53 * @return the result of the evaluation
michael@0 54 **/
michael@0 55 virtual nsresult evaluate(txIEvalContext* aContext,
michael@0 56 txAExprResult** aResult) = 0;
michael@0 57
michael@0 58
michael@0 59 /**
michael@0 60 * Returns the type of this expression.
michael@0 61 */
michael@0 62 enum ExprType {
michael@0 63 LOCATIONSTEP_EXPR,
michael@0 64 PATH_EXPR,
michael@0 65 UNION_EXPR,
michael@0 66 LITERAL_EXPR,
michael@0 67 OTHER_EXPR
michael@0 68 };
michael@0 69 virtual ExprType getType()
michael@0 70 {
michael@0 71 return OTHER_EXPR;
michael@0 72 }
michael@0 73
michael@0 74 /**
michael@0 75 * Returns the type or types of results this Expr return.
michael@0 76 */
michael@0 77 typedef uint16_t ResultType;
michael@0 78 enum {
michael@0 79 NODESET_RESULT = 0x01,
michael@0 80 BOOLEAN_RESULT = 0x02,
michael@0 81 NUMBER_RESULT = 0x04,
michael@0 82 STRING_RESULT = 0x08,
michael@0 83 RTF_RESULT = 0x10,
michael@0 84 ANY_RESULT = 0xFFFF
michael@0 85 };
michael@0 86 virtual ResultType getReturnType() = 0;
michael@0 87 bool canReturnType(ResultType aType)
michael@0 88 {
michael@0 89 return (getReturnType() & aType) != 0;
michael@0 90 }
michael@0 91
michael@0 92 typedef uint16_t ContextSensitivity;
michael@0 93 enum {
michael@0 94 NO_CONTEXT = 0x00,
michael@0 95 NODE_CONTEXT = 0x01,
michael@0 96 POSITION_CONTEXT = 0x02,
michael@0 97 SIZE_CONTEXT = 0x04,
michael@0 98 NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
michael@0 99 VARIABLES_CONTEXT = 0x08,
michael@0 100 PRIVATE_CONTEXT = 0x10,
michael@0 101 ANY_CONTEXT = 0xFFFF
michael@0 102 };
michael@0 103
michael@0 104 /**
michael@0 105 * Returns true if this expression is sensitive to *any* of
michael@0 106 * the requested contexts in aContexts.
michael@0 107 */
michael@0 108 virtual bool isSensitiveTo(ContextSensitivity aContexts) = 0;
michael@0 109
michael@0 110 /**
michael@0 111 * Returns sub-expression at given position
michael@0 112 */
michael@0 113 virtual Expr* getSubExprAt(uint32_t aPos) = 0;
michael@0 114
michael@0 115 /**
michael@0 116 * Replace sub-expression at given position. Does not delete the old
michael@0 117 * expression, that is the responsibility of the caller.
michael@0 118 */
michael@0 119 virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
michael@0 120
michael@0 121 virtual nsresult evaluateToBool(txIEvalContext* aContext,
michael@0 122 bool& aResult);
michael@0 123
michael@0 124 virtual nsresult evaluateToString(txIEvalContext* aContext,
michael@0 125 nsString& aResult);
michael@0 126
michael@0 127 #ifdef TX_TO_STRING
michael@0 128 /**
michael@0 129 * Returns the String representation of this Expr.
michael@0 130 * @param dest the String to use when creating the String
michael@0 131 * representation. The String representation will be appended to
michael@0 132 * any data in the destination String, to allow cascading calls to
michael@0 133 * other #toString() methods for Expressions.
michael@0 134 * @return the String representation of this Expr.
michael@0 135 **/
michael@0 136 virtual void toString(nsAString& str) = 0;
michael@0 137 #endif
michael@0 138 }; //-- Expr
michael@0 139
michael@0 140 #ifdef TX_TO_STRING
michael@0 141 #define TX_DECL_TOSTRING \
michael@0 142 void toString(nsAString& aDest);
michael@0 143 #define TX_DECL_GETNAMEATOM \
michael@0 144 nsresult getNameAtom(nsIAtom** aAtom);
michael@0 145 #else
michael@0 146 #define TX_DECL_TOSTRING
michael@0 147 #define TX_DECL_GETNAMEATOM
michael@0 148 #endif
michael@0 149
michael@0 150 #define TX_DECL_EXPR_BASE \
michael@0 151 nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
michael@0 152 ResultType getReturnType(); \
michael@0 153 bool isSensitiveTo(ContextSensitivity aContexts);
michael@0 154
michael@0 155 #define TX_DECL_EXPR \
michael@0 156 TX_DECL_EXPR_BASE \
michael@0 157 TX_DECL_TOSTRING \
michael@0 158 Expr* getSubExprAt(uint32_t aPos); \
michael@0 159 void setSubExprAt(uint32_t aPos, Expr* aExpr);
michael@0 160
michael@0 161 #define TX_DECL_OPTIMIZABLE_EXPR \
michael@0 162 TX_DECL_EXPR \
michael@0 163 ExprType getType();
michael@0 164
michael@0 165
michael@0 166 #define TX_DECL_FUNCTION \
michael@0 167 TX_DECL_GETNAMEATOM \
michael@0 168 TX_DECL_EXPR_BASE
michael@0 169
michael@0 170 #define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
michael@0 171 Expr::ResultType \
michael@0 172 _class::getReturnType() \
michael@0 173 { \
michael@0 174 return _ReturnType; \
michael@0 175 }
michael@0 176
michael@0 177 #define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType) \
michael@0 178 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
michael@0 179 Expr* \
michael@0 180 _class::getSubExprAt(uint32_t aPos) \
michael@0 181 { \
michael@0 182 return nullptr; \
michael@0 183 } \
michael@0 184 void \
michael@0 185 _class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
michael@0 186 { \
michael@0 187 NS_NOTREACHED("setting bad subexpression index"); \
michael@0 188 }
michael@0 189
michael@0 190 #define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1) \
michael@0 191 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
michael@0 192 Expr* \
michael@0 193 _class::getSubExprAt(uint32_t aPos) \
michael@0 194 { \
michael@0 195 if (aPos == 0) { \
michael@0 196 return _Expr1; \
michael@0 197 } \
michael@0 198 return nullptr; \
michael@0 199 } \
michael@0 200 void \
michael@0 201 _class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
michael@0 202 { \
michael@0 203 NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
michael@0 204 _Expr1.forget(); \
michael@0 205 _Expr1 = aExpr; \
michael@0 206 }
michael@0 207
michael@0 208 #define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
michael@0 209 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
michael@0 210 Expr* \
michael@0 211 _class::getSubExprAt(uint32_t aPos) \
michael@0 212 { \
michael@0 213 switch(aPos) { \
michael@0 214 case 0: \
michael@0 215 return _Expr1; \
michael@0 216 case 1: \
michael@0 217 return _Expr2; \
michael@0 218 default: \
michael@0 219 break; \
michael@0 220 } \
michael@0 221 return nullptr; \
michael@0 222 } \
michael@0 223 void \
michael@0 224 _class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
michael@0 225 { \
michael@0 226 NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
michael@0 227 if (aPos == 0) { \
michael@0 228 _Expr1.forget(); \
michael@0 229 _Expr1 = aExpr; \
michael@0 230 } \
michael@0 231 else { \
michael@0 232 _Expr2.forget(); \
michael@0 233 _Expr2 = aExpr; \
michael@0 234 } \
michael@0 235 }
michael@0 236
michael@0 237 #define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
michael@0 238 TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
michael@0 239 Expr* \
michael@0 240 _class::getSubExprAt(uint32_t aPos) \
michael@0 241 { \
michael@0 242 return _ExprList.SafeElementAt(aPos); \
michael@0 243 } \
michael@0 244 void \
michael@0 245 _class::setSubExprAt(uint32_t aPos, Expr* aExpr) \
michael@0 246 { \
michael@0 247 NS_ASSERTION(aPos < _ExprList.Length(), \
michael@0 248 "setting bad subexpression index"); \
michael@0 249 _ExprList[aPos] = aExpr; \
michael@0 250 }
michael@0 251
michael@0 252
michael@0 253 /**
michael@0 254 * This class represents a FunctionCall as defined by the XPath 1.0
michael@0 255 * Recommendation.
michael@0 256 **/
michael@0 257 class FunctionCall : public Expr
michael@0 258 {
michael@0 259 public:
michael@0 260 /**
michael@0 261 * Adds the given parameter to this FunctionCall's parameter list.
michael@0 262 * The ownership of the given Expr is passed over to the FunctionCall,
michael@0 263 * even on failure.
michael@0 264 * @param aExpr the Expr to add to this FunctionCall's parameter list
michael@0 265 * @return nsresult indicating out of memory
michael@0 266 */
michael@0 267 nsresult addParam(Expr* aExpr)
michael@0 268 {
michael@0 269 return mParams.AppendElement(aExpr) ?
michael@0 270 NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 271 }
michael@0 272
michael@0 273 /**
michael@0 274 * Check if the number of parameters falls within a range.
michael@0 275 *
michael@0 276 * @param aParamCountMin minimum number of required parameters.
michael@0 277 * @param aParamCountMax maximum number of parameters. If aParamCountMax
michael@0 278 * is negative the maximum number is not checked.
michael@0 279 * @return boolean representing whether the number of parameters falls
michael@0 280 * within the expected range or not.
michael@0 281 *
michael@0 282 * XXX txIEvalContext should be txIParseContest, bug 143291
michael@0 283 */
michael@0 284 virtual bool requireParams(int32_t aParamCountMin,
michael@0 285 int32_t aParamCountMax,
michael@0 286 txIEvalContext* aContext);
michael@0 287
michael@0 288 TX_DECL_TOSTRING
michael@0 289 Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE;
michael@0 290 void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE;
michael@0 291
michael@0 292 protected:
michael@0 293
michael@0 294 txOwningArray<Expr> mParams;
michael@0 295
michael@0 296 /*
michael@0 297 * Evaluates the given Expression and converts its result to a number.
michael@0 298 */
michael@0 299 static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
michael@0 300 double* aResult);
michael@0 301
michael@0 302 /*
michael@0 303 * Evaluates the given Expression and converts its result to a NodeSet.
michael@0 304 * If the result is not a NodeSet an error is returned.
michael@0 305 */
michael@0 306 static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
michael@0 307 txNodeSet** aResult);
michael@0 308
michael@0 309 /**
michael@0 310 * Returns true if any argument is sensitive to the given context.
michael@0 311 */
michael@0 312 bool argsSensitiveTo(ContextSensitivity aContexts);
michael@0 313
michael@0 314
michael@0 315 #ifdef TX_TO_STRING
michael@0 316 /*
michael@0 317 * Returns the name of the function as an atom.
michael@0 318 */
michael@0 319 virtual nsresult getNameAtom(nsIAtom** aAtom) = 0;
michael@0 320 #endif
michael@0 321 };
michael@0 322
michael@0 323 class txCoreFunctionCall : public FunctionCall
michael@0 324 {
michael@0 325 public:
michael@0 326
michael@0 327 // This must be ordered in the same order as descriptTable in
michael@0 328 // txCoreFunctionCall.cpp. If you change one, change the other.
michael@0 329 enum eType {
michael@0 330 COUNT = 0, // count()
michael@0 331 ID, // id()
michael@0 332 LAST, // last()
michael@0 333 LOCAL_NAME, // local-name()
michael@0 334 NAMESPACE_URI, // namespace-uri()
michael@0 335 NAME, // name()
michael@0 336 POSITION, // position()
michael@0 337
michael@0 338 CONCAT, // concat()
michael@0 339 CONTAINS, // contains()
michael@0 340 NORMALIZE_SPACE, // normalize-space()
michael@0 341 STARTS_WITH, // starts-with()
michael@0 342 STRING, // string()
michael@0 343 STRING_LENGTH, // string-length()
michael@0 344 SUBSTRING, // substring()
michael@0 345 SUBSTRING_AFTER, // substring-after()
michael@0 346 SUBSTRING_BEFORE, // substring-before()
michael@0 347 TRANSLATE, // translate()
michael@0 348
michael@0 349 NUMBER, // number()
michael@0 350 ROUND, // round()
michael@0 351 FLOOR, // floor()
michael@0 352 CEILING, // ceiling()
michael@0 353 SUM, // sum()
michael@0 354
michael@0 355 BOOLEAN, // boolean()
michael@0 356 _FALSE, // false()
michael@0 357 LANG, // lang()
michael@0 358 _NOT, // not()
michael@0 359 _TRUE // true()
michael@0 360 };
michael@0 361
michael@0 362 /*
michael@0 363 * Creates a txCoreFunctionCall of the given type
michael@0 364 */
michael@0 365 txCoreFunctionCall(eType aType) : mType(aType)
michael@0 366 {
michael@0 367 }
michael@0 368
michael@0 369 TX_DECL_FUNCTION
michael@0 370
michael@0 371 static bool getTypeFromAtom(nsIAtom* aName, eType& aType);
michael@0 372
michael@0 373 private:
michael@0 374 eType mType;
michael@0 375 };
michael@0 376
michael@0 377
michael@0 378 /*
michael@0 379 * This class represents a NodeTest as defined by the XPath spec
michael@0 380 */
michael@0 381 class txNodeTest
michael@0 382 {
michael@0 383 public:
michael@0 384 txNodeTest()
michael@0 385 {
michael@0 386 MOZ_COUNT_CTOR(txNodeTest);
michael@0 387 }
michael@0 388 virtual ~txNodeTest()
michael@0 389 {
michael@0 390 MOZ_COUNT_DTOR(txNodeTest);
michael@0 391 }
michael@0 392
michael@0 393 /*
michael@0 394 * Virtual methods
michael@0 395 * pretty much a txPattern, but not supposed to be used
michael@0 396 * standalone. The NodeTest node() is different to the
michael@0 397 * Pattern "node()" (document node isn't matched)
michael@0 398 */
michael@0 399 virtual bool matches(const txXPathNode& aNode,
michael@0 400 txIMatchContext* aContext) = 0;
michael@0 401 virtual double getDefaultPriority() = 0;
michael@0 402
michael@0 403 /**
michael@0 404 * Returns the type of this nodetest.
michael@0 405 */
michael@0 406 enum NodeTestType {
michael@0 407 NAME_TEST,
michael@0 408 NODETYPE_TEST,
michael@0 409 OTHER_TEST
michael@0 410 };
michael@0 411 virtual NodeTestType getType()
michael@0 412 {
michael@0 413 return OTHER_TEST;
michael@0 414 }
michael@0 415
michael@0 416 /**
michael@0 417 * Returns true if this expression is sensitive to *any* of
michael@0 418 * the requested flags.
michael@0 419 */
michael@0 420 virtual bool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
michael@0 421
michael@0 422 #ifdef TX_TO_STRING
michael@0 423 virtual void toString(nsAString& aDest) = 0;
michael@0 424 #endif
michael@0 425 };
michael@0 426
michael@0 427 #define TX_DECL_NODE_TEST \
michael@0 428 TX_DECL_TOSTRING \
michael@0 429 bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
michael@0 430 double getDefaultPriority(); \
michael@0 431 bool isSensitiveTo(Expr::ContextSensitivity aContext);
michael@0 432
michael@0 433 /*
michael@0 434 * This class represents a NameTest as defined by the XPath spec
michael@0 435 */
michael@0 436 class txNameTest : public txNodeTest
michael@0 437 {
michael@0 438 public:
michael@0 439 /*
michael@0 440 * Creates a new txNameTest with the given type and the given
michael@0 441 * principal node type
michael@0 442 */
michael@0 443 txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID,
michael@0 444 uint16_t aNodeType);
michael@0 445
michael@0 446 NodeTestType getType() MOZ_OVERRIDE;
michael@0 447
michael@0 448 TX_DECL_NODE_TEST
michael@0 449
michael@0 450 nsCOMPtr<nsIAtom> mPrefix;
michael@0 451 nsCOMPtr<nsIAtom> mLocalName;
michael@0 452 int32_t mNamespace;
michael@0 453 private:
michael@0 454 uint16_t mNodeType;
michael@0 455 };
michael@0 456
michael@0 457 /*
michael@0 458 * This class represents a NodeType as defined by the XPath spec
michael@0 459 */
michael@0 460 class txNodeTypeTest : public txNodeTest
michael@0 461 {
michael@0 462 public:
michael@0 463 enum NodeType {
michael@0 464 COMMENT_TYPE,
michael@0 465 TEXT_TYPE,
michael@0 466 PI_TYPE,
michael@0 467 NODE_TYPE
michael@0 468 };
michael@0 469
michael@0 470 /*
michael@0 471 * Creates a new txNodeTypeTest of the given type
michael@0 472 */
michael@0 473 txNodeTypeTest(NodeType aNodeType)
michael@0 474 : mNodeType(aNodeType)
michael@0 475 {
michael@0 476 }
michael@0 477
michael@0 478 /*
michael@0 479 * Sets the name of the node to match. Only availible for pi nodes
michael@0 480 */
michael@0 481 void setNodeName(const nsAString& aName)
michael@0 482 {
michael@0 483 mNodeName = do_GetAtom(aName);
michael@0 484 }
michael@0 485
michael@0 486 NodeType getNodeTestType()
michael@0 487 {
michael@0 488 return mNodeType;
michael@0 489 }
michael@0 490
michael@0 491 NodeTestType getType() MOZ_OVERRIDE;
michael@0 492
michael@0 493 TX_DECL_NODE_TEST
michael@0 494
michael@0 495 private:
michael@0 496 NodeType mNodeType;
michael@0 497 nsCOMPtr<nsIAtom> mNodeName;
michael@0 498 };
michael@0 499
michael@0 500 /**
michael@0 501 * Class representing a nodetest combined with a predicate. May only be used
michael@0 502 * if the predicate is not sensitive to the context-nodelist.
michael@0 503 */
michael@0 504 class txPredicatedNodeTest : public txNodeTest
michael@0 505 {
michael@0 506 public:
michael@0 507 txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
michael@0 508 TX_DECL_NODE_TEST
michael@0 509
michael@0 510 private:
michael@0 511 nsAutoPtr<txNodeTest> mNodeTest;
michael@0 512 nsAutoPtr<Expr> mPredicate;
michael@0 513 };
michael@0 514
michael@0 515 /**
michael@0 516 * Represents an ordered list of Predicates,
michael@0 517 * for use with Step and Filter Expressions
michael@0 518 **/
michael@0 519 class PredicateList {
michael@0 520 public:
michael@0 521 /**
michael@0 522 * Adds the given Expr to the list.
michael@0 523 * The ownership of the given Expr is passed over the PredicateList,
michael@0 524 * even on failure.
michael@0 525 * @param aExpr the Expr to add to the list
michael@0 526 * @return nsresult indicating out of memory
michael@0 527 */
michael@0 528 nsresult add(Expr* aExpr)
michael@0 529 {
michael@0 530 NS_ASSERTION(aExpr, "missing expression");
michael@0 531 return mPredicates.AppendElement(aExpr) ?
michael@0 532 NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 533 }
michael@0 534
michael@0 535 nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
michael@0 536
michael@0 537 /**
michael@0 538 * Drops the first predicate without deleting it.
michael@0 539 */
michael@0 540 void dropFirst()
michael@0 541 {
michael@0 542 mPredicates.RemoveElementAt(0);
michael@0 543 }
michael@0 544
michael@0 545 /**
michael@0 546 * returns true if this predicate list is empty
michael@0 547 **/
michael@0 548 bool isEmpty()
michael@0 549 {
michael@0 550 return mPredicates.IsEmpty();
michael@0 551 }
michael@0 552
michael@0 553 #ifdef TX_TO_STRING
michael@0 554 /**
michael@0 555 * Returns the String representation of this PredicateList.
michael@0 556 * @param dest the String to use when creating the String
michael@0 557 * representation. The String representation will be appended to
michael@0 558 * any data in the destination String, to allow cascading calls to
michael@0 559 * other #toString() methods for Expressions.
michael@0 560 * @return the String representation of this PredicateList.
michael@0 561 **/
michael@0 562 void toString(nsAString& dest);
michael@0 563 #endif
michael@0 564
michael@0 565 protected:
michael@0 566 bool isSensitiveTo(Expr::ContextSensitivity aContext);
michael@0 567 Expr* getSubExprAt(uint32_t aPos)
michael@0 568 {
michael@0 569 return mPredicates.SafeElementAt(aPos);
michael@0 570 }
michael@0 571 void setSubExprAt(uint32_t aPos, Expr* aExpr)
michael@0 572 {
michael@0 573 NS_ASSERTION(aPos < mPredicates.Length(),
michael@0 574 "setting bad subexpression index");
michael@0 575 mPredicates[aPos] = aExpr;
michael@0 576 }
michael@0 577
michael@0 578 //-- list of predicates
michael@0 579 txOwningArray<Expr> mPredicates;
michael@0 580 }; //-- PredicateList
michael@0 581
michael@0 582 class LocationStep : public Expr,
michael@0 583 public PredicateList
michael@0 584 {
michael@0 585 public:
michael@0 586 enum LocationStepType {
michael@0 587 ANCESTOR_AXIS = 0,
michael@0 588 ANCESTOR_OR_SELF_AXIS,
michael@0 589 ATTRIBUTE_AXIS,
michael@0 590 CHILD_AXIS,
michael@0 591 DESCENDANT_AXIS,
michael@0 592 DESCENDANT_OR_SELF_AXIS,
michael@0 593 FOLLOWING_AXIS,
michael@0 594 FOLLOWING_SIBLING_AXIS,
michael@0 595 NAMESPACE_AXIS,
michael@0 596 PARENT_AXIS,
michael@0 597 PRECEDING_AXIS,
michael@0 598 PRECEDING_SIBLING_AXIS,
michael@0 599 SELF_AXIS
michael@0 600 };
michael@0 601
michael@0 602 /**
michael@0 603 * Creates a new LocationStep using the given NodeExpr and Axis Identifier
michael@0 604 * @param nodeExpr the NodeExpr to use when matching Nodes
michael@0 605 * @param axisIdentifier the Axis Identifier in which to search for nodes
michael@0 606 **/
michael@0 607 LocationStep(txNodeTest* aNodeTest,
michael@0 608 LocationStepType aAxisIdentifier)
michael@0 609 : mNodeTest(aNodeTest),
michael@0 610 mAxisIdentifier(aAxisIdentifier)
michael@0 611 {
michael@0 612 }
michael@0 613
michael@0 614 TX_DECL_OPTIMIZABLE_EXPR
michael@0 615
michael@0 616 txNodeTest* getNodeTest()
michael@0 617 {
michael@0 618 return mNodeTest;
michael@0 619 }
michael@0 620 void setNodeTest(txNodeTest* aNodeTest)
michael@0 621 {
michael@0 622 mNodeTest.forget();
michael@0 623 mNodeTest = aNodeTest;
michael@0 624 }
michael@0 625 LocationStepType getAxisIdentifier()
michael@0 626 {
michael@0 627 return mAxisIdentifier;
michael@0 628 }
michael@0 629 void setAxisIdentifier(LocationStepType aAxisIdentifier)
michael@0 630 {
michael@0 631 mAxisIdentifier = aAxisIdentifier;
michael@0 632 }
michael@0 633
michael@0 634 private:
michael@0 635 void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
michael@0 636 txNodeSet* aNodes);
michael@0 637 void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs,
michael@0 638 txNodeSet* aNodes);
michael@0 639
michael@0 640 nsAutoPtr<txNodeTest> mNodeTest;
michael@0 641 LocationStepType mAxisIdentifier;
michael@0 642 };
michael@0 643
michael@0 644 class FilterExpr : public Expr,
michael@0 645 public PredicateList
michael@0 646 {
michael@0 647 public:
michael@0 648
michael@0 649 /**
michael@0 650 * Creates a new FilterExpr using the given Expr
michael@0 651 * @param expr the Expr to use for evaluation
michael@0 652 */
michael@0 653 FilterExpr(Expr* aExpr)
michael@0 654 : expr(aExpr)
michael@0 655 {
michael@0 656 }
michael@0 657
michael@0 658 TX_DECL_EXPR
michael@0 659
michael@0 660 private:
michael@0 661 nsAutoPtr<Expr> expr;
michael@0 662
michael@0 663 }; //-- FilterExpr
michael@0 664
michael@0 665
michael@0 666 class txLiteralExpr : public Expr {
michael@0 667 public:
michael@0 668 txLiteralExpr(double aDbl)
michael@0 669 : mValue(new NumberResult(aDbl, nullptr))
michael@0 670 {
michael@0 671 }
michael@0 672 txLiteralExpr(const nsAString& aStr)
michael@0 673 : mValue(new StringResult(aStr, nullptr))
michael@0 674 {
michael@0 675 }
michael@0 676 txLiteralExpr(txAExprResult* aValue)
michael@0 677 : mValue(aValue)
michael@0 678 {
michael@0 679 }
michael@0 680
michael@0 681 TX_DECL_EXPR
michael@0 682
michael@0 683 private:
michael@0 684 nsRefPtr<txAExprResult> mValue;
michael@0 685 };
michael@0 686
michael@0 687 /**
michael@0 688 * Represents an UnaryExpr. Returns the negative value of its expr.
michael@0 689 **/
michael@0 690 class UnaryExpr : public Expr {
michael@0 691
michael@0 692 public:
michael@0 693
michael@0 694 UnaryExpr(Expr* aExpr)
michael@0 695 : expr(aExpr)
michael@0 696 {
michael@0 697 }
michael@0 698
michael@0 699 TX_DECL_EXPR
michael@0 700
michael@0 701 private:
michael@0 702 nsAutoPtr<Expr> expr;
michael@0 703 }; //-- UnaryExpr
michael@0 704
michael@0 705 /**
michael@0 706 * Represents a BooleanExpr, a binary expression that
michael@0 707 * performs a boolean operation between its lvalue and rvalue.
michael@0 708 **/
michael@0 709 class BooleanExpr : public Expr
michael@0 710 {
michael@0 711 public:
michael@0 712
michael@0 713 //-- BooleanExpr Types
michael@0 714 enum _BooleanExprType { AND = 1, OR };
michael@0 715
michael@0 716 BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
michael@0 717 : leftExpr(aLeftExpr),
michael@0 718 rightExpr(aRightExpr),
michael@0 719 op(aOp)
michael@0 720 {
michael@0 721 }
michael@0 722
michael@0 723 TX_DECL_EXPR
michael@0 724
michael@0 725 private:
michael@0 726 nsAutoPtr<Expr> leftExpr, rightExpr;
michael@0 727 short op;
michael@0 728 }; //-- BooleanExpr
michael@0 729
michael@0 730 /**
michael@0 731 * Represents a MultiplicativeExpr, a binary expression that
michael@0 732 * performs a multiplicative operation between its lvalue and rvalue:
michael@0 733 * * : multiply
michael@0 734 * mod : modulus
michael@0 735 * div : divide
michael@0 736 *
michael@0 737 **/
michael@0 738 class txNumberExpr : public Expr
michael@0 739 {
michael@0 740 public:
michael@0 741
michael@0 742 enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
michael@0 743
michael@0 744 txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
michael@0 745 : mLeftExpr(aLeftExpr),
michael@0 746 mRightExpr(aRightExpr),
michael@0 747 mOp(aOp)
michael@0 748 {
michael@0 749 }
michael@0 750
michael@0 751 TX_DECL_EXPR
michael@0 752
michael@0 753 private:
michael@0 754 nsAutoPtr<Expr> mLeftExpr, mRightExpr;
michael@0 755 eOp mOp;
michael@0 756 }; //-- MultiplicativeExpr
michael@0 757
michael@0 758 /**
michael@0 759 * Represents a RelationalExpr, an expression that compares its lvalue
michael@0 760 * to its rvalue using:
michael@0 761 * = : equal to
michael@0 762 * < : less than
michael@0 763 * > : greater than
michael@0 764 * <= : less than or equal to
michael@0 765 * >= : greater than or equal to
michael@0 766 *
michael@0 767 **/
michael@0 768 class RelationalExpr : public Expr
michael@0 769 {
michael@0 770 public:
michael@0 771 enum RelationalExprType {
michael@0 772 EQUAL,
michael@0 773 NOT_EQUAL,
michael@0 774 LESS_THAN,
michael@0 775 GREATER_THAN,
michael@0 776 LESS_OR_EQUAL,
michael@0 777 GREATER_OR_EQUAL
michael@0 778 };
michael@0 779
michael@0 780 RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
michael@0 781 : mLeftExpr(aLeftExpr),
michael@0 782 mRightExpr(aRightExpr),
michael@0 783 mOp(aOp)
michael@0 784 {
michael@0 785 }
michael@0 786
michael@0 787
michael@0 788 TX_DECL_EXPR
michael@0 789
michael@0 790 private:
michael@0 791 bool compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
michael@0 792 txAExprResult* aRight);
michael@0 793
michael@0 794 nsAutoPtr<Expr> mLeftExpr;
michael@0 795 nsAutoPtr<Expr> mRightExpr;
michael@0 796 RelationalExprType mOp;
michael@0 797 };
michael@0 798
michael@0 799 /**
michael@0 800 * VariableRefExpr
michael@0 801 * Represents a variable reference ($refname)
michael@0 802 **/
michael@0 803 class VariableRefExpr : public Expr {
michael@0 804
michael@0 805 public:
michael@0 806
michael@0 807 VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID);
michael@0 808
michael@0 809 TX_DECL_EXPR
michael@0 810
michael@0 811 private:
michael@0 812 nsCOMPtr<nsIAtom> mPrefix;
michael@0 813 nsCOMPtr<nsIAtom> mLocalName;
michael@0 814 int32_t mNamespace;
michael@0 815 };
michael@0 816
michael@0 817 /**
michael@0 818 * Represents a PathExpr
michael@0 819 **/
michael@0 820 class PathExpr : public Expr {
michael@0 821
michael@0 822 public:
michael@0 823
michael@0 824 //-- Path Operators
michael@0 825 //-- RELATIVE_OP is the default
michael@0 826 //-- LF, changed from static const short to enum
michael@0 827 enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
michael@0 828
michael@0 829 /**
michael@0 830 * Adds the Expr to this PathExpr
michael@0 831 * The ownership of the given Expr is passed over the PathExpr,
michael@0 832 * even on failure.
michael@0 833 * @param aExpr the Expr to add to this PathExpr
michael@0 834 * @return nsresult indicating out of memory
michael@0 835 */
michael@0 836 nsresult addExpr(Expr* aExpr, PathOperator pathOp);
michael@0 837
michael@0 838 /**
michael@0 839 * Removes and deletes the expression at the given index.
michael@0 840 */
michael@0 841 void deleteExprAt(uint32_t aPos)
michael@0 842 {
michael@0 843 NS_ASSERTION(aPos < mItems.Length(),
michael@0 844 "killing bad expression index");
michael@0 845 mItems.RemoveElementAt(aPos);
michael@0 846 }
michael@0 847
michael@0 848 TX_DECL_OPTIMIZABLE_EXPR
michael@0 849
michael@0 850 PathOperator getPathOpAt(uint32_t aPos)
michael@0 851 {
michael@0 852 NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
michael@0 853 return mItems[aPos].pathOp;
michael@0 854 }
michael@0 855 void setPathOpAt(uint32_t aPos, PathOperator aPathOp)
michael@0 856 {
michael@0 857 NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
michael@0 858 mItems[aPos].pathOp = aPathOp;
michael@0 859 }
michael@0 860
michael@0 861 private:
michael@0 862 class PathExprItem {
michael@0 863 public:
michael@0 864 nsAutoPtr<Expr> expr;
michael@0 865 PathOperator pathOp;
michael@0 866 };
michael@0 867
michael@0 868 nsTArray<PathExprItem> mItems;
michael@0 869
michael@0 870 /*
michael@0 871 * Selects from the descendants of the context node
michael@0 872 * all nodes that match the Expr
michael@0 873 */
michael@0 874 nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode,
michael@0 875 txIMatchContext* aContext,
michael@0 876 txNodeSet* resNodes);
michael@0 877 };
michael@0 878
michael@0 879 /**
michael@0 880 * This class represents a RootExpr, which only matches the Document node
michael@0 881 **/
michael@0 882 class RootExpr : public Expr {
michael@0 883 public:
michael@0 884 /**
michael@0 885 * Creates a new RootExpr
michael@0 886 */
michael@0 887 RootExpr()
michael@0 888 #ifdef TX_TO_STRING
michael@0 889 : mSerialize(true)
michael@0 890 #endif
michael@0 891 {
michael@0 892 }
michael@0 893
michael@0 894 TX_DECL_EXPR
michael@0 895
michael@0 896 #ifdef TX_TO_STRING
michael@0 897 public:
michael@0 898 void setSerialize(bool aSerialize)
michael@0 899 {
michael@0 900 mSerialize = aSerialize;
michael@0 901 }
michael@0 902
michael@0 903 private:
michael@0 904 // When a RootExpr is used in a PathExpr it shouldn't be serialized
michael@0 905 bool mSerialize;
michael@0 906 #endif
michael@0 907 }; //-- RootExpr
michael@0 908
michael@0 909 /**
michael@0 910 * Represents a UnionExpr
michael@0 911 **/
michael@0 912 class UnionExpr : public Expr {
michael@0 913 public:
michael@0 914 /**
michael@0 915 * Adds the PathExpr to this UnionExpr
michael@0 916 * The ownership of the given Expr is passed over the UnionExpr,
michael@0 917 * even on failure.
michael@0 918 * @param aExpr the Expr to add to this UnionExpr
michael@0 919 * @return nsresult indicating out of memory
michael@0 920 */
michael@0 921 nsresult addExpr(Expr* aExpr)
michael@0 922 {
michael@0 923 return mExpressions.AppendElement(aExpr) ?
michael@0 924 NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 925 }
michael@0 926
michael@0 927 /**
michael@0 928 * Removes and deletes the expression at the given index.
michael@0 929 */
michael@0 930 void deleteExprAt(uint32_t aPos)
michael@0 931 {
michael@0 932 NS_ASSERTION(aPos < mExpressions.Length(),
michael@0 933 "killing bad expression index");
michael@0 934
michael@0 935 delete mExpressions[aPos];
michael@0 936 mExpressions.RemoveElementAt(aPos);
michael@0 937 }
michael@0 938
michael@0 939 TX_DECL_OPTIMIZABLE_EXPR
michael@0 940
michael@0 941 private:
michael@0 942
michael@0 943 txOwningArray<Expr> mExpressions;
michael@0 944
michael@0 945 }; //-- UnionExpr
michael@0 946
michael@0 947 /**
michael@0 948 * Class specializing in executing expressions like "@foo" where we are
michael@0 949 * interested in different result-types, and expressions like "@foo = 'hi'"
michael@0 950 */
michael@0 951 class txNamedAttributeStep : public Expr
michael@0 952 {
michael@0 953 public:
michael@0 954 txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix,
michael@0 955 nsIAtom* aLocalName);
michael@0 956
michael@0 957 TX_DECL_EXPR
michael@0 958
michael@0 959 private:
michael@0 960 int32_t mNamespace;
michael@0 961 nsCOMPtr<nsIAtom> mPrefix;
michael@0 962 nsCOMPtr<nsIAtom> mLocalName;
michael@0 963 };
michael@0 964
michael@0 965 /**
michael@0 966 *
michael@0 967 */
michael@0 968 class txUnionNodeTest : public txNodeTest
michael@0 969 {
michael@0 970 public:
michael@0 971 nsresult addNodeTest(txNodeTest* aNodeTest)
michael@0 972 {
michael@0 973 return mNodeTests.AppendElement(aNodeTest) ?
michael@0 974 NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 975 }
michael@0 976
michael@0 977 TX_DECL_NODE_TEST
michael@0 978
michael@0 979 private:
michael@0 980 txOwningArray<txNodeTest> mNodeTests;
michael@0 981 };
michael@0 982
michael@0 983 /**
michael@0 984 * Expression that failed to parse
michael@0 985 */
michael@0 986 class txErrorExpr : public Expr
michael@0 987 {
michael@0 988 public:
michael@0 989 #ifdef TX_TO_STRING
michael@0 990 txErrorExpr(const nsAString& aStr)
michael@0 991 : mStr(aStr)
michael@0 992 {
michael@0 993 }
michael@0 994 #endif
michael@0 995
michael@0 996 TX_DECL_EXPR
michael@0 997
michael@0 998 #ifdef TX_TO_STRING
michael@0 999 private:
michael@0 1000 nsString mStr;
michael@0 1001 #endif
michael@0 1002 };
michael@0 1003
michael@0 1004 #endif
michael@0 1005
michael@0 1006

mercurial