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