dom/xslt/xpath/txExpr.h

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

mercurial