Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/xslt/xpath/txExpr.h
Line
Count
Source (jump to first uncovered line)
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 "nsAtom.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 nsAtom;
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
    Expr()
40
0
    {
41
0
        MOZ_COUNT_CTOR(Expr);
42
0
    }
43
    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
    virtual ExprType getType()
70
0
    {
71
0
      return OTHER_EXPR;
72
0
    }
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
0
    {
89
0
        return (getReturnType() & aType) != 0;
90
0
    }
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_APPENDNAME \
144
    void appendName(nsAString& aDest) override;
145
#else
146
#define TX_DECL_TOSTRING
147
#define TX_DECL_APPENDNAME
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_APPENDNAME \
167
    TX_DECL_EXPR_BASE
168
169
#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)          \
170
Expr::ResultType                                              \
171
0
_class::getReturnType()                                       \
172
0
{                                                             \
173
0
    return _ReturnType;                                       \
174
0
}
Unexecuted instantiation: BooleanExpr::getReturnType()
Unexecuted instantiation: txErrorExpr::getReturnType()
Unexecuted instantiation: FilterExpr::getReturnType()
Unexecuted instantiation: LocationStep::getReturnType()
Unexecuted instantiation: txNamedAttributeStep::getReturnType()
Unexecuted instantiation: txNumberExpr::getReturnType()
Unexecuted instantiation: PathExpr::getReturnType()
Unexecuted instantiation: RelationalExpr::getReturnType()
Unexecuted instantiation: RootExpr::getReturnType()
Unexecuted instantiation: UnaryExpr::getReturnType()
Unexecuted instantiation: UnionExpr::getReturnType()
Unexecuted instantiation: VariableRefExpr::getReturnType()
175
176
#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType)             \
177
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
178
Expr*                                                         \
179
0
_class::getSubExprAt(uint32_t aPos)                           \
180
0
{                                                             \
181
0
    return nullptr;                                            \
182
0
}                                                             \
Unexecuted instantiation: txErrorExpr::getSubExprAt(unsigned int)
Unexecuted instantiation: txNamedAttributeStep::getSubExprAt(unsigned int)
Unexecuted instantiation: RootExpr::getSubExprAt(unsigned int)
Unexecuted instantiation: VariableRefExpr::getSubExprAt(unsigned int)
183
void                                                          \
184
0
_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
185
0
{                                                             \
186
0
    MOZ_ASSERT_UNREACHABLE("setting bad subexpression index");\
187
0
}
Unexecuted instantiation: txErrorExpr::setSubExprAt(unsigned int, Expr*)
Unexecuted instantiation: txNamedAttributeStep::setSubExprAt(unsigned int, Expr*)
Unexecuted instantiation: RootExpr::setSubExprAt(unsigned int, Expr*)
Unexecuted instantiation: VariableRefExpr::setSubExprAt(unsigned int, Expr*)
188
189
#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1)     \
190
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
191
Expr*                                                         \
192
0
_class::getSubExprAt(uint32_t aPos)                           \
193
0
{                                                             \
194
0
    if (aPos == 0) {                                          \
195
0
        return _Expr1;                                        \
196
0
    }                                                         \
197
0
    return nullptr;                                            \
198
0
}                                                             \
199
void                                                          \
200
0
_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
201
0
{                                                             \
202
0
    NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
203
0
    _Expr1.forget();                                          \
204
0
    _Expr1 = aExpr;                                           \
205
0
}
206
207
#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
208
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
209
Expr*                                                         \
210
0
_class::getSubExprAt(uint32_t aPos)                           \
211
0
{                                                             \
212
0
    switch(aPos) {                                            \
213
0
        case 0:                                               \
214
0
            return _Expr1;                                    \
215
0
        case 1:                                               \
216
0
            return _Expr2;                                    \
217
0
        default:                                              \
218
0
            break;                                            \
219
0
    }                                                         \
220
0
    return nullptr;                                            \
221
0
}                                                             \
Unexecuted instantiation: BooleanExpr::getSubExprAt(unsigned int)
Unexecuted instantiation: txNumberExpr::getSubExprAt(unsigned int)
Unexecuted instantiation: RelationalExpr::getSubExprAt(unsigned int)
222
void                                                          \
223
0
_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
224
0
{                                                             \
225
0
    NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
226
0
    if (aPos == 0) {                                          \
227
0
        _Expr1.forget();                                      \
228
0
        _Expr1 = aExpr;                                       \
229
0
    }                                                         \
230
0
    else {                                                    \
231
0
        _Expr2.forget();                                      \
232
0
        _Expr2 = aExpr;                                       \
233
0
    }                                                         \
234
0
}
Unexecuted instantiation: BooleanExpr::setSubExprAt(unsigned int, Expr*)
Unexecuted instantiation: txNumberExpr::setSubExprAt(unsigned int, Expr*)
Unexecuted instantiation: RelationalExpr::setSubExprAt(unsigned int, Expr*)
235
236
#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
237
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
238
Expr*                                                         \
239
0
_class::getSubExprAt(uint32_t aPos)                           \
240
0
{                                                             \
241
0
    return _ExprList.SafeElementAt(aPos);                     \
242
0
}                                                             \
243
void                                                          \
244
0
_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
245
0
{                                                             \
246
0
    NS_ASSERTION(aPos < _ExprList.Length(),                   \
247
0
                 "setting bad subexpression index");          \
248
0
    _ExprList[aPos] = aExpr;                                  \
249
0
}
250
251
252
/**
253
 * This class represents a FunctionCall as defined by the XPath 1.0
254
 * Recommendation.
255
**/
256
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
    nsresult addParam(Expr* aExpr)
