txExpr.h 26 KB

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