Bug 208172: Implement optimizable XPath. r=peterv sr=jst
git-svn-id: svn://10.0.0.236/trunk@188201 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -231,6 +231,26 @@ void txList::clear()
|
||||
itemCount = 0;
|
||||
}
|
||||
|
||||
void*
|
||||
txList::replace(PRUint32 aIndex, void* aObjPtr)
|
||||
{
|
||||
PRUint32 i = 0;
|
||||
ListItem* item = firstItem;
|
||||
while (i < aIndex && item) {
|
||||
item = item->nextItem;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void* oldObj = item->objPtr;
|
||||
item->objPtr = aObjPtr;
|
||||
|
||||
return oldObj;
|
||||
}
|
||||
|
||||
//------------------------------------/
|
||||
//- Implementation of txListIterator -/
|
||||
//------------------------------------/
|
||||
|
||||
@@ -74,6 +74,14 @@ public:
|
||||
**/
|
||||
PRInt32 getLength();
|
||||
|
||||
/**
|
||||
* Returns true if there are no items in this txList
|
||||
*/
|
||||
inline PRBool isEmpty()
|
||||
{
|
||||
return itemCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Object to the specified position in the list
|
||||
**/
|
||||
@@ -94,6 +102,14 @@ public:
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Replaces the Object at the given index with a new Object.
|
||||
* If the given index is outside the list null is returned.
|
||||
* @param aIndex index of Object to replace.
|
||||
* @param aObjPtr new Object to put in the list.
|
||||
* @return the old Object pointer
|
||||
*/
|
||||
void* replace(PRUint32 aIndex, void* aObjPtr);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ CPPSRCS = txAdditiveExpr.cpp \
|
||||
txNumberFunctionCall.cpp \
|
||||
txNumberResult.cpp \
|
||||
txPathExpr.cpp \
|
||||
txPredicatedNodeTest.cpp \
|
||||
txPredicateList.cpp \
|
||||
txRelationalExpr.cpp \
|
||||
txRootExpr.cpp \
|
||||
@@ -86,6 +87,7 @@ CPPSRCS = txAdditiveExpr.cpp \
|
||||
txErrorExpr.cpp \
|
||||
txLiteralExpr.cpp \
|
||||
txNameTest.cpp \
|
||||
txNamedAttributeStep.cpp \
|
||||
txNodeSet.cpp \
|
||||
txNodeTypeTest.cpp \
|
||||
txForwardContext.cpp \
|
||||
@@ -93,7 +95,8 @@ CPPSRCS = txAdditiveExpr.cpp \
|
||||
txResultRecycler.cpp \
|
||||
txUnionExpr.cpp \
|
||||
txUnaryExpr.cpp \
|
||||
txVariableRefExpr.cpp
|
||||
txVariableRefExpr.cpp \
|
||||
txXPathOptimizer.cpp
|
||||
ifndef MOZ_XSLT_STANDALONE
|
||||
CPPSRCS += nsXPathEvaluator.cpp \
|
||||
nsXPathExpression.cpp \
|
||||
|
||||
@@ -83,6 +83,15 @@ AdditiveExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return aContext->recycler()->getNumberResult(result, aResult);
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_2(AdditiveExpr, NUMBER_RESULT, leftExpr, rightExpr)
|
||||
|
||||
PRBool
|
||||
AdditiveExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return leftExpr->isSensitiveTo(aContext) ||
|
||||
rightExpr->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
AdditiveExpr::toString(nsAString& str)
|
||||
@@ -103,4 +112,3 @@ AdditiveExpr::toString(nsAString& str)
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -85,6 +85,15 @@ BooleanExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_2(BooleanExpr, BOOLEAN_RESULT, leftExpr, rightExpr)
|
||||
|
||||
PRBool
|
||||
BooleanExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return leftExpr->isSensitiveTo(aContext) ||
|
||||
rightExpr->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
BooleanExpr::toString(nsAString& str)
|
||||
|
||||
@@ -143,6 +143,19 @@ BooleanFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
BooleanFunctionCall::getReturnType()
|
||||
{
|
||||
return BOOLEAN_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
BooleanFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext) ||
|
||||
(mType == TX_LANG && (aContext & NODE_CONTEXT));
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
BooleanFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -57,6 +57,16 @@ txErrorExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_XPATH_INVALID_EXPRESSION_EVALUATED;
|
||||
}
|
||||
|
||||
TX_IMPL_EXPR_STUBS_0(txErrorExpr, ANY_RESULT)
|
||||
|
||||
PRBool
|
||||
txErrorExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txErrorExpr::toString(nsAString& aStr)
|
||||
|
||||
@@ -87,6 +87,69 @@ public:
|
||||
virtual nsresult evaluate(txIEvalContext* aContext,
|
||||
txAExprResult** aResult) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type of this expression.
|
||||
*/
|
||||
enum ExprType {
|
||||
LOCATIONSTEP_ATTRIBUTE_EXPR,
|
||||
LOCATIONSTEP_OTHER_EXPR,
|
||||
OTHER_EXPR
|
||||
};
|
||||
virtual ExprType getType()
|
||||
{
|
||||
return OTHER_EXPR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type or types of results this Expr return.
|
||||
*/
|
||||
typedef PRUint16 ResultType;
|
||||
enum {
|
||||
NODESET_RESULT = 0x01,
|
||||
BOOLEAN_RESULT = 0x02,
|
||||
NUMBER_RESULT = 0x04,
|
||||
STRING_RESULT = 0x08,
|
||||
RTF_RESULT = 0x10,
|
||||
ANY_RESULT = 0xFFFF
|
||||
};
|
||||
virtual ResultType getReturnType() = 0;
|
||||
PRBool canReturnType(ResultType aType)
|
||||
{
|
||||
return (getReturnType() & aType) != 0;
|
||||
}
|
||||
|
||||
typedef PRUint16 ContextSensitivity;
|
||||
enum {
|
||||
NO_CONTEXT = 0x00,
|
||||
DOCUMENT_CONTEXT = 0x01,
|
||||
NODE_ONLY_CONTEXT = 0x02,
|
||||
NODE_CONTEXT = DOCUMENT_CONTEXT | NODE_ONLY_CONTEXT,
|
||||
POSITION_CONTEXT = 0x04,
|
||||
SIZE_CONTEXT = 0x08,
|
||||
NODESET_CONTEXT = POSITION_CONTEXT | SIZE_CONTEXT,
|
||||
VARIABLES_CONTEXT = 0x10,
|
||||
PRIVATE_CONTEXT = 0x20,
|
||||
ANY_CONTEXT = 0xFFFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this expression is sensitive to *any* of
|
||||
* the requested contexts in aContexts.
|
||||
*/
|
||||
virtual PRBool isSensitiveTo(ContextSensitivity aContexts) = 0;
|
||||
|
||||
/**
|
||||
* Returns sub-expression at given position
|
||||
*/
|
||||
virtual Expr* getSubExprAt(PRUint32 aPos) = 0;
|
||||
|
||||
/**
|
||||
* Replace sub-expression at given position. Does not delete the old
|
||||
* expression, that is the responsibility of the caller.
|
||||
*/
|
||||
virtual void setSubExprAt(PRUint32 aPos, Expr* aExpr) = 0;
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
@@ -100,21 +163,118 @@ public:
|
||||
#endif
|
||||
}; //-- Expr
|
||||
|
||||
#define TX_DECL_EVALUATE \
|
||||
nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
|
||||
#ifndef TX_TO_STRING
|
||||
#define TX_DECL_EXPR TX_DECL_EVALUATE
|
||||
#define TX_DECL_FUNCTION TX_DECL_EVALUATE
|
||||
#ifdef TX_TO_STRING
|
||||
#define TX_DECL_TOSTRING \
|
||||
void toString(nsAString& aDest);
|
||||
#define TX_DECL_GETNAMEATOM \
|
||||
nsresult getNameAtom(nsIAtom** aAtom);
|
||||
#else
|
||||
#define TX_DECL_TOSTRING
|
||||
#define TX_DECL_GETNAMEATOM
|
||||
#endif
|
||||
|
||||
#define TX_DECL_EXPR_BASE \
|
||||
nsresult evaluate(txIEvalContext* aContext, txAExprResult** aResult); \
|
||||
ResultType getReturnType(); \
|
||||
PRBool isSensitiveTo(ContextSensitivity aContexts)
|
||||
|
||||
#define TX_DECL_EXPR \
|
||||
TX_DECL_EVALUATE; \
|
||||
void toString(nsAString& aDest)
|
||||
TX_DECL_EXPR_BASE; \
|
||||
TX_DECL_TOSTRING \
|
||||
Expr* getSubExprAt(PRUint32 aPos); \
|
||||
void setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
|
||||
#define TX_DECL_OPTIMIZABLE_EXPR \
|
||||
TX_DECL_EXPR; \
|
||||
ExprType getType()
|
||||
|
||||
|
||||
#define TX_DECL_FUNCTION \
|
||||
TX_DECL_EVALUATE; \
|
||||
nsresult getNameAtom(nsIAtom** aAtom)
|
||||
#endif
|
||||
TX_DECL_GETNAMEATOM \
|
||||
TX_DECL_EXPR_BASE
|
||||
|
||||
#define TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
|
||||
Expr::ResultType \
|
||||
_class::getReturnType() \
|
||||
{ \
|
||||
return _ReturnType; \
|
||||
}
|
||||
|
||||
#define TX_IMPL_EXPR_STUBS_0(_class, _ReturnType) \
|
||||
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
|
||||
Expr* \
|
||||
_class::getSubExprAt(PRUint32 aPos) \
|
||||
{ \
|
||||
return nsnull; \
|
||||
} \
|
||||
void \
|
||||
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
|
||||
{ \
|
||||
NS_NOTREACHED("setting bad subexpression index"); \
|
||||
}
|
||||
|
||||
#define TX_IMPL_EXPR_STUBS_1(_class, _ReturnType, _Expr1) \
|
||||
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
|
||||
Expr* \
|
||||
_class::getSubExprAt(PRUint32 aPos) \
|
||||
{ \
|
||||
if (aPos == 0) { \
|
||||
return _Expr1; \
|
||||
} \
|
||||
return nsnull; \
|
||||
} \
|
||||
void \
|
||||
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
|
||||
{ \
|
||||
NS_ASSERTION(aPos < 1, "setting bad subexpression index");\
|
||||
_Expr1.forget(); \
|
||||
_Expr1 = aExpr; \
|
||||
}
|
||||
|
||||
#define TX_IMPL_EXPR_STUBS_2(_class, _ReturnType, _Expr1, _Expr2) \
|
||||
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
|
||||
Expr* \
|
||||
_class::getSubExprAt(PRUint32 aPos) \
|
||||
{ \
|
||||
switch(aPos) { \
|
||||
case 0: \
|
||||
return _Expr1; \
|
||||
case 1: \
|
||||
return _Expr2; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
return nsnull; \
|
||||
} \
|
||||
void \
|
||||
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
|
||||
{ \
|
||||
NS_ASSERTION(aPos < 2, "setting bad subexpression index");\
|
||||
if (aPos == 0) { \
|
||||
_Expr1.forget(); \
|
||||
_Expr1 = aExpr; \
|
||||
} \
|
||||
else { \
|
||||
_Expr2.forget(); \
|
||||
_Expr2 = aExpr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TX_IMPL_EXPR_STUBS_LIST(_class, _ReturnType, _ExprList) \
|
||||
TX_IMPL_EXPR_STUBS_BASE(_class, _ReturnType) \
|
||||
Expr* \
|
||||
_class::getSubExprAt(PRUint32 aPos) \
|
||||
{ \
|
||||
return NS_STATIC_CAST(Expr*, _ExprList.get(aPos)); \
|
||||
} \
|
||||
void \
|
||||
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
|
||||
{ \
|
||||
NS_ASSERTION(aPos < (PRUint32)_ExprList.getLength(), \
|
||||
"setting bad subexpression index"); \
|
||||
_ExprList.replace(aPos, aExpr); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class represents a FunctionCall as defined by the XPath 1.0
|
||||
@@ -149,9 +309,9 @@ public:
|
||||
PRInt32 aParamCountMax,
|
||||
txIEvalContext* aContext);
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void toString(nsAString& aDest);
|
||||
#endif
|
||||
TX_DECL_TOSTRING
|
||||
Expr* getSubExprAt(PRUint32 aPos);
|
||||
void setSubExprAt(PRUint32 aPos, Expr* aExpr);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -183,6 +343,12 @@ protected:
|
||||
nsresult evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext,
|
||||
txNodeSet** aResult);
|
||||
|
||||
/**
|
||||
* Returns true if any argument is sensitive to the given context.
|
||||
*/
|
||||
PRBool argsSensitiveTo(ContextSensitivity aContexts);
|
||||
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
/*
|
||||
* Returns the name of the function as an atom.
|
||||
@@ -232,22 +398,34 @@ public:
|
||||
txIMatchContext* aContext) = 0;
|
||||
virtual double getDefaultPriority() = 0;
|
||||
|
||||
/**
|
||||
* Returns the type of this nodetest.
|
||||
*/
|
||||
enum NodeTestType {
|
||||
NAME_TEST,
|
||||
OTHER_TEST
|
||||
};
|
||||
virtual NodeTestType getType()
|
||||
{
|
||||
return OTHER_TEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this expression is sensitive to *any* of
|
||||
* the requested flags.
|
||||
*/
|
||||
virtual PRBool isSensitiveTo(Expr::ContextSensitivity aContext) = 0;
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
virtual void toString(nsAString& aDest) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define TX_DECL_NODE_TEST_BASE \
|
||||
PRBool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
|
||||
double getDefaultPriority()
|
||||
|
||||
#ifndef TX_TO_STRING
|
||||
#define TX_DECL_NODE_TEST TX_DECL_NODE_TEST_BASE
|
||||
#else
|
||||
#define TX_DECL_NODE_TEST \
|
||||
TX_DECL_NODE_TEST_BASE; \
|
||||
void toString(nsAString& aDest)
|
||||
#endif
|
||||
TX_DECL_TOSTRING \
|
||||
PRBool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
|
||||
double getDefaultPriority(); \
|
||||
PRBool isSensitiveTo(Expr::ContextSensitivity aContext);
|
||||
|
||||
/*
|
||||
* This class represents a NameTest as defined by the XPath spec
|
||||
@@ -262,14 +440,14 @@ public:
|
||||
txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
PRUint16 aNodeType);
|
||||
|
||||
~txNameTest();
|
||||
NodeTestType getType();
|
||||
|
||||
TX_DECL_NODE_TEST;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
PRInt32 mNamespace;
|
||||
private:
|
||||
PRUint16 mNodeType;
|
||||
};
|
||||
|
||||
@@ -291,8 +469,6 @@ public:
|
||||
*/
|
||||
txNodeTypeTest(NodeType aNodeType);
|
||||
|
||||
~txNodeTypeTest();
|
||||
|
||||
/*
|
||||
* Sets the name of the node to match. Only availible for pi nodes
|
||||
*/
|
||||
@@ -305,6 +481,21 @@ private:
|
||||
nsCOMPtr<nsIAtom> mNodeName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class representing a nodetest combined with a predicate. May only be used
|
||||
* if the predicate is not sensitive to the context-nodelist.
|
||||
*/
|
||||
class txPredicatedNodeTest : public txNodeTest
|
||||
{
|
||||
public:
|
||||
txPredicatedNodeTest(txNodeTest* aNodeTest, Expr* aPredicate);
|
||||
TX_DECL_NODE_TEST;
|
||||
|
||||
private:
|
||||
nsAutoPtr<txNodeTest> mNodeTest;
|
||||
nsAutoPtr<Expr> mPredicate;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an ordered list of Predicates,
|
||||
* for use with Step and Filter Expressions
|
||||
@@ -334,6 +525,11 @@ public:
|
||||
|
||||
nsresult evaluatePredicates(txNodeSet* aNodes, txIMatchContext* aContext);
|
||||
|
||||
/**
|
||||
* Drops the first predicate without deleting it.
|
||||
*/
|
||||
void dropFirst();
|
||||
|
||||
/**
|
||||
* returns true if this predicate list is empty
|
||||
**/
|
||||
@@ -352,6 +548,10 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
PRBool isSensitiveTo(Expr::ContextSensitivity aContext);
|
||||
Expr* getSubExprAt(PRUint32 aPos);
|
||||
void setSubExprAt(PRUint32 aPos, Expr* aExpr);
|
||||
|
||||
//-- list of predicates
|
||||
List predicates;
|
||||
}; //-- PredicateList
|
||||
@@ -388,7 +588,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
TX_DECL_EXPR;
|
||||
TX_DECL_OPTIMIZABLE_EXPR;
|
||||
|
||||
txNodeTest* getNodeTest()
|
||||
{
|
||||
return mNodeTest;
|
||||
}
|
||||
void setNodeTest(txNodeTest* aNodeTest)
|
||||
{
|
||||
mNodeTest.forget();
|
||||
mNodeTest = aNodeTest;
|
||||
}
|
||||
|
||||
private:
|
||||
void fromDescendants(const txXPathNode& aNode, txIMatchContext* aCs,
|
||||
@@ -588,7 +798,6 @@ class VariableRefExpr : public Expr {
|
||||
public:
|
||||
|
||||
VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID);
|
||||
~VariableRefExpr();
|
||||
|
||||
TX_DECL_EXPR;
|
||||
|
||||
@@ -717,6 +926,24 @@ private:
|
||||
|
||||
}; //-- UnionExpr
|
||||
|
||||
/**
|
||||
* Class specializing in executing expressions like "@foo" where we are
|
||||
* interested in different result-types, and expressions like "@foo = 'hi'"
|
||||
*/
|
||||
class txNamedAttributeStep : public Expr
|
||||
{
|
||||
public:
|
||||
txNamedAttributeStep(PRInt32 aNsID, nsIAtom* aPrefix,
|
||||
nsIAtom* aLocalName);
|
||||
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
PRInt32 mNamespace;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Expression that failed to parse
|
||||
*/
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "txIXPathContext.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "txXPathNode.h"
|
||||
#include "txXPathOptimizer.h"
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
@@ -193,10 +194,9 @@ txExprParser::createExprInternal(const nsSubstring& aExpression,
|
||||
aContext->SetErrorOffset(lexer.mPosition - start + aSubStringPos);
|
||||
return rv;
|
||||
}
|
||||
rv = createExpr(lexer, aContext, aExpr);
|
||||
nsAutoPtr<Expr> expr;
|
||||
rv = createExpr(lexer, aContext, getter_Transfers(expr));
|
||||
if (NS_SUCCEEDED(rv) && lexer.peek()->mType != Token::END) {
|
||||
delete *aExpr;
|
||||
*aExpr = nsnull;
|
||||
rv = NS_ERROR_XPATH_BINARY_EXPECTED;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -204,7 +204,15 @@ txExprParser::createExprInternal(const nsSubstring& aExpression,
|
||||
aExpression.BeginReading(start);
|
||||
aContext->SetErrorOffset(lexer.peek()->mStart - start + aSubStringPos);
|
||||
}
|
||||
return rv;
|
||||
|
||||
txXPathOptimizer optimizer;
|
||||
Expr* newExpr = nsnull;
|
||||
rv = optimizer.optimize(expr, &newExpr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aExpr = newExpr ? newExpr : expr.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,8 +58,10 @@ class txAExprResult : public TxObject
|
||||
{
|
||||
public:
|
||||
friend class txResultRecycler;
|
||||
|
||||
// Update txLiteralExpr::getReturnType if this enum is changed.
|
||||
enum ResultType {
|
||||
NODESET,
|
||||
NODESET = 0,
|
||||
BOOLEAN,
|
||||
NUMBER,
|
||||
STRING,
|
||||
|
||||
@@ -86,6 +86,36 @@ FilterExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_BASE(FilterExpr, NODESET_RESULT)
|
||||
|
||||
Expr*
|
||||
FilterExpr::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
if (aPos == 0) {
|
||||
return expr;
|
||||
}
|
||||
return PredicateList::getSubExprAt(aPos - 1);
|
||||
}
|
||||
|
||||
void
|
||||
FilterExpr::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
if (aPos == 0) {
|
||||
expr.forget();
|
||||
expr = aExpr;
|
||||
}
|
||||
else {
|
||||
PredicateList::setSubExprAt(aPos - 1, aExpr);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
FilterExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return expr->isSensitiveTo(aContext) ||
|
||||
PredicateList::isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
FilterExpr::toString(nsAString& str)
|
||||
|
||||
@@ -171,6 +171,33 @@ PRBool FunctionCall::requireParams(PRInt32 aParamCountMin,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
Expr*
|
||||
FunctionCall::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
return NS_STATIC_CAST(Expr*, params.get(aPos));
|
||||
}
|
||||
|
||||
void
|
||||
FunctionCall::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
NS_ASSERTION(aPos < (PRUint32)params.getLength(),
|
||||
"setting bad subexpression index");
|
||||
params.replace(aPos, aExpr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
FunctionCall::argsSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
txListIterator iter(¶ms);
|
||||
while (iter.hasNext()) {
|
||||
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(aContext)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
FunctionCall::toString(nsAString& aDest)
|
||||
|
||||
@@ -60,6 +60,38 @@ txLiteralExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static Expr::ResultType resultTypes[] =
|
||||
{
|
||||
Expr::NODESET_RESULT, // NODESET
|
||||
Expr::BOOLEAN_RESULT, // BOOLEAN
|
||||
Expr::NUMBER_RESULT, // NUMBER
|
||||
Expr::STRING_RESULT, // STRING
|
||||
Expr::RTF_RESULT // RESULT_TREE_FRAGMENT
|
||||
};
|
||||
|
||||
Expr::ResultType
|
||||
txLiteralExpr::getReturnType()
|
||||
{
|
||||
return resultTypes[mValue->getResultType()];
|
||||
}
|
||||
|
||||
Expr*
|
||||
txLiteralExpr::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
void
|
||||
txLiteralExpr::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
NS_NOTREACHED("setting bad subexpression index");
|
||||
}
|
||||
|
||||
PRBool
|
||||
txLiteralExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txLiteralExpr::toString(nsAString& aStr)
|
||||
|
||||
@@ -276,6 +276,37 @@ void LocationStep::fromDescendantsRev(const txXPathNode& aNode,
|
||||
} while (walker.moveToPreviousSibling());
|
||||
}
|
||||
|
||||
Expr::ExprType
|
||||
LocationStep::getType()
|
||||
{
|
||||
return mAxisIdentifier == ATTRIBUTE_AXIS ?
|
||||
LOCATIONSTEP_ATTRIBUTE_EXPR :
|
||||
LOCATIONSTEP_OTHER_EXPR;
|
||||
}
|
||||
|
||||
|
||||
TX_IMPL_EXPR_STUBS_BASE(LocationStep, NODESET_RESULT)
|
||||
|
||||
Expr*
|
||||
LocationStep::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
return PredicateList::getSubExprAt(aPos);
|
||||
}
|
||||
|
||||
void
|
||||
LocationStep::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
return PredicateList::setSubExprAt(aPos, aExpr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
LocationStep::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return (aContext & NODE_CONTEXT) ||
|
||||
mNodeTest->isSensitiveTo(aContext) ||
|
||||
PredicateList::isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
LocationStep::toString(nsAString& str)
|
||||
|
||||
@@ -151,6 +151,25 @@ txXPathTreeWalker::moveToValidAttribute(PRUint32 aStartIndex)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txXPathTreeWalker::moveToNamedAttribute(nsIAtom* aLocalName, PRInt32 aNSID)
|
||||
{
|
||||
if (!mPosition.isContent()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
const nsAttrName* name;
|
||||
PRUint32 i;
|
||||
for (i = 0; (name = mPosition.mContent->GetAttrNameAt(i)); ++i) {
|
||||
if (name->Equals(aLocalName, aNSID)) {
|
||||
mPosition.mIndex = i;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txXPathTreeWalker::moveToFirstChild()
|
||||
{
|
||||
|
||||
@@ -114,6 +114,15 @@ MultiplicativeExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return aContext->recycler()->getNumberResult(result, aResult);
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_2(MultiplicativeExpr, NUMBER_RESULT, leftExpr, rightExpr)
|
||||
|
||||
PRBool
|
||||
MultiplicativeExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return leftExpr->isSensitiveTo(aContext) ||
|
||||
rightExpr->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
MultiplicativeExpr::toString(nsAString& str)
|
||||
|
||||
@@ -56,10 +56,6 @@ txNameTest::txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
"Go fix txNameTest::matches");
|
||||
}
|
||||
|
||||
txNameTest::~txNameTest()
|
||||
{
|
||||
}
|
||||
|
||||
PRBool txNameTest::matches(const txXPathNode& aNode, txIMatchContext* aContext)
|
||||
{
|
||||
if ((mNodeType == txXPathNodeType::ELEMENT_NODE &&
|
||||
@@ -100,6 +96,18 @@ double txNameTest::getDefaultPriority()
|
||||
return 0;
|
||||
}
|
||||
|
||||
txNodeTest::NodeTestType
|
||||
txNameTest::getType()
|
||||
{
|
||||
return NAME_TEST;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txNameTest::isSensitiveTo(Expr::ContextSensitivity aContext)
|
||||
{
|
||||
return !!(aContext & Expr::NODE_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txNameTest::toString(nsAString& aDest)
|
||||
|
||||
96
mozilla/content/xslt/src/xpath/txNamedAttributeStep.cpp
Executable file
96
mozilla/content/xslt/src/xpath/txNamedAttributeStep.cpp
Executable file
@@ -0,0 +1,96 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIAtom.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txExpr.h"
|
||||
|
||||
txNamedAttributeStep::txNamedAttributeStep(PRInt32 aNsID,
|
||||
nsIAtom* aPrefix,
|
||||
nsIAtom* aLocalName)
|
||||
: mNamespace(aNsID),
|
||||
mPrefix(aPrefix),
|
||||
mLocalName(aLocalName)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
txNamedAttributeStep::evaluate(txIEvalContext* aContext,
|
||||
txAExprResult** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = aContext->recycler()->getNodeSet(getter_AddRefs(nodes));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txXPathTreeWalker walker(aContext->getContextNode());
|
||||
if (walker.moveToNamedAttribute(mLocalName, mNamespace)) {
|
||||
rv = nodes->append(walker.getCurrentPosition());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
NS_ADDREF(*aResult = nodes);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TX_IMPL_EXPR_STUBS_0(txNamedAttributeStep, NODESET_RESULT);
|
||||
|
||||
PRBool
|
||||
txNamedAttributeStep::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return !!(aContext & NODE_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txNamedAttributeStep::toString(nsAString& aDest)
|
||||
{
|
||||
aDest.Append(PRUnichar('@'));
|
||||
if (mPrefix) {
|
||||
nsAutoString prefix;
|
||||
mPrefix->ToString(prefix);
|
||||
aDest.Append(prefix);
|
||||
aDest.Append(PRUnichar(':'));
|
||||
}
|
||||
nsAutoString localName;
|
||||
mLocalName->ToString(localName);
|
||||
aDest.Append(localName);
|
||||
}
|
||||
#endif
|
||||
@@ -227,6 +227,59 @@ NodeSetFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
static Expr::ResultType resultTypes[] =
|
||||
{
|
||||
Expr::NUMBER_RESULT, // COUNT
|
||||
Expr::NODESET_RESULT, // ID
|
||||
Expr::NUMBER_RESULT, // LAST
|
||||
Expr::STRING_RESULT, // LOCAL_NAME
|
||||
Expr::STRING_RESULT, // NAMESPACE_URI
|
||||
Expr::STRING_RESULT, // NAME
|
||||
Expr::NUMBER_RESULT // POSITION
|
||||
};
|
||||
|
||||
Expr::ResultType
|
||||
NodeSetFunctionCall::getReturnType()
|
||||
{
|
||||
return resultTypes[mType];
|
||||
}
|
||||
|
||||
PRBool
|
||||
NodeSetFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
switch (mType) {
|
||||
case COUNT:
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
case ID:
|
||||
{
|
||||
return (aContext & DOCUMENT_CONTEXT) ||
|
||||
argsSensitiveTo(aContext);
|
||||
}
|
||||
case LAST:
|
||||
{
|
||||
return !!(aContext & SIZE_CONTEXT);
|
||||
}
|
||||
case LOCAL_NAME:
|
||||
case NAME:
|
||||
case NAMESPACE_URI:
|
||||
{
|
||||
if (params.isEmpty()) {
|
||||
return !!(aContext & NODE_CONTEXT);
|
||||
}
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
case POSITION:
|
||||
{
|
||||
return !!(aContext & POSITION_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
NS_NOTREACHED("how'd we get here?");
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
NodeSetFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -49,10 +49,6 @@ txNodeTypeTest::txNodeTypeTest(NodeType aNodeType)
|
||||
{
|
||||
}
|
||||
|
||||
txNodeTypeTest::~txNodeTypeTest()
|
||||
{
|
||||
}
|
||||
|
||||
void txNodeTypeTest::setNodeName(const nsAString& aName)
|
||||
{
|
||||
mNodeName = do_GetAtom(aName);
|
||||
@@ -94,6 +90,12 @@ double txNodeTypeTest::getDefaultPriority()
|
||||
return mNodeName ? 0 : -0.5;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txNodeTypeTest::isSensitiveTo(Expr::ContextSensitivity aContext)
|
||||
{
|
||||
return !!(aContext & Expr::NODE_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txNodeTypeTest::toString(nsAString& aDest)
|
||||
|
||||
@@ -153,6 +153,22 @@ NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
NumberFunctionCall::getReturnType()
|
||||
{
|
||||
return NUMBER_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
NumberFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
if (mType == NUMBER && params.isEmpty()) {
|
||||
return !!(aContext & NODE_CONTEXT);
|
||||
}
|
||||
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
NumberFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -102,13 +102,29 @@ PathExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsRefPtr<txNodeSet> nodes;
|
||||
nsresult rv = aContext->recycler()->getNodeSet(aContext->getContextNode(),
|
||||
getter_AddRefs(nodes));
|
||||
// We need to evaluate the first step with the current context since it
|
||||
// can depend on the context size and position. For example:
|
||||
// key('books', concat('book', position()))
|
||||
txListIterator iter(&expressions);
|
||||
PathExprItem* pxi = NS_STATIC_CAST(PathExprItem*, iter.next());
|
||||
nsRefPtr<txAExprResult> res;
|
||||
nsresult rv = pxi->expr->evaluate(aContext, getter_AddRefs(res));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txListIterator iter(&expressions);
|
||||
PathExprItem* pxi;
|
||||
NS_ENSURE_TRUE(res->getResultType() == txAExprResult::NODESET,
|
||||
NS_ERROR_XSLT_NODESET_EXPECTED);
|
||||
|
||||
nsRefPtr<txNodeSet> nodes = NS_STATIC_CAST(txNodeSet*,
|
||||
NS_STATIC_CAST(txAExprResult*,
|
||||
res));
|
||||
if (nodes->isEmpty()) {
|
||||
res.swap(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
res = nsnull; // To allow recycling
|
||||
|
||||
// Evaluate remaining steps
|
||||
while ((pxi = (PathExprItem*)iter.next())) {
|
||||
nsRefPtr<txNodeSet> tmpNodes;
|
||||
txNodeSetContext eContext(nodes, aContext);
|
||||
@@ -216,6 +232,53 @@ PathExpr::evalDescendants(Expr* aStep, const txXPathNode& aNode,
|
||||
return NS_OK;
|
||||
} //-- evalDescendants
|
||||
|
||||
TX_IMPL_EXPR_STUBS_BASE(PathExpr, NODESET_RESULT)
|
||||
|
||||
Expr*
|
||||
PathExpr::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
PathExprItem* pxi = NS_STATIC_CAST(PathExprItem*, expressions.get(aPos));
|
||||
|
||||
return pxi ? pxi->expr.get() : nsnull;
|
||||
}
|
||||
void
|
||||
PathExpr::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
NS_ASSERTION(aPos < (PRUint32)expressions.getLength(),
|
||||
"setting bad subexpression index");
|
||||
PathExprItem* pxi = NS_STATIC_CAST(PathExprItem*, expressions.get(aPos));
|
||||
pxi->expr.forget();
|
||||
pxi->expr = aExpr;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
PathExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
txListIterator iter(&expressions);
|
||||
PathExprItem* pxi = NS_STATIC_CAST(PathExprItem*, iter.next());
|
||||
if (pxi->expr->isSensitiveTo(aContext)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// We're creating a new node/nodeset so we can ignore those bits.
|
||||
Expr::ContextSensitivity context =
|
||||
aContext & ~(Expr::NODE_CONTEXT | Expr::NODESET_CONTEXT);
|
||||
if (context == NO_CONTEXT) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
while ((pxi = NS_STATIC_CAST(PathExprItem*, iter.next()))) {
|
||||
NS_ASSERTION(!pxi->expr->isSensitiveTo(Expr::NODESET_CONTEXT),
|
||||
"Step cannot depend on nodeset-context");
|
||||
if (pxi->expr->isSensitiveTo(context)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
PathExpr::toString(nsAString& dest)
|
||||
|
||||
@@ -116,6 +116,12 @@ PredicateList::evaluatePredicates(txNodeSet* nodes,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PredicateList::dropFirst()
|
||||
{
|
||||
predicates.remove(predicates.get(0));
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if this predicate list is empty
|
||||
*/
|
||||
@@ -124,6 +130,40 @@ MBool PredicateList::isEmpty()
|
||||
return (MBool)(predicates.getLength() == 0);
|
||||
} // isEmpty
|
||||
|
||||
Expr*
|
||||
PredicateList::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
return NS_STATIC_CAST(Expr*, predicates.get(aPos));
|
||||
}
|
||||
|
||||
void
|
||||
PredicateList::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
NS_ASSERTION(aPos < (PRUint32)predicates.getLength(),
|
||||
"setting bad subexpression index");
|
||||
predicates.replace(aPos, aExpr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
PredicateList::isSensitiveTo(Expr::ContextSensitivity aContext)
|
||||
{
|
||||
// We're creating a new node/nodeset so we can ignore those bits.
|
||||
Expr::ContextSensitivity context =
|
||||
aContext & ~(Expr::NODE_CONTEXT | Expr::NODESET_CONTEXT);
|
||||
if (context == Expr::NO_CONTEXT) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
txListIterator iter(&predicates);
|
||||
while (iter.hasNext()) {
|
||||
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(context)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void PredicateList::toString(nsAString& dest)
|
||||
{
|
||||
|
||||
90
mozilla/content/xslt/src/xpath/txPredicatedNodeTest.cpp
Executable file
90
mozilla/content/xslt/src/xpath/txPredicatedNodeTest.cpp
Executable file
@@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txExpr.h"
|
||||
#include "txExprResult.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
|
||||
txPredicatedNodeTest::txPredicatedNodeTest(txNodeTest* aNodeTest,
|
||||
Expr* aPredicate)
|
||||
: mNodeTest(aNodeTest),
|
||||
mPredicate(aPredicate)
|
||||
{
|
||||
NS_ASSERTION(!mPredicate->isSensitiveTo(Expr::NODESET_CONTEXT),
|
||||
"predicate must not be context-nodeset-sensitive");
|
||||
}
|
||||
|
||||
PRBool
|
||||
txPredicatedNodeTest::matches(const txXPathNode& aNode,
|
||||
txIMatchContext* aContext)
|
||||
{
|
||||
if (!mNodeTest->matches(aNode, aContext)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
txSingleNodeContext context(aNode, aContext);
|
||||
nsRefPtr<txAExprResult> res;
|
||||
nsresult rv = mPredicate->evaluate(&context, getter_AddRefs(res));
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
return res->booleanValue();
|
||||
}
|
||||
|
||||
double
|
||||
txPredicatedNodeTest::getDefaultPriority()
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txPredicatedNodeTest::isSensitiveTo(Expr::ContextSensitivity aContext)
|
||||
{
|
||||
return mNodeTest->isSensitiveTo(aContext) ||
|
||||
mPredicate->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txPredicatedNodeTest::toString(nsAString& aDest)
|
||||
{
|
||||
mNodeTest->toString(aDest);
|
||||
aDest.Append(PRUnichar('['));
|
||||
mPredicate->toString(aDest);
|
||||
aDest.Append(PRUnichar(']'));
|
||||
}
|
||||
#endif
|
||||
@@ -205,6 +205,15 @@ RelationalExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TX_IMPL_EXPR_STUBS_2(RelationalExpr, BOOLEAN_RESULT, mLeftExpr, mRightExpr)
|
||||
|
||||
PRBool
|
||||
RelationalExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return mLeftExpr->isSensitiveTo(aContext) ||
|
||||
mRightExpr->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
RelationalExpr::toString(nsAString& str)
|
||||
|
||||
@@ -67,6 +67,14 @@ RootExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return aContext->recycler()->getNodeSet(*document, aResult);
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_0(RootExpr, NODESET_RESULT)
|
||||
|
||||
PRBool
|
||||
RootExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return !!(aContext & DOCUMENT_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
RootExpr::toString(nsAString& dest)
|
||||
|
||||
@@ -133,6 +133,31 @@ txXPathTreeWalker::moveToNextAttribute()
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txXPathTreeWalker::moveToNamedAttribute(nsIAtom* aLocalName, PRInt32 aNSID)
|
||||
{
|
||||
if (INNER->nodeType != Node::ELEMENT_NODE) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
Element* element = NS_STATIC_CAST(Element*, INNER);
|
||||
NamedNodeMap* attrs = element->getAttributes();
|
||||
NodeListDefinition::ListItem* item = attrs->firstItem;
|
||||
// find requested attribute
|
||||
nsCOMPtr<nsIAtom> localName;
|
||||
while (item && (item->node->getNamespaceID() != aNSID ||
|
||||
!item->node->getLocalName(getter_AddRefs(localName)) ||
|
||||
localName != aLocalName) {
|
||||
item = item->next;
|
||||
}
|
||||
if (!item) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
INNER = NS_STATIC_CAST(NodeDefinition*, item->node);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txXPathTreeWalker::moveToFirstChild()
|
||||
{
|
||||
|
||||
@@ -350,6 +350,39 @@ StringFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
static Expr::ResultType resultTypes[] =
|
||||
{
|
||||
Expr::STRING_RESULT, // CONCAT
|
||||
Expr::BOOLEAN_RESULT, // CONTAINS
|
||||
Expr::STRING_RESULT, // NORMALIZE_SPACE
|
||||
Expr::BOOLEAN_RESULT, // STARTS_WITH
|
||||
Expr::STRING_RESULT, // STRING
|
||||
Expr::NUMBER_RESULT, // STRING_LENGTH
|
||||
Expr::STRING_RESULT, // SUBSTRING
|
||||
Expr::STRING_RESULT, // SUBSTRING_AFTER
|
||||
Expr::STRING_RESULT, // SUBSTRING_BEFORE
|
||||
Expr::STRING_RESULT // TRANSLATE
|
||||
};
|
||||
|
||||
Expr::ResultType
|
||||
StringFunctionCall::getReturnType()
|
||||
{
|
||||
return resultTypes[mType];
|
||||
}
|
||||
|
||||
PRBool
|
||||
StringFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
if (params.isEmpty() &&
|
||||
(mType == NORMALIZE_SPACE ||
|
||||
mType == STRING ||
|
||||
mType == STRING_LENGTH)) {
|
||||
return !!(aContext & NODE_CONTEXT);
|
||||
}
|
||||
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
StringFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -69,6 +69,14 @@ UnaryExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
#endif
|
||||
}
|
||||
|
||||
TX_IMPL_EXPR_STUBS_1(UnaryExpr, NODESET_RESULT, expr)
|
||||
|
||||
PRBool
|
||||
UnaryExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return expr->isSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
UnaryExpr::toString(nsAString& str)
|
||||
|
||||
@@ -125,6 +125,21 @@ UnionExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
} //-- evaluate
|
||||
|
||||
TX_IMPL_EXPR_STUBS_LIST(UnionExpr, NODESET_RESULT, expressions)
|
||||
|
||||
PRBool
|
||||
UnionExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
txListIterator iter(&expressions);
|
||||
while (iter.hasNext()) {
|
||||
if (NS_STATIC_CAST(Expr*, iter.next())->isSensitiveTo(aContext)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
UnionExpr::toString(nsAString& dest)
|
||||
|
||||
@@ -58,13 +58,6 @@ VariableRefExpr::VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName,
|
||||
mPrefix = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the local name atom
|
||||
*/
|
||||
VariableRefExpr::~VariableRefExpr()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
@@ -83,6 +76,14 @@ VariableRefExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TX_IMPL_EXPR_STUBS_0(VariableRefExpr, ANY_RESULT)
|
||||
|
||||
PRBool
|
||||
VariableRefExpr::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return !!(aContext & VARIABLES_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
VariableRefExpr::toString(nsAString& aDest)
|
||||
|
||||
@@ -517,6 +517,22 @@ XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
XFormsFunctionCall::getReturnType()
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return ANY_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XFormsFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
XFormsFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
126
mozilla/content/xslt/src/xpath/txXPathOptimizer.cpp
Executable file
126
mozilla/content/xslt/src/xpath/txXPathOptimizer.cpp
Executable file
@@ -0,0 +1,126 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txXPathOptimizer.h"
|
||||
#include "txExprResult.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txXPathNode.h"
|
||||
#include "txExpr.h"
|
||||
|
||||
nsresult
|
||||
txXPathOptimizer::optimize(Expr* aInExpr, Expr** aOutExpr)
|
||||
{
|
||||
*aOutExpr = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// First optimize sub expressions
|
||||
PRUint32 i = 0;
|
||||
Expr* subExpr;
|
||||
while ((subExpr = aInExpr->getSubExprAt(i))) {
|
||||
Expr* newExpr = nsnull;
|
||||
rv = optimize(subExpr, &newExpr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (newExpr) {
|
||||
delete subExpr;
|
||||
aInExpr->setSubExprAt(i, newExpr);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
// Then see if current expression can be optimized
|
||||
switch (aInExpr->getType()) {
|
||||
case Expr::LOCATIONSTEP_ATTRIBUTE_EXPR:
|
||||
return optimizeAttributeStep(aInExpr, aOutExpr);
|
||||
|
||||
case Expr::LOCATIONSTEP_OTHER_EXPR:
|
||||
return optimizeStep(aInExpr, aOutExpr);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txXPathOptimizer::optimizeAttributeStep(Expr* aInExpr, Expr** aOutExpr)
|
||||
{
|
||||
LocationStep* step = NS_STATIC_CAST(LocationStep*, aInExpr);
|
||||
|
||||
// Test for @foo type steps.
|
||||
txNameTest* nameTest = nsnull;
|
||||
if (!step->getSubExprAt(0) &&
|
||||
step->getNodeTest()->getType() == txNameTest::NAME_TEST &&
|
||||
(nameTest = NS_STATIC_CAST(txNameTest*, step->getNodeTest()))->
|
||||
mLocalName != txXPathAtoms::_asterix) {
|
||||
|
||||
*aOutExpr = new txNamedAttributeStep(nameTest->mNamespace,
|
||||
nameTest->mPrefix,
|
||||
nameTest->mLocalName);
|
||||
NS_ENSURE_TRUE(*aOutExpr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK; // return since we no longer have a step-object.
|
||||
}
|
||||
|
||||
// Do general step optimizations
|
||||
|
||||
return optimizeStep(aInExpr, aOutExpr);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
txXPathOptimizer::optimizeStep(Expr* aInExpr, Expr** aOutExpr)
|
||||
{
|
||||
LocationStep* step = NS_STATIC_CAST(LocationStep*, aInExpr);
|
||||
|
||||
// Test for predicates that can be combined into the nodetest
|
||||
Expr* pred;
|
||||
while ((pred = step->getSubExprAt(0)) &&
|
||||
!pred->canReturnType(Expr::NUMBER_RESULT) &&
|
||||
!pred->isSensitiveTo(Expr::NODESET_CONTEXT)) {
|
||||
txNodeTest* predTest = new txPredicatedNodeTest(step->getNodeTest(), pred);
|
||||
NS_ENSURE_TRUE(predTest, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
step->dropFirst();
|
||||
step->setNodeTest(predTest);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
63
mozilla/content/xslt/src/xpath/txXPathOptimizer.h
Executable file
63
mozilla/content/xslt/src/xpath/txXPathOptimizer.h
Executable file
@@ -0,0 +1,63 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef txXPathOptimizer_h__
|
||||
#define txXPathOptimizer_h__
|
||||
|
||||
#include "txCore.h"
|
||||
|
||||
class Expr;
|
||||
|
||||
class txXPathOptimizer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Optimize the given expression.
|
||||
* @param aInExpr Expression to optimize.
|
||||
* @param aOutExpr Resulting expression, null if optimization didn't
|
||||
* result in a new expression.
|
||||
*/
|
||||
nsresult optimize(Expr* aInExpr, Expr** aOutExpr);
|
||||
|
||||
private:
|
||||
// Helper methods for optimizing specific classes
|
||||
nsresult optimizeAttributeStep(Expr* aInExpr, Expr** aOutExpr);
|
||||
nsresult optimizeStep(Expr* aInExpr, Expr** aOutExpr);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
PRBool moveToElementById(const nsAString& aID);
|
||||
PRBool moveToFirstAttribute();
|
||||
PRBool moveToNextAttribute();
|
||||
PRBool moveToNamedAttribute(nsIAtom* aLocalName, PRInt32 aNSID);
|
||||
PRBool moveToFirstChild();
|
||||
PRBool moveToLastChild();
|
||||
PRBool moveToNextSibling();
|
||||
|
||||
@@ -94,6 +94,7 @@ CPPSRCS = \
|
||||
txToplevelItems.cpp \
|
||||
txXSLTNumber.cpp \
|
||||
txXSLTNumberCounters.cpp \
|
||||
txPatternOptimizer.cpp \
|
||||
txXSLTPatterns.cpp \
|
||||
txXSLTProcessor.cpp \
|
||||
txPatternParser.cpp \
|
||||
|
||||
@@ -35,7 +35,19 @@ CurrentFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return aContext->recycler()->getNodeSet(
|
||||
es->getEvalContext()->getContextNode(), aResult);
|
||||
es->getEvalContext()->getContextNode(), aResult);
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
CurrentFunctionCall::getReturnType()
|
||||
{
|
||||
return NODESET_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
CurrentFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return (aContext & PRIVATE_CONTEXT);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
|
||||
@@ -177,6 +177,18 @@ DocumentFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
DocumentFunctionCall::getReturnType()
|
||||
{
|
||||
return NODESET_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
DocumentFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
DocumentFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -130,6 +130,18 @@ ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
ElementAvailableFunctionCall::getReturnType()
|
||||
{
|
||||
return BOOLEAN_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ElementAvailableFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
ElementAvailableFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -406,6 +406,18 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
return aContext->recycler()->getStringResult(res, aResult);
|
||||
} //-- evaluate
|
||||
|
||||
Expr::ResultType
|
||||
txFormatNumberFunctionCall::getReturnType()
|
||||
{
|
||||
return STRING_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txFormatNumberFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
txFormatNumberFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -129,6 +129,18 @@ FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
FunctionAvailableFunctionCall::getReturnType()
|
||||
{
|
||||
return BOOLEAN_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
FunctionAvailableFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
FunctionAvailableFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -105,6 +105,22 @@ GenerateIdFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
GenerateIdFunctionCall::getReturnType()
|
||||
{
|
||||
return STRING_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
GenerateIdFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
if (params.isEmpty()) {
|
||||
return !!(aContext & NODE_CONTEXT);
|
||||
}
|
||||
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
GenerateIdFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -126,6 +126,18 @@ txKeyFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
txKeyFunctionCall::getReturnType()
|
||||
{
|
||||
return NODESET_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txKeyFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return (aContext & DOCUMENT_CONTEXT) || argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
txKeyFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
109
mozilla/content/xslt/src/xslt/txPatternOptimizer.cpp
Executable file
109
mozilla/content/xslt/src/xslt/txPatternOptimizer.cpp
Executable file
@@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txPatternOptimizer.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
nsresult
|
||||
txPatternOptimizer::optimize(txPattern* aInPattern, txPattern** aOutPattern)
|
||||
{
|
||||
*aOutPattern = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// First optimize sub expressions
|
||||
PRUint32 i = 0;
|
||||
Expr* subExpr;
|
||||
while ((subExpr = aInPattern->getSubExprAt(i))) {
|
||||
Expr* newExpr = nsnull;
|
||||
rv = mXPathOptimizer.optimize(subExpr, &newExpr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (newExpr) {
|
||||
delete subExpr;
|
||||
aInPattern->setSubExprAt(i, newExpr);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
// Then optimize sub patterns
|
||||
txPattern* subPattern;
|
||||
i = 0;
|
||||
while ((subPattern = aInPattern->getSubPatternAt(i))) {
|
||||
txPattern* newPattern = nsnull;
|
||||
rv = optimize(subPattern, &newPattern);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (newPattern) {
|
||||
delete subPattern;
|
||||
aInPattern->setSubPatternAt(i, newPattern);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
// Finally see if current pattern can be optimized
|
||||
switch (aInPattern->getType()) {
|
||||
case txPattern::STEP_PATTERN:
|
||||
return optimizeStep(aInPattern, aOutPattern);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
txPatternOptimizer::optimizeStep(txPattern* aInPattern,
|
||||
txPattern** aOutPattern)
|
||||
{
|
||||
txStepPattern* step = NS_STATIC_CAST(txStepPattern*, aInPattern);
|
||||
|
||||
// Test for predicates that can be combined into the nodetest
|
||||
Expr* pred;
|
||||
while ((pred = step->getSubExprAt(0)) &&
|
||||
!pred->canReturnType(Expr::NUMBER_RESULT) &&
|
||||
!pred->isSensitiveTo(Expr::NODESET_CONTEXT)) {
|
||||
txNodeTest* predTest = new txPredicatedNodeTest(step->getNodeTest(),
|
||||
pred);
|
||||
step->dropFirst();
|
||||
step->setNodeTest(predTest);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
65
mozilla/content/xslt/src/xslt/txPatternOptimizer.h
Executable file
65
mozilla/content/xslt/src/xslt/txPatternOptimizer.h
Executable file
@@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* IBM Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* IBM Corporation
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef txPatternOptimizer_h__
|
||||
#define txPatternOptimizer_h__
|
||||
|
||||
#include "txXPathOptimizer.h"
|
||||
|
||||
class txPattern;
|
||||
|
||||
class txPatternOptimizer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Optimize the given pattern.
|
||||
* @param aInPattern Pattern to optimize.
|
||||
* @param aOutPattern Resulting pattern, null if optimization didn't
|
||||
* result in a new pattern.
|
||||
*/
|
||||
nsresult optimize(txPattern* aInPattern, txPattern** aOutPattern);
|
||||
|
||||
private:
|
||||
|
||||
// Helper methods for optimizing specific classes
|
||||
nsresult optimizeStep(txPattern* aInPattern, txPattern** aOutPattern);
|
||||
|
||||
txXPathOptimizer mXPathOptimizer;
|
||||
};
|
||||
|
||||
#endif //txPatternOptimizer_h__
|
||||
@@ -43,23 +43,31 @@
|
||||
#include "txStringUtils.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "txPatternOptimizer.h"
|
||||
|
||||
|
||||
txPattern* txPatternParser::createPattern(const nsAFlatString& aPattern,
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
txPattern* pattern = 0;
|
||||
txExprLexer lexer;
|
||||
nsresult rv = lexer.parse(aPattern);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report parsing error
|
||||
return 0;
|
||||
}
|
||||
rv = createUnionPattern(lexer, aContext, pattern);
|
||||
nsAutoPtr<txPattern> pattern;
|
||||
rv = createUnionPattern(lexer, aContext, *getter_Transfers(pattern));
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report parsing error
|
||||
return 0;
|
||||
}
|
||||
return pattern;
|
||||
|
||||
txPatternOptimizer optimizer;
|
||||
txPattern* newPattern = nsnull;
|
||||
rv = optimizer.optimize(pattern, &newPattern);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
return newPattern ? newPattern : pattern.forget();
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createUnionPattern(txExprLexer& aLexer,
|
||||
|
||||
@@ -884,6 +884,22 @@ txErrorFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
return NS_ERROR_XPATH_BAD_EXTENSION_FUNCTION;
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
txErrorFunctionCall::getReturnType()
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return ANY_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
txErrorFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
// It doesn't really matter what we return here, but it might
|
||||
// be a good idea to try to keep this as unoptimizable as possible
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
txErrorFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -109,6 +109,18 @@ SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext,
|
||||
|
||||
}
|
||||
|
||||
Expr::ResultType
|
||||
SystemPropertyFunctionCall::getReturnType()
|
||||
{
|
||||
return STRING_RESULT | NUMBER_RESULT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SystemPropertyFunctionCall::isSensitiveTo(ContextSensitivity aContext)
|
||||
{
|
||||
return argsSensitiveTo(aContext);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
nsresult
|
||||
SystemPropertyFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
|
||||
@@ -129,6 +129,22 @@ nsresult txUnionPattern::getSimplePatterns(txList& aList)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txUnionPattern);
|
||||
txPattern*
|
||||
txUnionPattern::getSubPatternAt(PRUint32 aPos)
|
||||
{
|
||||
return NS_STATIC_CAST(txPattern*, mLocPathPatterns.get(aPos));
|
||||
}
|
||||
|
||||
void
|
||||
txUnionPattern::setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
|
||||
{
|
||||
NS_ASSERTION(aPos < (PRUint32)mLocPathPatterns.getLength(),
|
||||
"setting bad subexpression index");
|
||||
mLocPathPatterns.replace(aPos, aPattern);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txUnionPattern::toString(nsAString& aDest)
|
||||
@@ -254,6 +270,25 @@ double txLocPathPattern::getDefaultPriority()
|
||||
return ((Step*)mSteps.get(0))->pattern->getDefaultPriority();
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txLocPathPattern);
|
||||
txPattern*
|
||||
txLocPathPattern::getSubPatternAt(PRUint32 aPos)
|
||||
{
|
||||
Step* step = NS_STATIC_CAST(Step*, mSteps.get(aPos));
|
||||
|
||||
return step ? step->pattern.get() : nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
txLocPathPattern::setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
|
||||
{
|
||||
NS_ASSERTION(aPos < (PRUint32)mSteps.getLength(),
|
||||
"setting bad subexpression index");
|
||||
Step* step = NS_STATIC_CAST(Step*, mSteps.get(aPos));
|
||||
step->pattern.forget();
|
||||
step->pattern = aPattern;
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txLocPathPattern::toString(nsAString& aDest)
|
||||
@@ -300,6 +335,9 @@ double txRootPattern::getDefaultPriority()
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txRootPattern);
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(txRootPattern);
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txRootPattern::toString(nsAString& aDest)
|
||||
@@ -383,6 +421,9 @@ double txIdPattern::getDefaultPriority()
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txIdPattern);
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(txIdPattern);
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txIdPattern::toString(nsAString& aDest)
|
||||
@@ -436,6 +477,9 @@ double txKeyPattern::getDefaultPriority()
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(txKeyPattern);
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(txKeyPattern);
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txKeyPattern::toString(nsAString& aDest)
|
||||
@@ -467,11 +511,6 @@ txKeyPattern::toString(nsAString& aDest)
|
||||
* a txPattern to hold the NodeTest and the Predicates of a StepPattern
|
||||
*/
|
||||
|
||||
txStepPattern::~txStepPattern()
|
||||
{
|
||||
delete mNodeTest;
|
||||
}
|
||||
|
||||
MBool txStepPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(mNodeTest, "Internal error");
|
||||
@@ -586,6 +625,25 @@ double txStepPattern::getDefaultPriority()
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
txPattern::Type
|
||||
txStepPattern::getType()
|
||||
{
|
||||
return STEP_PATTERN;
|
||||
}
|
||||
|
||||
TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(txStepPattern);
|
||||
Expr*
|
||||
txStepPattern::getSubExprAt(PRUint32 aPos)
|
||||
{
|
||||
return PredicateList::getSubExprAt(aPos);
|
||||
}
|
||||
|
||||
void
|
||||
txStepPattern::setSubExprAt(PRUint32 aPos, Expr* aExpr)
|
||||
{
|
||||
return PredicateList::setSubExprAt(aPos, aExpr);
|
||||
}
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
void
|
||||
txStepPattern::toString(nsAString& aDest)
|
||||
|
||||
@@ -74,6 +74,40 @@ public:
|
||||
*/
|
||||
virtual nsresult getSimplePatterns(txList &aList);
|
||||
|
||||
/**
|
||||
* Returns the type of this pattern.
|
||||
*/
|
||||
enum Type {
|
||||
STEP_PATTERN,
|
||||
OTHER_PATTERN
|
||||
};
|
||||
virtual Type getType()
|
||||
{
|
||||
return OTHER_PATTERN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sub-expression at given position
|
||||
*/
|
||||
virtual Expr* getSubExprAt(PRUint32 aPos) = 0;
|
||||
|
||||
/**
|
||||
* Replace sub-expression at given position. Does not delete the old
|
||||
* expression, that is the responsibility of the caller.
|
||||
*/
|
||||
virtual void setSubExprAt(PRUint32 aPos, Expr* aExpr) = 0;
|
||||
|
||||
/**
|
||||
* Returns sub-pattern at given position
|
||||
*/
|
||||
virtual txPattern* getSubPatternAt(PRUint32 aPos) = 0;
|
||||
|
||||
/**
|
||||
* Replace sub-pattern at given position. Does not delete the old
|
||||
* pattern, that is the responsibility of the caller.
|
||||
*/
|
||||
virtual void setSubPatternAt(PRUint32 aPos, txPattern* aPattern) = 0;
|
||||
|
||||
#ifdef TX_TO_STRING
|
||||
/*
|
||||
* Returns the String representation of this Pattern.
|
||||
@@ -89,7 +123,11 @@ public:
|
||||
|
||||
#define TX_DECL_PATTERN_BASE \
|
||||
MBool matches(const txXPathNode& aNode, txIMatchContext* aContext); \
|
||||
double getDefaultPriority()
|
||||
double getDefaultPriority(); \
|
||||
virtual Expr* getSubExprAt(PRUint32 aPos); \
|
||||
virtual void setSubExprAt(PRUint32 aPos, Expr* aExpr); \
|
||||
virtual txPattern* getSubPatternAt(PRUint32 aPos); \
|
||||
virtual void setSubPatternAt(PRUint32 aPos, txPattern* aPattern)
|
||||
|
||||
#ifndef TX_TO_STRING
|
||||
#define TX_DECL_PATTERN TX_DECL_PATTERN_BASE
|
||||
@@ -103,6 +141,29 @@ public:
|
||||
TX_DECL_PATTERN; \
|
||||
nsresult getSimplePatterns(txList &aList)
|
||||
|
||||
#define TX_IMPL_PATTERN_STUBS_NO_SUB_EXPR(_class) \
|
||||
Expr* \
|
||||
_class::getSubExprAt(PRUint32 aPos) \
|
||||
{ \
|
||||
return nsnull; \
|
||||
} \
|
||||
void \
|
||||
_class::setSubExprAt(PRUint32 aPos, Expr* aExpr) \
|
||||
{ \
|
||||
NS_NOTREACHED("setting bad subexpression index"); \
|
||||
}
|
||||
|
||||
#define TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(_class) \
|
||||
txPattern* \
|
||||
_class::getSubPatternAt(PRUint32 aPos) \
|
||||
{ \
|
||||
return nsnull; \
|
||||
} \
|
||||
void \
|
||||
_class::setSubPatternAt(PRUint32 aPos, txPattern* aPattern) \
|
||||
{ \
|
||||
NS_NOTREACHED("setting bad subexpression index"); \
|
||||
}
|
||||
|
||||
class txUnionPattern : public txPattern
|
||||
{
|
||||
@@ -142,12 +203,7 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
~Step()
|
||||
{
|
||||
delete pattern;
|
||||
}
|
||||
|
||||
txPattern* pattern;
|
||||
nsAutoPtr<txPattern> pattern;
|
||||
MBool isChild;
|
||||
};
|
||||
|
||||
@@ -221,12 +277,21 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
~txStepPattern();
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
Type getType();
|
||||
|
||||
txNodeTest* getNodeTest()
|
||||
{
|
||||
return mNodeTest;
|
||||
}
|
||||
void setNodeTest(txNodeTest* aNodeTest)
|
||||
{
|
||||
mNodeTest.forget();
|
||||
mNodeTest = aNodeTest;
|
||||
}
|
||||
|
||||
private:
|
||||
txNodeTest* mNodeTest;
|
||||
nsAutoPtr<txNodeTest> mNodeTest;
|
||||
MBool mIsAttr;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user