267
0
    {
268
0
        return mParams.AppendElement(aExpr) ?
269
0
            NS_OK : NS_ERROR_OUT_OF_MEMORY;
270
0
    }
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
     * Appends the name of the function to `aStr`.
317
     */
318
    virtual void appendName(nsAString& aStr) = 0;
319
#endif
320
};
321
322
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
    explicit txCoreFunctionCall(eType aType) : mType(aType)
365
0
    {
366
0
    }
367
368
    TX_DECL_FUNCTION
369
370
    static bool getTypeFromAtom(nsAtom* 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
    txNodeTest()
384
0
    {
385
0
        MOZ_COUNT_CTOR(txNodeTest);
386
0
    }
387
    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
    virtual NodeTestType getType()
412
0
    {
413
0
      return OTHER_TEST;
414
0
    }
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
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(nsAtom* aPrefix, nsAtom* aLocalName, int32_t aNSID,
446
               uint16_t aNodeType);
447
448
    NodeTestType getType() override;
449
450
    TX_DECL_NODE_TEST
451
452
    RefPtr<nsAtom> mPrefix;
453
    RefPtr<nsAtom> 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
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
    explicit txNodeTypeTest(NodeType aNodeType)
476
        : mNodeType(aNodeType)
477
0
    {
478
0
    }
479
480
    /*
481
     * Sets the name of the node to match. Only availible for pi nodes
482
     */
483
    void setNodeName(const nsAString& aName)
484
0
    {
485
0
        mNodeName = NS_Atomize(aName);
486
0
    }
487
488
    NodeType getNodeTestType()
489
0
    {
490
0
        return mNodeType;
491
0
    }
492
493
    NodeTestType getType() override;
494
495
    TX_DECL_NODE_TEST
496
497
private:
498
    NodeType mNodeType;
499
    RefPtr<nsAtom> 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
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
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
    nsresult add(Expr* aExpr)
531
0
    {
532
0
        NS_ASSERTION(aExpr, "missing expression");
533
0
        return mPredicates.AppendElement(aExpr) ?
534
0
            NS_OK : NS_ERROR_OUT_OF_MEMORY;
535
0
    }
536
537
    nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
538
539
    /**
540
     * Drops the first predicate without deleting it.
541
     */
542
    void dropFirst()
543
0
    {
544
0
        mPredicates.RemoveElementAt(0);
545
0
    }
546
547
    /**
548
     * returns true if this predicate list is empty
549
    **/
550
    bool isEmpty()
551
0
    {
552
0
        return mPredicates.IsEmpty();
553
0
    }
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
    Expr* getSubExprAt(uint32_t aPos)
570
0
    {
571
0
        return mPredicates.SafeElementAt(aPos);
572
0
    }
573
    void setSubExprAt(uint32_t aPos, Expr* aExpr)
574
0
    {
575
0
        NS_ASSERTION(aPos < mPredicates.Length(),
576
0
                     "setting bad subexpression index");
577
0
        mPredicates[aPos] = aExpr;
578
0
    }
579
580
    //-- list of predicates
581
    txOwningArray<Expr> mPredicates;
582
}; //-- PredicateList
583
584
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
    LocationStep(txNodeTest* aNodeTest,
610
                 LocationStepType aAxisIdentifier)
611
        : mNodeTest(aNodeTest),
612
          mAxisIdentifier(aAxisIdentifier)
613
0
    {
614
0
    }
615
616
    TX_DECL_OPTIMIZABLE_EXPR
617
618
    txNodeTest* getNodeTest()
619
0
    {
620
0
        return mNodeTest;
621
0
    }
622
    void setNodeTest(txNodeTest* aNodeTest)
623
0
    {
624
0
        mNodeTest.forget();
625
0
        mNodeTest = aNodeTest;
626
0
    }
627
    LocationStepType getAxisIdentifier()
628
0
    {
629
0
        return mAxisIdentifier;
630
0
    }
631
    void setAxisIdentifier(LocationStepType aAxisIdentifier)
