|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "txExpr.h" |
|
7 #include "nsIAtom.h" |
|
8 #include "txIXPathContext.h" |
|
9 #include "txNodeSet.h" |
|
10 |
|
11 /** |
|
12 * This class represents a FunctionCall as defined by the XSL Working Draft |
|
13 **/ |
|
14 |
|
15 //------------------/ |
|
16 //- Public Methods -/ |
|
17 //------------------/ |
|
18 |
|
19 /* |
|
20 * Evaluates the given Expression and converts its result to a number. |
|
21 */ |
|
22 // static |
|
23 nsresult |
|
24 FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext, |
|
25 double* aResult) |
|
26 { |
|
27 NS_ASSERTION(aExpr, "missing expression"); |
|
28 nsRefPtr<txAExprResult> exprResult; |
|
29 nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult)); |
|
30 NS_ENSURE_SUCCESS(rv, rv); |
|
31 |
|
32 *aResult = exprResult->numberValue(); |
|
33 |
|
34 return NS_OK; |
|
35 } |
|
36 |
|
37 /* |
|
38 * Evaluates the given Expression and converts its result to a NodeSet. |
|
39 * If the result is not a NodeSet nullptr is returned. |
|
40 */ |
|
41 nsresult |
|
42 FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext, |
|
43 txNodeSet** aResult) |
|
44 { |
|
45 NS_ASSERTION(aExpr, "Missing expression to evaluate"); |
|
46 *aResult = nullptr; |
|
47 |
|
48 nsRefPtr<txAExprResult> exprRes; |
|
49 nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprRes)); |
|
50 NS_ENSURE_SUCCESS(rv, rv); |
|
51 |
|
52 if (exprRes->getResultType() != txAExprResult::NODESET) { |
|
53 aContext->receiveError(NS_LITERAL_STRING("NodeSet expected as argument"), NS_ERROR_XSLT_NODESET_EXPECTED); |
|
54 return NS_ERROR_XSLT_NODESET_EXPECTED; |
|
55 } |
|
56 |
|
57 *aResult = |
|
58 static_cast<txNodeSet*>(static_cast<txAExprResult*>(exprRes)); |
|
59 NS_ADDREF(*aResult); |
|
60 |
|
61 return NS_OK; |
|
62 } |
|
63 |
|
64 bool FunctionCall::requireParams(int32_t aParamCountMin, |
|
65 int32_t aParamCountMax, |
|
66 txIEvalContext* aContext) |
|
67 { |
|
68 int32_t argc = mParams.Length(); |
|
69 if (argc < aParamCountMin || |
|
70 (aParamCountMax > -1 && argc > aParamCountMax)) { |
|
71 nsAutoString err(NS_LITERAL_STRING("invalid number of parameters for function")); |
|
72 #ifdef TX_TO_STRING |
|
73 err.AppendLiteral(": "); |
|
74 toString(err); |
|
75 #endif |
|
76 aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); |
|
77 |
|
78 return false; |
|
79 } |
|
80 |
|
81 return true; |
|
82 } |
|
83 |
|
84 Expr* |
|
85 FunctionCall::getSubExprAt(uint32_t aPos) |
|
86 { |
|
87 return mParams.SafeElementAt(aPos); |
|
88 } |
|
89 |
|
90 void |
|
91 FunctionCall::setSubExprAt(uint32_t aPos, Expr* aExpr) |
|
92 { |
|
93 NS_ASSERTION(aPos < mParams.Length(), |
|
94 "setting bad subexpression index"); |
|
95 mParams[aPos] = aExpr; |
|
96 } |
|
97 |
|
98 bool |
|
99 FunctionCall::argsSensitiveTo(ContextSensitivity aContext) |
|
100 { |
|
101 uint32_t i, len = mParams.Length(); |
|
102 for (i = 0; i < len; ++i) { |
|
103 if (mParams[i]->isSensitiveTo(aContext)) { |
|
104 return true; |
|
105 } |
|
106 } |
|
107 |
|
108 return false; |
|
109 } |
|
110 |
|
111 #ifdef TX_TO_STRING |
|
112 void |
|
113 FunctionCall::toString(nsAString& aDest) |
|
114 { |
|
115 nsCOMPtr<nsIAtom> functionNameAtom; |
|
116 if (NS_FAILED(getNameAtom(getter_AddRefs(functionNameAtom)))) { |
|
117 NS_ERROR("Can't get function name."); |
|
118 return; |
|
119 } |
|
120 |
|
121 |
|
122 |
|
123 aDest.Append(nsDependentAtomString(functionNameAtom) + |
|
124 NS_LITERAL_STRING("(")); |
|
125 for (uint32_t i = 0; i < mParams.Length(); ++i) { |
|
126 if (i != 0) { |
|
127 aDest.Append(char16_t(',')); |
|
128 } |
|
129 mParams[i]->toString(aDest); |
|
130 } |
|
131 aDest.Append(char16_t(')')); |
|
132 } |
|
133 #endif |