diff -r 000000000000 -r 1918ee327afb src/xmlpatterns/expr/qoptimizerframework_p.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xmlpatterns/expr/qoptimizerframework_p.h Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** 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_OptimizerFramework_H +#define Patternist_OptimizerFramework_H + +#include + +#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 + * @ingroup Patternist_expressions + */ + class ExpressionCreator : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer 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 + * @ingroup Patternist_expressions + */ + class ExpressionIdentifier : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList 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 + * @ingroup Patternist_expressions + */ + class OptimizationPass : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList 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 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