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