632
0
    {
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
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
    explicit FilterExpr(Expr* aExpr)
676
        : expr(aExpr)
677
0
    {
678
0
    }
679
680
    TX_DECL_EXPR
681
682
private:
683
    nsAutoPtr<Expr> expr;
684
685
}; //-- FilterExpr
686
687
688
class txLiteralExpr : public Expr {
689
public:
690
    explicit txLiteralExpr(double aDbl)
691
        : mValue(new NumberResult(aDbl, nullptr))
692
0
    {
693
0
    }
694
    explicit txLiteralExpr(const nsAString& aStr)
695
        : mValue(new StringResult(aStr, nullptr))
696
0
    {
697
0
    }
698
    explicit txLiteralExpr(txAExprResult* aValue)
699
        : mValue(aValue)
700
0
    {
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
class UnaryExpr : public Expr {
713
714
public:
715
716
    explicit UnaryExpr(Expr* aExpr)
717
        : expr(aExpr)
718
0
    {
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
class BooleanExpr : public Expr
732
{
733
public:
734
735
    //-- BooleanExpr Types
736
    enum _BooleanExprType { AND = 1, OR };
737
738
     BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
739
         : leftExpr(aLeftExpr),
740
           rightExpr(aRightExpr),
741
           op(aOp)
742
0
    {
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
class txNumberExpr : public Expr
761
{
762
public:
763
764
    enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
765
766
    txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
767
        : mLeftExpr(aLeftExpr),
768
          mRightExpr(aRightExpr),
769
          mOp(aOp)
770
0
    {
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
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
    RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
803
        : mLeftExpr(aLeftExpr),
804
          mRightExpr(aRightExpr),
805
          mOp(aOp)
806
0
    {
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
class VariableRefExpr : public Expr {
826
827
public:
828
829
    VariableRefExpr(nsAtom* aPrefix, nsAtom* aLocalName, int32_t aNSID);
830
831
    TX_DECL_EXPR
832
833
private:
834
    RefPtr<nsAtom> mPrefix;
835
    RefPtr<nsAtom> mLocalName;
836
    int32_t mNamespace;
837
};
838
839
/**
840
 *  Represents a PathExpr
841
**/
842
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
    void deleteExprAt(uint32_t aPos)
864
0
    {
865
0
        NS_ASSERTION(aPos < mItems.Length(),
866
0
                     "killing bad expression index");
867
0
        mItems.RemoveElementAt(aPos);
868
0
    }
869
870
    TX_DECL_OPTIMIZABLE_EXPR
871
872
    PathOperator getPathOpAt(uint32_t aPos)
873
0
    {
874
0
        NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
875
0
        return mItems[aPos].pathOp;
876
0
    }
877
    void setPathOpAt(uint32_t aPos, PathOperator aPathOp)
878
0
    {
879
0
        NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
880
0
        mItems[aPos].pathOp = aPathOp;
881
0
    }
882
883
private:
884
    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
class RootExpr : public Expr {
905
public:
906
    /**
907
     * Creates a new RootExpr
908
     */
909
    RootExpr()
910
#ifdef TX_TO_STRING
911
        : mSerialize(true)
912
#endif
913
0
    {
914
0
    }
915
916
    TX_DECL_EXPR
917
918
#ifdef TX_TO_STRING
919
public:
920
    void setSerialize(bool aSerialize)
921
    {
922
        mSerialize = aSerialize;
923
    }
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
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
    nsresult addExpr(Expr* aExpr)
944
0
    {
945
0
        return mExpressions.AppendElement(aExpr) ?
946
0
            NS_OK : NS_ERROR_OUT_OF_MEMORY;
947
0
    }
948
949
    /**
950
     * Removes and deletes the expression at the given index.
951
     */
952
    void deleteExprAt(uint32_t aPos)
953
0
    {
954
0
        NS_ASSERTION(aPos < mExpressions.Length(),
955
0
                     "killing bad expression index");
956
0
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
class txNamedAttributeStep : public Expr
974
{
975
public:
976
    txNamedAttributeStep(int32_t aNsID, nsAtom* aPrefix,
977
                         nsAtom* aLocalName);
978
979
    TX_DECL_EXPR
980
981
private:
982
    int32_t mNamespace;
983
    RefPtr<nsAtom> mPrefix;
984
    RefPtr<nsAtom> mLocalName;
985
};
986
987
/**
988
 *
989
 */
990
class txUnionNodeTest : public txNodeTest
991
{
992
public:
993
    nsresult addNodeTest(txNodeTest* aNodeTest)
994
0
    {
995
0
        return mNodeTests.AppendElement(aNodeTest) ?
996
0
            NS_OK : NS_ERROR_OUT_OF_MEMORY;
997
0
    }
998
999
    TX_DECL_NODE_TEST
1000
1001
private:
1002
    txOwningArray<txNodeTest> mNodeTests;
1003
};
1004
1005
/**
1006
 *  Expression that failed to parse
1007
 */
1008
class txErrorExpr : public Expr
1009
{
1010
public:
1011
#ifdef TX_TO_STRING
1012
    explicit txErrorExpr(const nsAString& aStr)
1013
      : mStr(aStr)
1014
    {
1015
    }
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