diff options
Diffstat (limited to 'src/xmlpatterns/expr/qoptimizerframework_p.h')
-rw-r--r-- | src/xmlpatterns/expr/qoptimizerframework_p.h | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/src/xmlpatterns/expr/qoptimizerframework_p.h b/src/xmlpatterns/expr/qoptimizerframework_p.h new file mode 100644 index 0000000..6a67483 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizerframework_p.h @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@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_OptimizerFramework_H +#define Patternist_OptimizerFramework_H + +#include <QSharedData> + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A factory for creating Expression instances. + * + * ExpressionIdentifier is one of the building block of Patternist's + * optimizer framework. An ExpressionIdentifier sub-class has + * the responsibility of creating the Expression that should be + * the result of the optimization. + * + * This class and sub-classes are never used on their own, + * but in cooperation with OptimizationPass. + * + * @author Frans englich <fenglich@trolltech.com> + * @ingroup Patternist_expressions + */ + class ExpressionCreator : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer<ExpressionCreator> Ptr; + + /** + * For some reason this constructor cannot be synthesized. + */ + inline ExpressionCreator() + { + } + + virtual ~ExpressionCreator(); + /** + * Creates an expression that has @p operands as operands. + * + * The Expression that is returned is guaranteed, by the caller, + * to get a treatment identical to if the expression was created + * in an ordinary compilation(via the parser, and so forth). That is, + * Expression::typeCheck() and Expression::compress() stages will be + * carried out on the returned expression. + * + * @returns an Expression::Ptr that never is non @c null, valid pointer + */ + virtual Expression::Ptr create(const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const) const = 0; + + private: + Q_DISABLE_COPY(ExpressionCreator) + }; + + /** + * @short Abstract base class for all classes that identify Expressions + * based on some criteria. + * + * ExpressionIdentifier is one of the building block of Patternist's + * optimizer framework. An ExpressionIdentifier sub-class has + * the responsibility of determining whether a particular Expression + * is the one an OptimizationPass should apply for. + * + * This class and sub-classes are never used on their own, + * but in cooperation with OptimizationPass. + * + * @author Frans englich <fenglich@trolltech.com> + * @ingroup Patternist_expressions + */ + class ExpressionIdentifier : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer<ExpressionIdentifier> Ptr; + typedef QList<ExpressionIdentifier::Ptr> List; + + /** + * For some reason this constructor cannot be synthesized. + */ + inline ExpressionIdentifier() + { + } + + virtual ~ExpressionIdentifier(); + /** + * @param expr the Expression to be tested. This is guranteed + * to always be a non @c null, valid pointer. + * + * @returns @c true if @p expr matches as according to this ExpressionIdentifier, + * otherwise @c false. + */ + virtual bool matches(const Expression::Ptr &expr) const = 0; + + private: + Q_DISABLE_COPY(ExpressionIdentifier) + }; + + /** + * @short Describes how a particular optimization pass should be carried out. + * + * OptimizationPass is essentially a declaration, which describes + * how an optimization pass in the form of an AST rewrite should be done, + * by describing what that should be rewritten into what how. + * + * Each OptimizationPass is applied to a "start" Expression. The Expression + * that qualifies as a start Expression for the OptimizationPass in question is + * determined by startIdentifier; if its ExpressionIdentifier::matches() function + * returns @c true, the optimizer continues to apply this OptimizationPass. + * + * After a start Expression has been found, it is verified if the operands matches + * as well by applying the ExpressionIdentifiers in operandIdentifiers to the + * start Expression's operands. Similarly, if the operands matches what + * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass. + * + * At this stage, it has been concluded that the OptimizationPass validly applies, and + * what now remains is to carry out the actual rewrite. The Expression rewritten + * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator + * variable. + * + * How these components, startIdentifier, operandIdentifiers, sourceExpression, + * and resultCreator interacts with one another is described in more detail + * in the member documentation as well as the classes they are instances of. + * + * @author Frans englich <fenglich@trolltech.com> + * @ingroup Patternist_expressions + */ + class OptimizationPass : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer<OptimizationPass> Ptr; + typedef QList<OptimizationPass::Ptr> List; + + enum OperandsMatchMethod + { + /** + * All operands must match in the same order the ExpressionMarkers do. + */ + Sequential = 1, + + /** + * Matches if all operands are matched, regardless of their order. This is + * useful when an OptimizationPass is matching an Expression that has two operands + * and that both of them can appear on the left or right hand as long as it is those + * two. + * + * This comparison method only works when two operands + * needs to be matched. + */ + AnyOrder + }; + + /** + * An ExpressionMarker identifies an operand Expression relatively + * the start Expression by that each integer identifies a step + * in a descending AST walk. For example an ExpressionMarker with + * only one entry that is 0(zero), identifies the first operand of the + * start Expression. An ExpressionMarker containing 1, 2 in that order + * identifies the third operand of the second operand of the start Expression. + */ + typedef QList<qint8> ExpressionMarker; + + /** + * Creates an OptimizationPass and sets its public variables + * to the corresponding values passed in this constructor. + */ + OptimizationPass(const ExpressionIdentifier::Ptr &startID, + const ExpressionIdentifier::List &operandIDs, + const ExpressionMarker &sourceExpr, + const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(), + const OperandsMatchMethod matchMethod = Sequential); + + /** + * The ExpressionIdentifier that must the Expression this OptimizationPass concerns. + * + * If this variable is @c null, it means that the start Expression does + * not have to match any particular ExpressionIdentifier, but is fine as is. + * + * One might wonder what the purpose of this startIdentifier is, considering + * that what start Expression an OptimizationPass can at all apply to is + * naturally determined by what Expression::optimizationPasses() re-implementation that + * returns this OptimizationPass. The reason is that in some cases an OptimizationPass + * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison + * might depend on what operator that is in use. + * + * May be @c null or point to an ExpressionIdentifier. + */ + const ExpressionIdentifier::Ptr startIdentifier; + + /** + * In order for an OptimizationPass to apply, the start Expression's + * operands must be matched with this list of ExpressionIdentifier instances. + * The first ExpressionIdentifier is applied to the first operand, the second + * ExpressionIdentifier to the second operand, and so forth until all operands + * have been iterated. + * + * Entries in this list may be @c null, and those signals that the corresponding + * operand is not constrained. For example, if the third ExpressionIdentifier in + * the list is @c null, it signals that the third operand may be anykind of expression. + * + * May be empty or contain an arbitrary amount of objects or @c null pointers. + */ + const ExpressionIdentifier::List operandIdentifiers; + + /** + * Identifies the expression that should be part of the new expression + * that this OptimizationPass rewrites to. If this list is empty, it + * means that the result is not derived from the existing tree, and + * that resultCreator will exclusively be used for creating the result + * Expression. + * + * How the ExpressionMarker identifies an Expression is document in + * its documentation. + * + * May be empty. + */ + const ExpressionMarker sourceExpression; + + /** + * This is the ExpressionCreator that will be used to create the + * Expression which is the result. ExpressionCreator::create() + * will be passed as operands the Expression that sourceExpression + * specify, if any. + * + * If this variable is @c null, the result Expression will be the one + * sourceExpression identifies. + */ + const ExpressionCreator::Ptr resultCreator; + + const OperandsMatchMethod operandsMatchMethod; + private: + Q_DISABLE_COPY(OptimizationPass) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif |