dom/xslt/xpath/txExpr.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/xslt/xpath/txExpr.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1006 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef TRANSFRMX_EXPR_H
    1.10 +#define TRANSFRMX_EXPR_H
    1.11 +
    1.12 +#include "mozilla/Attributes.h"
    1.13 +#include "nsAutoPtr.h"
    1.14 +#include "txExprResult.h"
    1.15 +#include "txCore.h"
    1.16 +#include "nsString.h"
    1.17 +#include "txOwningArray.h"
    1.18 +#include "nsIAtom.h"
    1.19 +
    1.20 +#ifdef DEBUG
    1.21 +#define TX_TO_STRING
    1.22 +#endif
    1.23 +
    1.24 +/*
    1.25 +  XPath class definitions.
    1.26 +  Much of this code was ported from XSL:P.
    1.27 +*/
    1.28 +
    1.29 +class nsIAtom;
    1.30 +class txIParseContext;
    1.31 +class txIMatchContext;
    1.32 +class txIEvalContext;
    1.33 +class txNodeSet;
    1.34 +class txXPathNode;
    1.35 +
    1.36 +/**
    1.37 + * A Base Class for all XSL Expressions
    1.38 +**/
    1.39 +class Expr
    1.40 +{
    1.41 +public:
    1.42 +    Expr()
    1.43 +    {
    1.44 +        MOZ_COUNT_CTOR(Expr);
    1.45 +    }
    1.46 +    virtual ~Expr()
    1.47 +    {
    1.48 +        MOZ_COUNT_DTOR(Expr);
    1.49 +    }
    1.50 +
    1.51 +    /**
    1.52 +     * Evaluates this Expr based on the given context node and processor state
    1.53 +     * @param context the context node for evaluation of this Expr
    1.54 +     * @param ps the ContextState containing the stack information needed
    1.55 +     * for evaluation
    1.56 +     * @return the result of the evaluation
    1.57 +    **/
    1.58 +    virtual nsresult evaluate(txIEvalContext* aContext,
    1.59 +                              txAExprResult** aResult) = 0;
    1.60 +
    1.61 +
    1.62 +    /**
    1.63 +     * Returns the type of this expression.
    1.64 +     */
    1.65 +    enum ExprType {
    1.66 +        LOCATIONSTEP_EXPR,
    1.67 +        PATH_EXPR,
    1.68 +        UNION_EXPR,
    1.69 +        LITERAL_EXPR,
    1.70 +        OTHER_EXPR
    1.71 +    };
    1.72 +    virtual ExprType getType()
    1.73 +    {
    1.74 +      return OTHER_EXPR;
    1.75 +    }
    1.76 +
    1.77 +    /**
    1.78 +     * Returns the type or types of results this Expr return.
    1.79 +     */
    1.80 +    typedef uint16_t ResultType;
    1.81 +    enum {
    1.82 +        NODESET_RESULT = 0x01,
    1.83 +        BOOLEAN_RESULT = 0x02,
    1.84 +        NUMBER_RESULT = 0x04,
    1.85 +        STRING_RESULT = 0x08,
    1.86 +        RTF_RESULT = 0x10,
    1.87 +        ANY_RESULT = 0xFFFF
    1.88 +    };
    1.89 +    virtual ResultType getReturnType() = 0;
    1.90 +    bool canReturnType(ResultType aType)
    1.91 +    {
    1.92 +        return (getReturnType() & aType) != 0;
    1.93 +    }
    1.94 +
    1.95 +    typedef uint16_t ContextSensitivity;
    1.96 +    enum {
    1.97 +        NO_CONTEXT = 0x00,
    1.98 +        NODE_CONTEXT = 0x01,
    1.99 +        POSITION_CONTEXT = 0x02,
   1.100 +        SIZE_CONTEXT = 0x04,
   1.101 +        NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
   1.102 +        VARIABLES_CONTEXT = 0x08,
   1.103 +        PRIVATE_CONTEXT = 0x10,
   1.104 +        ANY_CONTEXT = 0xFFFF
   1.105 +    };
   1.106 +
   1.107 +    /**
   1.108 +     * Returns true if this expression is sensitive to *any* of
   1.109 +     * the requested contexts in aContexts.
   1.110 +     */
   1.111 +    virtual bool isSensitiveTo(ContextSensitivity aContexts) = 0;
   1.112 +
   1.113 +    /**
   1.114 +     * Returns sub-expression at given position
   1.115 +     */
   1.116 +    virtual Expr* getSubExprAt(uint32_t aPos) = 0;
   1.117 +
   1.118 +    /**
   1.119 +     * Replace sub-expression at given position. Does not delete the old
   1.120 +     * expression, that is the responsibility of the caller.
   1.121 +     */
   1.122 +    virtual void setSubExprAt(uint32_t aPos, Expr* aExpr) = 0;
   1.123 +
   1.124 +    virtual nsresult evaluateToBool(txIEvalContext* aContext,
   1.125 +                                    bool& aResult);
   1.126 +
   1.127 +    virtual nsresult evaluateToString(txIEvalContext* aContext,
   1.128 +                                      nsString& aResult);
   1.129 +
   1.130 +#ifdef TX_TO_STRING
   1.131 +    /**
   1.132 +     * Returns the String representation of this Expr.
   1.133 +     * @param dest the String to use when creating the String
   1.134 +     * representation. The String representation will be appended to
   1.135 +     * any data in the destination String, to allow cascading calls to
   1.136 +     * other #toString() methods for Expressions.
   1.137 +     * @return the String representation of this Expr.
   1.138 +    **/
   1.139 +    virtual void toString(nsAString& str) = 0;
   1.140 +#endif
   1.141 +}; //-- Expr
   1.142 +
   1.143 +#ifdef TX_TO_STRING
   1.144 +#define TX_DECL_TOSTRING \
   1.145 +    void toString(nsAString& aDest);
   1.146 +#define TX_DECL_GETNAMEATOM \
   1.147 +    nsresult getNameAtom(nsIAtom** aAtom);
   1.148 +#else
   1.149 +#define TX_DECL_TOSTRING
   1.150 +#define TX_DECL_GETNAMEATOM
   1.151 +#endif
   1.152 +
   1.153 +#define TX_DECL_EXPR_BASE \
   1.154 +    nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
   1.155 +    ResultType getReturnType(); \
   1.156 +    bool isSensitiveTo(ContextSensitivity aContexts);
   1.157 +
   1.158 +#define TX_DECL_EXPR \
   1.159 +    TX_DECL_EXPR_BASE \
   1.160 +    TX_DECL_TOSTRING \
   1.161 +    Expr* getSubExprAt(uint32_t aPos); \
   1.162 +    void setSubExprAt(uint32_t aPos, Expr* aExpr);
   1.163 +
   1.164 +#define TX_DECL_OPTIMIZABLE_EXPR \
   1.165 +    TX_DECL_EXPR \
   1.166 +    ExprType getType();
   1.167 +    
   1.168 +
   1.169 +#define TX_DECL_FUNCTION \
   1.170 +    TX_DECL_GETNAMEATOM \
   1.171 +    TX_DECL_EXPR_BASE
   1.172 +
   1.173 +#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)          \
   1.174 +Expr::ResultType                                              \
   1.175 +_class::getReturnType()                                       \
   1.176 +{                                                             \
   1.177 +    return _ReturnType;                                       \
   1.178 +}
   1.179 +
   1.180 +#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType)             \
   1.181 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   1.182 +Expr*                                                         \
   1.183 +_class::getSubExprAt(uint32_t aPos)                           \
   1.184 +{                                                             \
   1.185 +    return nullptr;                                            \
   1.186 +}                                                             \
   1.187 +void                                                          \
   1.188 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   1.189 +{                                                             \
   1.190 +    NS_NOTREACHED("setting bad subexpression index");         \
   1.191 +}
   1.192 +
   1.193 +#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1)     \
   1.194 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   1.195 +Expr*                                                         \
   1.196 +_class::getSubExprAt(uint32_t aPos)                           \
   1.197 +{                                                             \
   1.198 +    if (aPos == 0) {                                          \
   1.199 +        return _Expr1;                                        \
   1.200 +    }                                                         \
   1.201 +    return nullptr;                                            \
   1.202 +}                                                             \
   1.203 +void                                                          \
   1.204 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   1.205 +{                                                             \
   1.206 +    NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
   1.207 +    _Expr1.forget();                                          \
   1.208 +    _Expr1 = aExpr;                                           \
   1.209 +}
   1.210 +
   1.211 +#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
   1.212 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   1.213 +Expr*                                                         \
   1.214 +_class::getSubExprAt(uint32_t aPos)                           \
   1.215 +{                                                             \
   1.216 +    switch(aPos) {                                            \
   1.217 +        case 0:                                               \
   1.218 +            return _Expr1;                                    \
   1.219 +        case 1:                                               \
   1.220 +            return _Expr2;                                    \
   1.221 +        default:                                              \
   1.222 +            break;                                            \
   1.223 +    }                                                         \
   1.224 +    return nullptr;                                            \
   1.225 +}                                                             \
   1.226 +void                                                          \
   1.227 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   1.228 +{                                                             \
   1.229 +    NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
   1.230 +    if (aPos == 0) {                                          \
   1.231 +        _Expr1.forget();                                      \
   1.232 +        _Expr1 = aExpr;                                       \
   1.233 +    }                                                         \
   1.234 +    else {                                                    \
   1.235 +        _Expr2.forget();                                      \
   1.236 +        _Expr2 = aExpr;                                       \
   1.237 +    }                                                         \
   1.238 +}
   1.239 +
   1.240 +#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
   1.241 +TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType)                  \
   1.242 +Expr*                                                         \
   1.243 +_class::getSubExprAt(uint32_t aPos)                           \
   1.244 +{                                                             \
   1.245 +    return _ExprList.SafeElementAt(aPos);                     \
   1.246 +}                                                             \
   1.247 +void                                                          \
   1.248 +_class::setSubExprAt(uint32_t aPos, Expr* aExpr)              \
   1.249 +{                                                             \
   1.250 +    NS_ASSERTION(aPos < _ExprList.Length(),                   \
   1.251 +                 "setting bad subexpression index");          \
   1.252 +    _ExprList[aPos] = aExpr;                                  \
   1.253 +}
   1.254 +
   1.255 +
   1.256 +/**
   1.257 + * This class represents a FunctionCall as defined by the XPath 1.0
   1.258 + * Recommendation.
   1.259 +**/
   1.260 +class FunctionCall : public Expr
   1.261 +{
   1.262 +public:
   1.263 +    /**
   1.264 +     * Adds the given parameter to this FunctionCall's parameter list.
   1.265 +     * The ownership of the given Expr is passed over to the FunctionCall,
   1.266 +     * even on failure.
   1.267 +     * @param aExpr the Expr to add to this FunctionCall's parameter list
   1.268 +     * @return nsresult indicating out of memory
   1.269 +     */
   1.270 +    nsresult addParam(Expr* aExpr)
   1.271 +    {
   1.272 +        return mParams.AppendElement(aExpr) ?
   1.273 +            NS_OK : NS_ERROR_OUT_OF_MEMORY;
   1.274 +    }
   1.275 +
   1.276 +    /**
   1.277 +     * Check if the number of parameters falls within a range.
   1.278 +     *
   1.279 +     * @param aParamCountMin minimum number of required parameters.
   1.280 +     * @param aParamCountMax maximum number of parameters. If aParamCountMax
   1.281 +     *                       is negative the maximum number is not checked.
   1.282 +     * @return boolean representing whether the number of parameters falls
   1.283 +     *         within the expected range or not.
   1.284 +     *
   1.285 +     * XXX txIEvalContext should be txIParseContest, bug 143291
   1.286 +     */
   1.287 +    virtual bool requireParams(int32_t aParamCountMin,
   1.288 +                                 int32_t aParamCountMax,
   1.289 +                                 txIEvalContext* aContext);
   1.290 +
   1.291 +    TX_DECL_TOSTRING
   1.292 +    Expr* getSubExprAt(uint32_t aPos) MOZ_OVERRIDE;
   1.293 +    void setSubExprAt(uint32_t aPos, Expr* aExpr) MOZ_OVERRIDE;
   1.294 +
   1.295 +protected:
   1.296 +
   1.297 +    txOwningArray<Expr> mParams;
   1.298 +
   1.299 +    /*
   1.300 +     * Evaluates the given Expression and converts its result to a number.
   1.301 +     */
   1.302 +    static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
   1.303 +                                     double* aResult);
   1.304 +
   1.305 +    /*
   1.306 +     * Evaluates the given Expression and converts its result to a NodeSet.
   1.307 +     * If the result is not a NodeSet an error is returned.
   1.308 +     */
   1.309 +    static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
   1.310 +                                      txNodeSet** aResult);
   1.311 +
   1.312 +    /**
   1.313 +     * Returns true if any argument is sensitive to the given context.
   1.314 +     */
   1.315 +    bool argsSensitiveTo(ContextSensitivity aContexts);
   1.316 +
   1.317 +
   1.318 +#ifdef TX_TO_STRING
   1.319 +    /*
   1.320 +     * Returns the name of the function as an atom.
   1.321 +     */
   1.322 +    virtual nsresult getNameAtom(nsIAtom** aAtom) = 0;
   1.323 +#endif
   1.324 +};
   1.325 +
   1.326 +class txCoreFunctionCall : public FunctionCall
   1.327 +{
   1.328 +public:
   1.329 +
   1.330 +    // This must be ordered in the same order as descriptTable in
   1.331 +    // txCoreFunctionCall.cpp. If you change one, change the other.
   1.332 +    enum eType {
   1.333 +        COUNT = 0,         // count()
   1.334 +        ID,                // id()
   1.335 +        LAST,              // last()
   1.336 +        LOCAL_NAME,        // local-name()
   1.337 +        NAMESPACE_URI,     // namespace-uri()
   1.338 +        NAME,              // name()
   1.339 +        POSITION,          // position()
   1.340 +
   1.341 +        CONCAT,            // concat()
   1.342 +        CONTAINS,          // contains()
   1.343 +        NORMALIZE_SPACE,   // normalize-space()
   1.344 +        STARTS_WITH,       // starts-with()
   1.345 +        STRING,            // string()
   1.346 +        STRING_LENGTH,     // string-length()
   1.347 +        SUBSTRING,         // substring()
   1.348 +        SUBSTRING_AFTER,   // substring-after()
   1.349 +        SUBSTRING_BEFORE,  // substring-before()
   1.350 +        TRANSLATE,         // translate()
   1.351 +
   1.352 +        NUMBER,            // number()
   1.353 +        ROUND,             // round()
   1.354 +        FLOOR,             // floor()
   1.355 +        CEILING,           // ceiling()
   1.356 +        SUM,               // sum()
   1.357 +
   1.358 +        BOOLEAN,           // boolean()
   1.359 +        _FALSE,            // false()
   1.360 +        LANG,              // lang()
   1.361 +        _NOT,              // not()
   1.362 +        _TRUE              // true()
   1.363 +    };
   1.364 +
   1.365 +    /*
   1.366 +     * Creates a txCoreFunctionCall of the given type
   1.367 +     */
   1.368 +    txCoreFunctionCall(eType aType) : mType(aType)
   1.369 +    {
   1.370 +    }
   1.371 +
   1.372 +    TX_DECL_FUNCTION
   1.373 +
   1.374 +    static bool getTypeFromAtom(nsIAtom* aName, eType& aType);
   1.375 +
   1.376 +private:
   1.377 +    eType mType;
   1.378 +};
   1.379 +
   1.380 +
   1.381 +/*
   1.382 + * This class represents a NodeTest as defined by the XPath spec
   1.383 + */
   1.384 +class txNodeTest
   1.385 +{
   1.386 +public:
   1.387 +    txNodeTest()
   1.388 +    {
   1.389 +        MOZ_COUNT_CTOR(txNodeTest);
   1.390 +    }
   1.391 +    virtual ~txNodeTest()
   1.392 +    {
   1.393 +        MOZ_COUNT_DTOR(txNodeTest);
   1.394 +    }
   1.395 +
   1.396 +    /*
   1.397 +     * Virtual methods
   1.398 +     * pretty much a txPattern, but not supposed to be used 
   1.399 +     * standalone. The NodeTest node() is different to the
   1.400 +     * Pattern "node()" (document node isn't matched)
   1.401 +     */
   1.402 +    virtual bool matches(const txXPathNode& aNode,
   1.403 +                           txIMatchContext* aContext) = 0;
   1.404 +    virtual double getDefaultPriority() = 0;
   1.405 +
   1.406 +    /**
   1.407 +     * Returns the type of this nodetest.
   1.408 +     */
   1.409 +    enum NodeTestType {
   1.410 +        NAME_TEST,
   1.411 +        NODETYPE_TEST,
   1.412 +        OTHER_TEST
   1.413 +    };
   1.414 +    virtual NodeTestType getType()
   1.415 +    {
   1.416 +      return OTHER_TEST;
   1.417 +    }
   1.418 +
   1.419 +    /**
   1.420 +     * Returns true if this expression is sensitive to *any* of
   1.421 +     * the requested flags.
   1.422 +     */
   1.423 +    virtual bool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
   1.424 +
   1.425 +#ifdef TX_TO_STRING
   1.426 +    virtual void toString(nsAString& aDest) = 0;
   1.427 +#endif
   1.428 +};
   1.429 +
   1.430 +#define TX_DECL_NODE_TEST \
   1.431 +    TX_DECL_TOSTRING \
   1.432 +    bool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
   1.433 +    double getDefaultPriority(); \
   1.434 +    bool isSensitiveTo(Expr::ContextSensitivity aContext);
   1.435 +
   1.436 +/*
   1.437 + * This class represents a NameTest as defined by the XPath spec
   1.438 + */
   1.439 +class txNameTest : public txNodeTest
   1.440 +{
   1.441 +public:
   1.442 +    /*
   1.443 +     * Creates a new txNameTest with the given type and the given
   1.444 +     * principal node type
   1.445 +     */
   1.446 +    txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID,
   1.447 +               uint16_t aNodeType);
   1.448 +
   1.449 +    NodeTestType getType() MOZ_OVERRIDE;
   1.450 +
   1.451 +    TX_DECL_NODE_TEST
   1.452 +
   1.453 +    nsCOMPtr<nsIAtom> mPrefix;
   1.454 +    nsCOMPtr<nsIAtom> mLocalName;
   1.455 +    int32_t mNamespace;
   1.456 +private:
   1.457 +    uint16_t mNodeType;
   1.458 +};
   1.459 +
   1.460 +/*
   1.461 + * This class represents a NodeType as defined by the XPath spec
   1.462 + */
   1.463 +class txNodeTypeTest : public txNodeTest
   1.464 +{
   1.465 +public:
   1.466 +    enum NodeType {
   1.467 +        COMMENT_TYPE,
   1.468 +        TEXT_TYPE,
   1.469 +        PI_TYPE,
   1.470 +        NODE_TYPE
   1.471 +    };
   1.472 +
   1.473 +    /*
   1.474 +     * Creates a new txNodeTypeTest of the given type
   1.475 +     */
   1.476 +    txNodeTypeTest(NodeType aNodeType)
   1.477 +        : mNodeType(aNodeType)
   1.478 +    {
   1.479 +    }
   1.480 +
   1.481 +    /*
   1.482 +     * Sets the name of the node to match. Only availible for pi nodes
   1.483 +     */
   1.484 +    void setNodeName(const nsAString& aName)
   1.485 +    {
   1.486 +        mNodeName = do_GetAtom(aName);
   1.487 +    }
   1.488 +
   1.489 +    NodeType getNodeTestType()
   1.490 +    {
   1.491 +        return mNodeType;
   1.492 +    }
   1.493 +
   1.494 +    NodeTestType getType() MOZ_OVERRIDE;
   1.495 +
   1.496 +    TX_DECL_NODE_TEST
   1.497 +
   1.498 +private:
   1.499 +    NodeType mNodeType;
   1.500 +    nsCOMPtr<nsIAtom> mNodeName;
   1.501 +};
   1.502 +
   1.503 +/**
   1.504 + * Class representing a nodetest combined with a predicate. May only be used
   1.505 + * if the predicate is not sensitive to the context-nodelist.
   1.506 + */
   1.507 +class txPredicatedNodeTest : public txNodeTest
   1.508 +{
   1.509 +public:
   1.510 +    txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
   1.511 +    TX_DECL_NODE_TEST
   1.512 +
   1.513 +private:
   1.514 +    nsAutoPtr<txNodeTest> mNodeTest;
   1.515 +    nsAutoPtr<Expr> mPredicate;
   1.516 +};
   1.517 +
   1.518 +/**
   1.519 + * Represents an ordered list of Predicates,
   1.520 + * for use with Step and Filter Expressions
   1.521 +**/
   1.522 +class PredicateList  {
   1.523 +public:
   1.524 +    /**
   1.525 +     * Adds the given Expr to the list.
   1.526 +     * The ownership of the given Expr is passed over the PredicateList,
   1.527 +     * even on failure.
   1.528 +     * @param aExpr the Expr to add to the list
   1.529 +     * @return nsresult indicating out of memory
   1.530 +     */
   1.531 +    nsresult add(Expr* aExpr)
   1.532 +    {
   1.533 +        NS_ASSERTION(aExpr, "missing expression");
   1.534 +        return mPredicates.AppendElement(aExpr) ?
   1.535 +            NS_OK : NS_ERROR_OUT_OF_MEMORY;
   1.536 +    }
   1.537 +
   1.538 +    nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
   1.539 +
   1.540 +    /**
   1.541 +     * Drops the first predicate without deleting it.
   1.542 +     */
   1.543 +    void dropFirst()
   1.544 +    {
   1.545 +        mPredicates.RemoveElementAt(0);
   1.546 +    }
   1.547 +
   1.548 +    /**
   1.549 +     * returns true if this predicate list is empty
   1.550 +    **/
   1.551 +    bool isEmpty()
   1.552 +    {
   1.553 +        return mPredicates.IsEmpty();
   1.554 +    }
   1.555 +
   1.556 +#ifdef TX_TO_STRING
   1.557 +    /**
   1.558 +     * Returns the String representation of this PredicateList.
   1.559 +     * @param dest the String to use when creating the String
   1.560 +     * representation. The String representation will be appended to
   1.561 +     * any data in the destination String, to allow cascading calls to
   1.562 +     * other #toString() methods for Expressions.
   1.563 +     * @return the String representation of this PredicateList.
   1.564 +    **/
   1.565 +    void toString(nsAString& dest);
   1.566 +#endif
   1.567 +
   1.568 +protected:
   1.569 +    bool isSensitiveTo(Expr::ContextSensitivity aContext);
   1.570 +    Expr* getSubExprAt(uint32_t aPos)
   1.571 +    {
   1.572 +        return mPredicates.SafeElementAt(aPos);
   1.573 +    }
   1.574 +    void setSubExprAt(uint32_t aPos, Expr* aExpr)
   1.575 +    {
   1.576 +        NS_ASSERTION(aPos < mPredicates.Length(),
   1.577 +                     "setting bad subexpression index");
   1.578 +        mPredicates[aPos] = aExpr;
   1.579 +    }
   1.580 +
   1.581 +    //-- list of predicates
   1.582 +    txOwningArray<Expr> mPredicates;
   1.583 +}; //-- PredicateList
   1.584 +
   1.585 +class LocationStep : public Expr,
   1.586 +                     public PredicateList
   1.587 +{
   1.588 +public:
   1.589 +    enum LocationStepType {
   1.590 +        ANCESTOR_AXIS = 0,
   1.591 +        ANCESTOR_OR_SELF_AXIS,
   1.592 +        ATTRIBUTE_AXIS,
   1.593 +        CHILD_AXIS,
   1.594 +        DESCENDANT_AXIS,
   1.595 +        DESCENDANT_OR_SELF_AXIS,
   1.596 +        FOLLOWING_AXIS,
   1.597 +        FOLLOWING_SIBLING_AXIS,
   1.598 +        NAMESPACE_AXIS,
   1.599 +        PARENT_AXIS,
   1.600 +        PRECEDING_AXIS,
   1.601 +        PRECEDING_SIBLING_AXIS,
   1.602 +        SELF_AXIS
   1.603 +    };
   1.604 +
   1.605 +    /**
   1.606 +     * Creates a new LocationStep using the given NodeExpr and Axis Identifier
   1.607 +     * @param nodeExpr the NodeExpr to use when matching Nodes
   1.608 +     * @param axisIdentifier the Axis Identifier in which to search for nodes
   1.609 +    **/
   1.610 +    LocationStep(txNodeTest* aNodeTest,
   1.611 +                 LocationStepType aAxisIdentifier)
   1.612 +        : mNodeTest(aNodeTest),
   1.613 +          mAxisIdentifier(aAxisIdentifier)
   1.614 +    {
   1.615 +    }
   1.616 +
   1.617 +    TX_DECL_OPTIMIZABLE_EXPR
   1.618 +
   1.619 +    txNodeTest* getNodeTest()
   1.620 +    {
   1.621 +        return mNodeTest;
   1.622 +    }
   1.623 +    void setNodeTest(txNodeTest* aNodeTest)
   1.624 +    {
   1.625 +        mNodeTest.forget();
   1.626 +        mNodeTest = aNodeTest;
   1.627 +    }
   1.628 +    LocationStepType getAxisIdentifier()
   1.629 +    {
   1.630 +        return mAxisIdentifier;
   1.631 +    }
   1.632 +    void setAxisIdentifier(LocationStepType aAxisIdentifier)
   1.633 +    {
   1.634 +        mAxisIdentifier = aAxisIdentifier;
   1.635 +    }
   1.636 +
   1.637 +private:
   1.638 +    void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
   1.639 +                         txNodeSet* aNodes);
   1.640 +    void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs,
   1.641 +                            txNodeSet* aNodes);
   1.642 +
   1.643 +    nsAutoPtr<txNodeTest> mNodeTest;
   1.644 +    LocationStepType mAxisIdentifier;
   1.645 +};
   1.646 +
   1.647 +class FilterExpr : public Expr,
   1.648 +                   public PredicateList
   1.649 +{
   1.650 +public:
   1.651 +
   1.652 +    /**
   1.653 +     * Creates a new FilterExpr using the given Expr
   1.654 +     * @param expr the Expr to use for evaluation
   1.655 +     */
   1.656 +    FilterExpr(Expr* aExpr)
   1.657 +        : expr(aExpr)
   1.658 +    {
   1.659 +    }
   1.660 +
   1.661 +    TX_DECL_EXPR
   1.662 +
   1.663 +private:
   1.664 +    nsAutoPtr<Expr> expr;
   1.665 +
   1.666 +}; //-- FilterExpr
   1.667 +
   1.668 +
   1.669 +class txLiteralExpr : public Expr {
   1.670 +public:
   1.671 +    txLiteralExpr(double aDbl)
   1.672 +        : mValue(new NumberResult(aDbl, nullptr))
   1.673 +    {
   1.674 +    }
   1.675 +    txLiteralExpr(const nsAString& aStr)
   1.676 +        : mValue(new StringResult(aStr, nullptr))
   1.677 +    {
   1.678 +    }
   1.679 +    txLiteralExpr(txAExprResult* aValue)
   1.680 +        : mValue(aValue)
   1.681 +    {
   1.682 +    }
   1.683 +
   1.684 +    TX_DECL_EXPR
   1.685 +
   1.686 +private:
   1.687 +    nsRefPtr<txAExprResult> mValue;
   1.688 +};
   1.689 +
   1.690 +/**
   1.691 + * Represents an UnaryExpr. Returns the negative value of its expr.
   1.692 +**/
   1.693 +class UnaryExpr : public Expr {
   1.694 +
   1.695 +public:
   1.696 +
   1.697 +    UnaryExpr(Expr* aExpr)
   1.698 +        : expr(aExpr)
   1.699 +    {
   1.700 +    }
   1.701 +
   1.702 +    TX_DECL_EXPR
   1.703 +
   1.704 +private:
   1.705 +    nsAutoPtr<Expr> expr;
   1.706 +}; //-- UnaryExpr
   1.707 +
   1.708 +/**
   1.709 + * Represents a BooleanExpr, a binary expression that
   1.710 + * performs a boolean operation between its lvalue and rvalue.
   1.711 +**/
   1.712 +class BooleanExpr : public Expr
   1.713 +{
   1.714 +public:
   1.715 +
   1.716 +    //-- BooleanExpr Types
   1.717 +    enum _BooleanExprType { AND = 1, OR };
   1.718 +
   1.719 +     BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
   1.720 +         : leftExpr(aLeftExpr),
   1.721 +           rightExpr(aRightExpr),
   1.722 +           op(aOp)
   1.723 +    {
   1.724 +    }
   1.725 +
   1.726 +    TX_DECL_EXPR
   1.727 +
   1.728 +private:
   1.729 +    nsAutoPtr<Expr> leftExpr, rightExpr;
   1.730 +    short op;
   1.731 +}; //-- BooleanExpr
   1.732 +
   1.733 +/**
   1.734 + * Represents a MultiplicativeExpr, a binary expression that
   1.735 + * performs a multiplicative operation between its lvalue and rvalue:
   1.736 + *  *   : multiply
   1.737 + * mod  : modulus
   1.738 + * div  : divide
   1.739 + *
   1.740 +**/
   1.741 +class txNumberExpr : public Expr
   1.742 +{
   1.743 +public:
   1.744 +
   1.745 +    enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
   1.746 +
   1.747 +    txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
   1.748 +        : mLeftExpr(aLeftExpr),
   1.749 +          mRightExpr(aRightExpr),
   1.750 +          mOp(aOp)
   1.751 +    {
   1.752 +    }
   1.753 +
   1.754 +    TX_DECL_EXPR
   1.755 +
   1.756 +private:
   1.757 +    nsAutoPtr<Expr> mLeftExpr, mRightExpr;
   1.758 +    eOp mOp;
   1.759 +}; //-- MultiplicativeExpr
   1.760 +
   1.761 +/**
   1.762 + * Represents a RelationalExpr, an expression that compares its lvalue
   1.763 + * to its rvalue using:
   1.764 + * =  : equal to
   1.765 + * <  : less than
   1.766 + * >  : greater than
   1.767 + * <= : less than or equal to
   1.768 + * >= : greater than or equal to
   1.769 + *
   1.770 +**/
   1.771 +class RelationalExpr : public Expr
   1.772 +{
   1.773 +public:
   1.774 +    enum RelationalExprType {
   1.775 +        EQUAL,
   1.776 +        NOT_EQUAL,
   1.777 +        LESS_THAN,
   1.778 +        GREATER_THAN,
   1.779 +        LESS_OR_EQUAL,
   1.780 +        GREATER_OR_EQUAL
   1.781 +    };
   1.782 +
   1.783 +    RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
   1.784 +        : mLeftExpr(aLeftExpr),
   1.785 +          mRightExpr(aRightExpr),
   1.786 +          mOp(aOp)
   1.787 +    {
   1.788 +    }
   1.789 +
   1.790 +
   1.791 +    TX_DECL_EXPR
   1.792 +
   1.793 +private:
   1.794 +    bool compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
   1.795 +                          txAExprResult* aRight);
   1.796 +
   1.797 +    nsAutoPtr<Expr> mLeftExpr;
   1.798 +    nsAutoPtr<Expr> mRightExpr;
   1.799 +    RelationalExprType mOp;
   1.800 +};
   1.801 +
   1.802 +/**
   1.803 + * VariableRefExpr
   1.804 + * Represents a variable reference ($refname)
   1.805 +**/
   1.806 +class VariableRefExpr : public Expr {
   1.807 +
   1.808 +public:
   1.809 +
   1.810 +    VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID);
   1.811 +
   1.812 +    TX_DECL_EXPR
   1.813 +
   1.814 +private:
   1.815 +    nsCOMPtr<nsIAtom> mPrefix;
   1.816 +    nsCOMPtr<nsIAtom> mLocalName;
   1.817 +    int32_t mNamespace;
   1.818 +};
   1.819 +
   1.820 +/**
   1.821 + *  Represents a PathExpr
   1.822 +**/
   1.823 +class PathExpr : public Expr {
   1.824 +
   1.825 +public:
   1.826 +
   1.827 +    //-- Path Operators
   1.828 +    //-- RELATIVE_OP is the default
   1.829 +    //-- LF, changed from static const short to enum
   1.830 +    enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
   1.831 +
   1.832 +    /**
   1.833 +     * Adds the Expr to this PathExpr
   1.834 +     * The ownership of the given Expr is passed over the PathExpr,
   1.835 +     * even on failure.
   1.836 +     * @param aExpr the Expr to add to this PathExpr
   1.837 +     * @return nsresult indicating out of memory
   1.838 +     */
   1.839 +    nsresult addExpr(Expr* aExpr, PathOperator pathOp);
   1.840 +
   1.841 +    /**
   1.842 +     * Removes and deletes the expression at the given index.
   1.843 +     */
   1.844 +    void deleteExprAt(uint32_t aPos)
   1.845 +    {
   1.846 +        NS_ASSERTION(aPos < mItems.Length(),
   1.847 +                     "killing bad expression index");
   1.848 +        mItems.RemoveElementAt(aPos);
   1.849 +    }
   1.850 +
   1.851 +    TX_DECL_OPTIMIZABLE_EXPR
   1.852 +
   1.853 +    PathOperator getPathOpAt(uint32_t aPos)
   1.854 +    {
   1.855 +        NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
   1.856 +        return mItems[aPos].pathOp;
   1.857 +    }
   1.858 +    void setPathOpAt(uint32_t aPos, PathOperator aPathOp)
   1.859 +    {
   1.860 +        NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
   1.861 +        mItems[aPos].pathOp = aPathOp;
   1.862 +    }
   1.863 +
   1.864 +private:
   1.865 +    class PathExprItem {
   1.866 +    public:
   1.867 +        nsAutoPtr<Expr> expr;
   1.868 +        PathOperator pathOp;
   1.869 +    };
   1.870 +
   1.871 +    nsTArray<PathExprItem> mItems;
   1.872 +
   1.873 +    /*
   1.874 +     * Selects from the descendants of the context node
   1.875 +     * all nodes that match the Expr
   1.876 +     */
   1.877 +    nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode,
   1.878 +                             txIMatchContext* aContext,
   1.879 +                             txNodeSet* resNodes);
   1.880 +};
   1.881 +
   1.882 +/**
   1.883 + * This class represents a RootExpr, which only matches the Document node
   1.884 +**/
   1.885 +class RootExpr : public Expr {
   1.886 +public:
   1.887 +    /**
   1.888 +     * Creates a new RootExpr
   1.889 +     */
   1.890 +    RootExpr()
   1.891 +#ifdef TX_TO_STRING
   1.892 +        : mSerialize(true)
   1.893 +#endif
   1.894 +    {
   1.895 +    }
   1.896 +
   1.897 +    TX_DECL_EXPR
   1.898 +
   1.899 +#ifdef TX_TO_STRING
   1.900 +public:
   1.901 +    void setSerialize(bool aSerialize)
   1.902 +    {
   1.903 +        mSerialize = aSerialize;
   1.904 +    }
   1.905 +
   1.906 +private:
   1.907 +    // When a RootExpr is used in a PathExpr it shouldn't be serialized
   1.908 +    bool mSerialize;
   1.909 +#endif
   1.910 +}; //-- RootExpr
   1.911 +
   1.912 +/**
   1.913 + *  Represents a UnionExpr
   1.914 +**/
   1.915 +class UnionExpr : public Expr {
   1.916 +public:
   1.917 +    /**
   1.918 +     * Adds the PathExpr to this UnionExpr
   1.919 +     * The ownership of the given Expr is passed over the UnionExpr,
   1.920 +     * even on failure.
   1.921 +     * @param aExpr the Expr to add to this UnionExpr
   1.922 +     * @return nsresult indicating out of memory
   1.923 +     */
   1.924 +    nsresult addExpr(Expr* aExpr)
   1.925 +    {
   1.926 +        return mExpressions.AppendElement(aExpr) ?
   1.927 +            NS_OK : NS_ERROR_OUT_OF_MEMORY;
   1.928 +    }
   1.929 +
   1.930 +    /**
   1.931 +     * Removes and deletes the expression at the given index.
   1.932 +     */
   1.933 +    void deleteExprAt(uint32_t aPos)
   1.934 +    {
   1.935 +        NS_ASSERTION(aPos < mExpressions.Length(),
   1.936 +                     "killing bad expression index");
   1.937 +
   1.938 +        delete mExpressions[aPos];
   1.939 +        mExpressions.RemoveElementAt(aPos);
   1.940 +    }
   1.941 +
   1.942 +    TX_DECL_OPTIMIZABLE_EXPR
   1.943 +
   1.944 +private:
   1.945 +
   1.946 +   txOwningArray<Expr> mExpressions;
   1.947 +
   1.948 +}; //-- UnionExpr
   1.949 +
   1.950 +/**
   1.951 + * Class specializing in executing expressions like "@foo" where we are
   1.952 + * interested in different result-types, and expressions like "@foo = 'hi'"
   1.953 + */
   1.954 +class txNamedAttributeStep : public Expr
   1.955 +{
   1.956 +public:
   1.957 +    txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix,
   1.958 +                         nsIAtom* aLocalName);
   1.959 +
   1.960 +    TX_DECL_EXPR
   1.961 +
   1.962 +private:
   1.963 +    int32_t mNamespace;
   1.964 +    nsCOMPtr<nsIAtom> mPrefix;
   1.965 +    nsCOMPtr<nsIAtom> mLocalName;
   1.966 +};
   1.967 +
   1.968 +/**
   1.969 + *
   1.970 + */
   1.971 +class txUnionNodeTest : public txNodeTest
   1.972 +{
   1.973 +public:
   1.974 +    nsresult addNodeTest(txNodeTest* aNodeTest)
   1.975 +    {
   1.976 +        return mNodeTests.AppendElement(aNodeTest) ?
   1.977 +            NS_OK : NS_ERROR_OUT_OF_MEMORY;
   1.978 +    }
   1.979 +
   1.980 +    TX_DECL_NODE_TEST
   1.981 +
   1.982 +private:
   1.983 +    txOwningArray<txNodeTest> mNodeTests;
   1.984 +};
   1.985 +
   1.986 +/**
   1.987 + *  Expression that failed to parse
   1.988 + */
   1.989 +class txErrorExpr : public Expr
   1.990 +{
   1.991 +public:
   1.992 +#ifdef TX_TO_STRING
   1.993 +    txErrorExpr(const nsAString& aStr)
   1.994 +      : mStr(aStr)
   1.995 +    {
   1.996 +    }
   1.997 +#endif
   1.998 +
   1.999 +    TX_DECL_EXPR
  1.1000 +
  1.1001 +#ifdef TX_TO_STRING
  1.1002 +private:
  1.1003 +    nsString mStr;
  1.1004 +#endif
  1.1005 +};
  1.1006 +
  1.1007 +#endif
  1.1008 +
  1.1009 +

mercurial