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
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/
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
15
* The Original Code is TransforMiiX XSLT processor code.
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.
23
* Keith Visco <kvisco@ziplink.net> (Original Author)
24
* Larry Fitzpatick, OpenText <lef@opentext.com>
25
* Jonas Sicking <sicking@bigfoot.com>
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.
39
* ***** END LICENSE BLOCK ***** */
41
#ifndef TRANSFRMX_EXPR_H
42
#define TRANSFRMX_EXPR_H
44
#include "nsAutoPtr.h"
45
#include "txExprResult.h"
48
#include "txOwningArray.h"
56
XPath class definitions.
57
Much of this code was ported from XSL:P.
61
class txIParseContext;
62
class txIMatchContext;
68
* A Base Class for all XSL Expressions
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
87
* @return the result of the evaluation
89
virtual nsresult evaluate(txIEvalContext* aContext,
90
txAExprResult** aResult) = 0;
94
* Returns the type of this expression.
103
virtual ExprType getType()
109
* Returns the type or types of results this Expr return.
111
typedef PRUint16 ResultType;
113
NODESET_RESULT = 0x01,
114
BOOLEAN_RESULT = 0x02,
115
NUMBER_RESULT = 0x04,
116
STRING_RESULT = 0x08,
120
virtual ResultType getReturnType() = 0;
121
PRBool canReturnType(ResultType aType)
123
return (getReturnType() & aType) != 0;
126
typedef PRUint16 ContextSensitivity;
130
POSITION_CONTEXT = 0x02,
132
NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
133
VARIABLES_CONTEXT = 0x08,
134
PRIVATE_CONTEXT = 0x10,
139
* Returns true if this expression is sensitive to *any* of
140
* the requested contexts in aContexts.
142
virtual PRBool isSensitiveTo(ContextSensitivity aContexts) = 0;
145
* Returns sub-expression at given position
147
virtual Expr* getSubExprAt(PRUint32 aPos) = 0;
150
* Replace sub-expression at given position. Does not delete the old
151
* expression, that is the responsibility of the caller.
153
virtual void setSubExprAt(PRUint32 aPos, Expr* aExpr) = 0;
155
virtual nsresult evaluateToBool(txIEvalContext* aContext,
158
virtual nsresult evaluateToString(txIEvalContext* aContext,
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.
170
virtual void toString(nsAString& str) = 0;
175
#define TX_DECL_TOSTRING \
176
void toString(nsAString& aDest);
177
#define TX_DECL_GETNAMEATOM \
178
nsresult getNameAtom(nsIAtom** aAtom);
180
#define TX_DECL_TOSTRING
181
#define TX_DECL_GETNAMEATOM
184
#define TX_DECL_EXPR_BASE \
185
nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
186
ResultType getReturnType(); \
187
PRBool isSensitiveTo(ContextSensitivity aContexts);
189
#define TX_DECL_EXPR \
192
Expr* getSubExprAt(PRUint32 aPos); \
193
void setSubExprAt(PRUint32 aPos, Expr* aExpr);
195
#define TX_DECL_OPTIMIZABLE_EXPR \
200
#define TX_DECL_FUNCTION \
201
TX_DECL_GETNAMEATOM \
204
#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
206
_class::getReturnType() \
208
return _ReturnType; \
211
#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType) \
212
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
214
_class::getSubExprAt(PRUint32 aPos) \
219
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
221
NS_NOTREACHED("setting bad subexpression index"); \
224
#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1) \
225
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
227
_class::getSubExprAt(PRUint32 aPos) \
235
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
237
NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
242
#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
243
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
245
_class::getSubExprAt(PRUint32 aPos) \
258
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
260
NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
271
#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
272
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
274
_class::getSubExprAt(PRUint32 aPos) \
276
return _ExprList.SafeElementAt(aPos); \
279
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
281
NS_ASSERTION(aPos < _ExprList.Length(), \
282
"setting bad subexpression index"); \
283
_ExprList[aPos] = aExpr; \
288
* This class represents a FunctionCall as defined by the XPath 1.0
291
class FunctionCall : public Expr
295
* Adds the given parameter to this FunctionCall's parameter list.
296
* The ownership of the given Expr is passed over to the FunctionCall,
298
* @param aExpr the Expr to add to this FunctionCall's parameter list
299
* @return nsresult indicating out of memory
301
nsresult addParam(Expr* aExpr)
303
return mParams.AppendElement(aExpr) ?
304
NS_OK : NS_ERROR_OUT_OF_MEMORY;
308
* Check if the number of parameters falls within a range.
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.
316
* XXX txIEvalContext should be txIParseContest, bug 143291
318
virtual PRBool requireParams(PRInt32 aParamCountMin,
319
PRInt32 aParamCountMax,
320
txIEvalContext* aContext);
323
Expr* getSubExprAt(PRUint32 aPos);
324
void setSubExprAt(PRUint32 aPos, Expr* aExpr);
328
txOwningArray<Expr> mParams;
331
* Evaluates the given Expression and converts its result to a number.
333
static double evaluateToNumber(Expr* aExpr, txIEvalContext* aContext);
336
* Evaluates the given Expression and converts its result to a NodeSet.
337
* If the result is not a NodeSet an error is returned.
339
static nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
340
txNodeSet** aResult);
343
* Returns true if any argument is sensitive to the given context.
345
PRBool argsSensitiveTo(ContextSensitivity aContexts);
350
* Returns the name of the function as an atom.
352
virtual nsresult getNameAtom(nsIAtom** aAtom) = 0;
356
class txCoreFunctionCall : public FunctionCall
360
// This must be ordered in the same order as descriptTable in
361
// txCoreFunctionCall.cpp. If you change one, change the other.
363
COUNT = 0, // count()
366
LOCAL_NAME, // local-name()
367
NAMESPACE_URI, // namespace-uri()
369
POSITION, // position()
372
CONTAINS, // contains()
373
NORMALIZE_SPACE, // normalize-space()
374
STARTS_WITH, // starts-with()
376
STRING_LENGTH, // string-length()
377
SUBSTRING, // substring()
378
SUBSTRING_AFTER, // substring-after()
379
SUBSTRING_BEFORE, // substring-before()
380
TRANSLATE, // translate()
385
CEILING, // ceiling()
388
BOOLEAN, // boolean()
396
* Creates a txCoreFunctionCall of the given type
398
txCoreFunctionCall(eType aType) : mType(aType)
404
static PRBool getTypeFromAtom(nsIAtom* aName, eType& aType);
412
* This class represents a NodeTest as defined by the XPath spec
419
MOZ_COUNT_CTOR(txNodeTest);
421
virtual ~txNodeTest()
423
MOZ_COUNT_DTOR(txNodeTest);
428
* pretty much a txPattern, but not supposed to be used
429
* standalone. The NodeTest node() is different to the
430
* Pattern "node()" (document node isn't matched)
432
virtual PRBool matches(const txXPathNode& aNode,
433
txIMatchContext* aContext) = 0;
434
virtual double getDefaultPriority() = 0;
437
* Returns the type of this nodetest.
444
virtual NodeTestType getType()
450
* Returns true if this expression is sensitive to *any* of
451
* the requested flags.
453
virtual PRBool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
456
virtual void toString(nsAString& aDest) = 0;
460
#define TX_DECL_NODE_TEST \
462
PRBool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
463
double getDefaultPriority(); \
464
PRBool isSensitiveTo(Expr::ContextSensitivity aContext);
467
* This class represents a NameTest as defined by the XPath spec
469
class txNameTest : public txNodeTest
473
* Creates a new txNameTest with the given type and the given
474
* principal node type
476
txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID,
479
NodeTestType getType();
483
nsCOMPtr<nsIAtom> mPrefix;
484
nsCOMPtr<nsIAtom> mLocalName;
491
* This class represents a NodeType as defined by the XPath spec
493
class txNodeTypeTest : public txNodeTest
504
* Creates a new txNodeTypeTest of the given type
506
txNodeTypeTest(NodeType aNodeType)
507
: mNodeType(aNodeType)
512
* Sets the name of the node to match. Only availible for pi nodes
514
void setNodeName(const nsAString& aName)
516
mNodeName = do_GetAtom(aName);
519
NodeType getNodeTestType()
524
NodeTestType getType();
530
nsCOMPtr<nsIAtom> mNodeName;
534
* Class representing a nodetest combined with a predicate. May only be used
535
* if the predicate is not sensitive to the context-nodelist.
537
class txPredicatedNodeTest : public txNodeTest
540
txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
544
nsAutoPtr<txNodeTest> mNodeTest;
545
nsAutoPtr<Expr> mPredicate;
549
* Represents an ordered list of Predicates,
550
* for use with Step and Filter Expressions
552
class PredicateList {
555
* Adds the given Expr to the list.
556
* The ownership of the given Expr is passed over the PredicateList,
558
* @param aExpr the Expr to add to the list
559
* @return nsresult indicating out of memory
561
nsresult add(Expr* aExpr)
563
NS_ASSERTION(aExpr, "missing expression");
564
return mPredicates.AppendElement(aExpr) ?
565
NS_OK : NS_ERROR_OUT_OF_MEMORY;
568
nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
571
* Drops the first predicate without deleting it.
575
mPredicates.RemoveElementAt(0);
579
* returns true if this predicate list is empty
583
return mPredicates.IsEmpty();
588
* Returns the String representation of this PredicateList.
589
* @param dest the String to use when creating the String
590
* representation. The String representation will be appended to
591
* any data in the destination String, to allow cascading calls to
592
* other #toString() methods for Expressions.
593
* @return the String representation of this PredicateList.
595
void toString(nsAString& dest);
599
PRBool isSensitiveTo(Expr::ContextSensitivity aContext);
600
Expr* getSubExprAt(PRUint32 aPos)
602
return mPredicates.SafeElementAt(aPos);
604
void setSubExprAt(PRUint32 aPos, Expr* aExpr)
606
NS_ASSERTION(aPos < mPredicates.Length(),
607
"setting bad subexpression index");
608
mPredicates[aPos] = aExpr;
611
//-- list of predicates
612
txOwningArray<Expr> mPredicates;
613
}; //-- PredicateList
615
class LocationStep : public Expr,
619
enum LocationStepType {
621
ANCESTOR_OR_SELF_AXIS,
625
DESCENDANT_OR_SELF_AXIS,
627
FOLLOWING_SIBLING_AXIS,
631
PRECEDING_SIBLING_AXIS,
636
* Creates a new LocationStep using the given NodeExpr and Axis Identifier
637
* @param nodeExpr the NodeExpr to use when matching Nodes
638
* @param axisIdentifier the Axis Identifier in which to search for nodes
640
LocationStep(txNodeTest* aNodeTest,
641
LocationStepType aAxisIdentifier)
642
: mNodeTest(aNodeTest),
643
mAxisIdentifier(aAxisIdentifier)
647
TX_DECL_OPTIMIZABLE_EXPR
649
txNodeTest* getNodeTest()
653
void setNodeTest(txNodeTest* aNodeTest)
656
mNodeTest = aNodeTest;
658
LocationStepType getAxisIdentifier()
660
return mAxisIdentifier;
662
void setAxisIdentifier(LocationStepType aAxisIdentifier)
664
mAxisIdentifier = aAxisIdentifier;
668
void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
670
void fromDescendantsRev(const txXPathNode& aNode, txIMatchContext* aCs,
673
nsAutoPtr<txNodeTest> mNodeTest;
674
LocationStepType mAxisIdentifier;
677
class FilterExpr : public Expr,
683
* Creates a new FilterExpr using the given Expr
684
* @param expr the Expr to use for evaluation
686
FilterExpr(Expr* aExpr)
694
nsAutoPtr<Expr> expr;
699
class txLiteralExpr : public Expr {
701
txLiteralExpr(double aDbl)
702
: mValue(new NumberResult(aDbl, nsnull))
705
txLiteralExpr(const nsAString& aStr)
706
: mValue(new StringResult(aStr, nsnull))
709
txLiteralExpr(txAExprResult* aValue)
717
nsRefPtr<txAExprResult> mValue;
721
* Represents an UnaryExpr. Returns the negative value of it's expr.
723
class UnaryExpr : public Expr {
727
UnaryExpr(Expr* aExpr)
735
nsAutoPtr<Expr> expr;
739
* Represents a BooleanExpr, a binary expression that
740
* performs a boolean operation between it's lvalue and rvalue.
742
class BooleanExpr : public Expr
746
//-- BooleanExpr Types
747
enum _BooleanExprType { AND = 1, OR };
749
BooleanExpr(Expr* aLeftExpr, Expr* aRightExpr, short aOp)
750
: leftExpr(aLeftExpr),
751
rightExpr(aRightExpr),
759
nsAutoPtr<Expr> leftExpr, rightExpr;
764
* Represents a MultiplicativeExpr, a binary expression that
765
* performs a multiplicative operation between it's lvalue and rvalue:
771
class txNumberExpr : public Expr
775
enum eOp { ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS };
777
txNumberExpr(Expr* aLeftExpr, Expr* aRightExpr, eOp aOp)
778
: mLeftExpr(aLeftExpr),
779
mRightExpr(aRightExpr),
787
nsAutoPtr<Expr> mLeftExpr, mRightExpr;
789
}; //-- MultiplicativeExpr
792
* Represents a RelationalExpr, an expression that compares it's lvalue
793
* to it's rvalue using:
797
* <= : less than or equal to
798
* >= : greater than or equal to
801
class RelationalExpr : public Expr
804
enum RelationalExprType {
813
RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp)
814
: mLeftExpr(aLeftExpr),
815
mRightExpr(aRightExpr),
824
PRBool compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
825
txAExprResult* aRight);
827
nsAutoPtr<Expr> mLeftExpr;
828
nsAutoPtr<Expr> mRightExpr;
829
RelationalExprType mOp;
834
* Represents a variable reference ($refname)
836
class VariableRefExpr : public Expr {
840
VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID);
845
nsCOMPtr<nsIAtom> mPrefix;
846
nsCOMPtr<nsIAtom> mLocalName;
851
* Represents a PathExpr
853
class PathExpr : public Expr {
858
//-- RELATIVE_OP is the default
859
//-- LF, changed from static const short to enum
860
enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
863
* Adds the Expr to this PathExpr
864
* The ownership of the given Expr is passed over the PathExpr,
866
* @param aExpr the Expr to add to this PathExpr
867
* @return nsresult indicating out of memory
869
nsresult addExpr(Expr* aExpr, PathOperator pathOp);
872
* Removes and deletes the expression at the given index.
874
void deleteExprAt(PRUint32 aPos)
876
NS_ASSERTION(aPos < mItems.Length(),
877
"killing bad expression index");
878
mItems.RemoveElementAt(aPos);
881
TX_DECL_OPTIMIZABLE_EXPR
883
PathOperator getPathOpAt(PRUint32 aPos)
885
NS_ASSERTION(aPos < mItems.Length(), "getting bad pathop index");
886
return mItems[aPos].pathOp;
888
void setPathOpAt(PRUint32 aPos, PathOperator aPathOp)
890
NS_ASSERTION(aPos < mItems.Length(), "setting bad pathop index");
891
mItems[aPos].pathOp = aPathOp;
897
nsAutoPtr<Expr> expr;
901
nsTArray<PathExprItem> mItems;
904
* Selects from the descendants of the context node
905
* all nodes that match the Expr
907
nsresult evalDescendants(Expr* aStep, const txXPathNode& aNode,
908
txIMatchContext* aContext,
909
txNodeSet* resNodes);
913
* This class represents a RootExpr, which only matches the Document node
915
class RootExpr : public Expr {
918
* Creates a new RootExpr
922
: mSerialize(PR_TRUE)
931
void setSerialize(PRBool aSerialize)
933
mSerialize = aSerialize;
937
// When a RootExpr is used in a PathExpr it shouldn't be serialized
943
* Represents a UnionExpr
945
class UnionExpr : public Expr {
948
* Adds the PathExpr to this UnionExpr
949
* The ownership of the given Expr is passed over the UnionExpr,
951
* @param aExpr the Expr to add to this UnionExpr
952
* @return nsresult indicating out of memory
954
nsresult addExpr(Expr* aExpr)
956
return mExpressions.AppendElement(aExpr) ?
957
NS_OK : NS_ERROR_OUT_OF_MEMORY;
961
* Removes and deletes the expression at the given index.
963
void deleteExprAt(PRUint32 aPos)
965
NS_ASSERTION(aPos < mExpressions.Length(),
966
"killing bad expression index");
968
delete mExpressions[aPos];
969
mExpressions.RemoveElementAt(aPos);
972
TX_DECL_OPTIMIZABLE_EXPR
976
txOwningArray<Expr> mExpressions;
981
* Class specializing in executing expressions like "@foo" where we are
982
* interested in different result-types, and expressions like "@foo = 'hi'"
984
class txNamedAttributeStep : public Expr
987
txNamedAttributeStep(PRInt32 aNsID, nsIAtom* aPrefix,
988
nsIAtom* aLocalName);
994
nsCOMPtr<nsIAtom> mPrefix;
995
nsCOMPtr<nsIAtom> mLocalName;
1001
class txUnionNodeTest : public txNodeTest
1004
nsresult addNodeTest(txNodeTest* aNodeTest)
1006
return mNodeTests.AppendElement(aNodeTest) ?
1007
NS_OK : NS_ERROR_OUT_OF_MEMORY;
1013
txOwningArray<txNodeTest> mNodeTests;
1017
* Expression that failed to parse
1019
class txErrorExpr : public Expr
1023
txErrorExpr(const nsAString& aStr)