michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "txExpr.h" michael@0: #include "nsIAtom.h" michael@0: #include "txIXPathContext.h" michael@0: #include "txNodeSet.h" michael@0: michael@0: /** michael@0: * This class represents a FunctionCall as defined by the XSL Working Draft michael@0: **/ michael@0: michael@0: //------------------/ michael@0: //- Public Methods -/ michael@0: //------------------/ michael@0: michael@0: /* michael@0: * Evaluates the given Expression and converts its result to a number. michael@0: */ michael@0: // static michael@0: nsresult michael@0: FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext, michael@0: double* aResult) michael@0: { michael@0: NS_ASSERTION(aExpr, "missing expression"); michael@0: nsRefPtr exprResult; michael@0: nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aResult = exprResult->numberValue(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* michael@0: * Evaluates the given Expression and converts its result to a NodeSet. michael@0: * If the result is not a NodeSet nullptr is returned. michael@0: */ michael@0: nsresult michael@0: FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext, michael@0: txNodeSet** aResult) michael@0: { michael@0: NS_ASSERTION(aExpr, "Missing expression to evaluate"); michael@0: *aResult = nullptr; michael@0: michael@0: nsRefPtr exprRes; michael@0: nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprRes)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (exprRes->getResultType() != txAExprResult::NODESET) { michael@0: aContext->receiveError(NS_LITERAL_STRING("NodeSet expected as argument"), NS_ERROR_XSLT_NODESET_EXPECTED); michael@0: return NS_ERROR_XSLT_NODESET_EXPECTED; michael@0: } michael@0: michael@0: *aResult = michael@0: static_cast(static_cast(exprRes)); michael@0: NS_ADDREF(*aResult); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool FunctionCall::requireParams(int32_t aParamCountMin, michael@0: int32_t aParamCountMax, michael@0: txIEvalContext* aContext) michael@0: { michael@0: int32_t argc = mParams.Length(); michael@0: if (argc < aParamCountMin || michael@0: (aParamCountMax > -1 && argc > aParamCountMax)) { michael@0: nsAutoString err(NS_LITERAL_STRING("invalid number of parameters for function")); michael@0: #ifdef TX_TO_STRING michael@0: err.AppendLiteral(": "); michael@0: toString(err); michael@0: #endif michael@0: aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG); michael@0: michael@0: return false; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: Expr* michael@0: FunctionCall::getSubExprAt(uint32_t aPos) michael@0: { michael@0: return mParams.SafeElementAt(aPos); michael@0: } michael@0: michael@0: void michael@0: FunctionCall::setSubExprAt(uint32_t aPos, Expr* aExpr) michael@0: { michael@0: NS_ASSERTION(aPos < mParams.Length(), michael@0: "setting bad subexpression index"); michael@0: mParams[aPos] = aExpr; michael@0: } michael@0: michael@0: bool michael@0: FunctionCall::argsSensitiveTo(ContextSensitivity aContext) michael@0: { michael@0: uint32_t i, len = mParams.Length(); michael@0: for (i = 0; i < len; ++i) { michael@0: if (mParams[i]->isSensitiveTo(aContext)) { michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: #ifdef TX_TO_STRING michael@0: void michael@0: FunctionCall::toString(nsAString& aDest) michael@0: { michael@0: nsCOMPtr functionNameAtom; michael@0: if (NS_FAILED(getNameAtom(getter_AddRefs(functionNameAtom)))) { michael@0: NS_ERROR("Can't get function name."); michael@0: return; michael@0: } michael@0: michael@0: michael@0: michael@0: aDest.Append(nsDependentAtomString(functionNameAtom) + michael@0: NS_LITERAL_STRING("(")); michael@0: for (uint32_t i = 0; i < mParams.Length(); ++i) { michael@0: if (i != 0) { michael@0: aDest.Append(char16_t(',')); michael@0: } michael@0: mParams[i]->toString(aDest); michael@0: } michael@0: aDest.Append(char16_t(')')); michael@0: } michael@0: #endif