1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 // This file is not part of the Qt API. It exists purely as an
47 // implementation detail. This header file may change from version to
48 // version without notice, or even be removed.
52 #ifndef Patternist_OptimizerFramework_H
53 #define Patternist_OptimizerFramework_H
55 #include <QSharedData>
57 #include <private/qexpression_p.h>
66 * @short A factory for creating Expression instances.
68 * ExpressionIdentifier is one of the building block of Patternist's
69 * optimizer framework. An ExpressionIdentifier sub-class has
70 * the responsibility of creating the Expression that should be
71 * the result of the optimization.
73 * This class and sub-classes are never used on their own,
74 * but in cooperation with OptimizationPass.
76 * @author Frans englich <frans.englich@nokia.com>
77 * @ingroup Patternist_expressions
79 class ExpressionCreator : public QSharedData
82 typedef QExplicitlySharedDataPointer<ExpressionCreator> Ptr;
85 * For some reason this constructor cannot be synthesized.
87 inline ExpressionCreator()
91 virtual ~ExpressionCreator();
93 * Creates an expression that has @p operands as operands.
95 * The Expression that is returned is guaranteed, by the caller,
96 * to get a treatment identical to if the expression was created
97 * in an ordinary compilation(via the parser, and so forth). That is,
98 * Expression::typeCheck() and Expression::compress() stages will be
99 * carried out on the returned expression.
101 * @returns an Expression::Ptr that never is non @c null, valid pointer
103 virtual Expression::Ptr create(const Expression::List &operands,
104 const StaticContext::Ptr &context,
105 const SourceLocationReflection *const) const = 0;
108 Q_DISABLE_COPY(ExpressionCreator)
112 * @short Abstract base class for all classes that identify Expressions
113 * based on some criteria.
115 * ExpressionIdentifier is one of the building block of Patternist's
116 * optimizer framework. An ExpressionIdentifier sub-class has
117 * the responsibility of determining whether a particular Expression
118 * is the one an OptimizationPass should apply for.
120 * This class and sub-classes are never used on their own,
121 * but in cooperation with OptimizationPass.
123 * @author Frans englich <frans.englich@nokia.com>
124 * @ingroup Patternist_expressions
126 class ExpressionIdentifier : public QSharedData
129 typedef QExplicitlySharedDataPointer<ExpressionIdentifier> Ptr;
130 typedef QList<ExpressionIdentifier::Ptr> List;
133 * For some reason this constructor cannot be synthesized.
135 inline ExpressionIdentifier()
139 virtual ~ExpressionIdentifier();
141 * @param expr the Expression to be tested. This is guranteed
142 * to always be a non @c null, valid pointer.
144 * @returns @c true if @p expr matches as according to this ExpressionIdentifier,
145 * otherwise @c false.
147 virtual bool matches(const Expression::Ptr &expr) const = 0;
150 Q_DISABLE_COPY(ExpressionIdentifier)
154 * @short Describes how a particular optimization pass should be carried out.
156 * OptimizationPass is essentially a declaration, which describes
157 * how an optimization pass in the form of an AST rewrite should be done,
158 * by describing what that should be rewritten into what how.
160 * Each OptimizationPass is applied to a "start" Expression. The Expression
161 * that qualifies as a start Expression for the OptimizationPass in question is
162 * determined by startIdentifier; if its ExpressionIdentifier::matches() function
163 * returns @c true, the optimizer continues to apply this OptimizationPass.
165 * After a start Expression has been found, it is verified if the operands matches
166 * as well by applying the ExpressionIdentifiers in operandIdentifiers to the
167 * start Expression's operands. Similarly, if the operands matches what
168 * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass.
170 * At this stage, it has been concluded that the OptimizationPass validly applies, and
171 * what now remains is to carry out the actual rewrite. The Expression rewritten
172 * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator
175 * How these components, startIdentifier, operandIdentifiers, sourceExpression,
176 * and resultCreator interacts with one another is described in more detail
177 * in the member documentation as well as the classes they are instances of.
179 * @author Frans englich <frans.englich@nokia.com>
180 * @ingroup Patternist_expressions
182 class OptimizationPass : public QSharedData
185 typedef QExplicitlySharedDataPointer<OptimizationPass> Ptr;
186 typedef QList<OptimizationPass::Ptr> List;
188 enum OperandsMatchMethod
191 * All operands must match in the same order the ExpressionMarkers do.
196 * Matches if all operands are matched, regardless of their order. This is
197 * useful when an OptimizationPass is matching an Expression that has two operands
198 * and that both of them can appear on the left or right hand as long as it is those
201 * This comparison method only works when two operands
202 * needs to be matched.
208 * An ExpressionMarker identifies an operand Expression relatively
209 * the start Expression by that each integer identifies a step
210 * in a descending AST walk. For example an ExpressionMarker with
211 * only one entry that is 0(zero), identifies the first operand of the
212 * start Expression. An ExpressionMarker containing 1, 2 in that order
213 * identifies the third operand of the second operand of the start Expression.
215 typedef QList<qint8> ExpressionMarker;
218 * Creates an OptimizationPass and sets its public variables
219 * to the corresponding values passed in this constructor.
221 OptimizationPass(const ExpressionIdentifier::Ptr &startID,
222 const ExpressionIdentifier::List &operandIDs,
223 const ExpressionMarker &sourceExpr,
224 const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(),
225 const OperandsMatchMethod matchMethod = Sequential);
228 * The ExpressionIdentifier that must the Expression this OptimizationPass concerns.
230 * If this variable is @c null, it means that the start Expression does
231 * not have to match any particular ExpressionIdentifier, but is fine as is.
233 * One might wonder what the purpose of this startIdentifier is, considering
234 * that what start Expression an OptimizationPass can at all apply to is
235 * naturally determined by what Expression::optimizationPasses() re-implementation that
236 * returns this OptimizationPass. The reason is that in some cases an OptimizationPass
237 * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison
238 * might depend on what operator that is in use.
240 * May be @c null or point to an ExpressionIdentifier.
242 const ExpressionIdentifier::Ptr startIdentifier;
245 * In order for an OptimizationPass to apply, the start Expression's
246 * operands must be matched with this list of ExpressionIdentifier instances.
247 * The first ExpressionIdentifier is applied to the first operand, the second
248 * ExpressionIdentifier to the second operand, and so forth until all operands
249 * have been iterated.
251 * Entries in this list may be @c null, and those signals that the corresponding
252 * operand is not constrained. For example, if the third ExpressionIdentifier in
253 * the list is @c null, it signals that the third operand may be anykind of expression.
255 * May be empty or contain an arbitrary amount of objects or @c null pointers.
257 const ExpressionIdentifier::List operandIdentifiers;
260 * Identifies the expression that should be part of the new expression
261 * that this OptimizationPass rewrites to. If this list is empty, it
262 * means that the result is not derived from the existing tree, and
263 * that resultCreator will exclusively be used for creating the result
266 * How the ExpressionMarker identifies an Expression is document in
271 const ExpressionMarker sourceExpression;
274 * This is the ExpressionCreator that will be used to create the
275 * Expression which is the result. ExpressionCreator::create()
276 * will be passed as operands the Expression that sourceExpression
279 * If this variable is @c null, the result Expression will be the one
280 * sourceExpression identifies.
282 const ExpressionCreator::Ptr resultCreator;
284 const OperandsMatchMethod operandsMatchMethod;
286 Q_DISABLE_COPY(OptimizationPass)