diff -r 000000000000 -r 1918ee327afb src/xmlpatterns/functions/qsequencefns_p.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xmlpatterns/functions/qsequencefns_p.h Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,344 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SequenceFNs_H +#define Patternist_SequenceFNs_H + +#include "qatomiccomparator_p.h" +#include "qcomparisonplatform_p.h" +#include "qliteral_p.h" +#include "qfunctioncall_p.h" + +/** + * @file + * @short Contains classes implementing the functions found in + * XQuery 1.0 and + * XPath 2.0 Functions and Operators, 15.1 General Functions and Operators on Sequences. + * + * @todo document that some functions have both eval funcs implented. + * + * @ingroup Patternist_functions + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the function fn:boolean(). + * + * @see EBVExtractor + * @ingroup Patternist_functions + * @author Frans Englich + */ + class BooleanFN : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + /** + * If @p reqType is CommonSequenceTypes::EBV, the type check of + * the operand is returned. Hence, this removes redundant calls + * to fn:boolean(). + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + }; + + /** + * @short Implements the function fn:index-of(). + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + class IndexOfFN : public FunctionCall, + public ComparisonPlatform + { + public: + inline IndexOfFN() : ComparisonPlatform() + { + } + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + inline AtomicComparator::Operator operatorID() const + { + return AtomicComparator::OperatorEqual; + } + }; + + /** + * @short Implements the functions fn:exists() and fn:empty(). + * + * Existence is a template value class. Appropriate implementations are achieved + * by instantiating it with either IDExistsFN or IDEmptyFN. + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + template + class Existence : public FunctionCall + { + public: + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const + { + if(Id == IDExistsFN) + return !m_operands.first()->evaluateSequence(context)->isEmpty(); + else + return m_operands.first()->evaluateSequence(context)->isEmpty(); + } + + /** + * Attempts to rewrite to @c false or @c true by looking at the static + * cardinality of its operand. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context) + { + // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is + // passed directly into another constructor. + Q_ASSERT(Id == IDExistsFN || Id == IDEmptyFN); + + const Expression::Ptr me(FunctionCall::compress(context)); + + if(me != this) + return me; + + // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is + // passed directly into another constructor. + Expression::ID tempId = Id; + const Cardinality myCard((tempId == IDExistsFN) ? Cardinality::oneOrMore() : Cardinality::empty()); + + const Cardinality card(m_operands.first()->staticType()->cardinality()); + if(myCard.isMatch(card)) + { /* Since the dynamic type always is narrower than the static type or equal, and that the + static type is in scope, it means we will always be true. */ + return wrapLiteral(CommonValues::BooleanTrue, context, this); + } + else + { + /* Is it even possible to hit? */ + if(myCard.canMatch(card)) + { + return me; + } + else + { /* We can never hit. */ + return wrapLiteral(CommonValues::BooleanFalse, context, this); + } + } + } + }; + + /** + * @short Implements the function fn:distinct-values(). + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + class DistinctValuesFN : public FunctionCall, + public ComparisonPlatform + { + public: + inline DistinctValuesFN() : ComparisonPlatform() + { + } + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + /** + * Performs necessary type checks, but also implements the optimization + * of rewriting to its operand if the operand's cardinality is zero-or-one + * or exactly-one. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + /** + * @returns a type whose item type is the type of the first operand, and + * a cardinality which is non-empty if the first operand's type is non-empty + * and allows exactly-one. The latter is needed for operands which has the + * cardinality 2+, since distinct-values possibly removes items from the + * source sequence. + */ + virtual SequenceType::Ptr staticType() const; + + protected: + inline AtomicComparator::Operator operatorID() const + { + return AtomicComparator::OperatorEqual; + } + }; + + /** + * @short Implements the function fn:insert-before(). + * + * @todo docs, explain why evaluateSequence and evaluateSingleton is implemented + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + class InsertBeforeFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Implements the static enferences rules. The function's static item type + * is the union type of the first and third argument, and the cardinality is + * the cardinalities of the two operands added together. For example, + * insert-before((1, "str"), 1, xs:double(0)) has the static type xs:anyAtomicType+. + * + * @see XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.15 The fn:insert-before function + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function fn:remove(). + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + class RemoveFN : public FunctionCall + { + public: + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Implements the static enferences rules, "Since one item may be removed + * from the sequence, the resulting type is made optional:" + * + * statEnv |- (FN-URI,"remove")(Type, Type1) : prime(Type) * quantifier(Type)? + * + * However, because Patternist's type system is more fine grained than Formal Semantics, + * the sequence isn't made optional. Instead its minimum length is reduced with one. + * + * @see XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.11 The fn:remove function + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function fn:reverse(). + * + * @ingroup Patternist_functions + * @author Frans Englich + */ + class ReverseFN : public FunctionCall + { + public: + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * Formally speaking, the type inference is: + * +@verbatim +statEnv |- (FN-URI,"reverse")(Type) : prime(Type) * quantifier(Type) +@endverbatim + * + * @see XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.12 The fn:reverse function + * @returns the static type of the function's first argument. + */ + virtual SequenceType::Ptr staticType() const; + }; + + /** + * @short Implements the function fn:subsequence(). + * + * @ingroup Patternist_functions + * @author Frans Englich + * @todo Type inference can be made stronger for this function + */ + class SubsequenceFN : public FunctionCall + { + public: + SubsequenceFN(); + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * This function implements rewrites the SubsequenceFN instance into an + * empty sequence if its third argument, the sequence length argument, is + * evaluated and is effectively equal or less than zero. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * Partially implements the static type inference rules. + * + * @see XQuery 1.0 + * and XPath 2.0 Formal Semantics, 7.2.13 The fn:subsequence function + */ + virtual SequenceType::Ptr staticType() const; + + private: + bool m_hasTypeChecked; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif