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 "txNodeSet.h" michael@0: #include "txIXPathContext.h" michael@0: michael@0: //-- Implementation of FilterExpr --/ michael@0: michael@0: //-----------------------------/ michael@0: //- Virtual methods from Expr -/ michael@0: //-----------------------------/ michael@0: michael@0: /** michael@0: * Evaluates this Expr based on the given context node and processor state michael@0: * @param context the context node for evaluation of this Expr michael@0: * @param ps the ProcessorState containing the stack information needed michael@0: * for evaluation michael@0: * @return the result of the evaluation michael@0: * @see Expr michael@0: **/ michael@0: nsresult michael@0: FilterExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) michael@0: { michael@0: *aResult = nullptr; michael@0: michael@0: nsRefPtr exprRes; michael@0: nsresult rv = expr->evaluate(aContext, getter_AddRefs(exprRes)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: NS_ENSURE_TRUE(exprRes->getResultType() == txAExprResult::NODESET, michael@0: NS_ERROR_XSLT_NODESET_EXPECTED); michael@0: michael@0: nsRefPtr nodes = michael@0: static_cast(static_cast(exprRes)); michael@0: // null out exprRes so that we can test for shared-ness michael@0: exprRes = nullptr; michael@0: michael@0: nsRefPtr nonShared; michael@0: rv = aContext->recycler()->getNonSharedNodeSet(nodes, michael@0: getter_AddRefs(nonShared)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = evaluatePredicates(nonShared, aContext); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aResult = nonShared; michael@0: NS_ADDREF(*aResult); michael@0: michael@0: return NS_OK; michael@0: } //-- evaluate michael@0: michael@0: TX_IMPL_EXPR_STUBS_BASE(FilterExpr, NODESET_RESULT) michael@0: michael@0: Expr* michael@0: FilterExpr::getSubExprAt(uint32_t aPos) michael@0: { michael@0: if (aPos == 0) { michael@0: return expr; michael@0: } michael@0: return PredicateList::getSubExprAt(aPos - 1); michael@0: } michael@0: michael@0: void michael@0: FilterExpr::setSubExprAt(uint32_t aPos, Expr* aExpr) michael@0: { michael@0: if (aPos == 0) { michael@0: expr.forget(); michael@0: expr = aExpr; michael@0: } michael@0: else { michael@0: PredicateList::setSubExprAt(aPos - 1, aExpr); michael@0: } michael@0: } michael@0: michael@0: bool michael@0: FilterExpr::isSensitiveTo(ContextSensitivity aContext) michael@0: { michael@0: return expr->isSensitiveTo(aContext) || michael@0: PredicateList::isSensitiveTo(aContext); michael@0: } michael@0: michael@0: #ifdef TX_TO_STRING michael@0: void michael@0: FilterExpr::toString(nsAString& str) michael@0: { michael@0: if ( expr ) expr->toString(str); michael@0: else str.AppendLiteral("null"); michael@0: PredicateList::toString(str); michael@0: } michael@0: #endif michael@0: